1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License
15  */
16 
17 package libcore.java.nio.file;
18 
19 import org.junit.rules.TestRule;
20 import org.junit.runner.Description;
21 import org.junit.runners.model.Statement;
22 
23 import java.io.BufferedWriter;
24 import java.io.File;
25 import java.io.FileWriter;
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.io.OutputStream;
29 import java.nio.file.CopyOption;
30 import java.nio.file.DirectoryStream;
31 import java.nio.file.Files;
32 import java.nio.file.LinkOption;
33 import java.nio.file.OpenOption;
34 import java.nio.file.Path;
35 import java.nio.file.Paths;
36 import java.nio.file.attribute.BasicFileAttributes;
37 
38 class FilesSetup implements TestRule {
39 
40     final static String DATA_FILE = "dataFile";
41 
42     final static String NON_EXISTENT_FILE = "nonExistentFile";
43 
44     final static String TEST_FILE_DATA = "hello";
45 
46     final static String TEST_FILE_DATA_2 = "test";
47 
48     /**
49      *  Data that includes characters code above the US-ASCII range and will be more obviously
50      *  corrupted if encoded / decoded incorrectly than
51      *  {@link #TEST_FILE_DATA} / {@link #TEST_FILE_DATA_2}.
52      */
53     final static String UTF_16_DATA = "परीक्षण";
54 
55     private String testDir;
56 
57     private Path dataFilePath;
58 
59     private Path testPath;
60 
61     private Path testDirPath;
62 
63     private boolean filesInitialized = false;
64 
setUp()65     void setUp() throws Exception {
66         initializeFiles();
67     }
68 
tearDown()69     void tearDown() throws Exception {
70         filesInitialized = false;
71         clearAll();
72     }
73 
initializeFiles()74     private void initializeFiles() throws IOException {
75         testDirPath = Files.createTempDirectory("testDir");
76         testDir = testDirPath.toString();
77         dataFilePath = Paths.get(testDir, DATA_FILE);
78         testPath = Paths.get(testDir, NON_EXISTENT_FILE);
79         File testInputFile = new File(testDir, DATA_FILE);
80         if (!testInputFile.exists()) {
81             testInputFile.createNewFile();
82         }
83         FileWriter fw = new FileWriter(testInputFile.getAbsoluteFile());
84         BufferedWriter bw = new BufferedWriter(fw);
85         bw.write(TEST_FILE_DATA);
86         bw.close();
87         filesInitialized = true;
88     }
89 
getTestPath()90     Path getTestPath() {
91         checkState();
92         return testPath;
93     }
94 
getDataFilePath()95     Path getDataFilePath() {
96         checkState();
97         return dataFilePath;
98     }
99 
getTestDirPath()100     Path getTestDirPath() {
101         checkState();
102         return testDirPath;
103     }
104 
getTestDir()105     String getTestDir() {
106         checkState();
107         return testDir;
108     }
109 
checkState()110     private void checkState() {
111         if (!filesInitialized) {
112             throw new IllegalStateException("Files are not setup.");
113         }
114     }
115 
clearAll()116     void clearAll() throws IOException {
117         Path root = Paths.get(testDir);
118         delete(root);
119     }
120 
reset()121     void reset() throws IOException {
122         clearAll();
123         initializeFiles();
124     }
125 
delete(Path path)126     private static void delete(Path path) throws IOException {
127         if (Files.isDirectory(path)) {
128             DirectoryStream<Path> dirStream = Files.newDirectoryStream(path);
129             dirStream.forEach(
130                     p -> {
131                         try {
132                             delete(p);
133                         } catch (IOException e) {
134                             throw new RuntimeException(e);
135                         }
136                     }
137             );
138             dirStream.close();
139         }
140         try {
141             Files.deleteIfExists(path);
142         } catch (Exception e) {
143             // Do nothing
144         }
145     }
146 
writeToFile(Path file, String data, OpenOption... option)147     static void writeToFile(Path file, String data, OpenOption... option) throws IOException {
148         OutputStream os = Files.newOutputStream(file, option);
149         os.write(data.getBytes());
150         os.close();
151     }
152 
readFromFile(Path file)153     static String readFromFile(Path file) throws IOException {
154         InputStream is = Files.newInputStream(file);
155         return readFromInputStream(is);
156     }
157 
readFromInputStream(InputStream is)158     static String readFromInputStream(InputStream is) throws IOException {
159         byte[] input = new byte[10000];
160         is.read(input);
161         return new String(input, "UTF-8").trim();
162     }
163 
execCmdAndWaitForTermination(String... cmdList)164     static Process execCmdAndWaitForTermination(String... cmdList)
165             throws InterruptedException, IOException {
166         Process process = Runtime.getRuntime().exec(cmdList);
167         // Wait for the process to terminate.
168         process.waitFor();
169         return process;
170     }
171 
172     @Override
apply(Statement statement, Description description)173     public Statement apply(Statement statement, Description description) {
174         return new Statement() {
175             @Override
176             public void evaluate() throws Throwable {
177                 try {
178                     setUp();
179                     statement.evaluate();
180                 } finally {
181                     tearDown();
182                 }
183             }
184         };
185     }
186 
187     Path getPathInTestDir(String path) {
188         return Paths.get(getTestDir(), path);
189     }
190 
191     /**
192      * Non Standard CopyOptions.
193      */
194     enum NonStandardOption implements CopyOption, OpenOption {
195         OPTION1,
196     }
197 
198 }
199