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.vfs2;
18  
19  import java.io.ByteArrayOutputStream;
20  import java.io.InputStream;
21  import java.nio.charset.StandardCharsets;
22  
23  import org.junit.Test;
24  
25  /**
26   * Test cases for reading file content.
27   */
28  public class ContentTests extends AbstractProviderTestCase {
29  
30      /**
31       * Asserts every file in a folder exists and has the expected content.
32       */
33      private void assertSameContent(final FileInfo expected, final FileObject folder) throws Exception {
34          for (final FileInfo fileInfo : expected.children.values()) {
35              final FileObject child = folder.resolveFile(fileInfo.baseName, NameScope.CHILD);
36  
37              assertTrue(child.getName().toString(), child.exists());
38              if (fileInfo.type == FileType.FILE) {
39                  assertSameContent(fileInfo.content, child);
40              } else {
41                  assertSameContent(fileInfo, child);
42              }
43          }
44      }
45  
46      /**
47       * Asserts that every expected file exists, and has the expected content.
48       */
49      @Test
50      public void testAllContent() throws Exception {
51          final FileInfo expectedFileInfo = buildExpectedStructure();
52          final FileObject actualFolder = getReadFolder();
53  
54          assertSameContent(expectedFileInfo, actualFolder);
55      }
56  
57      /**
58       * Tests attributes
59       */
60      @Test
61      public void testAttributes() throws FileSystemException {
62          this.getReadFolder().getContent().getAttributes();
63      }
64  
65      /**
66       * Tests that input streams are cleaned up on file close.
67       */
68      @Test
69      public void testByteArrayReadAll() throws Exception {
70          // Get the test file
71          try (final FileObject file = getReadFolder().resolveFile("file1.txt")) {
72              assertEquals(FileType.FILE, file.getType());
73              assertTrue(file.isFile());
74  
75              assertEquals(FILE1_CONTENT, new String(file.getContent().getByteArray()));
76          }
77      }
78  
79      /**
80       * Tests that children cannot be listed for non-folders.
81       */
82      @Test
83      public void testChildren() throws FileSystemException {
84          // Check for file
85          FileObject file = getReadFolder().resolveFile("file1.txt");
86          assertSame(FileType.FILE, file.getType());
87          assertTrue(file.isFile());
88          try {
89              file.getChildren();
90              fail();
91          } catch (final FileSystemException e) {
92              assertSameMessage("vfs.provider/list-children-not-folder.error", file, e);
93          }
94  
95          // Should be able to get child by name
96          file = file.resolveFile("some-child");
97          assertNotNull(file);
98  
99          // Check for unknown file
100         file = getReadFolder().resolveFile("unknown-file");
101         assertFalse(file.exists());
102         try {
103             file.getChildren();
104             fail();
105         } catch (final FileSystemException e) {
106             assertSameMessage("vfs.provider/list-children-not-folder.error", file, e);
107         }
108 
109         // Should be able to get child by name
110         final FileObject child = file.resolveFile("some-child");
111         assertNotNull(child);
112     }
113 
114     /**
115      * Tests content.
116      */
117     @Test
118     public void testContent() throws Exception {
119         // Test non-empty file
120         FileObject file = getReadFolder().resolveFile("file1.txt");
121         assertSameContent(FILE1_CONTENT, file);
122 
123         // Test empty file
124         file = getReadFolder().resolveFile("empty.txt");
125         assertSameContent("", file);
126     }
127 
128     /**
129      * Tests existence determination.
130      */
131     @Test
132     public void testExists() throws Exception {
133         // Test a file
134         FileObject file = getReadFolder().resolveFile("file1.txt");
135         assertTrue("file exists", file.exists());
136         assertNotSame("file exists", file.getType(), FileType.IMAGINARY);
137 
138         // Test a folder
139         file = getReadFolder().resolveFile("dir1");
140         assertTrue("folder exists", file.exists());
141         assertNotSame("folder exists", file.getType(), FileType.IMAGINARY);
142 
143         // Test an unknown file
144         file = getReadFolder().resolveFile("unknown-child");
145         assertFalse("unknown file does not exist", file.exists());
146         assertSame("unknown file does not exist", file.getType(), FileType.IMAGINARY);
147 
148         // Test an unknown file in an unknown folder
149         file = getReadFolder().resolveFile("unknown-folder/unknown-child");
150         assertFalse("unknown file does not exist", file.exists());
151         assertSame("unknown file does not exist", file.getType(), FileType.IMAGINARY);
152     }
153 
154     @Test
155     public void testGetString_Charset() throws Exception {
156         // Get the test file
157         try (final FileObject file = getReadFolder().resolveFile("file1.txt")) {
158             assertEquals(FileType.FILE, file.getType());
159             assertTrue(file.isFile());
160 
161             assertEquals(FILE1_CONTENT, new String(file.getContent().getString(StandardCharsets.UTF_8)));
162         }
163     }
164 
165     @Test
166     public void testGetString_String() throws Exception {
167         // Get the test file
168         try (final FileObject file = getReadFolder().resolveFile("file1.txt")) {
169             assertEquals(FileType.FILE, file.getType());
170             assertTrue(file.isFile());
171 
172             assertEquals(FILE1_CONTENT, new String(file.getContent().getString(StandardCharsets.UTF_8.name())));
173         }
174     }
175 
176     /**
177      * Tests that input streams are cleaned up on file close.
178      */
179     @Test
180     public void testInputStreamMultipleCleanup() throws Exception {
181         // Get the test file
182         final FileObject file = getReadFolder().resolveFile("file1.txt");
183         assertEquals(FileType.FILE, file.getType());
184         assertTrue(file.isFile());
185 
186         // Open some input streams
187         final InputStream instr1 = file.getContent().getInputStream();
188         assertEquals(instr1.read(), FILE1_CONTENT.charAt(0));
189         final InputStream instr2 = file.getContent().getInputStream();
190         assertEquals(instr2.read(), FILE1_CONTENT.charAt(0));
191 
192         // Close the file
193         file.close();
194 
195         // Check
196         assertEquals(instr1.read(), -1);
197         assertEquals(instr2.read(), -1);
198     }
199 
200     /**
201      * Tests that input streams are cleaned up on file close.
202      */
203     @Test
204     public void testInputStreamReadAll() throws Exception {
205         // Get the test file
206         try (final FileObject file = getReadFolder().resolveFile("file1.txt")) {
207             assertEquals(FileType.FILE, file.getType());
208             assertTrue(file.isFile());
209 
210             final ByteArrayOutputStream output = new ByteArrayOutputStream();
211             file.getContent().write(output);
212             assertEquals(FILE1_CONTENT, new String(output.toByteArray()));
213         }
214     }
215 
216     /**
217      * Tests that input streams are cleaned up on file close.
218      */
219     @Test
220     public void testInputStreamSingleCleanup() throws Exception {
221         // Get the test file
222         final FileObject file = getReadFolder().resolveFile("file1.txt");
223         assertEquals(FileType.FILE, file.getType());
224         assertTrue(file.isFile());
225 
226         // Open some input streams
227         final InputStream instr1 = file.getContent().getInputStream();
228         assertEquals(instr1.read(), FILE1_CONTENT.charAt(0));
229 
230         // Close the file
231         file.close();
232 
233         // Check
234         assertEquals(instr1.read(), -1);
235     }
236 
237     /**
238      * Tests parent identity
239      */
240     @Test
241     public void testParent() throws FileSystemException {
242         // Test when both exist
243         FileObject folder = getReadFolder().resolveFile("dir1");
244         FileObject child = folder.resolveFile("file3.txt");
245         assertTrue("folder exists", folder.exists());
246         assertTrue("child exists", child.exists());
247         assertSame(folder, child.getParent());
248 
249         // Test when file does not exist
250         child = folder.resolveFile("unknown-file");
251         assertTrue("folder exists", folder.exists());
252         assertFalse("child does not exist", child.exists());
253         assertSame(folder, child.getParent());
254 
255         // Test when neither exists
256         folder = getReadFolder().resolveFile("unknown-folder");
257         child = folder.resolveFile("unknown-file");
258         assertFalse("folder does not exist", folder.exists());
259         assertFalse("child does not exist", child.exists());
260         assertSame(folder, child.getParent());
261 
262         // Test the parent of the root of the file system
263         // TODO - refactor out test cases for layered vs originating fs
264         final FileSystem fileSystem = getFileSystem();
265         final FileObject root = fileSystem.getRoot();
266         if (fileSystem.getParentLayer() == null) {
267             // No parent layer, so parent should be null
268             assertNull("root has null parent", root.getParent());
269         } else {
270             // Parent should be parent of parent layer.
271             assertSame(fileSystem.getParentLayer().getParent(), root.getParent());
272         }
273     }
274 
275     /**
276      * Tests concurrent reads on different files works.
277      */
278     @Test
279     public void testReadMultipleConcurrent() throws Exception {
280         final FileObject file = getReadFolder().resolveFile("file1.txt");
281         assertTrue(file.exists());
282         final FileObject emptyFile = getReadFolder().resolveFile("empty.txt");
283         assertTrue(emptyFile.exists());
284 
285         // Start reading from the file
286         try (InputStream instr = file.getContent().getInputStream()) {
287             // Try to read from other file
288             assertSameContent("", emptyFile);
289         }
290     }
291 
292     /**
293      * Tests concurrent reads on a file.
294      */
295     @Test
296     public void testReadSingleConcurrent() throws Exception {
297         final FileObject file = getReadFolder().resolveFile("file1.txt");
298         assertTrue(file.exists());
299 
300         // Start reading from the file
301         try (InputStream instr = file.getContent().getInputStream()) {
302             // Start reading again
303             file.getContent().getInputStream().close();
304         }
305     }
306 
307     /**
308      * Tests concurrent reads on a file.
309      */
310     @Test
311     public void testReadSingleSequencial() throws Exception {
312         final FileObject file = getReadFolder().resolveFile("file1.txt");
313         assertTrue(file.exists());
314 
315         file.getContent().getInputStream().close();
316         file.getContent().getInputStream().close();
317     }
318 
319     /**
320      * Tests that content and file objects are usable after being closed.
321      */
322     @Test
323     public void testReuse() throws Exception {
324         // Get the test file
325         final FileObject file = getReadFolder().resolveFile("file1.txt");
326         assertEquals(FileType.FILE, file.getType());
327         assertTrue(file.isFile());
328 
329         // Get the file content
330         assertSameContent(FILE1_CONTENT, file);
331 
332         // Read the content again
333         assertSameContent(FILE1_CONTENT, file);
334 
335         // Close the content + file
336         file.getContent().close();
337         file.close();
338 
339         // Read the content again
340         assertSameContent(FILE1_CONTENT, file);
341     }
342 
343     private void testRoot(final FileObject root) throws FileSystemException {
344         assertTrue(root.exists());
345         assertNotSame(root.getType(), FileType.IMAGINARY);
346     }
347 
348     /**
349      * Tests root of file system exists.
350      */
351     @Test
352     public void testRootAPI() throws FileSystemException {
353         if (!this.getProviderConfig().isFileSystemRootAccessible()) {
354             return;
355         }
356         testRoot(getFileSystem().getRoot());
357     }
358 
359     /**
360      * Tests root of file system exists.
361      */
362     @Test
363     public void testRootURI() throws FileSystemException {
364         if (!this.getProviderConfig().isFileSystemRootAccessible()) {
365             return;
366         }
367         final FileSystem fileSystem = getFileSystem();
368         final String uri = fileSystem.getRootURI();
369         testRoot(getManager().resolveFile(uri, fileSystem.getFileSystemOptions()));
370     }
371 
372     /**
373      * Tests that unknown files have no content.
374      */
375     @Test
376     public void testUnknownContent() throws Exception {
377 
378         // Try getting the content of an unknown file
379         final FileObject unknownFile = getReadFolder().resolveFile("unknown-file");
380         final FileContent content = unknownFile.getContent();
381         try {
382             content.getInputStream();
383             fail();
384         } catch (final FileSystemException e) {
385             assertSameMessage("vfs.provider/read-not-file.error", unknownFile, e);
386         }
387         try {
388             content.getSize();
389             fail();
390         } catch (final FileSystemException e) {
391             assertSameMessage("vfs.provider/get-size-not-file.error", unknownFile, e);
392         }
393     }
394 }