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  package org.apache.commons.io;
18  
19  import java.io.BufferedReader;
20  import java.io.ByteArrayInputStream;
21  import java.io.File;
22  import java.io.IOException;
23  import java.io.InputStream;
24  import java.io.InputStreamReader;
25  import java.io.OutputStream;
26  
27  import junit.framework.Test;
28  import junit.framework.TestSuite;
29  import junit.textui.TestRunner;
30  
31  import org.apache.commons.io.testtools.FileBasedTestCase;
32  
33  /**
34   * This is used to test FileSystemUtils.
35   *
36   * @version $Id: FileSystemUtilsTestCase.java 453889 2006-10-07 11:56:25Z scolebourne $
37   */
38  public class FileSystemUtilsTestCase extends FileBasedTestCase {
39  
40      public static void main(String[] args) {
41          TestRunner.run(suite());
42          
43  //        try {
44  //            System.out.println(FileSystemUtils.freeSpace("C:\\"));
45  //        } catch (IOException ex) {
46  //            ex.printStackTrace();
47  //        }
48      }
49  
50      public static Test suite() {
51          return new TestSuite(FileSystemUtilsTestCase.class);
52      }
53  
54      public FileSystemUtilsTestCase(String name) throws IOException {
55          super(name);
56      }
57  
58      protected void setUp() throws Exception {
59      }
60  
61      protected void tearDown() throws Exception {
62      }
63  
64      //-----------------------------------------------------------------------
65      public void testGetFreeSpace_String() throws Exception {
66          // test coverage, as we can't check value
67          if (File.separatorChar == '/') {
68              // have to figure out unix block size
69              String[] cmd = null;
70              String osName = System.getProperty("os.name");
71              if (osName.indexOf("hp-ux") >= 0 || osName.indexOf("aix") >= 0) {
72                  cmd = new String[] {"df", "-P", "/"};
73              } else {
74                  cmd = new String[] {"df", "/"};
75              }
76              Process proc = Runtime.getRuntime().exec(cmd);
77              boolean kilobyteBlock = true;
78              BufferedReader r = null;
79              try {
80                  r = new BufferedReader(new InputStreamReader(proc.getInputStream()));
81                  String line = r.readLine();
82                  if (line.toLowerCase().indexOf("512") >= 0) {
83                      kilobyteBlock = false;
84                  }
85              } finally {
86                  IOUtils.closeQuietly(r);
87              }
88              
89              // now perform the test
90              long free = FileSystemUtils.freeSpace("/");
91              long kb = FileSystemUtils.freeSpaceKb("/");
92              if (kilobyteBlock) {
93                  assertEquals((double) free, (double) kb, 256d);
94              } else {
95                  assertEquals((double) free / 2d, (double) kb, 256d);
96              }
97          } else {
98              long bytes = FileSystemUtils.freeSpace("");
99              long kb = FileSystemUtils.freeSpaceKb("");
100             assertEquals((double) bytes / 1024, (double) kb, 256d);
101         }
102     }
103 
104     //-----------------------------------------------------------------------
105     public void testGetFreeSpaceOS_String_NullPath() throws Exception {
106         FileSystemUtils fsu = new FileSystemUtils();
107         try {
108             fsu.freeSpaceOS(null, 1, false);
109             fail();
110         } catch (IllegalArgumentException ex) {}
111         try {
112             fsu.freeSpaceOS(null, 1, true);
113             fail();
114         } catch (IllegalArgumentException ex) {}
115     }
116 
117     public void testGetFreeSpaceOS_String_InitError() throws Exception {
118         FileSystemUtils fsu = new FileSystemUtils();
119         try {
120             fsu.freeSpaceOS("", -1, false);
121             fail();
122         } catch (IllegalStateException ex) {}
123         try {
124             fsu.freeSpaceOS("", -1, true);
125             fail();
126         } catch (IllegalStateException ex) {}
127     }
128 
129     public void testGetFreeSpaceOS_String_Other() throws Exception {
130         FileSystemUtils fsu = new FileSystemUtils();
131         try {
132             fsu.freeSpaceOS("", 0, false);
133             fail();
134         } catch (IllegalStateException ex) {}
135         try {
136             fsu.freeSpaceOS("", 0, true);
137             fail();
138         } catch (IllegalStateException ex) {}
139     }
140 
141     public void testGetFreeSpaceOS_String_Windows() throws Exception {
142         FileSystemUtils fsu = new FileSystemUtils() {
143             protected long freeSpaceWindows(String path) throws IOException {
144                 return 12345L;
145             }
146         };
147         assertEquals(12345L, fsu.freeSpaceOS("", 1, false));
148         assertEquals(12345L / 1024, fsu.freeSpaceOS("", 1, true));
149     }
150 
151     public void testGetFreeSpaceOS_String_Unix() throws Exception {
152         FileSystemUtils fsu = new FileSystemUtils() {
153             protected long freeSpaceUnix(String path, boolean kb, boolean posix) throws IOException {
154                 return (kb ? 12345L : 54321);
155             }
156         };
157         assertEquals(54321L, fsu.freeSpaceOS("", 2, false));
158         assertEquals(12345L, fsu.freeSpaceOS("", 2, true));
159     }
160 
161     //-----------------------------------------------------------------------
162     public void testGetFreeSpaceWindows_String_ParseCommaFormatBytes() throws Exception {
163         // this is the format of response when calling dir /c
164         // we have now switched to dir /-c, so we should never get this
165         String lines =
166             " Volume in drive C is HDD\n" +
167             " Volume Serial Number is XXXX-YYYY\n" +
168             "\n" +
169             " Directory of C:\\Documents and Settings\\Xxxx\n" +
170             "\n" +
171             "19/08/2005  22:43    <DIR>          .\n" +
172             "19/08/2005  22:43    <DIR>          ..\n" +
173             "11/08/2005  01:07                81 build.properties\n" +
174             "17/08/2005  21:44    <DIR>          Desktop\n" +
175             "               7 File(s)        180,260 bytes\n" +
176             "              10 Dir(s)  41,411,551,232 bytes free";
177         FileSystemUtils fsu = new MockFileSystemUtils(0, lines);
178         assertEquals(41411551232L, fsu.freeSpaceWindows(""));
179     }
180 
181     //-----------------------------------------------------------------------
182     public void testGetFreeSpaceWindows_String_EmptyPath() throws Exception {
183         String lines =
184             " Volume in drive C is HDD\n" +
185             " Volume Serial Number is XXXX-YYYY\n" +
186             "\n" +
187             " Directory of C:\\Documents and Settings\\Xxxx\n" +
188             "\n" +
189             "19/08/2005  22:43    <DIR>          .\n" +
190             "19/08/2005  22:43    <DIR>          ..\n" +
191             "11/08/2005  01:07                81 build.properties\n" +
192             "17/08/2005  21:44    <DIR>          Desktop\n" +
193             "               7 File(s)         180260 bytes\n" +
194             "              10 Dir(s)     41411551232 bytes free";
195         FileSystemUtils fsu = new MockFileSystemUtils(0, lines, "dir /-c ");
196         assertEquals(41411551232L, fsu.freeSpaceWindows(""));
197     }
198 
199     public void testGetFreeSpaceWindows_String_NormalResponse() throws Exception {
200         String lines =
201             " Volume in drive C is HDD\n" +
202             " Volume Serial Number is XXXX-YYYY\n" +
203             "\n" +
204             " Directory of C:\\Documents and Settings\\Xxxx\n" +
205             "\n" +
206             "19/08/2005  22:43    <DIR>          .\n" +
207             "19/08/2005  22:43    <DIR>          ..\n" +
208             "11/08/2005  01:07                81 build.properties\n" +
209             "17/08/2005  21:44    <DIR>          Desktop\n" +
210             "               7 File(s)         180260 bytes\n" +
211             "              10 Dir(s)     41411551232 bytes free";
212         FileSystemUtils fsu = new MockFileSystemUtils(0, lines, "dir /-c C:");
213         assertEquals(41411551232L, fsu.freeSpaceWindows("C:"));
214     }
215 
216     public void testGetFreeSpaceWindows_String_StripDrive() throws Exception {
217         String lines =
218             " Volume in drive C is HDD\n" +
219             " Volume Serial Number is XXXX-YYYY\n" +
220             "\n" +
221             " Directory of C:\\Documents and Settings\\Xxxx\n" +
222             "\n" +
223             "19/08/2005  22:43    <DIR>          .\n" +
224             "19/08/2005  22:43    <DIR>          ..\n" +
225             "11/08/2005  01:07                81 build.properties\n" +
226             "17/08/2005  21:44    <DIR>          Desktop\n" +
227             "               7 File(s)         180260 bytes\n" +
228             "              10 Dir(s)     41411551232 bytes free";
229         FileSystemUtils fsu = new MockFileSystemUtils(0, lines, "dir /-c C:");
230         assertEquals(41411551232L, fsu.freeSpaceWindows("C:\\somedir"));
231     }
232 
233     public void testGetFreeSpaceWindows_String_EmptyResponse() throws Exception {
234         String lines = "";
235         FileSystemUtils fsu = new MockFileSystemUtils(0, lines);
236         try {
237             fsu.freeSpaceWindows("C:");
238             fail();
239         } catch (IOException ex) {}
240     }
241 
242     public void testGetFreeSpaceWindows_String_EmptyMultiLineResponse() throws Exception {
243         String lines = "\n\n";
244         FileSystemUtils fsu = new MockFileSystemUtils(0, lines);
245         try {
246             fsu.freeSpaceWindows("C:");
247             fail();
248         } catch (IOException ex) {}
249     }
250 
251     public void testGetFreeSpaceWindows_String_InvalidTextResponse() throws Exception {
252         String lines = "BlueScreenOfDeath";
253         FileSystemUtils fsu = new MockFileSystemUtils(0, lines);
254         try {
255             fsu.freeSpaceWindows("C:");
256             fail();
257         } catch (IOException ex) {}
258     }
259 
260     public void testGetFreeSpaceWindows_String_NoSuchDirectoryResponse() throws Exception {
261         String lines =
262             " Volume in drive C is HDD\n" +
263             " Volume Serial Number is XXXX-YYYY\n" +
264             "\n" +
265             " Directory of C:\\Documents and Settings\\empty" +
266             "\n";
267         FileSystemUtils fsu = new MockFileSystemUtils(1, lines);
268         try {
269             fsu.freeSpaceWindows("C:");
270             fail();
271         } catch (IOException ex) {}
272     }
273 
274     //-----------------------------------------------------------------------
275     public void testGetFreeSpaceUnix_String_EmptyPath() throws Exception {
276         String lines =
277             "Filesystem           1K-blocks      Used Available Use% Mounted on\n" +
278             "xxx:/home/users/s     14428928  12956424   1472504  90% /home/users/s";
279         FileSystemUtils fsu = new MockFileSystemUtils(0, lines);
280         try {
281             fsu.freeSpaceUnix("", false, false);
282             fail();
283         } catch (IllegalArgumentException ex) {}
284         try {
285             fsu.freeSpaceUnix("", true, false);
286             fail();
287         } catch (IllegalArgumentException ex) {}
288         try {
289             fsu.freeSpaceUnix("", true, true);
290             fail();
291         } catch (IllegalArgumentException ex) {}
292         try {
293             fsu.freeSpaceUnix("", false, true);
294             fail();
295         } catch (IllegalArgumentException ex) {}
296         
297     }
298 
299     public void testGetFreeSpaceUnix_String_NormalResponseLinux() throws Exception {
300         // from Sourceforge 'GNU bash, version 2.05b.0(1)-release (i386-redhat-linux-gnu)'
301         String lines =
302             "Filesystem           1K-blocks      Used Available Use% Mounted on\n" +
303             "/dev/xxx                497944    308528    189416  62% /";
304         FileSystemUtils fsu = new MockFileSystemUtils(0, lines);
305         assertEquals(189416L, fsu.freeSpaceUnix("/", false, false));
306     }
307 
308     public void testGetFreeSpaceUnix_String_NormalResponseFreeBSD() throws Exception {
309         // from Apache 'FreeBSD 6.1-RELEASE (SMP-turbo)'
310         String lines =
311             "Filesystem  1K-blocks      Used    Avail Capacity  Mounted on\n" +
312             "/dev/xxxxxx    128990    102902    15770    87%    /";
313         FileSystemUtils fsu = new MockFileSystemUtils(0, lines);
314         assertEquals(15770L, fsu.freeSpaceUnix("/", false, false));
315     }
316 
317     //-----------------------------------------------------------------------
318     public void testGetFreeSpaceUnix_String_NormalResponseKbLinux() throws Exception {
319         // from Sourceforge 'GNU bash, version 2.05b.0(1)-release (i386-redhat-linux-gnu)'
320         // df, df -k and df -kP are all identical
321         String lines =
322             "Filesystem           1K-blocks      Used Available Use% Mounted on\n" +
323             "/dev/xxx                497944    308528    189416  62% /";
324         FileSystemUtils fsu = new MockFileSystemUtils(0, lines);
325         assertEquals(189416L, fsu.freeSpaceUnix("/", true, false));
326     }
327 
328     public void testGetFreeSpaceUnix_String_NormalResponseKbFreeBSD() throws Exception {
329         // from Apache 'FreeBSD 6.1-RELEASE (SMP-turbo)'
330         // df and df -k are identical, but df -kP uses 512 blocks (not relevant as not used)
331         String lines =
332             "Filesystem  1K-blocks      Used    Avail Capacity  Mounted on\n" +
333             "/dev/xxxxxx    128990    102902    15770    87%    /";
334         FileSystemUtils fsu = new MockFileSystemUtils(0, lines);
335         assertEquals(15770L, fsu.freeSpaceUnix("/", true, false));
336     }
337 
338     public void testGetFreeSpaceUnix_String_NormalResponseKbSolaris() throws Exception {
339         // from IO-91 - ' SunOS et 5.10 Generic_118822-25 sun4u sparc SUNW,Ultra-4'
340         // non-kb response does not contain free space - see IO-91
341         String lines =
342             "Filesystem            kbytes    used   avail capacity  Mounted on\n" +
343             "/dev/dsk/x0x0x0x0    1350955  815754  481163    63%";
344         FileSystemUtils fsu = new MockFileSystemUtils(0, lines);
345         assertEquals(481163L, fsu.freeSpaceUnix("/dev/dsk/x0x0x0x0", true, false));
346     }
347 
348     public void testGetFreeSpaceUnix_String_LongResponse() throws Exception {
349         String lines =
350             "Filesystem           1K-blocks      Used Available Use% Mounted on\n" +
351             "xxx-yyyyyyy-zzz:/home/users/s\n" +
352             "                      14428928  12956424   1472504  90% /home/users/s";
353         FileSystemUtils fsu = new MockFileSystemUtils(0, lines);
354         assertEquals(1472504L, fsu.freeSpaceUnix("/home/users/s", false, false));
355     }
356 
357     public void testGetFreeSpaceUnix_String_LongResponseKb() throws Exception {
358         String lines =
359             "Filesystem           1K-blocks      Used Available Use% Mounted on\n" +
360             "xxx-yyyyyyy-zzz:/home/users/s\n" +
361             "                      14428928  12956424   1472504  90% /home/users/s";
362         FileSystemUtils fsu = new MockFileSystemUtils(0, lines);
363         assertEquals(1472504L, fsu.freeSpaceUnix("/home/users/s", true, false));
364     }
365 
366     public void testGetFreeSpaceUnix_String_EmptyResponse() throws Exception {
367         String lines = "";
368         FileSystemUtils fsu = new MockFileSystemUtils(0, lines);
369         try {
370             fsu.freeSpaceUnix("/home/users/s", false, false);
371             fail();
372         } catch (IOException ex) {}
373         try {
374             fsu.freeSpaceUnix("/home/users/s", true, false);
375             fail();
376         } catch (IOException ex) {}
377         try {
378             fsu.freeSpaceUnix("/home/users/s", false, true);
379             fail();
380         } catch (IOException ex) {}
381         try {
382             fsu.freeSpaceUnix("/home/users/s", true, true);
383             fail();
384         } catch (IOException ex) {}
385     }
386 
387     public void testGetFreeSpaceUnix_String_InvalidResponse1() throws Exception {
388         String lines =
389             "Filesystem           1K-blocks      Used Available Use% Mounted on\n" +
390             "                      14428928  12956424       100";
391         FileSystemUtils fsu = new MockFileSystemUtils(0, lines);
392         try {
393             fsu.freeSpaceUnix("/home/users/s", false, false);
394             fail();
395         } catch (IOException ex) {}
396         try {
397             fsu.freeSpaceUnix("/home/users/s", true, false);
398             fail();
399         } catch (IOException ex) {}
400         try {
401             fsu.freeSpaceUnix("/home/users/s", false, true);
402             fail();
403         } catch (IOException ex) {}
404         try {
405             fsu.freeSpaceUnix("/home/users/s", true, true);
406             fail();
407         } catch (IOException ex) {}
408     }
409 
410     public void testGetFreeSpaceUnix_String_InvalidResponse2() throws Exception {
411         String lines =
412             "Filesystem           1K-blocks      Used Available Use% Mounted on\n" +
413             "xxx:/home/users/s     14428928  12956424   nnnnnnn  90% /home/users/s";
414         FileSystemUtils fsu = new MockFileSystemUtils(0, lines);
415         try {
416             fsu.freeSpaceUnix("/home/users/s", false, false);
417             fail();
418         } catch (IOException ex) {}
419         try {
420             fsu.freeSpaceUnix("/home/users/s", true, false);
421             fail();
422         } catch (IOException ex) {}
423         try {
424             fsu.freeSpaceUnix("/home/users/s", false, true);
425             fail();
426         } catch (IOException ex) {}
427         try {
428             fsu.freeSpaceUnix("/home/users/s", true, true);
429             fail();
430         } catch (IOException ex) {}
431     }
432 
433     public void testGetFreeSpaceUnix_String_InvalidResponse3() throws Exception {
434         String lines =
435             "Filesystem           1K-blocks      Used Available Use% Mounted on\n" +
436             "xxx:/home/users/s     14428928  12956424        -1  90% /home/users/s";
437         FileSystemUtils fsu = new MockFileSystemUtils(0, lines);
438         try {
439             fsu.freeSpaceUnix("/home/users/s", false, false);
440             fail();
441         } catch (IOException ex) {}
442         try {
443             fsu.freeSpaceUnix("/home/users/s", true, false);
444             fail();
445         } catch (IOException ex) {}
446         try {
447             fsu.freeSpaceUnix("/home/users/s", false, true);
448             fail();
449         } catch (IOException ex) {}
450         try {
451             fsu.freeSpaceUnix("/home/users/s", true, true);
452             fail();
453         } catch (IOException ex) {}
454     }
455 
456     public void testGetFreeSpaceUnix_String_InvalidResponse4() throws Exception {
457         String lines =
458             "Filesystem           1K-blocks      Used Available Use% Mounted on\n" +
459             "xxx-yyyyyyy-zzz:/home/users/s";
460         FileSystemUtils fsu = new MockFileSystemUtils(0, lines);
461         try {
462             fsu.freeSpaceUnix("/home/users/s", false, false);
463             fail();
464         } catch (IOException ex) {}
465         try {
466             fsu.freeSpaceUnix("/home/users/s", true, false);
467             fail();
468         } catch (IOException ex) {}
469         try {
470             fsu.freeSpaceUnix("/home/users/s", false, true);
471             fail();
472         } catch (IOException ex) {}
473         try {
474             fsu.freeSpaceUnix("/home/users/s", true, true);
475             fail();
476         } catch (IOException ex) {}
477     }
478 
479     //-----------------------------------------------------------------------
480     static class MockFileSystemUtils extends FileSystemUtils {
481         private final int exitCode;
482         private final byte[] bytes;
483         private final String cmd;
484         public MockFileSystemUtils(int exitCode, String lines) {
485             this(exitCode, lines, null);
486         }
487         public MockFileSystemUtils(int exitCode, String lines, String cmd) {
488             this.exitCode = exitCode;
489             this.bytes = lines.getBytes();
490             this.cmd = cmd;
491         }
492         Process openProcess(String[] params) {
493             if (cmd != null) {
494                 assertEquals(cmd, params[params.length - 1]);
495             }
496             return new Process() {
497                 public InputStream getErrorStream() {
498                     return null;
499                 }
500                 public InputStream getInputStream() {
501                     return new ByteArrayInputStream(bytes);
502                 }
503                 public OutputStream getOutputStream() {
504                     return null;
505                 }
506                 public int waitFor() throws InterruptedException {
507                     return exitCode;
508                 }
509                 public int exitValue() {
510                     return exitCode;
511                 }
512                 public void destroy() {
513                 }
514             };
515         }
516     }
517 
518 }