1/* 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}