1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.vfs2.impl;
18
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertTrue;
21
22 import java.io.BufferedWriter;
23 import java.io.File;
24 import java.io.IOException;
25 import java.nio.file.Files;
26 import java.util.concurrent.atomic.AtomicLong;
27
28 import org.apache.commons.vfs2.AbstractVfsTestCase;
29 import org.apache.commons.vfs2.FileChangeEvent;
30 import org.apache.commons.vfs2.FileListener;
31 import org.apache.commons.vfs2.FileObject;
32 import org.apache.commons.vfs2.FileSystemManager;
33 import org.apache.commons.vfs2.VFS;
34 import org.junit.After;
35 import org.junit.Before;
36 import org.junit.BeforeClass;
37 import org.junit.Ignore;
38 import org.junit.Test;
39
40
41
42
43 public class DefaultFileMonitorTest {
44
45 private static class CountingListener implements FileListener {
46 private final AtomicLong created = new AtomicLong();
47 private final AtomicLong changed = new AtomicLong();
48 private final AtomicLong deleted = new AtomicLong();
49
50 @Override
51 public void fileChanged(final FileChangeEvent event) {
52 changed.incrementAndGet();
53 }
54
55 @Override
56 public void fileCreated(final FileChangeEvent event) {
57 created.incrementAndGet();
58 }
59
60 @Override
61 public void fileDeleted(final FileChangeEvent event) {
62 deleted.incrementAndGet();
63 }
64 }
65
66 private enum Status {
67 CHANGED, DELETED, CREATED
68 }
69
70 private class TestFileListener implements FileListener {
71 @Override
72 public void fileChanged(final FileChangeEvent event) throws Exception {
73 status = Status.CHANGED;
74 }
75
76 @Override
77 public void fileCreated(final FileChangeEvent event) throws Exception {
78 status = Status.CREATED;
79 }
80
81 @Override
82 public void fileDeleted(final FileChangeEvent event) throws Exception {
83 status = Status.DELETED;
84 }
85 }
86
87 private static final int DELAY_MILLIS = 100;
88
89 private FileSystemManager fileSystemManager;
90
91 private File testDir;
92
93 private volatile Status status;
94
95 private File testFile;
96
97 private void deleteTestFileIfPresent() {
98 if (testFile != null && testFile.exists()) {
99 final boolean deleted = testFile.delete();
100 assertTrue(testFile.toString(), deleted);
101 }
102 }
103
104
105
106
107
108
109 @Ignore("VFS-299")
110 @Test
111 public void ignore_testAddRemove() throws Exception {
112 try (final FileObject fileObject = fileSystemManager.resolveFile(testFile.toURI().toString())) {
113 final CountingListener listener = new CountingListener();
114 final DefaultFileMonitor monitor = new DefaultFileMonitor(listener);
115 monitor.setDelay(DELAY_MILLIS);
116 try {
117 monitor.addFile(fileObject);
118 monitor.removeFile(fileObject);
119 monitor.addFile(fileObject);
120 monitor.start();
121 writeToFile(testFile);
122 Thread.sleep(DELAY_MILLIS * 3);
123 assertEquals("Created event is only fired once", 1, listener.created.get());
124 } finally {
125 monitor.stop();
126 }
127 }
128 }
129
130
131
132
133
134
135 @Ignore("VFS-299")
136 @Test
137 public void ignore_testStartStop() throws Exception {
138 try (final FileObject fileObject = fileSystemManager.resolveFile(testFile.toURI().toString())) {
139 final CountingListener stoppedListener = new CountingListener();
140 final DefaultFileMonitor stoppedMonitor = new DefaultFileMonitor(stoppedListener);
141 stoppedMonitor.start();
142 try {
143 stoppedMonitor.addFile(fileObject);
144 } finally {
145 stoppedMonitor.stop();
146 }
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162 final CountingListener activeListener = new CountingListener();
163 final DefaultFileMonitor activeMonitor = new DefaultFileMonitor(activeListener);
164 activeMonitor.setDelay(DELAY_MILLIS);
165 activeMonitor.addFile(fileObject);
166 activeMonitor.start();
167 try {
168 writeToFile(testFile);
169 Thread.sleep(DELAY_MILLIS * 10);
170
171 assertEquals("The listener of the active monitor received one created event", 1, activeListener.created.get());
172 assertEquals("The listener of the stopped monitor received no events", 0, stoppedListener.created.get());
173 } finally {
174 activeMonitor.stop();
175 }
176 }
177 }
178
179 @Before
180 public void setUp() throws Exception {
181 fileSystemManager = VFS.getManager();
182 testDir = AbstractVfsTestCase.getTestDirectoryFile();
183 status = null;
184 testFile = new File(testDir, "testReload.properties");
185 deleteTestFileIfPresent();
186 }
187
188 @After
189 public void tearDown() {
190
191 deleteTestFileIfPresent();
192 }
193
194 @Test
195 public void testChildFileDeletedWithoutRecursiveChecking() throws Exception {
196 writeToFile(testFile);
197 try (final FileObject fileObject = fileSystemManager.resolveFile(testDir.toURI().toURL().toString())) {
198 final DefaultFileMonitor monitor = new DefaultFileMonitor(new TestFileListener());
199 monitor.setDelay(2000);
200 monitor.setRecursive(false);
201 monitor.addFile(fileObject);
202 monitor.start();
203 try {
204 status = null;
205 Thread.sleep(DELAY_MILLIS * 5);
206 testFile.delete();
207 Thread.sleep(DELAY_MILLIS * 30);
208 assertEquals("Event should not have occurred", null, status);
209 } finally {
210 monitor.stop();
211 }
212 }
213 }
214
215 @Test
216 public void testChildFileRecreated() throws Exception {
217 writeToFile(testFile);
218 try (final FileObject fileObj = fileSystemManager.resolveFile(testDir.toURI().toURL().toString())) {
219 final DefaultFileMonitor monitor = new DefaultFileMonitor(new TestFileListener());
220 monitor.setDelay(2000);
221 monitor.setRecursive(true);
222 monitor.addFile(fileObj);
223 monitor.start();
224 try {
225 status = null;
226 Thread.sleep(DELAY_MILLIS * 5);
227 testFile.delete();
228 waitFor(Status.DELETED, DELAY_MILLIS * 30);
229 status = null;
230 Thread.sleep(DELAY_MILLIS * 5);
231 writeToFile(testFile);
232 waitFor(Status.CREATED, DELAY_MILLIS * 30);
233 } finally {
234 monitor.stop();
235 }
236 }
237 }
238
239 @Test
240 public void testFileCreated() throws Exception {
241 try (final FileObject fileObject = fileSystemManager.resolveFile(testFile.toURI().toURL().toString())) {
242 final DefaultFileMonitor monitor = new DefaultFileMonitor(new TestFileListener());
243
244 monitor.setDelay(DELAY_MILLIS);
245 monitor.addFile(fileObject);
246 monitor.start();
247 try {
248 writeToFile(testFile);
249 Thread.sleep(DELAY_MILLIS * 5);
250 waitFor(Status.CREATED, DELAY_MILLIS * 5);
251 } finally {
252 monitor.stop();
253 }
254 }
255 }
256
257 @Test
258 public void testFileDeleted() throws Exception {
259 writeToFile(testFile);
260 try (final FileObject fileObject = fileSystemManager.resolveFile(testFile.toURI().toString())) {
261 final DefaultFileMonitor monitor = new DefaultFileMonitor(new TestFileListener());
262
263 monitor.setDelay(DELAY_MILLIS);
264 monitor.addFile(fileObject);
265 monitor.start();
266 try {
267 testFile.delete();
268 waitFor(Status.DELETED, DELAY_MILLIS * 5);
269 } finally {
270 monitor.stop();
271 }
272 }
273 }
274
275 @Test
276 public void testFileModified() throws Exception {
277 writeToFile(testFile);
278 try (final FileObject fileObject = fileSystemManager.resolveFile(testFile.toURI().toURL().toString())) {
279 final DefaultFileMonitor monitor = new DefaultFileMonitor(new TestFileListener());
280
281 monitor.setDelay(DELAY_MILLIS);
282 monitor.addFile(fileObject);
283 monitor.start();
284 try {
285
286
287 Thread.sleep(DELAY_MILLIS * 10);
288 final long valueMillis = System.currentTimeMillis();
289 final boolean rcMillis = testFile.setLastModified(valueMillis);
290 assertTrue("setLastModified succeeded", rcMillis);
291 waitFor(Status.CHANGED, DELAY_MILLIS * 5);
292 } finally {
293 monitor.stop();
294 }
295 }
296 }
297
298 @Test
299 public void testFileMonitorRestarted() throws Exception {
300 try (final FileObject fileObject = fileSystemManager.resolveFile(testFile.toURI().toString())) {
301 final DefaultFileMonitor monitor = new DefaultFileMonitor(new TestFileListener());
302
303 monitor.setDelay(DELAY_MILLIS);
304 monitor.addFile(fileObject);
305
306 monitor.start();
307 try {
308 writeToFile(testFile);
309 Thread.sleep(DELAY_MILLIS * 5);
310 } finally {
311 monitor.stop();
312 }
313
314 monitor.start();
315 try {
316 testFile.delete();
317 waitFor(Status.DELETED, DELAY_MILLIS * 5);
318 } finally {
319 monitor.stop();
320 }
321 }
322 }
323
324 @Test
325 public void testFileRecreated() throws Exception {
326 try (final FileObject fileObject = fileSystemManager.resolveFile(testFile.toURI())) {
327 final DefaultFileMonitor monitor = new DefaultFileMonitor(new TestFileListener());
328
329 monitor.setDelay(DELAY_MILLIS);
330 monitor.addFile(fileObject);
331 monitor.start();
332 try {
333 writeToFile(testFile);
334 waitFor(Status.CREATED, DELAY_MILLIS * 10);
335 status = null;
336 testFile.delete();
337 waitFor(Status.DELETED, DELAY_MILLIS * 10);
338 status = null;
339 Thread.sleep(DELAY_MILLIS * 5);
340 monitor.addFile(fileObject);
341 writeToFile(testFile);
342 waitFor(Status.CREATED, DELAY_MILLIS * 10);
343 } finally {
344 monitor.stop();
345 }
346 }
347 }
348
349 private void waitFor(final Status expected, final long timeoutMillis) throws InterruptedException {
350 if (expected == status) {
351 return;
352 }
353 long remaining = timeoutMillis;
354 final long interval = timeoutMillis / 10;
355 while (remaining > 0) {
356 Thread.sleep(interval);
357 remaining -= interval;
358 if (expected == status) {
359 return;
360 }
361 }
362 assertTrue("No event occurred", status != null);
363 assertEquals("Incorrect event " + status, expected, status);
364 }
365
366 private void writeToFile(final File file) throws IOException {
367
368 try (final BufferedWriter out = Files.newBufferedWriter(file.toPath())) {
369 out.write("string=value1");
370 }
371 }
372
373 }