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 public class FileAlterationMonitorTest extends AbstractMonitorTest {
42
43
44
45
46 public 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 public 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 public 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 public 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 public 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 public void testDefaultConstructor() {
126 final FileAlterationMonitor monitor = new FileAlterationMonitor();
127 assertEquals(10000, monitor.getInterval(), "Interval");
128 }
129
130
131
132
133
134 @Test
135 public void testMonitor() throws Exception {
136 final long interval = 100;
137 listener.clear();
138 final FileAlterationMonitor monitor = new FileAlterationMonitor(interval, observer);
139 assertEquals(interval, monitor.getInterval(), "Interval");
140 monitor.start();
141
142
143 assertThrows(IllegalStateException.class, () -> monitor.start());
144
145
146 checkCollectionsEmpty("A");
147 File file1 = touch(new File(testDir, "file1.java"));
148 checkFile("Create", file1, listener.getCreatedFiles());
149 listener.clear();
150
151
152 checkCollectionsEmpty("B");
153 file1 = touch(file1);
154 checkFile("Update", file1, listener.getChangedFiles());
155 listener.clear();
156
157
158 checkCollectionsEmpty("C");
159 file1.delete();
160 checkFile("Delete", file1, listener.getDeletedFiles());
161 listener.clear();
162
163
164 monitor.stop();
165
166
167 assertThrows(IllegalStateException.class, () -> monitor.stop());
168 }
169
170
171
172
173
174
175 @Test
176 public void testStopWhileWaitingForNextInterval() throws Exception {
177 final Collection<Thread> createdThreads = new ArrayList<>(1);
178 final ThreadFactory threadFactory = new ThreadFactory() {
179 private final ThreadFactory delegate = Executors.defaultThreadFactory();
180
181 @Override
182 public Thread newThread(final Runnable r) {
183 final Thread thread = delegate.newThread(r);
184 thread.setDaemon(true);
185 createdThreads.add(thread);
186 return thread;
187 }
188 };
189
190 final FileAlterationMonitor monitor = new FileAlterationMonitor(1_000);
191 monitor.setThreadFactory(threadFactory);
192
193 monitor.start();
194 assertFalse(createdThreads.isEmpty());
195
196 ThreadUtils.sleep(Duration.ofMillis(10));
197 monitor.stop(100);
198
199 createdThreads.forEach(thread -> assertFalse(thread.isAlive(), "The FileAlterationMonitor did not stop the threads it created."));
200 }
201
202
203
204
205
206 @Test
207 public void testThreadFactory() throws Exception {
208 final long interval = 100;
209 listener.clear();
210 final FileAlterationMonitor monitor = new FileAlterationMonitor(interval, observer);
211 monitor.setThreadFactory(Executors.defaultThreadFactory());
212 assertEquals(interval, monitor.getInterval(), "Interval");
213 monitor.start();
214
215
216 checkCollectionsEmpty("A");
217 final File file2 = touch(new File(testDir, "file2.java"));
218 checkFile("Create", file2, listener.getCreatedFiles());
219 listener.clear();
220
221
222 checkCollectionsEmpty("B");
223 file2.delete();
224 checkFile("Delete", file2, listener.getDeletedFiles());
225 listener.clear();
226
227
228 monitor.stop();
229 }
230 }