/* * Syncany, www.syncany.org * Copyright (C) 2011-2015 Philipp C. Heckel <philipp.heckel@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.syncany.tests.integration.operations; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertTrue; import java.io.File; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import org.junit.Test; import org.syncany.config.Logging; import org.syncany.operations.watch.DefaultRecursiveWatcher; import org.syncany.operations.watch.RecursiveWatcher.WatchListener; import org.syncany.tests.unit.util.TestFileUtil; public class RecursiveWatcherTest { static { Logging.init(); } @Test public void testWatchOneFile() throws Exception { // Setup File tempDir = TestFileUtil.createTempDirectoryInSystemTemp(); TestFileUtil.createRandomFilesInDirectory(tempDir, 50*1024, 20); // Test final AtomicBoolean eventOccurred = new AtomicBoolean(false); DefaultRecursiveWatcher watcher = new DefaultRecursiveWatcher(Paths.get(tempDir.getAbsolutePath()), new ArrayList<Path>(), 300, new WatchListener() { @Override public void watchEventsOccurred() { eventOccurred.set(true); } }); // Start watcher and wait for watch service to set watch on all folders watcher.start(); Thread.sleep(100); // Event 1 TestFileUtil.createRandomFileInDirectory(tempDir, 10); assertFalse(eventOccurred.get()); Thread.sleep(550); assertTrue(eventOccurred.get()); // Stop watcher (close watches) watcher.stop(); // Tear down TestFileUtil.deleteDirectory(tempDir); } @Test public void testWatchExistingSubfolderEvent() throws Exception { // Setup File tempDir = TestFileUtil.createTempDirectoryInSystemTemp(); File subDir1 = new File(tempDir+"/subdir1"); // Test final AtomicBoolean eventOccurred = new AtomicBoolean(false); DefaultRecursiveWatcher watcher = new DefaultRecursiveWatcher(Paths.get(tempDir.getAbsolutePath()), new ArrayList<Path>(), 300, new WatchListener() { @Override public void watchEventsOccurred() { eventOccurred.set(true); } }); // Create sub folder BEFORE watcher starts subDir1.mkdir(); // Start watcher and wait for watch service to set watch on all folders watcher.start(); Thread.sleep(100); // Event 1 TestFileUtil.createRandomFileInDirectory(subDir1, 10); assertFalse(eventOccurred.get()); Thread.sleep(350); assertTrue(eventOccurred.get()); // Stop watcher (close watches) watcher.stop(); // Tear down TestFileUtil.deleteDirectory(tempDir); } @Test public void testWatchNewSubfolderEvent() throws Exception { // Setup File tempDir = TestFileUtil.createTempDirectoryInSystemTemp(); File subDir1 = new File(tempDir+"/subdir1"); // Test final AtomicBoolean eventOccurred = new AtomicBoolean(false); DefaultRecursiveWatcher watcher = new DefaultRecursiveWatcher(Paths.get(tempDir.getAbsolutePath()), new ArrayList<Path>(), 300, new WatchListener() { @Override public void watchEventsOccurred() { eventOccurred.set(true); } }); // Start watcher and wait for watch service to set watch on all folders watcher.start(); Thread.sleep(150); // Create sub folder AFTER watcher starts subDir1.mkdir(); Thread.sleep(370); assertTrue(eventOccurred.get()); eventOccurred.set(false); // Event on NEW subfolder TestFileUtil.createRandomFileInDirectory(subDir1, 10); assertFalse(eventOccurred.get()); Thread.sleep(350); assertTrue(eventOccurred.get()); // Stop watcher (close watches) watcher.stop(); // Tear down TestFileUtil.deleteDirectory(tempDir); } @Test public void testWatch100LevelsOfNewSubfolders() throws Exception { // Setup File tempDir = TestFileUtil.createTempDirectoryInSystemTemp(); // Test final AtomicBoolean eventOccurred = new AtomicBoolean(false); DefaultRecursiveWatcher watcher = new DefaultRecursiveWatcher(Paths.get(tempDir.getAbsolutePath()), new ArrayList<Path>(), 300, new WatchListener() { @Override public void watchEventsOccurred() { eventOccurred.set(true); } }); // Start watcher and wait for watch service to set watch on all folders watcher.start(); Thread.sleep(100); // Create sub folder hierarchy File lastSubFolder = tempDir; for (int i=0; i<100; i++) { lastSubFolder.mkdir(); lastSubFolder = new File(lastSubFolder+"/"+i); } lastSubFolder.mkdir(); // Wait for settlement Thread.sleep(350); eventOccurred.set(false); // Event on DEEPEST new subfolder TestFileUtil.createRandomFileInDirectory(lastSubFolder, 10*1024); assertFalse(eventOccurred.get()); Thread.sleep(500); assertTrue(eventOccurred.get()); // Stop watcher (close watches) watcher.stop(); // Tear down TestFileUtil.deleteDirectory(tempDir); } @Test public void testWatchFireOnceWhenLargeFileFinishes() throws Exception { // Setup File tempDir = TestFileUtil.createTempDirectoryInSystemTemp(); // Test final AtomicLong watcherEventOccurredTime = new AtomicLong(0L); final AtomicInteger watcherEventOccurredCount = new AtomicInteger(0); final AtomicLong fileWrittenTime = new AtomicLong(0L); DefaultRecursiveWatcher watcher = new DefaultRecursiveWatcher(Paths.get(tempDir.getAbsolutePath()), new ArrayList<Path>(), 300, new WatchListener() { @Override public void watchEventsOccurred() { watcherEventOccurredCount.addAndGet(1); watcherEventOccurredTime.set(System.currentTimeMillis()); } }); // Start watcher watcher.start(); Thread.sleep(400); // Wait for watch service to set watch on all folders File largeFile = new File(tempDir+"/largefile"); TestFileUtil.createRandomFile(largeFile, 50*1024*1024); fileWrittenTime.set(System.currentTimeMillis()); // Stop watcher (close watches) Thread.sleep(800); // Wait for the watcher to fire an event watcher.stop(); // Test assertNotSame(0L, watcherEventOccurredTime.get()); assertEquals(1, watcherEventOccurredCount.get()); assertNotSame(0L, fileWrittenTime.get()); assertTrue(watcherEventOccurredTime.get() >= fileWrittenTime.get()); // Tear down TestFileUtil.deleteDirectory(tempDir); } @Test public void testWatchFireEventCount() throws Exception { // Setup File tempDir = TestFileUtil.createTempDirectoryInSystemTemp(); // Test final AtomicInteger watcherEventOccurredCount = new AtomicInteger(0); DefaultRecursiveWatcher watcher = new DefaultRecursiveWatcher(Paths.get(tempDir.getAbsolutePath()), new ArrayList<Path>(), 300, new WatchListener() { @Override public void watchEventsOccurred() { watcherEventOccurredCount.addAndGet(1); } }); // Start watcher watcher.start(); Thread.sleep(200); // Wait for watch service to set watch on all folders for (int i=0; i<20; i++) { TestFileUtil.createRandomFile(new File(tempDir+"/"+i), 50*1024); } // Stop watcher (close watches) Thread.sleep(400); // Wait for the watcher to fire an event watcher.stop(); // Test assertEquals(1, watcherEventOccurredCount.get()); // not 20! // Tear down TestFileUtil.deleteDirectory(tempDir); } }