1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.jci.monitor;
19  
20  import java.io.File;
21  import java.io.FileOutputStream;
22  import java.io.FileWriter;
23  import java.io.IOException;
24  
25  import junit.framework.TestCase;
26  
27  import org.apache.commons.io.FileUtils;
28  import org.apache.commons.jci.listeners.AbstractFilesystemAlterationListener;
29  import org.apache.commons.logging.Log;
30  import org.apache.commons.logging.LogFactory;
31  
32  
33  /**
34   * 
35   * @author tcurdt
36   */
37  public final class FilesystemAlterationMonitorTestCase extends TestCase {
38  
39      private final Log log = LogFactory.getLog(FilesystemAlterationMonitorTestCase.class);
40  
41      private FilesystemAlterationMonitor fam;
42      private MyFilesystemAlterationListener listener;
43  
44      private File directory;
45  
46      
47      protected void setUp() throws Exception {
48          directory = createTempDirectory();
49          assertTrue(directory.exists());
50          assertTrue(directory.isDirectory());
51      }
52      
53      protected void tearDown() throws Exception {
54          FileUtils.deleteDirectory(directory);
55      }
56      
57      
58      protected File createDirectory( final String pName ) throws Exception {
59          final File newDirectory = new File(directory, pName);
60          assertTrue(newDirectory.mkdir());
61          assertTrue(newDirectory.exists());
62          assertTrue(newDirectory.isDirectory());
63          return newDirectory;
64      }
65      
66      protected File writeFile( final String pName, final byte[] pData ) throws Exception {
67          final File file = new File(directory, pName);
68          final File parent = file.getParentFile();
69          if (!parent.exists()) {
70              if (!parent.mkdirs()) {
71                  throw new IOException("could not create" + parent);
72              }
73          }
74          
75          log.debug("writing file " + pName + " (" + pData.length + " bytes)");
76          
77          final FileOutputStream os = new FileOutputStream(file);
78          os.write(pData);
79          os.close();
80          
81          assertTrue(file.exists());
82          assertTrue(file.isFile());
83          
84          return file;
85      }
86  
87      protected File writeFile( final String pName, final String pText ) throws Exception {
88          final File file = new File(directory, pName);
89          final File parent = file.getParentFile();
90          if (!parent.exists()) {
91              if (!parent.mkdirs()) {
92                  throw new IOException("could not create" + parent);
93              }
94          }
95          log.debug("writing " + file);
96          final FileWriter writer = new FileWriter(file);
97          writer.write(pText);
98          writer.close();
99          
100         assertTrue(file.exists());
101         assertTrue(file.isFile());
102         
103         return file;
104     }
105 
106     protected File createTempDirectory() throws IOException {
107         final File tempFile = File.createTempFile("jci", null);
108         
109         if (!tempFile.delete()) {
110             throw new IOException();
111         }
112         
113         if (!tempFile.mkdir()) {
114             throw new IOException();
115         }
116         
117         return tempFile;         
118     }
119 
120 
121     protected void delay() {
122         try {
123             Thread.sleep(1500);
124         } catch (final InterruptedException e) {
125         }
126     }
127 
128 
129     
130     private static class MyFilesystemAlterationListener extends AbstractFilesystemAlterationListener {
131     }
132 
133     private void start() throws Exception {
134         fam = new FilesystemAlterationMonitor();
135         listener = new MyFilesystemAlterationListener();
136         fam.addListener(directory, listener);
137         fam.start();
138         listener.waitForFirstCheck();
139     }
140     
141     private void stop() {
142         fam.stop();
143     }
144     
145     public void testListenerDoublication() throws Exception {
146         fam = new FilesystemAlterationMonitor();
147         listener = new MyFilesystemAlterationListener();
148         
149         fam.addListener(directory, listener);
150         assertTrue(fam.getListenersFor(directory).length == 1);
151         
152         fam.addListener(directory, listener); 
153         assertTrue(fam.getListenersFor(directory).length == 1);
154     }
155 
156     public void testDirectoryDoublication() throws Exception {
157         fam = new FilesystemAlterationMonitor();
158 
159         fam.addListener(directory, new MyFilesystemAlterationListener()); 
160         assertTrue(fam.getListenersFor(directory).length == 1);
161         
162         fam.addListener(directory, new MyFilesystemAlterationListener()); 
163         assertTrue(fam.getListenersFor(directory).length == 2);
164     }
165 
166     public void testCreateFileDetection() throws Exception {
167         start();
168         
169         writeFile("file", "file");
170         
171         listener.waitForCheck();
172         
173         assertTrue(listener.getCreatedFiles().size() == 1);
174         
175         stop();
176     }
177 
178     public void testCreateDirectoryDetection() throws Exception {
179         start();
180 
181         createDirectory("dir");
182         
183         listener.waitForCheck();
184         
185         assertTrue(listener.getCreatedDirectories().size() == 1);
186         
187         stop();
188     }
189 
190     public void testDeleteFileDetection() throws Exception {
191         start();
192 
193         final File file = writeFile("file", "file");
194         
195         listener.waitForCheck();
196         
197         assertTrue(listener.getCreatedFiles().size() == 1);
198         
199         file.delete();
200         assertTrue(!file.exists());
201 
202         listener.waitForCheck();
203         
204         assertTrue(listener.getDeletedFiles().size() == 1);
205         
206         stop();        
207     }
208     public void testDeleteDirectoryDetection() throws Exception {
209         start();
210 
211         final File dir = createDirectory("dir");
212         createDirectory("dir/sub");
213         final File file = writeFile("dir/sub/file", "file");
214 
215         listener.waitForCheck();
216         
217         assertEquals(2, listener.getCreatedDirectories().size());
218         assertEquals(1, listener.getCreatedFiles().size());
219 
220         delay();
221         
222         FileUtils.deleteDirectory(dir);
223         assertTrue(!dir.exists());
224         assertTrue(!file.exists());
225 
226         listener.waitForCheck();
227         
228         assertEquals(2, listener.getDeletedDirectories().size());
229         assertEquals(1, listener.getDeletedFiles().size());
230 
231         stop();
232     }
233 
234     public void testModifyFileDetection() throws Exception {
235         start();
236 
237         writeFile("file", "file");
238         
239         listener.waitForCheck();
240         
241         assertTrue(listener.getCreatedFiles().size() == 1);
242 
243         delay();
244 
245         writeFile("file", "changed file");
246 
247         listener.waitForCheck();
248         
249         assertTrue(listener.getChangedFiles().size() == 1);
250         
251         stop();
252     }
253 
254     public void testCreatingLocalDirectoryChangesLastModified() throws Exception {
255         final long modified = directory.lastModified();
256 
257         delay();
258         
259         createDirectory("directory");
260 
261         delay();
262                
263         assertTrue(directory.lastModified() != modified);
264     }
265 
266     public void testCreatingLocalFileChangesLastModified() throws Exception {
267         final long modified = directory.lastModified();
268 
269         delay();
270         
271         writeFile("file", "file");
272 
273         delay();
274 
275         assertTrue(directory.lastModified() != modified);
276     }
277 
278     public void testCreatingSubDirectoryChangesLastModified() throws Exception {
279         createDirectory("dir");
280 
281         final long modified = directory.lastModified();
282 
283         delay();
284 
285         createDirectory("dir/sub");
286 
287         assertTrue(directory.lastModified() == modified);
288     }
289 
290     public void testCreatingFileInSubDirectoryChangesLastModified() throws Exception {
291         createDirectory("dir");
292 
293         final long modified = directory.lastModified();
294 
295         delay();
296                 
297         writeFile("dir/file", "file");
298 
299         assertTrue(directory.lastModified() == modified);
300     }
301     
302     public void testInterval() throws Exception {
303 
304         final long interval = 1000;
305 
306         start();
307         fam.setInterval(interval);
308 
309         listener.waitForCheck();
310         long t1 = System.currentTimeMillis();
311 
312         listener.waitForCheck();
313         long t2 = System.currentTimeMillis();
314         
315         long diff = t2-t1;
316         
317         // interval should be at around the same interval
318         assertTrue("the interval was set to " + interval + " but the time difference was " + diff, (diff > (interval-50)) && (diff < (interval+50)));
319         
320         stop();
321     }    
322 }