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