1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.io.monitor;
18
19 import static org.junit.jupiter.api.Assertions.assertEquals;
20 import static org.junit.jupiter.api.Assertions.assertFalse;
21 import static org.junit.jupiter.api.Assertions.assertTrue;
22
23 import java.io.File;
24 import java.io.FileFilter;
25 import java.io.IOException;
26 import java.util.Iterator;
27
28 import org.apache.commons.io.FileUtils;
29 import org.apache.commons.io.FilenameUtils;
30 import org.apache.commons.io.IOCase;
31 import org.apache.commons.io.comparator.NameFileComparator;
32 import org.apache.commons.io.filefilter.CanReadFileFilter;
33 import org.apache.commons.io.filefilter.FileFilterUtils;
34 import org.apache.commons.io.monitor.FileAlterationObserver.Builder;
35 import org.junit.jupiter.api.Test;
36
37
38
39
40 class FileAlterationObserverTest extends AbstractMonitorTest {
41
42 private static final String PATH_STRING_FIXTURE = "/foo";
43
44
45
46
47 FileAlterationObserverTest() {
48 listener = new CollectionFileListener(true);
49 }
50
51
52
53
54 protected void checkAndNotify() {
55 observer.checkAndNotify();
56 }
57
58 private String directoryToUnixString(final FileAlterationObserver observer) {
59 return FilenameUtils.separatorsToUnix(observer.getDirectory().toString());
60 }
61
62
63
64
65 @Test
66 void testAddRemoveListeners() {
67 final FileAlterationObserver observer = FileAlterationObserver.builder().setFile(PATH_STRING_FIXTURE).getUnchecked();
68
69 observer.addListener(null);
70 assertFalse(observer.getListeners().iterator().hasNext(), "Listeners[1]");
71 observer.removeListener(null);
72 assertFalse(observer.getListeners().iterator().hasNext(), "Listeners[2]");
73
74
75 final FileAlterationListenerAdaptor listener = new FileAlterationListenerAdaptor();
76 observer.addListener(listener);
77 final Iterator<FileAlterationListener> it = observer.getListeners().iterator();
78 assertTrue(it.hasNext(), "Listeners[3]");
79 assertEquals(listener, it.next(), "Added");
80 assertFalse(it.hasNext(), "Listeners[4]");
81
82
83 observer.removeListener(listener);
84 assertFalse(observer.getListeners().iterator().hasNext(), "Listeners[5]");
85 }
86
87 @Test
88 void testBuilder_File() {
89 final File file = new File(PATH_STRING_FIXTURE);
90 final FileAlterationObserver observer = FileAlterationObserver.builder().setFile(file).getUnchecked();
91 assertEquals(file, observer.getDirectory());
92 }
93
94 @Test
95 void testBuilder_File_FileFilter() {
96 final File file = new File(PATH_STRING_FIXTURE);
97
98 final FileAlterationObserver observer = FileAlterationObserver.builder()
99 .setFile(file)
100 .setFileFilter(CanReadFileFilter.CAN_READ)
101 .getUnchecked();
102
103 assertEquals(file, observer.getDirectory());
104 assertEquals(CanReadFileFilter.CAN_READ, observer.getFileFilter());
105 }
106
107 @Test
108 void testBuilder_File_FileFilter_IOCase() {
109 final File file = new File(PATH_STRING_FIXTURE);
110
111 final FileAlterationObserver observer = FileAlterationObserver.builder()
112 .setFile(file)
113 .setFileFilter(CanReadFileFilter.CAN_READ)
114 .setIOCase(IOCase.INSENSITIVE)
115 .getUnchecked();
116
117 assertEquals(file, observer.getDirectory());
118 assertEquals(CanReadFileFilter.CAN_READ, observer.getFileFilter());
119 assertEquals(NameFileComparator.NAME_INSENSITIVE_COMPARATOR, observer.getComparator());
120 }
121
122 @Test
123 void testBuilder_String() {
124 final String file = PATH_STRING_FIXTURE;
125 final FileAlterationObserver observer = FileAlterationObserver.builder().setFile(file).getUnchecked();
126 assertEquals(file, directoryToUnixString(observer));
127 }
128
129 @Test
130 void testBuilder_String_FileFilter() {
131 final String file = PATH_STRING_FIXTURE;
132
133 final FileAlterationObserver observer = FileAlterationObserver.builder()
134 .setFile(file)
135 .setFileFilter(CanReadFileFilter.CAN_READ)
136 .getUnchecked();
137
138 assertEquals(file, directoryToUnixString(observer));
139 assertEquals(CanReadFileFilter.CAN_READ, observer.getFileFilter());
140 }
141
142 @Test
143 void testBuilder_String_FileFilter_IOCase() {
144 final String file = PATH_STRING_FIXTURE;
145
146 final FileAlterationObserver observer = FileAlterationObserver.builder()
147 .setFile(file)
148 .setFileFilter(CanReadFileFilter.CAN_READ)
149 .setIOCase(IOCase.INSENSITIVE)
150 .getUnchecked();
151
152 assertEquals(file, directoryToUnixString(observer));
153 assertEquals(CanReadFileFilter.CAN_READ, observer.getFileFilter());
154 assertEquals(NameFileComparator.NAME_INSENSITIVE_COMPARATOR, observer.getComparator());
155 }
156
157 @Test
158 void testConstructor_File() {
159 final File file = new File(PATH_STRING_FIXTURE);
160 @SuppressWarnings("deprecation")
161 final FileAlterationObserver observer = new FileAlterationObserver(file);
162 assertEquals(file, observer.getDirectory());
163 }
164
165 @Test
166 void testConstructor_File_FileFilter() {
167 final File file = new File(PATH_STRING_FIXTURE);
168 @SuppressWarnings("deprecation")
169 final FileAlterationObserver observer = new FileAlterationObserver(file, CanReadFileFilter.CAN_READ);
170 assertEquals(file, observer.getDirectory());
171 assertEquals(CanReadFileFilter.CAN_READ, observer.getFileFilter());
172 }
173
174 @Test
175 void testConstructor_File_FileFilter_IOCase() {
176 final File file = new File(PATH_STRING_FIXTURE);
177 @SuppressWarnings("deprecation")
178 final FileAlterationObserver observer = new FileAlterationObserver(file, CanReadFileFilter.CAN_READ, IOCase.INSENSITIVE);
179 assertEquals(file, observer.getDirectory());
180 assertEquals(CanReadFileFilter.CAN_READ, observer.getFileFilter());
181 assertEquals(NameFileComparator.NAME_INSENSITIVE_COMPARATOR, observer.getComparator());
182 }
183
184 @Test
185 void testConstructor_String() {
186 final String file = PATH_STRING_FIXTURE;
187 @SuppressWarnings("deprecation")
188 final FileAlterationObserver observer = new FileAlterationObserver(file);
189 assertEquals(file, directoryToUnixString(observer));
190 }
191
192 @Test
193 void testConstructor_String_FileFilter() {
194 final String file = PATH_STRING_FIXTURE;
195 @SuppressWarnings("deprecation")
196 final FileAlterationObserver observer = new FileAlterationObserver(file, CanReadFileFilter.CAN_READ);
197 assertEquals(file, directoryToUnixString(observer));
198 assertEquals(CanReadFileFilter.CAN_READ, observer.getFileFilter());
199 }
200
201 @Test
202 void testConstructor_String_FileFilter_IOCase() {
203 final String file = PATH_STRING_FIXTURE;
204 @SuppressWarnings("deprecation")
205 final FileAlterationObserver observer = new FileAlterationObserver(file, CanReadFileFilter.CAN_READ, IOCase.INSENSITIVE);
206 assertEquals(file, directoryToUnixString(observer));
207 assertEquals(CanReadFileFilter.CAN_READ, observer.getFileFilter());
208 assertEquals(NameFileComparator.NAME_INSENSITIVE_COMPARATOR, observer.getComparator());
209 }
210
211
212
213
214
215
216 @Test
217 void testDirectory() throws Exception {
218 checkAndNotify();
219 checkCollectionsEmpty("A");
220 final File testDirA = new File(testDir, "test-dir-A");
221 final File testDirB = new File(testDir, "test-dir-B");
222 final File testDirC = new File(testDir, "test-dir-C");
223 testDirA.mkdir();
224 testDirB.mkdir();
225 testDirC.mkdir();
226 final File testDirAFile1 = touch(new File(testDirA, "A-file1.java"));
227 final File testDirAFile2 = touch(new File(testDirA, "A-file2.txt"));
228 final File testDirAFile3 = touch(new File(testDirA, "A-file3.java"));
229 File testDirAFile4 = touch(new File(testDirA, "A-file4.java"));
230 final File testDirBFile1 = touch(new File(testDirB, "B-file1.java"));
231
232 checkAndNotify();
233 checkCollectionSizes("B", 3, 0, 0, 4, 0, 0);
234 assertTrue(listener.getCreatedDirectories().contains(testDirA), "B testDirA");
235 assertTrue(listener.getCreatedDirectories().contains(testDirB), "B testDirB");
236 assertTrue(listener.getCreatedDirectories().contains(testDirC), "B testDirC");
237 assertTrue(listener.getCreatedFiles().contains(testDirAFile1), "B testDirAFile1");
238 assertFalse(listener.getCreatedFiles().contains(testDirAFile2), "B testDirAFile2");
239 assertTrue(listener.getCreatedFiles().contains(testDirAFile3), "B testDirAFile3");
240 assertTrue(listener.getCreatedFiles().contains(testDirAFile4), "B testDirAFile4");
241 assertTrue(listener.getCreatedFiles().contains(testDirBFile1), "B testDirBFile1");
242
243 checkAndNotify();
244 checkCollectionsEmpty("C");
245
246 testDirAFile4 = touch(testDirAFile4);
247 FileUtils.deleteDirectory(testDirB);
248 checkAndNotify();
249 checkCollectionSizes("D", 0, 0, 1, 0, 1, 1);
250 assertTrue(listener.getDeletedDirectories().contains(testDirB), "D testDirB");
251 assertTrue(listener.getChangedFiles().contains(testDirAFile4), "D testDirAFile4");
252 assertTrue(listener.getDeletedFiles().contains(testDirBFile1), "D testDirBFile1");
253
254 FileUtils.deleteDirectory(testDir);
255 checkAndNotify();
256 checkCollectionSizes("E", 0, 0, 2, 0, 0, 3);
257 assertTrue(listener.getDeletedDirectories().contains(testDirA), "E testDirA");
258 assertTrue(listener.getDeletedFiles().contains(testDirAFile1), "E testDirAFile1");
259 assertFalse(listener.getDeletedFiles().contains(testDirAFile2), "E testDirAFile2");
260 assertTrue(listener.getDeletedFiles().contains(testDirAFile3), "E testDirAFile3");
261 assertTrue(listener.getDeletedFiles().contains(testDirAFile4), "E testDirAFile4");
262
263 testDir.mkdir();
264 checkAndNotify();
265 checkCollectionsEmpty("F");
266
267 checkAndNotify();
268 checkCollectionsEmpty("G");
269 }
270
271
272
273
274
275
276 @Test
277 void testFileCreate() throws IOException {
278 checkAndNotify();
279 checkCollectionsEmpty("A");
280 File testDirA = new File(testDir, "test-dir-A");
281 testDirA.mkdir();
282 testDir = touch(testDir);
283 testDirA = touch(testDirA);
284 File testDirAFile1 = new File(testDirA, "A-file1.java");
285 final File testDirAFile2 = touch(new File(testDirA, "A-file2.java"));
286 File testDirAFile3 = new File(testDirA, "A-file3.java");
287 final File testDirAFile4 = touch(new File(testDirA, "A-file4.java"));
288 File testDirAFile5 = new File(testDirA, "A-file5.java");
289
290 checkAndNotify();
291 checkCollectionSizes("B", 1, 0, 0, 2, 0, 0);
292 assertFalse(listener.getCreatedFiles().contains(testDirAFile1), "B testDirAFile1");
293 assertTrue(listener.getCreatedFiles().contains(testDirAFile2), "B testDirAFile2");
294 assertFalse(listener.getCreatedFiles().contains(testDirAFile3), "B testDirAFile3");
295 assertTrue(listener.getCreatedFiles().contains(testDirAFile4), "B testDirAFile4");
296 assertFalse(listener.getCreatedFiles().contains(testDirAFile5), "B testDirAFile5");
297
298 assertFalse(testDirAFile1.exists(), "B testDirAFile1 exists");
299 assertTrue(testDirAFile2.exists(), "B testDirAFile2 exists");
300 assertFalse(testDirAFile3.exists(), "B testDirAFile3 exists");
301 assertTrue(testDirAFile4.exists(), "B testDirAFile4 exists");
302 assertFalse(testDirAFile5.exists(), "B testDirAFile5 exists");
303
304 checkAndNotify();
305 checkCollectionsEmpty("C");
306
307
308 testDirAFile1 = touch(testDirAFile1);
309 testDirA = touch(testDirA);
310 checkAndNotify();
311 checkCollectionSizes("D", 0, 1, 0, 1, 0, 0);
312 assertTrue(testDirAFile1.exists(), "D testDirAFile1 exists");
313 assertTrue(listener.getCreatedFiles().contains(testDirAFile1), "D testDirAFile1");
314
315
316 testDirAFile3 = touch(testDirAFile3);
317 testDirA = touch(testDirA);
318 checkAndNotify();
319 checkCollectionSizes("E", 0, 1, 0, 1, 0, 0);
320 assertTrue(testDirAFile3.exists(), "E testDirAFile3 exists");
321 assertTrue(listener.getCreatedFiles().contains(testDirAFile3), "E testDirAFile3");
322
323
324 testDirAFile5 = touch(testDirAFile5);
325 testDirA = touch(testDirA);
326 checkAndNotify();
327 checkCollectionSizes("F", 0, 1, 0, 1, 0, 0);
328 assertTrue(testDirAFile5.exists(), "F testDirAFile5 exists");
329 assertTrue(listener.getCreatedFiles().contains(testDirAFile5), "F testDirAFile5");
330 }
331
332
333
334
335
336
337 @Test
338 void testFileDelete() throws IOException {
339 checkAndNotify();
340 checkCollectionsEmpty("A");
341 File testDirA = new File(testDir, "test-dir-A");
342 testDirA.mkdir();
343 testDir = touch(testDir);
344 testDirA = touch(testDirA);
345 final File testDirAFile1 = touch(new File(testDirA, "A-file1.java"));
346 final File testDirAFile2 = touch(new File(testDirA, "A-file2.java"));
347 final File testDirAFile3 = touch(new File(testDirA, "A-file3.java"));
348 final File testDirAFile4 = touch(new File(testDirA, "A-file4.java"));
349 final File testDirAFile5 = touch(new File(testDirA, "A-file5.java"));
350
351 assertTrue(testDirAFile1.exists(), "B testDirAFile1 exists");
352 assertTrue(testDirAFile2.exists(), "B testDirAFile2 exists");
353 assertTrue(testDirAFile3.exists(), "B testDirAFile3 exists");
354 assertTrue(testDirAFile4.exists(), "B testDirAFile4 exists");
355 assertTrue(testDirAFile5.exists(), "B testDirAFile5 exists");
356
357 checkAndNotify();
358 checkCollectionSizes("B", 1, 0, 0, 5, 0, 0);
359 assertTrue(listener.getCreatedFiles().contains(testDirAFile1), "B testDirAFile1");
360 assertTrue(listener.getCreatedFiles().contains(testDirAFile2), "B testDirAFile2");
361 assertTrue(listener.getCreatedFiles().contains(testDirAFile3), "B testDirAFile3");
362 assertTrue(listener.getCreatedFiles().contains(testDirAFile4), "B testDirAFile4");
363 assertTrue(listener.getCreatedFiles().contains(testDirAFile5), "B testDirAFile5");
364
365 checkAndNotify();
366 checkCollectionsEmpty("C");
367
368
369 FileUtils.deleteQuietly(testDirAFile1);
370 testDirA = touch(testDirA);
371 checkAndNotify();
372 checkCollectionSizes("D", 0, 1, 0, 0, 0, 1);
373 assertFalse(testDirAFile1.exists(), "D testDirAFile1 exists");
374 assertTrue(listener.getDeletedFiles().contains(testDirAFile1), "D testDirAFile1");
375
376
377 FileUtils.deleteQuietly(testDirAFile3);
378 testDirA = touch(testDirA);
379 checkAndNotify();
380 checkCollectionSizes("E", 0, 1, 0, 0, 0, 1);
381 assertFalse(testDirAFile3.exists(), "E testDirAFile3 exists");
382 assertTrue(listener.getDeletedFiles().contains(testDirAFile3), "E testDirAFile3");
383
384
385 FileUtils.deleteQuietly(testDirAFile5);
386 testDirA = touch(testDirA);
387 checkAndNotify();
388 checkCollectionSizes("F", 0, 1, 0, 0, 0, 1);
389 assertFalse(testDirAFile5.exists(), "F testDirAFile5 exists");
390 assertTrue(listener.getDeletedFiles().contains(testDirAFile5), "F testDirAFile5");
391 }
392
393
394
395
396
397
398 @Test
399 void testFileUpdate() throws IOException {
400 checkAndNotify();
401 checkCollectionsEmpty("A");
402 File testDirA = new File(testDir, "test-dir-A");
403 testDirA.mkdir();
404 testDir = touch(testDir);
405 testDirA = touch(testDirA);
406 File testDirAFile1 = touch(new File(testDirA, "A-file1.java"));
407 final File testDirAFile2 = touch(new File(testDirA, "A-file2.java"));
408 File testDirAFile3 = touch(new File(testDirA, "A-file3.java"));
409 final File testDirAFile4 = touch(new File(testDirA, "A-file4.java"));
410 File testDirAFile5 = touch(new File(testDirA, "A-file5.java"));
411
412 checkAndNotify();
413 checkCollectionSizes("B", 1, 0, 0, 5, 0, 0);
414 assertTrue(listener.getCreatedFiles().contains(testDirAFile1), "B testDirAFile1");
415 assertTrue(listener.getCreatedFiles().contains(testDirAFile2), "B testDirAFile2");
416 assertTrue(listener.getCreatedFiles().contains(testDirAFile3), "B testDirAFile3");
417 assertTrue(listener.getCreatedFiles().contains(testDirAFile4), "B testDirAFile4");
418 assertTrue(listener.getCreatedFiles().contains(testDirAFile5), "B testDirAFile5");
419
420 assertTrue(testDirAFile1.exists(), "B testDirAFile1 exists");
421 assertTrue(testDirAFile2.exists(), "B testDirAFile2 exists");
422 assertTrue(testDirAFile3.exists(), "B testDirAFile3 exists");
423 assertTrue(testDirAFile4.exists(), "B testDirAFile4 exists");
424 assertTrue(testDirAFile5.exists(), "B testDirAFile5 exists");
425
426 checkAndNotify();
427 checkCollectionsEmpty("C");
428
429
430 testDirAFile1 = touch(testDirAFile1);
431 testDirA = touch(testDirA);
432 checkAndNotify();
433 checkCollectionSizes("D", 0, 1, 0, 0, 1, 0);
434 assertTrue(listener.getChangedFiles().contains(testDirAFile1), "D testDirAFile1");
435
436
437 testDirAFile3 = touch(testDirAFile3);
438 testDirA = touch(testDirA);
439 checkAndNotify();
440 checkCollectionSizes("E", 0, 1, 0, 0, 1, 0);
441 assertTrue(listener.getChangedFiles().contains(testDirAFile3), "E testDirAFile3");
442
443
444 testDirAFile5 = touch(testDirAFile5);
445 testDirA = touch(testDirA);
446 checkAndNotify();
447 checkCollectionSizes("F", 0, 1, 0, 0, 1, 0);
448 assertTrue(listener.getChangedFiles().contains(testDirAFile5), "F testDirAFile5");
449 }
450
451
452
453
454
455
456 @Test
457 void testObserveSingleFile() throws IOException {
458 final File testDirA = new File(testDir, "test-dir-A");
459 File testDirAFile1 = new File(testDirA, "A-file1.java");
460 testDirA.mkdir();
461
462 final FileFilter nameFilter = FileFilterUtils.nameFileFilter(testDirAFile1.getName());
463 createObserver(testDirA, nameFilter);
464 checkAndNotify();
465 checkCollectionsEmpty("A");
466 assertFalse(testDirAFile1.exists(), "A testDirAFile1 exists");
467
468
469 testDirAFile1 = touch(testDirAFile1);
470 File testDirAFile2 = touch(new File(testDirA, "A-file2.txt"));
471 File testDirAFile3 = touch(new File(testDirA, "A-file3.java"));
472 assertTrue(testDirAFile1.exists(), "B testDirAFile1 exists");
473 assertTrue(testDirAFile2.exists(), "B testDirAFile2 exists");
474 assertTrue(testDirAFile3.exists(), "B testDirAFile3 exists");
475 checkAndNotify();
476 checkCollectionSizes("C", 0, 0, 0, 1, 0, 0);
477 assertTrue(listener.getCreatedFiles().contains(testDirAFile1), "C created");
478 assertFalse(listener.getCreatedFiles().contains(testDirAFile2), "C created");
479 assertFalse(listener.getCreatedFiles().contains(testDirAFile3), "C created");
480
481
482 testDirAFile1 = touch(testDirAFile1);
483 testDirAFile2 = touch(testDirAFile2);
484 testDirAFile3 = touch(testDirAFile3);
485 checkAndNotify();
486 checkCollectionSizes("D", 0, 0, 0, 0, 1, 0);
487 assertTrue(listener.getChangedFiles().contains(testDirAFile1), "D changed");
488 assertFalse(listener.getChangedFiles().contains(testDirAFile2), "D changed");
489 assertFalse(listener.getChangedFiles().contains(testDirAFile3), "D changed");
490
491
492 FileUtils.deleteQuietly(testDirAFile1);
493 FileUtils.deleteQuietly(testDirAFile2);
494 FileUtils.deleteQuietly(testDirAFile3);
495 assertFalse(testDirAFile1.exists(), "E testDirAFile1 exists");
496 assertFalse(testDirAFile2.exists(), "E testDirAFile2 exists");
497 assertFalse(testDirAFile3.exists(), "E testDirAFile3 exists");
498 checkAndNotify();
499 checkCollectionSizes("E", 0, 0, 0, 0, 0, 1);
500 assertTrue(listener.getDeletedFiles().contains(testDirAFile1), "E deleted");
501 assertFalse(listener.getDeletedFiles().contains(testDirAFile2), "E deleted");
502 assertFalse(listener.getDeletedFiles().contains(testDirAFile3), "E deleted");
503 }
504
505
506
507
508 @Test
509 void testToString() {
510 final File file = new File(PATH_STRING_FIXTURE);
511 final Builder builder = FileAlterationObserver.builder();
512 FileAlterationObserver observer = builder.setFile(file).getUnchecked();
513 assertEquals("FileAlterationObserver[file='" + file.getPath() + "', true, listeners=0]", observer.toString());
514 observer = builder.setFileFilter(CanReadFileFilter.CAN_READ).getUnchecked();
515 assertEquals("FileAlterationObserver[file='" + file.getPath() + "', CanReadFileFilter, listeners=0]", observer.toString());
516 assertEquals(file, observer.getDirectory());
517 }
518 }