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.assertThrows;
22 import static org.junit.jupiter.api.Assertions.assertTrue;
23 import static org.junit.jupiter.api.Assertions.fail;
24
25 import java.io.File;
26 import java.time.Duration;
27 import java.util.ArrayList;
28 import java.util.Arrays;
29 import java.util.Collection;
30 import java.util.Iterator;
31 import java.util.concurrent.Executors;
32 import java.util.concurrent.ThreadFactory;
33
34 import org.apache.commons.io.ThreadUtils;
35 import org.apache.commons.io.test.TestUtils;
36 import org.junit.jupiter.api.Test;
37
38
39
40
41 class FileAlterationMonitorTest extends AbstractMonitorTest {
42
43
44
45
46 FileAlterationMonitorTest() {
47 listener = new CollectionFileListener(false);
48 }
49
50
51
52
53 private void checkFile(final String label, final File file, final Collection<File> files) {
54 for (int i = 0; i < 20; i++) {
55 if (files.contains(file)) {
56 return;
57 }
58 TestUtils.sleepQuietly(pauseTime);
59 }
60 fail(label + " " + file + " not found");
61 }
62
63
64
65
66 @Test
67 void testAddRemoveObservers() {
68 FileAlterationObserver[] observers = null;
69
70
71 FileAlterationMonitor monitor = new FileAlterationMonitor(123, observers);
72 assertEquals(123, monitor.getInterval(), "Interval");
73 assertFalse(monitor.getObservers().iterator().hasNext(), "Observers[1]");
74
75
76 observers = new FileAlterationObserver[1];
77 monitor = new FileAlterationMonitor(456, observers);
78 assertFalse(monitor.getObservers().iterator().hasNext(), "Observers[2]");
79
80
81 monitor.addObserver(null);
82 assertFalse(monitor.getObservers().iterator().hasNext(), "Observers[3]");
83 monitor.removeObserver(null);
84
85
86 final FileAlterationObserver observer = new FileAlterationObserver("foo");
87 monitor.addObserver(observer);
88 final Iterator<FileAlterationObserver> it = monitor.getObservers().iterator();
89 assertTrue(it.hasNext(), "Observers[4]");
90 assertEquals(observer, it.next(), "Added");
91 assertFalse(it.hasNext(), "Observers[5]");
92
93
94 monitor.removeObserver(observer);
95 assertFalse(monitor.getObservers().iterator().hasNext(), "Observers[6]");
96 }
97
98 @Test
99 void testCollectionConstructor() {
100 observer = new FileAlterationObserver("foo");
101 final Collection<FileAlterationObserver> observers = Arrays.asList(observer);
102 final FileAlterationMonitor monitor = new FileAlterationMonitor(0, observers);
103 final Iterator<FileAlterationObserver> iterator = monitor.getObservers().iterator();
104 assertEquals(observer, iterator.next());
105 }
106
107 @Test
108 void testCollectionConstructorShouldDoNothingWithNullCollection() {
109 final Collection<FileAlterationObserver> observers = null;
110 final FileAlterationMonitor monitor = new FileAlterationMonitor(0, observers);
111 assertFalse(monitor.getObservers().iterator().hasNext());
112 }
113
114 @Test
115 void testCollectionConstructorShouldDoNothingWithNullObservers() {
116 final Collection<FileAlterationObserver> observers = new ArrayList<>(5);
117 final FileAlterationMonitor monitor = new FileAlterationMonitor(0, observers);
118 assertFalse(monitor.getObservers().iterator().hasNext());
119 }
120
121
122
123
124 @Test
125 void testDefaultConstructor() {
126 final FileAlterationMonitor monitor = new FileAlterationMonitor();
127 assertEquals(10000, monitor.getInterval(), "Interval");
128 }
129
130
131
132
133
134
135 @Test
136 void testMonitor() throws Exception {
137 final long interval = 100;
138 listener.clear();
139 final FileAlterationMonitor monitor = new FileAlterationMonitor(interval, observer);
140 assertEquals(interval, monitor.getInterval(), "Interval");
141 monitor.start();
142
143
144 assertThrows(IllegalStateException.class, () -> monitor.start());
145
146
147 checkCollectionsEmpty("A");
148 File file1 = touch(new File(testDir, "file1.java"));
149 checkFile("Create", file1, listener.getCreatedFiles());
150 listener.clear();
151
152
153 checkCollectionsEmpty("B");
154 file1 = touch(file1);
155 checkFile("Update", file1, listener.getChangedFiles());
156 listener.clear();
157
158
159 checkCollectionsEmpty("C");
160 file1.delete();
161 checkFile("Delete", file1, listener.getDeletedFiles());
162 listener.clear();
163
164
165 monitor.stop();
166
167
168 assertThrows(IllegalStateException.class, () -> monitor.stop());
169 }
170
171
172
173
174
175
176 @Test
177 void testStopWhileWaitingForNextInterval() throws Exception {
178 final Collection<Thread> createdThreads = new ArrayList<>(1);
179 final ThreadFactory threadFactory = new ThreadFactory() {
180 private final ThreadFactory delegate = Executors.defaultThreadFactory();
181
182 @Override
183 public Thread newThread(final Runnable r) {
184 final Thread thread = delegate.newThread(r);
185 thread.setDaemon(true);
186 createdThreads.add(thread);
187 return thread;
188 }
189 };
190
191 final FileAlterationMonitor monitor = new FileAlterationMonitor(1_000);
192 monitor.setThreadFactory(threadFactory);
193
194 monitor.start();
195 assertFalse(createdThreads.isEmpty());
196
197 ThreadUtils.sleep(Duration.ofMillis(10));
198 monitor.stop(100);
199
200 createdThreads.forEach(thread -> assertFalse(thread.isAlive(), "The FileAlterationMonitor did not stop the threads it created."));
201 }
202
203
204
205
206
207 @Test
208 void testThreadFactory() throws Exception {
209 final long interval = 100;
210 listener.clear();
211 final FileAlterationMonitor monitor = new FileAlterationMonitor(interval, observer);
212 monitor.setThreadFactory(Executors.defaultThreadFactory());
213 assertEquals(interval, monitor.getInterval(), "Interval");
214 monitor.start();
215
216
217 checkCollectionsEmpty("A");
218 final File file2 = touch(new File(testDir, "file2.java"));
219 checkFile("Create", file2, listener.getCreatedFiles());
220 listener.clear();
221
222
223 checkCollectionsEmpty("B");
224 file2.delete();
225 checkFile("Delete", file2, listener.getDeletedFiles());
226 listener.clear();
227
228
229 monitor.stop();
230 }
231 }