001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018 package org.apache.commons.jci.monitor;
019
020 import java.io.File;
021 import java.io.FileOutputStream;
022 import java.io.FileWriter;
023 import java.io.IOException;
024
025 import junit.framework.TestCase;
026
027 import org.apache.commons.io.FileUtils;
028 import org.apache.commons.jci.listeners.AbstractFilesystemAlterationListener;
029 import org.apache.commons.logging.Log;
030 import org.apache.commons.logging.LogFactory;
031
032
033 /**
034 *
035 * @author tcurdt
036 */
037 public final class FilesystemAlterationMonitorTestCase extends TestCase {
038
039 private final Log log = LogFactory.getLog(FilesystemAlterationMonitorTestCase.class);
040
041 private FilesystemAlterationMonitor fam;
042 private MyFilesystemAlterationListener listener;
043
044 private File directory;
045
046
047 @Override
048 protected void setUp() throws Exception {
049 directory = createTempDirectory();
050 assertTrue(directory.exists());
051 assertTrue(directory.isDirectory());
052 }
053
054 @Override
055 protected void tearDown() throws Exception {
056 FileUtils.deleteDirectory(directory);
057 }
058
059
060 protected File createDirectory( final String pName ) throws Exception {
061 final File newDirectory = new File(directory, pName);
062 assertTrue(newDirectory.mkdir());
063 assertTrue(newDirectory.exists());
064 assertTrue(newDirectory.isDirectory());
065 return newDirectory;
066 }
067
068 protected File writeFile( final String pName, final byte[] pData ) throws Exception {
069 final File file = new File(directory, pName);
070 final File parent = file.getParentFile();
071 if (!parent.mkdirs() && !parent.isDirectory()) {
072 throw new IOException("could not create" + parent);
073 }
074
075 log.debug("writing file " + pName + " (" + pData.length + " bytes)");
076
077 final FileOutputStream os = new FileOutputStream(file);
078 os.write(pData);
079 os.close();
080
081 assertTrue(file.exists());
082 assertTrue(file.isFile());
083
084 return file;
085 }
086
087 protected File writeFile( final String pName, final String pText ) throws Exception {
088 final File file = new File(directory, pName);
089 final File parent = file.getParentFile();
090 if (!parent.mkdirs() && !parent.isDirectory()) {
091 throw new IOException("could not create" + parent);
092 }
093 log.debug("writing " + file);
094 final FileWriter writer = new FileWriter(file);
095 writer.write(pText);
096 writer.close();
097
098 assertTrue(file.exists());
099 assertTrue(file.isFile());
100
101 return file;
102 }
103
104 protected File createTempDirectory() throws IOException {
105 final File tempFile = File.createTempFile("jci", null);
106
107 if (!tempFile.delete()) {
108 throw new IOException();
109 }
110
111 if (!tempFile.mkdir()) {
112 throw new IOException();
113 }
114
115 return tempFile;
116 }
117
118
119 protected void delay() {
120 try {
121 Thread.sleep(1500);
122 } catch (final InterruptedException e) {
123 }
124 }
125
126
127
128 private static class MyFilesystemAlterationListener extends AbstractFilesystemAlterationListener {
129 }
130
131 private void start() throws Exception {
132 fam = new FilesystemAlterationMonitor();
133 listener = new MyFilesystemAlterationListener();
134 fam.addListener(directory, listener);
135 fam.start();
136 listener.waitForFirstCheck();
137 }
138
139 private void stop() {
140 fam.stop();
141 }
142
143 public void testListenerDoublication() throws Exception {
144 fam = new FilesystemAlterationMonitor();
145 listener = new MyFilesystemAlterationListener();
146
147 fam.addListener(directory, listener);
148 assertEquals(1, fam.getListenersFor(directory).length);
149
150 fam.addListener(directory, listener);
151 assertEquals(1, fam.getListenersFor(directory).length);
152
153 fam.removeListener(listener);
154 assertEquals(0, fam.getListenersFor(directory).length);
155 }
156
157 public void testDirectoryDoublication() throws Exception {
158 fam = new FilesystemAlterationMonitor();
159
160 fam.addListener(directory, new MyFilesystemAlterationListener());
161 assertEquals(1, fam.getListenersFor(directory).length);
162
163 fam.addListener(directory, new MyFilesystemAlterationListener());
164 assertEquals(2, fam.getListenersFor(directory).length);
165 }
166
167 public void testCreateFileDetection() throws Exception {
168 start();
169
170 writeFile("file", "file");
171
172 listener.waitForCheck();
173
174 assertEquals(1, listener.getCreatedFiles().size());
175
176 stop();
177 }
178
179 public void testTimeout() throws Exception {
180 listener = new MyFilesystemAlterationListener();
181
182 try {
183 listener.waitForFirstCheck();
184 fail("should be an timeout");
185 } catch(Exception e) {
186 assertEquals("timeout", e.getMessage());
187 }
188
189 start();
190
191 try {
192 listener.waitForEvent();
193 fail("should be an timeout");
194 } catch(Exception e) {
195 assertEquals("timeout", e.getMessage());
196 }
197
198 stop();
199
200 try {
201 listener.waitForCheck();
202 fail("should be an timeout");
203 } catch(Exception e) {
204 assertEquals("timeout", e.getMessage());
205 }
206
207 }
208
209 public void testCreateDirectoryDetection() throws Exception {
210 start();
211
212 createDirectory("dir");
213
214 listener.waitForCheck();
215
216 assertEquals(1, listener.getCreatedDirectories().size());
217
218 stop();
219 }
220
221 public void testDeleteFileDetection() throws Exception {
222 start();
223
224 final File file = writeFile("file", "file");
225
226 assertTrue("file should exist", file.exists());
227
228 listener.waitForCheck();
229
230 assertEquals("expecting 1 file created", 1, listener.getCreatedFiles().size());
231 //assertEquals("expecting 0 directories changed", 0, listener.getChangedDirectories().size()); // todo investigate why this is failing on Windows
232
233 file.delete();
234 assertFalse("file should not exist", file.exists());
235
236 listener.waitForCheck();
237
238 assertEquals("expecting 1 file deleted", 1, listener.getDeletedFiles().size());
239
240 stop();
241 }
242 public void testDeleteDirectoryDetection() throws Exception {
243 start();
244
245 final File dir = createDirectory("dir");
246 createDirectory("dir/sub");
247 final File file = writeFile("dir/sub/file", "file");
248
249 listener.waitForCheck();
250
251 assertEquals(2, listener.getCreatedDirectories().size());
252 assertEquals(1, listener.getCreatedFiles().size());
253
254 delay();
255
256 FileUtils.deleteDirectory(dir);
257 assertTrue(!dir.exists());
258 assertTrue(!file.exists());
259
260 listener.waitForCheck();
261
262 assertEquals(2, listener.getDeletedDirectories().size());
263 assertEquals(1, listener.getDeletedFiles().size());
264
265 stop();
266 }
267
268 public void testModifyFileDetection() throws Exception {
269 start();
270
271 writeFile("file", "file");
272
273 listener.waitForCheck();
274
275 assertEquals(1, listener.getCreatedFiles().size());
276
277 delay();
278
279 writeFile("file", "changed file");
280
281 listener.waitForCheck();
282
283 assertEquals(1, listener.getChangedFiles().size());
284
285 stop();
286 }
287
288 public void testCreatingLocalDirectoryChangesLastModified() throws Exception {
289 final long modified = directory.lastModified();
290
291 delay();
292
293 createDirectory("directory");
294
295 delay();
296
297 assertTrue(directory.lastModified() != modified);
298 }
299
300 public void testCreatingLocalFileChangesLastModified() throws Exception {
301 final long modified = directory.lastModified();
302
303 delay();
304
305 writeFile("file", "file");
306
307 delay();
308
309 assertTrue(directory.lastModified() != modified);
310 }
311
312 public void testCreatingSubDirectoryChangesLastModified() throws Exception {
313 createDirectory("dir");
314
315 final long modified = directory.lastModified();
316
317 delay();
318
319 createDirectory("dir/sub");
320
321 assertTrue(directory.lastModified() == modified);
322 }
323
324 public void testCreatingFileInSubDirectoryChangesLastModified() throws Exception {
325 createDirectory("dir");
326
327 final long modified = directory.lastModified();
328
329 delay();
330
331 writeFile("dir/file", "file");
332
333 assertTrue(directory.lastModified() == modified);
334 }
335
336 public void testInterval() throws Exception {
337
338 final long interval = 1000;
339
340 start();
341 fam.setInterval(interval);
342
343 listener.waitForCheck();
344 long t1 = System.currentTimeMillis();
345
346 listener.waitForCheck();
347 long t2 = System.currentTimeMillis();
348
349 long diff = t2-t1;
350
351 // interval should be at around the same interval
352 assertTrue("the interval was set to " + interval + " but the time difference was " + diff, (diff > (interval-50)) && (diff < (interval+50)));
353
354 stop();
355 }
356 }