blob: d3ceaf9f07f2fc1f67d3c771082d1ea95ff4dead [file] [log] [blame]
chrismair00dc7bd2014-05-11 21:21:28 +00001/*
2 * Copyright 2010 the original author or authors.
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 */
16package org.mockftpserver.fake.filesystem
17
18import org.mockftpserver.test.AbstractGroovyTestCase
19
20/**
21 * Abstract superclass for tests of FileSystem implementation classes. Contains common
22 * tests and test infrastructure.
23 *
24 * @version $Revision$ - $Date$
25 *
26 * @author Chris Mair
27 */
28abstract class AbstractFileSystemTestCase extends AbstractGroovyTestCase {
29
30 public static final FILENAME1 = "File1.txt"
31 public static final FILENAME2 = "file2.txt"
32 public static final DIR1 = "dir1"
33 public static final NEW_DIRNAME = "testDir"
34 public static final ILLEGAL_FILE = "xx/yy////z!<>?*z.txt"
35 public static final EXISTING_FILE_CONTENTS = "abc 123 %^& xxx"
36 public static final DATE = new Date()
37
38 // These must be set by the concrete subclass (in its constructor)
39 protected String NEW_DIR = null
40 protected String NEW_FILE = null
41 protected String EXISTING_DIR = null
42 protected String EXISTING_FILE = null
43 protected NO_SUCH_DIR = null
44 protected NO_SUCH_FILE = null
45
46 protected FileSystem fileSystem
47
48 //-------------------------------------------------------------------------
49 // Common Tests
50 //-------------------------------------------------------------------------
51
52 void testExists() {
53 assert !fileSystem.exists(NEW_FILE)
54 assert !fileSystem.exists(NEW_DIR)
55 assert !fileSystem.exists(ILLEGAL_FILE)
56 assert fileSystem.exists(EXISTING_FILE)
57 assert fileSystem.exists(EXISTING_DIR)
58
59 shouldFailWithMessageContaining("path") { fileSystem.exists(null) }
60 }
61
62 void testIsDirectory() {
63 assert fileSystem.isDirectory(EXISTING_DIR)
64 assert !fileSystem.isDirectory(EXISTING_FILE)
65 assert !fileSystem.isDirectory(NO_SUCH_DIR)
66 assert !fileSystem.isDirectory(NO_SUCH_FILE)
67 assert !fileSystem.isDirectory(ILLEGAL_FILE)
68
69 shouldFailWithMessageContaining("path") { fileSystem.isDirectory(null) }
70 }
71
72 void testIsFile() {
73 assert fileSystem.isFile(EXISTING_FILE)
74 assert !fileSystem.isFile(EXISTING_DIR)
75 assert !fileSystem.isFile(NO_SUCH_DIR)
76 assert !fileSystem.isFile(NO_SUCH_FILE)
77 assert !fileSystem.isFile(ILLEGAL_FILE)
78
79 shouldFailWithMessageContaining("path") { fileSystem.isFile(null) }
80 }
81
82 void testAdd_Directory() {
83 assert !fileSystem.exists(NEW_DIR), "Before createDirectory"
84 fileSystem.add(new DirectoryEntry(NEW_DIR))
85 assert fileSystem.exists(NEW_DIR), "After createDirectory"
86
87 // Duplicate directory
88 shouldThrowFileSystemExceptionWithMessageKey('filesystem.pathAlreadyExists') {
89 fileSystem.add(new DirectoryEntry(NEW_DIR))
90 }
91
92 // The parent of the path does not exist
93 shouldThrowFileSystemExceptionWithMessageKey('filesystem.parentDirectoryDoesNotExist') {
94 fileSystem.add(new DirectoryEntry(NEW_DIR + "/abc/def"))
95 }
96
97 shouldFail(InvalidFilenameException) { fileSystem.add(new DirectoryEntry(ILLEGAL_FILE)) }
98 shouldFailWithMessageContaining("path") { fileSystem.add(new DirectoryEntry(null)) }
99 }
100
101 void testAdd_File() {
102 assert !fileSystem.exists(NEW_FILE), "Before createFile"
103 fileSystem.add(new FileEntry(NEW_FILE))
104 assert fileSystem.exists(NEW_FILE), "After createFile"
105
106 // File already exists
107 shouldThrowFileSystemExceptionWithMessageKey('filesystem.pathAlreadyExists') {
108 fileSystem.add(new FileEntry(NEW_FILE))
109 }
110
111 // The parent of the path does not exist
112 shouldThrowFileSystemExceptionWithMessageKey('filesystem.parentDirectoryDoesNotExist') {
113 fileSystem.add(new FileEntry(NEW_DIR + "/abc/def"))
114 }
115
116 shouldThrowFileSystemExceptionWithMessageKey('filesystem.parentDirectoryDoesNotExist') {
117 fileSystem.add(new FileEntry(NO_SUCH_DIR))
118 }
119
120 shouldFail(InvalidFilenameException) { fileSystem.add(new FileEntry(ILLEGAL_FILE)) }
121
122 shouldFailWithMessageContaining("path") { fileSystem.add(new FileEntry(null)) }
123 }
124
125 void testRename_NullFromPath() {
126 shouldFailWithMessageContaining("fromPath") { fileSystem.rename(null, FILENAME1) }
127 }
128
129 void testRename_NullToPath() {
130 shouldFailWithMessageContaining("toPath") { fileSystem.rename(FILENAME1, null) }
131 }
132
133 void testListNames() {
134 fileSystem.add(new DirectoryEntry(NEW_DIR))
135 assert fileSystem.listNames(NEW_DIR) == []
136
137 fileSystem.add(new FileEntry(p(NEW_DIR, FILENAME1)))
138 fileSystem.add(new FileEntry(p(NEW_DIR, FILENAME2)))
139 fileSystem.add(new DirectoryEntry(p(NEW_DIR, DIR1)))
140 fileSystem.add(new FileEntry(p(NEW_DIR, DIR1, "/abc.def")))
141
142 List filenames = fileSystem.listNames(NEW_DIR)
143 LOG.info("filenames=" + filenames)
144 assertSameIgnoringOrder(filenames, [FILENAME1, FILENAME2, DIR1])
145
146 // Specify a filename instead of a directory name
147 assert [FILENAME1] == fileSystem.listNames(p(NEW_DIR, FILENAME1))
148
149 assert [] == fileSystem.listNames(NO_SUCH_DIR)
150
151 shouldFailWithMessageContaining("path") { fileSystem.listNames(null) }
152 }
153
154 void testListNames_Wildcards() {
155 fileSystem.add(new DirectoryEntry(NEW_DIR))
156 fileSystem.add(new FileEntry(p(NEW_DIR, 'abc.txt')))
157 fileSystem.add(new FileEntry(p(NEW_DIR, 'def.txt')))
158
159 assertSameIgnoringOrder(fileSystem.listNames(p(NEW_DIR, '*.txt')), ['abc.txt', 'def.txt'])
160 assertSameIgnoringOrder(fileSystem.listNames(p(NEW_DIR, '*')), ['abc.txt', 'def.txt'])
161 assertSameIgnoringOrder(fileSystem.listNames(p(NEW_DIR, '???.???')), ['abc.txt', 'def.txt'])
162 assertSameIgnoringOrder(fileSystem.listNames(p(NEW_DIR, '*.exe')), [])
163 assertSameIgnoringOrder(fileSystem.listNames(p(NEW_DIR, 'abc.???')), ['abc.txt'])
164 assertSameIgnoringOrder(fileSystem.listNames(p(NEW_DIR, 'a?c.?xt')), ['abc.txt'])
165 assertSameIgnoringOrder(fileSystem.listNames(p(NEW_DIR, 'd?f.*')), ['def.txt'])
166 }
167
168 void testListFiles() {
169 fileSystem.add(new DirectoryEntry(NEW_DIR))
170 assert [] == fileSystem.listFiles(NEW_DIR)
171
172 def path1 = p(NEW_DIR, FILENAME1)
173 def fileEntry1 = new FileEntry(path1)
174 fileSystem.add(fileEntry1)
175 assert fileSystem.listFiles(NEW_DIR) == [fileEntry1]
176
177 // Specify a filename instead of a directory name
178 assert fileSystem.listFiles(p(NEW_DIR, FILENAME1)) == [fileEntry1]
179
180 def fileEntry2 = new FileEntry(p(NEW_DIR, FILENAME2))
181 fileSystem.add(fileEntry2)
182 assert fileSystem.listFiles(NEW_DIR) as Set == [fileEntry1, fileEntry2] as Set
183
184 // Write to the file to get a non-zero length
185 final byte[] CONTENTS = "1234567890".getBytes()
186 OutputStream out = fileEntry1.createOutputStream(false)
187 out.write(CONTENTS)
188 out.close()
189 assert fileSystem.listFiles(NEW_DIR) as Set == [fileEntry1, fileEntry2] as Set
190
191 def dirEntry3 = new DirectoryEntry(p(NEW_DIR, DIR1))
192 fileSystem.add(dirEntry3)
193 assert fileSystem.listFiles(NEW_DIR) as Set == [fileEntry1, fileEntry2, dirEntry3] as Set
194
195 assert fileSystem.listFiles(NO_SUCH_DIR) == []
196
197 shouldFailWithMessageContaining("path") { fileSystem.listFiles(null) }
198 }
199
200 void testListFiles_Wildcards() {
201 def dirEntry = new DirectoryEntry(NEW_DIR)
202 def fileEntry1 = new FileEntry(p(NEW_DIR, 'abc.txt'))
203 def fileEntry2 = new FileEntry(p(NEW_DIR, 'def.txt'))
204
205 fileSystem.add(dirEntry)
206 fileSystem.add(fileEntry1)
207 fileSystem.add(fileEntry2)
208
209 assert fileSystem.listFiles(p(NEW_DIR, '*.txt')) as Set == [fileEntry1, fileEntry2] as Set
210 assert fileSystem.listFiles(p(NEW_DIR, '*')) as Set == [fileEntry1, fileEntry2] as Set
211 assert fileSystem.listFiles(p(NEW_DIR, '???.???')) as Set == [fileEntry1, fileEntry2] as Set
212 assert fileSystem.listFiles(p(NEW_DIR, '*.exe')) as Set == [] as Set
213 assert fileSystem.listFiles(p(NEW_DIR, 'abc.???')) as Set == [fileEntry1] as Set
214 assert fileSystem.listFiles(p(NEW_DIR, 'a?c.?xt')) as Set == [fileEntry1] as Set
215 assert fileSystem.listFiles(p(NEW_DIR, 'd?f.*')) as Set == [fileEntry2] as Set
216 }
217
218 void testDelete() {
219 fileSystem.add(new FileEntry(NEW_FILE))
220 assert fileSystem.delete(NEW_FILE)
221 assert !fileSystem.exists(NEW_FILE)
222
223 assert !fileSystem.delete(NO_SUCH_FILE)
224
225 fileSystem.add(new DirectoryEntry(NEW_DIR))
226 assert fileSystem.delete(NEW_DIR)
227 assert !fileSystem.exists(NEW_DIR)
228
229 fileSystem.add(new DirectoryEntry(NEW_DIR))
230 fileSystem.add(new FileEntry(NEW_DIR + "/abc.txt"))
231
232 assert !fileSystem.delete(NEW_DIR), "Directory containing files"
233 assert fileSystem.exists(NEW_DIR)
234
235 shouldFailWithMessageContaining("path") { fileSystem.delete(null) }
236 }
237
238 void testRename() {
239 final FROM_FILE = NEW_FILE + "2"
240 fileSystem.add(new FileEntry(FROM_FILE))
241
242 fileSystem.rename(FROM_FILE, NEW_FILE)
243 assert fileSystem.exists(NEW_FILE)
244
245 fileSystem.add(new DirectoryEntry(NEW_DIR))
246
247 // Rename existing directory
248 final String TO_DIR = NEW_DIR + "2"
249 fileSystem.rename(NEW_DIR, TO_DIR)
250 assert !fileSystem.exists(NEW_DIR)
251 assert fileSystem.exists(TO_DIR)
252 }
253
254 void testRename_ToPathFileAlreadyExists() {
255 final FROM_FILE = EXISTING_FILE
256 final String TO_FILE = NEW_FILE
257 fileSystem.add(new FileEntry(TO_FILE))
258 shouldThrowFileSystemExceptionWithMessageKey('filesystem.alreadyExists') {
259 fileSystem.rename(FROM_FILE, TO_FILE)
260 }
261 }
262
263 void testRename_FromPathDoesNotExist() {
264 final TO_FILE2 = NEW_FILE + "2"
265 shouldThrowFileSystemExceptionWithMessageKey('filesystem.doesNotExist') {
266 fileSystem.rename(NO_SUCH_FILE, TO_FILE2)
267 }
268 assert !fileSystem.exists(TO_FILE2), "After failed rename"
269 }
270
271 void testRename_ToPathIsChildOfFromPath() {
272 final FROM_DIR = NEW_DIR
273 final TO_DIR = FROM_DIR + "/child"
274 fileSystem.add(new DirectoryEntry(FROM_DIR))
275 shouldThrowFileSystemExceptionWithMessageKey('filesystem.renameFailed') {
276 fileSystem.rename(FROM_DIR, TO_DIR)
277 }
278 assert !fileSystem.exists(TO_DIR), "After failed rename"
279 }
280
281 void testRename_EmptyDirectory() {
282 final FROM_DIR = NEW_DIR
283 final TO_DIR = FROM_DIR + "2"
284 fileSystem.add(new DirectoryEntry(FROM_DIR))
285 fileSystem.rename(FROM_DIR, TO_DIR)
286 assert !fileSystem.exists(FROM_DIR)
287 assert fileSystem.exists(TO_DIR)
288 }
289
290 void testRename_DirectoryContainsFiles() {
291 fileSystem.add(new DirectoryEntry(NEW_DIR))
292 fileSystem.add(new FileEntry(NEW_DIR + "/a.txt"))
293 fileSystem.add(new FileEntry(NEW_DIR + "/b.txt"))
294 fileSystem.add(new DirectoryEntry(NEW_DIR + "/subdir"))
295
296 final String TO_DIR = NEW_DIR + "2"
297 fileSystem.rename(NEW_DIR, TO_DIR)
298 assert !fileSystem.exists(NEW_DIR)
299 assert !fileSystem.exists(NEW_DIR + "/a.txt")
300 assert !fileSystem.exists(NEW_DIR + "/b.txt")
301 assert !fileSystem.exists(NEW_DIR + "/subdir")
302
303 assert fileSystem.exists(TO_DIR)
304 assert fileSystem.exists(TO_DIR + "/a.txt")
305 assert fileSystem.exists(TO_DIR + "/b.txt")
306 assert fileSystem.exists(TO_DIR + "/subdir")
307 }
308
309 void testRename_ParentOfToPathDoesNotExist() {
310 final String FROM_FILE = NEW_FILE
311 final String TO_FILE = fileSystem.path(NO_SUCH_DIR, "abc")
312 fileSystem.add(new FileEntry(FROM_FILE))
313
314 shouldThrowFileSystemExceptionWithMessageKey('filesystem.parentDirectoryDoesNotExist') {
315 fileSystem.rename(FROM_FILE, TO_FILE)
316 }
317 assert fileSystem.exists(FROM_FILE)
318 assert !fileSystem.exists(TO_FILE)
319 }
320
321 void testGetParent_Null() {
322 shouldFailWithMessageContaining("path") { fileSystem.getParent(null) }
323 }
324
325 //-------------------------------------------------------------------------
326 // Test setup
327 //-------------------------------------------------------------------------
328
329 void setUp() {
330 super.setUp()
331 fileSystem = createFileSystem()
332 }
333
334 //-------------------------------------------------------------------------
335 // Helper Methods
336 //-------------------------------------------------------------------------
337
338 protected void shouldThrowFileSystemExceptionWithMessageKey(String messageKey, Closure closure) {
339 def e = shouldThrow(FileSystemException, closure)
340 assert e.messageKey == messageKey, "Expected message key [$messageKey], but was [${e.messageKey}]"
341 }
342
343 private verifyEntries(List expected, List actual) {
344 expected.eachWithIndex {entry, index ->
345 def entryStr = entry.toString()
346 LOG.info("expected=$entryStr")
347 assert actual.find {actualEntry -> actualEntry.toString() == entryStr }
348 }
349 }
350
351 protected void assertSameIgnoringOrder(list1, list2) {
352 LOG.info("Comparing $list1 to $list2")
353 assert list1 as Set == list2 as Set, "list1=$list1 list2=$list2"
354 }
355
356 /**
357 * Return a new instance of the FileSystem implementation class under test
358 * @return a new FileSystem instance
359 * @throws Exception
360 */
361 protected abstract FileSystem createFileSystem()
362
363 /**
364 * Verify the contents of the file at the specified path read from its InputSteam
365 *
366 * @param fileSystem - the FileSystem instance
367 * @param expectedContents - the expected contents
368 * @throws IOException
369 */
370 protected abstract void verifyFileContents(FileSystem fileSystem, String path, String contents) throws Exception
371
372}