1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18package org.apache.harmony.luni.tests.java.io;
19
20import java.io.BufferedReader;
21import java.io.File;
22import java.io.IOException;
23import java.io.InputStream;
24import java.io.InputStreamReader;
25
26import junit.framework.TestCase;
27
28/**
29 * Please note that this case can only be passed on Linux due to some file
30 * system dependent reason.
31 */
32public class UnixFileTest extends TestCase {
33    private boolean root = false;
34
35    private File testFile;
36
37    private File testDir;
38
39    private static final int TOTAL_SPACE_NUM = 0;
40
41    private static final int FREE_SPACE_NUM = 1;
42
43    private static final int USABLE_SPACE_NUM = 2;
44
45    private static class ConsoleResulter extends Thread {
46        Process proc;
47
48        InputStream is;
49
50        String resStr;
51
52        ConsoleResulter(Process p, InputStream in) {
53            proc = p;
54            is = in;
55        }
56
57        @Override
58        public void run() {
59            StringBuffer result = new StringBuffer();
60            synchronized (result) {
61                try {
62                    BufferedReader br = new BufferedReader(
63                            new InputStreamReader(is));
64                    String line;
65                    while ((line = br.readLine()) != null) {
66                        result.append(line);
67                    }
68                    if (result.length() != 0) {
69                        resStr = result.toString();
70                    }
71
72                    br.close();
73                } catch (IOException ioe) {
74                    result = null;
75                }
76                synchronized (proc) {
77                    proc.notifyAll();
78                }
79            }
80        }
81    }
82
83    private static long getLinuxSpace(int index, File file) throws Exception {
84        long[] result = new long[3];
85        String par = file.getAbsolutePath();
86        String osName = System.getProperty("os.name");
87        // in case the test case will run under other OS.
88        if (osName.toLowerCase().indexOf("linux") != -1) {
89            String[] cmd = new String[2];
90            cmd[0] = "df";
91            cmd[1] = par; // get the total space of file
92            Runtime rt = Runtime.getRuntime();
93
94            Process proc = rt.exec(cmd);
95            // get output from the command
96            ConsoleResulter outputResult = new ConsoleResulter(proc, proc
97                    .getInputStream());
98
99            synchronized (proc) {
100                outputResult.start();
101                proc.wait();
102            }
103            // If there is no error, obtain the result
104            if (outputResult.resStr != null) {
105                // exit the subprocess safely
106                proc.waitFor();
107
108                // filter unnecessary information
109                String[] txtResult = outputResult.resStr
110                        .split("\\D|\\p{javaLowerCase}|\\p{javaUpperCase}");
111                for (int i = 0, j = 0; i < txtResult.length; i++) {
112                    if (txtResult[i].length() > 3) {
113                        result[j++] = Long.parseLong(txtResult[i]) * 1024L;
114                    }
115                }
116            }
117        }
118
119        // calculate free spaces according to df command
120        result[1] = result[0] - result[1];
121        return result[index];
122    }
123
124    /**
125     * @tests java.io.File#canExecute()
126     * @since 1.6
127     */
128    public void test_canExecute() {
129        assertFalse(testFile.canExecute());
130        assertTrue(testFile.setExecutable(true, false));
131        assertTrue(testFile.canExecute());
132        assertTrue(testFile.setExecutable(true, true));
133        assertTrue(testFile.canExecute());
134
135        assertTrue(testFile.setExecutable(false, false));
136        assertFalse(testFile.canExecute());
137        assertTrue(testFile.setExecutable(false, true));
138        assertFalse(testFile.canExecute());
139
140        assertTrue(testFile.setExecutable(true, false));
141        assertTrue(testFile.canExecute());
142
143        // tests directory
144        assertTrue(testDir.canExecute());
145        assertTrue(testDir.setExecutable(false, true));
146        if (root) {
147            assertTrue(testDir.canExecute());
148        } else {
149            assertFalse(testDir.canExecute());
150        }
151        assertTrue(testDir.setExecutable(true, false));
152        assertTrue(testDir.canExecute());
153    }
154
155    /**
156     * @tests java.io.File#getFreeSpace()
157     * @since 1.6
158     */
159    public void test_getFreeSpace() throws Exception {
160        long fileSpace = getLinuxSpace(FREE_SPACE_NUM, testFile);
161        long dirSpace = getLinuxSpace(FREE_SPACE_NUM, testDir);
162        // in case we cannot fetch the value from command line
163        if (fileSpace > 0) {
164            assertEquals(fileSpace, testFile.getFreeSpace());
165        }
166
167        if (dirSpace > 0) {
168            assertEquals(dirSpace, testDir.getFreeSpace());
169        }
170    }
171
172    /**
173     * @tests java.io.File#getTotalSpace()
174     * @since 1.6
175     */
176    public void test_getTotalSpace() throws Exception {
177        long fileSpace = getLinuxSpace(TOTAL_SPACE_NUM, testFile);
178        long dirSpace = getLinuxSpace(TOTAL_SPACE_NUM, testDir);
179        if (fileSpace > 0) {
180            assertEquals(fileSpace, testFile.getTotalSpace());
181        }
182        if (dirSpace > 0) {
183            assertEquals(dirSpace, testDir.getTotalSpace());
184        }
185    }
186
187    /**
188     * @tests java.io.File#getUsableSpace()
189     * @since 1.6
190     */
191    public void test_getUsableSpace() throws Exception {
192        long fileSpace = getLinuxSpace(USABLE_SPACE_NUM, testFile);
193        long dirSpace = getLinuxSpace(USABLE_SPACE_NUM, testDir);
194        if (fileSpace > 0) {
195            assertEquals(fileSpace, testFile.getUsableSpace());
196        }
197        if (dirSpace > 0) {
198            assertEquals(dirSpace, testDir.getUsableSpace());
199        }
200    }
201
202    /**
203     * @tests java.io.File#setExecutable(boolean, boolean)
204     * @since 1.6
205     */
206    public void test_setExecutableZZ() {
207        // setExecutable(true, true/false)
208        assertFalse(testFile.canExecute());
209        assertTrue(testFile.setExecutable(true, false));
210        assertTrue(testFile.canExecute());
211        assertTrue(testFile.setExecutable(true, true));
212        assertTrue(testFile.canExecute());
213
214        // setExecutable(false, true/false)
215        assertTrue(testFile.setExecutable(false, true));
216        if (root) {
217            assertTrue(testFile.canExecute());
218        } else {
219            assertFalse(testFile.canExecute());
220        }
221        assertTrue(testFile.setExecutable(false, false));
222        assertFalse(testFile.canExecute());
223
224        // tests directory
225        assertTrue(testDir.canExecute());
226        assertTrue(testDir.setExecutable(false, true));
227        if (root) {
228            assertTrue(testDir.canExecute());
229        } else {
230            assertFalse(testDir.canExecute());
231        }
232        assertTrue(testDir.setExecutable(false, false));
233        if (root) {
234            assertTrue(testDir.canExecute());
235        } else {
236            assertFalse(testDir.canExecute());
237        }
238
239        assertTrue(testDir.setExecutable(true, true));
240        assertTrue(testDir.canExecute());
241        assertTrue(testDir.setExecutable(true, false));
242        assertTrue(testDir.canExecute());
243    }
244
245    /**
246     * @tests java.io.File#setExecutable(boolean)
247     * @since 1.6
248     */
249    public void test_setExecutableZ() {
250        // So far this method only deals with the situation that the user is the
251        // owner of the file
252        assertTrue(testFile.setExecutable(true));
253        assertTrue(testFile.canExecute());
254        assertTrue(testFile.setExecutable(false));
255        assertFalse(testFile.canExecute());
256        assertTrue(testFile.setExecutable(true));
257
258        // tests directory
259        assertTrue(testDir.canExecute());
260        assertTrue(testDir.setExecutable(false));
261        if (root) {
262            assertTrue(testDir.canExecute());
263        } else {
264            assertFalse(testDir.canExecute());
265        }
266        assertTrue(testDir.setExecutable(true));
267        assertTrue(testDir.canExecute());
268    }
269
270    /**
271     * @tests java.io.File#setReadable(boolean, boolean)
272     * @since 1.6
273     */
274    public void test_setReadableZZ() throws Exception {
275        // setReadable(false, false/true) succeeds on Linux
276        // However, canRead() always returns true when the user is 'root'.
277        assertTrue(testFile.canRead());
278        assertTrue(testFile.setReadable(false, false));
279        if (root) {
280            assertTrue(testFile.canRead());
281        } else {
282            assertFalse(testFile.canRead());
283        }
284        assertTrue(testFile.setReadable(false, true));
285        if (root) {
286            assertTrue(testFile.canRead());
287        } else {
288            assertFalse(testFile.canRead());
289        }
290
291        // tests directory, setReadable(false, true/false)
292        assertTrue(testDir.canRead());
293        assertTrue(testDir.setReadable(false, true));
294        if (root) {
295            assertTrue(testDir.canRead());
296        } else {
297            assertFalse(testDir.canRead());
298        }
299        assertTrue(testDir.setReadable(false, false));
300        if (root) {
301            assertTrue(testDir.canRead());
302        } else {
303            assertFalse(testDir.canRead());
304        }
305
306        // setReadable(true, false/true) and set them in turn
307        assertTrue(testFile.setReadable(true, false));
308        assertTrue(testFile.canRead());
309        assertTrue(testFile.setReadable(false, true));
310        if (root) {
311            assertTrue(testFile.canRead());
312        } else {
313            assertFalse(testFile.canRead());
314        }
315        assertTrue(testFile.setReadable(true, true));
316        assertTrue(testFile.canRead());
317        assertTrue(testFile.setReadable(false, true));
318        if (root) {
319            assertTrue(testFile.canRead());
320        } else {
321            assertFalse(testFile.canRead());
322        }
323
324        // tests directory, setReadable(true, true/false)
325        assertTrue(testDir.setReadable(true, false));
326        assertTrue(testDir.canRead());
327        assertTrue(testDir.setReadable(true, true));
328        assertTrue(testDir.canRead());
329    }
330
331    /**
332     * @tests java.io.File#setReadable(boolean)
333     * @since 1.6
334     */
335    public void test_setReadableZ() {
336        // So far this method only deals with the situation that the user is the
337        // owner of the file. setReadable(false) succeeds on Linux
338        // However, canRead() always returns true when the user is 'root'.
339        assertTrue(testFile.canRead());
340        assertTrue(testFile.setReadable(false));
341        if (root) {
342            assertTrue(testFile.canRead());
343        } else {
344            assertFalse(testFile.canRead());
345        }
346        assertTrue(testFile.setReadable(true));
347        assertTrue(testFile.canRead());
348
349        assertTrue(testDir.canRead());
350        assertTrue(testDir.setReadable(false));
351        if (root) {
352            assertTrue(testDir.canRead());
353        } else {
354            assertFalse(testDir.canRead());
355        }
356    }
357
358    @Override
359    protected void setUp() throws Exception {
360        super.setUp();
361        testFile = File.createTempFile("testfile", null);
362        testDir = new File(System.getProperty("java.io.tmpdir") + "/temp");
363        if (!testDir.exists()) {
364            testDir.mkdir();
365        }
366        root = System.getProperty("user.name").equals("root");
367    }
368
369    @Override
370    protected void tearDown() throws Exception {
371        testFile.delete();
372        testDir.delete();
373        testFile = null;
374        testDir = null;
375        root = false;
376        super.tearDown();
377    }
378
379    public void test_getCanonicalPath() throws IOException,
380            InterruptedException {
381        File tmpFolder1 = new File("folder1");
382        tmpFolder1.mkdirs();
383        tmpFolder1.deleteOnExit();
384
385        File tmpFolder2 = new File(tmpFolder1.toString() + "/folder2");
386        tmpFolder2.mkdirs();
387        tmpFolder2.deleteOnExit();
388
389        File tmpFolder3 = new File(tmpFolder2.toString() + "/folder3");
390        tmpFolder3.mkdirs();
391        tmpFolder3.deleteOnExit();
392
393        File tmpFolder4 = new File(tmpFolder3.toString() + "/folder4");
394        tmpFolder4.mkdirs();
395        tmpFolder4.deleteOnExit();
396
397        // make a link to folder1/folder2
398        Process ln = Runtime.getRuntime().exec("ln -s folder1/folder2 folder2");
399        ln.waitFor();
400        File linkFile = new File("folder2");
401        linkFile.deleteOnExit();
402
403        File file = new File("folder2");
404        assertEquals(tmpFolder2.getCanonicalPath(), file.getCanonicalPath());
405
406        file = new File("folder1/folder2");
407        assertEquals(tmpFolder2.getCanonicalPath(), file.getCanonicalPath());
408
409        file = new File("folder2/folder3");
410        assertEquals(tmpFolder3.getCanonicalPath(), file.getCanonicalPath());
411
412        file = new File("folder2/folder3/folder4");
413        assertEquals(tmpFolder4.getCanonicalPath(), file.getCanonicalPath());
414
415        file = new File("folder1/folder2/folder3");
416        assertEquals(tmpFolder3.getCanonicalPath(), file.getCanonicalPath());
417
418        file = new File("folder1/folder2/folder3/folder4");
419        assertEquals(tmpFolder4.getCanonicalPath(), file.getCanonicalPath());
420    }
421}
422