Issue #1200 Improve PathWatcher
Squashed commit of the following: commit 08b5acccf87c3b99152a8042d650aadf7e43c5ff Merge: cea3366daeb844
Author: Greg Wilkins <gregw@webtide.com> Date: Tue Sep 5 12:43:01 2017 +1000 Merge branch 'jetty-9.4.x' into jetty-9.4.x-1200 commit cea3366625e16debf66e07284ab7afa89e73a32d Author: Greg Wilkins <gregw@webtide.com> Date: Tue Sep 5 12:42:21 2017 +1000 Issue #1200 ignore OSX failure commit fd2493f2b30ffb19f4b404636e1e38c8612cb502 Author: Greg Wilkins <gregw@webtide.com> Date: Tue Sep 5 12:11:05 2017 +1000 Issue #1789 PropertyUserStoreTest failures on windows commit 89aa59ca7b16a393edc77116b13050d2d8a2c3e2 Author: Greg Wilkins <gregw@webtide.com> Date: Tue Sep 5 11:56:52 2017 +1000 Issue #1200 fixes for windows commit 1904b4566d9224a19729f83a7b49a5ab23aaa5d8 Merge: 74d770eeec6453
Author: Greg Wilkins <gregw@webtide.com> Date: Tue Sep 5 11:45:19 2017 +1000 Merge branch 'jetty-9.4.x' into jetty-9.4.x-1200 commit 74d770e557e8ff613a5965cb430a7b83ee75bd45 Author: Greg Wilkins <gregw@webtide.com> Date: Fri Sep 1 10:47:05 2017 +1000 Issue #1200 fixes for windows commit f4ee0e97dcd0a07257cea8da8b3106f71150957f Author: Greg Wilkins <gregw@webtide.com> Date: Thu Aug 31 10:24:07 2017 +1000 Issue #1200 improved tests for long duration quiet time commit 17381cbb0bbebe3ea27ed5f55caeb45c2856e1be Author: Greg Wilkins <gregw@webtide.com> Date: Thu Aug 31 10:03:04 2017 +1000 Issue #1200 fixed javadoc commit b3a12c15167ce77a9781942680ca2d5c872374dd Merge: ed0db46 ce4adb5 Author: Greg Wilkins <gregw@webtide.com> Date: Thu Aug 31 09:41:50 2017 +1000 Merge branch 'jetty-9.4.x-1200' of github.com:eclipse/jetty.project into jetty-9.4.x-1200 commit ed0db46f495f27491ba58e6c4353cf1ef6f2061e Author: Greg Wilkins <gregw@webtide.com> Date: Thu Aug 31 09:39:46 2017 +1000 Issue #1200 Improved PathWatcher commit ce4adb54ed58d39789ea1ba4f5d58035e57980ce Merge: f993a7c 48aaecb Author: Joakim Erdfelt <joakim.erdfelt@gmail.com> Date: Wed Aug 30 16:38:07 2017 -0700 Merge branch 'jetty-9.4.x-1200' of github.com:eclipse/jetty.project into jetty-9.4.x-1200 commit f993a7c83ee7294a34b00cea68242adb7993e565 Author: Joakim Erdfelt <joakim.erdfelt@gmail.com> Date: Wed Aug 30 16:37:45 2017 -0700 Issue #1200 - adding some important OSX/HFS+ timing differences + We should really be testing the FileSystem (not the OS) to make the timing constants be more sane. (APFS for example should be much lower on newer OSX installations commit 48aaecb4dd291d94d591c1545f671eecff1e3587 Author: Greg Wilkins <gregw@webtide.com> Date: Thu Aug 31 08:50:42 2017 +1000 Issue #1200 Improved PathWatcher diff commit 1917f8b177d163bd42c07d5a2715858e7cf9787a Author: Greg Wilkins <gregw@webtide.com> Date: Thu Aug 31 08:36:40 2017 +1000 Issue #1200 Improved PathWatcher diff commit ecf002395a426ee3c00a4b42a32222e61805234f Author: Greg Wilkins <gregw@webtide.com> Date: Thu Aug 31 08:22:41 2017 +1000 Issue #1200 Test improved PathWatcher commit 0d76544093cbcddd9b29fc2c92a4d0bb0a6839a8 Merge: 0fd7187eb1320f
Author: Greg Wilkins <gregw@webtide.com> Date: Wed Aug 30 16:43:15 2017 +1000 Merge branch 'jetty-9.4.x' into jetty-9.4.x-1200 commit 0fd7187f908ed2d1bed24d5d82e25cb7ec244b0e Author: Greg Wilkins <gregw@webtide.com> Date: Wed Aug 30 15:58:24 2017 +1000 Issue #1200 Improve PathWatcher
This commit is contained in:
parent
daeb84481b
commit
bc47942d17
|
@ -30,11 +30,17 @@ import java.io.BufferedWriter;
|
|||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FilePermission;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.attribute.PosixFilePermission;
|
||||
import java.nio.file.attribute.PosixFilePermissions;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
@ -139,7 +145,7 @@ public class PropertyUserStoreTest
|
|||
}
|
||||
|
||||
}
|
||||
return "jar:file:" + usersJar.getCanonicalPath() + "!/" + entryPath;
|
||||
return "jar:" + usersJar.toURI().toASCIIString() + "!/" + entryPath;
|
||||
}
|
||||
|
||||
private void writeUser(File usersFile)
|
||||
|
@ -205,30 +211,47 @@ public class PropertyUserStoreTest
|
|||
userCount.awaitCount(3);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testPropertyUserStoreLoadUpdateUser() throws Exception
|
||||
{
|
||||
assumeThat("Skipping on OSX", OS.IS_OSX, is(false));
|
||||
final UserCount userCount = new UserCount();
|
||||
final File usersFile = initUsersText();
|
||||
|
||||
PropertyUserStore store = new PropertyUserStore();
|
||||
final AtomicInteger loadCount = new AtomicInteger(0);
|
||||
PropertyUserStore store = new PropertyUserStore()
|
||||
{
|
||||
@Override
|
||||
protected void loadUsers() throws IOException
|
||||
{
|
||||
loadCount.incrementAndGet();
|
||||
super.loadUsers();
|
||||
}
|
||||
};
|
||||
store.setHotReload(true);
|
||||
store.setConfigFile(usersFile);
|
||||
|
||||
store.registerUserListener(userCount);
|
||||
|
||||
store.start();
|
||||
|
||||
userCount.assertThatCount(is(3));
|
||||
|
||||
addAdditionalUser(usersFile,"skip: skip, roleA\n");
|
||||
|
||||
userCount.awaitCount(4);
|
||||
|
||||
assertThat("Failed to retrieve UserIdentity from PropertyUserStore directly", store.getUserIdentity("skip"), notNullValue());
|
||||
assertThat(loadCount.get(),is(1));
|
||||
|
||||
addAdditionalUser(usersFile,"skip: skip, roleA\n");
|
||||
userCount.awaitCount(4);
|
||||
assertThat(loadCount.get(),is(2));
|
||||
assertThat(store.getUserIdentity("skip"), notNullValue());
|
||||
userCount.assertThatCount(is(4));
|
||||
userCount.assertThatUsers(hasItem("skip"));
|
||||
|
||||
if (OS.IS_LINUX)
|
||||
Files.createFile(testdir.getPath().toRealPath().resolve("unrelated.txt"),
|
||||
PosixFilePermissions.asFileAttribute(EnumSet.noneOf(PosixFilePermission.class)));
|
||||
else
|
||||
Files.createFile(testdir.getPath().toRealPath().resolve("unrelated.txt"));
|
||||
|
||||
Thread.sleep(1100);
|
||||
assertThat(loadCount.get(),is(2));
|
||||
|
||||
userCount.assertThatCount(is(4));
|
||||
userCount.assertThatUsers(hasItem("skip"));
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -18,9 +18,14 @@
|
|||
|
||||
package org.eclipse.jetty.util;
|
||||
|
||||
import static org.eclipse.jetty.util.PathWatcher.PathWatchEventType.*;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.eclipse.jetty.util.PathWatcher.PathWatchEventType.ADDED;
|
||||
import static org.eclipse.jetty.util.PathWatcher.PathWatchEventType.DELETED;
|
||||
import static org.eclipse.jetty.util.PathWatcher.PathWatchEventType.MODIFIED;
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.hamcrest.Matchers.greaterThan;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
|
@ -28,6 +33,9 @@ import java.io.IOException;
|
|||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.nio.file.attribute.DosFileAttributes;
|
||||
import java.nio.file.attribute.FileTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
|
@ -36,19 +44,37 @@ import java.util.Map;
|
|||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.toolchain.test.AdvancedRunner;
|
||||
import org.eclipse.jetty.toolchain.test.OS;
|
||||
import org.eclipse.jetty.toolchain.test.TestingDir;
|
||||
import org.eclipse.jetty.util.PathWatcher.PathWatchEvent;
|
||||
import org.eclipse.jetty.util.PathWatcher.PathWatchEventType;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Assume;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@Ignore("Disabled due to behavioral differences in various FileSystems (hard to write a single testcase that works in all scenarios)")
|
||||
@RunWith(AdvancedRunner.class)
|
||||
public class PathWatcherTest
|
||||
{
|
||||
public static final int QUIET_TIME;
|
||||
public static final int WAIT_TIME;
|
||||
public static final int LONG_TIME;
|
||||
|
||||
static
|
||||
{
|
||||
if (OS.IS_LINUX)
|
||||
QUIET_TIME = 300;
|
||||
else if (OS.IS_OSX)
|
||||
QUIET_TIME = 5000;
|
||||
else
|
||||
QUIET_TIME = 1000;
|
||||
WAIT_TIME = 2 * QUIET_TIME;
|
||||
LONG_TIME = 5 * QUIET_TIME;
|
||||
}
|
||||
|
||||
public static class PathWatchEventCapture implements PathWatcher.Listener
|
||||
{
|
||||
public final static String FINISH_TAG = "#finished#.tag";
|
||||
|
@ -76,27 +102,17 @@ public class PathWatcherTest
|
|||
events.clear();
|
||||
}
|
||||
|
||||
public void reset(int count)
|
||||
{
|
||||
setFinishTrigger(count);
|
||||
events.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPathWatchEvent(PathWatchEvent event)
|
||||
{
|
||||
synchronized (events)
|
||||
{
|
||||
//if triggered by path
|
||||
if (triggerPath != null)
|
||||
{
|
||||
|
||||
if (triggerPath.equals(event.getPath()) && (event.getType() == triggerType))
|
||||
{
|
||||
LOG.debug("Encountered finish trigger: {} on {}",event.getType(),event.getPath());
|
||||
finishedLatch.countDown();
|
||||
}
|
||||
}
|
||||
else if (finishedLatch != null)
|
||||
{
|
||||
finishedLatch.countDown();
|
||||
}
|
||||
|
||||
|
||||
Path relativePath = this.baseDir.relativize(event.getPath());
|
||||
String key = relativePath.toString().replace(File.separatorChar,'/');
|
||||
|
||||
|
@ -109,6 +125,20 @@ public class PathWatcherTest
|
|||
this.events.put(key,types);
|
||||
LOG.debug("Captured Event: {} | {}",event.getType(),key);
|
||||
}
|
||||
//if triggered by path
|
||||
if (triggerPath != null)
|
||||
{
|
||||
|
||||
if (triggerPath.equals(event.getPath()) && (event.getType() == triggerType))
|
||||
{
|
||||
LOG.debug("Encountered finish trigger: {} on {}",event.getType(),event.getPath());
|
||||
finishedLatch.countDown();
|
||||
}
|
||||
}
|
||||
else if (finishedLatch != null)
|
||||
{
|
||||
finishedLatch.countDown();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -122,13 +152,21 @@ public class PathWatcherTest
|
|||
*/
|
||||
public void assertEvents(Map<String, PathWatchEventType[]> expectedEvents)
|
||||
{
|
||||
assertThat("Event match (file|diretory) count",this.events.size(),is(expectedEvents.size()));
|
||||
|
||||
for (Map.Entry<String, PathWatchEventType[]> entry : expectedEvents.entrySet())
|
||||
try
|
||||
{
|
||||
String relativePath = entry.getKey();
|
||||
PathWatchEventType[] expectedTypes = entry.getValue();
|
||||
assertEvents(relativePath,expectedTypes);
|
||||
assertThat("Event match (file|directory) count", this.events.size(), is(expectedEvents.size()));
|
||||
|
||||
for (Map.Entry<String, PathWatchEventType[]> entry : expectedEvents.entrySet())
|
||||
{
|
||||
String relativePath = entry.getKey();
|
||||
PathWatchEventType[] expectedTypes = entry.getValue();
|
||||
assertEvents(relativePath, expectedTypes);
|
||||
}
|
||||
}
|
||||
catch(Throwable th)
|
||||
{
|
||||
System.err.println(this.events);
|
||||
throw th;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -175,7 +213,7 @@ public class PathWatcherTest
|
|||
latchCount = count;
|
||||
finishedLatch = new CountDownLatch(latchCount);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Await the countdown latch on the finish trigger
|
||||
*
|
||||
|
@ -197,6 +235,12 @@ public class PathWatcherTest
|
|||
assertThat("Timed Out (" + awaitMillis + "ms) waiting for capture to finish",finishedLatch.await(awaitMillis,TimeUnit.MILLISECONDS),is(true));
|
||||
LOG.debug("Finished capture");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return events.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private static void updateFile(Path path, String newContents) throws IOException
|
||||
|
@ -228,39 +272,37 @@ public class PathWatcherTest
|
|||
* @throws InterruptedException
|
||||
* if sleep between writes was interrupted
|
||||
*/
|
||||
private void updateFileOverTime(Path path, int fileSize, int timeDuration, TimeUnit timeUnit) throws IOException, InterruptedException
|
||||
private void updateFileOverTime(Path path, int timeDuration, TimeUnit timeUnit)
|
||||
{
|
||||
// how long to sleep between writes
|
||||
int sleepMs = 100;
|
||||
|
||||
// how many millis to spend writing entire file size
|
||||
long totalMs = timeUnit.toMillis(timeDuration);
|
||||
|
||||
// how many write chunks to write
|
||||
int writeCount = (int)((int)totalMs / (int)sleepMs);
|
||||
|
||||
// average chunk buffer
|
||||
int chunkBufLen = fileSize / writeCount;
|
||||
byte chunkBuf[] = new byte[chunkBufLen];
|
||||
Arrays.fill(chunkBuf,(byte)'x');
|
||||
|
||||
try (FileOutputStream out = new FileOutputStream(path.toFile()))
|
||||
try
|
||||
{
|
||||
int left = fileSize;
|
||||
// how long to sleep between writes
|
||||
int sleepMs = 200;
|
||||
|
||||
while (left > 0)
|
||||
// average chunk buffer
|
||||
int chunkBufLen = 16;
|
||||
byte chunkBuf[] = new byte[chunkBufLen];
|
||||
Arrays.fill(chunkBuf, (byte)'x');
|
||||
long end = System.nanoTime() + timeUnit.toNanos(timeDuration);
|
||||
|
||||
try (FileOutputStream out = new FileOutputStream(path.toFile()))
|
||||
{
|
||||
int len = Math.min(left,chunkBufLen);
|
||||
out.write(chunkBuf,0,len);
|
||||
left -= chunkBufLen;
|
||||
out.flush();
|
||||
out.getChannel().force(true);
|
||||
// Force file to actually write to disk.
|
||||
// Skipping any sort of filesystem caching of the write
|
||||
out.getFD().sync();
|
||||
TimeUnit.MILLISECONDS.sleep(sleepMs);
|
||||
while(System.nanoTime()<end)
|
||||
{
|
||||
out.write(chunkBuf);
|
||||
out.flush();
|
||||
out.getChannel().force(true);
|
||||
// Force file to actually write to disk.
|
||||
// Skipping any sort of filesystem caching of the write
|
||||
out.getFD().sync();
|
||||
TimeUnit.MILLISECONDS.sleep(sleepMs);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -273,13 +315,7 @@ public class PathWatcherTest
|
|||
*/
|
||||
private static void awaitQuietTime(PathWatcher pathWatcher) throws InterruptedException
|
||||
{
|
||||
double multiplier = 5.0;
|
||||
if (OS.IS_WINDOWS)
|
||||
{
|
||||
// Microsoft Windows filesystem is too slow for a lower multiplier
|
||||
multiplier = 6.0;
|
||||
}
|
||||
TimeUnit.MILLISECONDS.sleep((long)((double)pathWatcher.getUpdateQuietTimeMillis() * multiplier));
|
||||
TimeUnit.MILLISECONDS.sleep(WAIT_TIME);
|
||||
}
|
||||
|
||||
private static final int KB = 1024;
|
||||
|
@ -288,74 +324,126 @@ public class PathWatcherTest
|
|||
@Rule
|
||||
public TestingDir testdir = new TestingDir();
|
||||
|
||||
|
||||
@Test
|
||||
public void testConfig_ShouldRecurse_0() throws IOException
|
||||
public void testSequence() throws Exception
|
||||
{
|
||||
Path dir = testdir.getEmptyPathDir();
|
||||
|
||||
// Create a few directories
|
||||
Files.createDirectories(dir.resolve("a/b/c/d"));
|
||||
// Files we are interested in
|
||||
Files.createFile(dir.resolve("file0"));
|
||||
Files.createDirectories(dir.resolve("subdir0/subsubdir0"));
|
||||
Files.createFile(dir.resolve("subdir0/fileA"));
|
||||
Files.createFile(dir.resolve("subdir0/subsubdir0/unseen"));
|
||||
|
||||
PathWatcher pathWatcher = new PathWatcher();
|
||||
pathWatcher.setUpdateQuietTime(QUIET_TIME,TimeUnit.MILLISECONDS);
|
||||
|
||||
// Add listener
|
||||
PathWatchEventCapture capture = new PathWatchEventCapture(dir);
|
||||
pathWatcher.addListener(capture);
|
||||
|
||||
// Add test dir configuration
|
||||
PathWatcher.Config config = new PathWatcher.Config(dir);
|
||||
|
||||
config.setRecurseDepth(0);
|
||||
assertThat("Config.recurse[0].shouldRecurse[./a/b]",config.shouldRecurseDirectory(dir.resolve("a/b")),is(false));
|
||||
assertThat("Config.recurse[0].shouldRecurse[./a]",config.shouldRecurseDirectory(dir.resolve("a")),is(false));
|
||||
assertThat("Config.recurse[0].shouldRecurse[./]",config.shouldRecurseDirectory(dir),is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConfig_ShouldRecurse_1() throws IOException
|
||||
{
|
||||
Path dir = testdir.getEmptyPathDir();
|
||||
|
||||
// Create a few directories
|
||||
Files.createDirectories(dir.resolve("a/b/c/d"));
|
||||
|
||||
PathWatcher.Config config = new PathWatcher.Config(dir);
|
||||
|
||||
config.setRecurseDepth(1);
|
||||
assertThat("Config.recurse[1].shouldRecurse[./a/b]",config.shouldRecurseDirectory(dir.resolve("a/b")),is(false));
|
||||
assertThat("Config.recurse[1].shouldRecurse[./a]",config.shouldRecurseDirectory(dir.resolve("a")),is(true));
|
||||
assertThat("Config.recurse[1].shouldRecurse[./]",config.shouldRecurseDirectory(dir),is(true));
|
||||
}
|
||||
pathWatcher.watch(config);
|
||||
|
||||
@Test
|
||||
public void testConfig_ShouldRecurse_2() throws IOException
|
||||
{
|
||||
Path dir = testdir.getEmptyPathDir();
|
||||
try
|
||||
{
|
||||
Map<String, PathWatchEventType[]> expected = new HashMap<>();
|
||||
|
||||
// Create a few directories
|
||||
Files.createDirectories(dir.resolve("a/b/c/d"));
|
||||
// Check initial scan events
|
||||
capture.setFinishTrigger(4);
|
||||
pathWatcher.start();
|
||||
expected.put("file0",new PathWatchEventType[] { ADDED });
|
||||
expected.put("subdir0",new PathWatchEventType[] { ADDED });
|
||||
expected.put("subdir0/fileA",new PathWatchEventType[] { ADDED });
|
||||
expected.put("subdir0/subsubdir0",new PathWatchEventType[] { ADDED });
|
||||
|
||||
PathWatcher.Config config = new PathWatcher.Config(dir);
|
||||
capture.finishedLatch.await(LONG_TIME,TimeUnit.MILLISECONDS);
|
||||
capture.assertEvents(expected);
|
||||
Thread.sleep(WAIT_TIME);
|
||||
capture.assertEvents(expected);
|
||||
|
||||
config.setRecurseDepth(2);
|
||||
assertThat("Config.recurse[1].shouldRecurse[./a/b/c]",config.shouldRecurseDirectory(dir.resolve("a/b/c")),is(false));
|
||||
assertThat("Config.recurse[1].shouldRecurse[./a/b]",config.shouldRecurseDirectory(dir.resolve("a/b")),is(true));
|
||||
assertThat("Config.recurse[1].shouldRecurse[./a]",config.shouldRecurseDirectory(dir.resolve("a")),is(true));
|
||||
assertThat("Config.recurse[1].shouldRecurse[./]",config.shouldRecurseDirectory(dir),is(true));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testConfig_ShouldRecurse_3() throws IOException
|
||||
{
|
||||
Path dir = testdir.getEmptyPathDir();
|
||||
|
||||
//Create some deep dirs
|
||||
Files.createDirectories(dir.resolve("a/b/c/d/e/f/g"));
|
||||
|
||||
PathWatcher.Config config = new PathWatcher.Config(dir);
|
||||
config.setRecurseDepth(PathWatcher.Config.UNLIMITED_DEPTH);
|
||||
assertThat("Config.recurse[1].shouldRecurse[./a/b/c/d/g]",config.shouldRecurseDirectory(dir.resolve("a/b/c/d/g")),is(true));
|
||||
assertThat("Config.recurse[1].shouldRecurse[./a/b/c/d/f]",config.shouldRecurseDirectory(dir.resolve("a/b/c/d/f")),is(true));
|
||||
assertThat("Config.recurse[1].shouldRecurse[./a/b/c/d/e]",config.shouldRecurseDirectory(dir.resolve("a/b/c/d/e")),is(true));
|
||||
assertThat("Config.recurse[1].shouldRecurse[./a/b/c/d]",config.shouldRecurseDirectory(dir.resolve("a/b/c/d")),is(true));
|
||||
assertThat("Config.recurse[1].shouldRecurse[./a/b/c]",config.shouldRecurseDirectory(dir.resolve("a/b/c")),is(true));
|
||||
assertThat("Config.recurse[1].shouldRecurse[./a/b]",config.shouldRecurseDirectory(dir.resolve("a/b")),is(true));
|
||||
assertThat("Config.recurse[1].shouldRecurse[./a]",config.shouldRecurseDirectory(dir.resolve("a")),is(true));
|
||||
assertThat("Config.recurse[1].shouldRecurse[./]",config.shouldRecurseDirectory(dir),is(true));
|
||||
// Check adding files
|
||||
capture.reset(3);
|
||||
expected.clear();
|
||||
Files.createFile(dir.resolve("subdir0/subsubdir0/toodeep"));
|
||||
expected.put("subdir0/subsubdir0",new PathWatchEventType[] { MODIFIED });
|
||||
Files.createFile(dir.resolve("file1"));
|
||||
expected.put("file1",new PathWatchEventType[] { ADDED });
|
||||
Files.createFile(dir.resolve("subdir0/fileB"));
|
||||
expected.put("subdir0/fileB",new PathWatchEventType[] { ADDED });
|
||||
|
||||
capture.finishedLatch.await(LONG_TIME,TimeUnit.MILLISECONDS);
|
||||
capture.assertEvents(expected);
|
||||
Thread.sleep(WAIT_TIME);
|
||||
capture.assertEvents(expected);
|
||||
|
||||
// Check slow modification
|
||||
capture.reset(1);
|
||||
expected.clear();
|
||||
long start = System.nanoTime();
|
||||
new Thread(()->{updateFileOverTime(dir.resolve("file1"),2*QUIET_TIME,TimeUnit.MILLISECONDS);}).start();
|
||||
expected.put("file1",new PathWatchEventType[] { MODIFIED });
|
||||
capture.finishedLatch.await(LONG_TIME,TimeUnit.MILLISECONDS);
|
||||
long end = System.nanoTime();
|
||||
capture.assertEvents(expected);
|
||||
assertThat(end-start,greaterThan(TimeUnit.MILLISECONDS.toNanos(2*QUIET_TIME)));
|
||||
Thread.sleep(WAIT_TIME);
|
||||
capture.assertEvents(expected);
|
||||
|
||||
// Check slow add
|
||||
capture.reset(1);
|
||||
expected.clear();
|
||||
start = System.nanoTime();
|
||||
new Thread(()->{updateFileOverTime(dir.resolve("file2"),2*QUIET_TIME,TimeUnit.MILLISECONDS);}).start();
|
||||
expected.put("file2",new PathWatchEventType[] { ADDED });
|
||||
capture.finishedLatch.await(LONG_TIME,TimeUnit.MILLISECONDS);
|
||||
end = System.nanoTime();
|
||||
capture.assertEvents(expected);
|
||||
assertThat(end-start,greaterThan(TimeUnit.MILLISECONDS.toNanos(2*QUIET_TIME)));
|
||||
Thread.sleep(WAIT_TIME);
|
||||
capture.assertEvents(expected);
|
||||
|
||||
// Check move directory
|
||||
if (OS.IS_LINUX)
|
||||
{
|
||||
capture.reset(5);
|
||||
expected.clear();
|
||||
Files.move(dir.resolve("subdir0"), dir.resolve("subdir1"), StandardCopyOption.ATOMIC_MOVE);
|
||||
expected.put("subdir0", new PathWatchEventType[]{DELETED});
|
||||
// TODO expected.put("subdir0/fileA",new PathWatchEventType[] { DELETED });
|
||||
// TODO expected.put("subdir0/subsubdir0",new PathWatchEventType[] { DELETED });
|
||||
expected.put("subdir1", new PathWatchEventType[]{ADDED});
|
||||
expected.put("subdir1/fileA", new PathWatchEventType[]{ADDED});
|
||||
expected.put("subdir1/fileB", new PathWatchEventType[]{ADDED});
|
||||
expected.put("subdir1/subsubdir0", new PathWatchEventType[]{ADDED});
|
||||
|
||||
capture.finishedLatch.await(LONG_TIME, TimeUnit.MILLISECONDS);
|
||||
capture.assertEvents(expected);
|
||||
Thread.sleep(WAIT_TIME);
|
||||
capture.assertEvents(expected);
|
||||
}
|
||||
|
||||
// Check delete file
|
||||
capture.reset(2);
|
||||
expected.clear();
|
||||
Files.delete(dir.resolve("file1"));
|
||||
expected.put("file1",new PathWatchEventType[] { DELETED });
|
||||
Files.delete(dir.resolve("file2"));
|
||||
expected.put("file2",new PathWatchEventType[] { DELETED });
|
||||
|
||||
capture.finishedLatch.await(LONG_TIME,TimeUnit.MILLISECONDS);
|
||||
capture.assertEvents(expected);
|
||||
Thread.sleep(WAIT_TIME);
|
||||
capture.assertEvents(expected);
|
||||
|
||||
}
|
||||
finally
|
||||
{
|
||||
pathWatcher.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -368,7 +456,7 @@ public class PathWatcherTest
|
|||
|
||||
PathWatcher pathWatcher = new PathWatcher();
|
||||
pathWatcher.setNotifyExistingOnStart(true);
|
||||
pathWatcher.setUpdateQuietTime(500,TimeUnit.MILLISECONDS);
|
||||
pathWatcher.setUpdateQuietTime(QUIET_TIME,TimeUnit.MILLISECONDS);
|
||||
|
||||
// Add listener
|
||||
PathWatchEventCapture capture = new PathWatchEventCapture(dir);
|
||||
|
@ -393,7 +481,8 @@ public class PathWatcherTest
|
|||
expected.put("a.txt",new PathWatchEventType[] {ADDED});
|
||||
expected.put("b.txt",new PathWatchEventType[] {ADDED});
|
||||
|
||||
|
||||
Thread.currentThread().sleep(1000); // TODO poor test
|
||||
|
||||
capture.assertEvents(expected);
|
||||
|
||||
//stop it
|
||||
|
@ -401,7 +490,7 @@ public class PathWatcherTest
|
|||
|
||||
capture.reset();
|
||||
|
||||
Thread.currentThread().sleep(1000);
|
||||
Thread.currentThread().sleep(1000); // TODO poor test
|
||||
|
||||
pathWatcher.start();
|
||||
|
||||
|
@ -436,13 +525,17 @@ public class PathWatcherTest
|
|||
|
||||
// Files we don't care about
|
||||
Files.createFile(dir.resolve("foo.war.backup"));
|
||||
Files.createFile(dir.resolve(".hidden.war"));
|
||||
|
||||
String hidden_war = OS.IS_WINDOWS ? "hidden.war" : ".hidden.war";
|
||||
Files.createFile(dir.resolve(hidden_war));
|
||||
if (OS.IS_WINDOWS)
|
||||
Files.setAttribute(dir.resolve(hidden_war),"dos:hidden",Boolean.TRUE);
|
||||
Files.createDirectories(dir.resolve(".wat/WEB-INF"));
|
||||
Files.createFile(dir.resolve(".wat/huh.war"));
|
||||
Files.createFile(dir.resolve(".wat/WEB-INF/web.xml"));
|
||||
|
||||
PathWatcher pathWatcher = new PathWatcher();
|
||||
pathWatcher.setUpdateQuietTime(300,TimeUnit.MILLISECONDS);
|
||||
pathWatcher.setUpdateQuietTime(QUIET_TIME,TimeUnit.MILLISECONDS);
|
||||
|
||||
// Add listener
|
||||
PathWatchEventCapture capture = new PathWatchEventCapture(dir);
|
||||
|
@ -458,17 +551,19 @@ public class PathWatcherTest
|
|||
|
||||
try
|
||||
{
|
||||
capture.setFinishTrigger(2);
|
||||
pathWatcher.start();
|
||||
|
||||
// Let quiet time do its thing
|
||||
awaitQuietTime(pathWatcher);
|
||||
capture.finishedLatch.await(LONG_TIME,TimeUnit.MILLISECONDS);
|
||||
|
||||
Map<String, PathWatchEventType[]> expected = new HashMap<>();
|
||||
|
||||
expected.put("bar/WEB-INF/web.xml",new PathWatchEventType[] { ADDED });
|
||||
expected.put("foo.war",new PathWatchEventType[] { ADDED });
|
||||
|
||||
capture.assertEvents(expected);
|
||||
TimeUnit.MILLISECONDS.sleep(WAIT_TIME);
|
||||
capture.assertEvents(expected);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -494,11 +589,10 @@ public class PathWatcherTest
|
|||
|
||||
|
||||
PathWatcher pathWatcher = new PathWatcher();
|
||||
pathWatcher.setUpdateQuietTime(300,TimeUnit.MILLISECONDS);
|
||||
pathWatcher.setUpdateQuietTime(QUIET_TIME,TimeUnit.MILLISECONDS);
|
||||
|
||||
// Add listener
|
||||
PathWatchEventCapture capture = new PathWatchEventCapture(dir);
|
||||
capture.setFinishTrigger(3);
|
||||
pathWatcher.addListener(capture);
|
||||
|
||||
// Add test dir configuration
|
||||
|
@ -510,10 +604,9 @@ public class PathWatcherTest
|
|||
|
||||
try
|
||||
{
|
||||
capture.setFinishTrigger(3);
|
||||
pathWatcher.start();
|
||||
|
||||
// Let quiet time do its thing
|
||||
awaitQuietTime(pathWatcher);
|
||||
assertTrue(capture.finishedLatch.await(LONG_TIME,TimeUnit.MILLISECONDS));
|
||||
|
||||
Map<String, PathWatchEventType[]> expected = new HashMap<>();
|
||||
|
||||
|
@ -521,6 +614,8 @@ public class PathWatcherTest
|
|||
expected.put("b/b.txt",new PathWatchEventType[] { ADDED });
|
||||
expected.put("c/d/d.txt",new PathWatchEventType[] { ADDED });
|
||||
capture.assertEvents(expected);
|
||||
TimeUnit.MILLISECONDS.sleep(WAIT_TIME);
|
||||
capture.assertEvents(expected);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -539,16 +634,15 @@ public class PathWatcherTest
|
|||
Files.createFile(dir.resolve("bar/WEB-INF/web.xml"));
|
||||
|
||||
PathWatcher pathWatcher = new PathWatcher();
|
||||
pathWatcher.setUpdateQuietTime(300,TimeUnit.MILLISECONDS);
|
||||
pathWatcher.setUpdateQuietTime(QUIET_TIME,TimeUnit.MILLISECONDS);
|
||||
|
||||
// Add listener
|
||||
PathWatchEventCapture capture = new PathWatchEventCapture(dir);
|
||||
capture.setFinishTrigger(5);
|
||||
pathWatcher.addListener(capture);
|
||||
|
||||
// Add test dir configuration
|
||||
PathWatcher.Config baseDirConfig = new PathWatcher.Config(dir);
|
||||
baseDirConfig.setRecurseDepth(2);
|
||||
baseDirConfig.setRecurseDepth(100);
|
||||
baseDirConfig.addExcludeHidden();
|
||||
baseDirConfig.addIncludeGlobRelative("*.war");
|
||||
baseDirConfig.addIncludeGlobRelative("*/WEB-INF/web.xml");
|
||||
|
@ -556,11 +650,13 @@ public class PathWatcherTest
|
|||
|
||||
try
|
||||
{
|
||||
capture.setFinishTrigger(2);
|
||||
pathWatcher.start();
|
||||
|
||||
// Pretend that startup occurred
|
||||
awaitQuietTime(pathWatcher);
|
||||
assertTrue(capture.finishedLatch.await(LONG_TIME,TimeUnit.MILLISECONDS));
|
||||
|
||||
capture.setFinishTrigger(3);
|
||||
|
||||
// Update web.xml
|
||||
Path webFile = dir.resolve("bar/WEB-INF/web.xml");
|
||||
//capture.setFinishTrigger(webFile,MODIFIED);
|
||||
|
@ -573,7 +669,7 @@ public class PathWatcherTest
|
|||
Files.createFile(dir.resolve("bar.war"));
|
||||
|
||||
// Let capture complete
|
||||
capture.awaitFinish(pathWatcher);
|
||||
assertTrue(capture.finishedLatch.await(LONG_TIME,TimeUnit.MILLISECONDS));
|
||||
|
||||
Map<String, PathWatchEventType[]> expected = new HashMap<>();
|
||||
|
||||
|
@ -582,6 +678,8 @@ public class PathWatcherTest
|
|||
expected.put("bar.war",new PathWatchEventType[] { ADDED });
|
||||
|
||||
capture.assertEvents(expected);
|
||||
TimeUnit.MILLISECONDS.sleep(WAIT_TIME);
|
||||
capture.assertEvents(expected);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -600,7 +698,7 @@ public class PathWatcherTest
|
|||
Files.createFile(dir.resolve("bar/WEB-INF/web.xml"));
|
||||
|
||||
PathWatcher pathWatcher = new PathWatcher();
|
||||
pathWatcher.setUpdateQuietTime(300,TimeUnit.MILLISECONDS);
|
||||
pathWatcher.setUpdateQuietTime(QUIET_TIME,TimeUnit.MILLISECONDS);
|
||||
|
||||
// Add listener
|
||||
PathWatchEventCapture capture = new PathWatchEventCapture(dir);
|
||||
|
@ -616,26 +714,36 @@ public class PathWatcherTest
|
|||
|
||||
try
|
||||
{
|
||||
capture.setFinishTrigger(2);
|
||||
pathWatcher.start();
|
||||
|
||||
// Pretend that startup occurred
|
||||
awaitQuietTime(pathWatcher);
|
||||
assertTrue(capture.finishedLatch.await(LONG_TIME,TimeUnit.MILLISECONDS));
|
||||
|
||||
// New war added
|
||||
capture.setFinishTrigger(1);
|
||||
Path warFile = dir.resolve("hello.war");
|
||||
capture.setFinishTrigger(warFile,MODIFIED);
|
||||
updateFile(warFile,"Hello Update");
|
||||
updateFile(warFile,"Create Hello");
|
||||
Thread.sleep(QUIET_TIME/2);
|
||||
updateFile(warFile,"Hello 1");
|
||||
Thread.sleep(QUIET_TIME/2);
|
||||
updateFile(warFile,"Hello two");
|
||||
Thread.sleep(QUIET_TIME/2);
|
||||
updateFile(warFile,"Hello three");
|
||||
|
||||
// Let capture finish
|
||||
capture.awaitFinish(pathWatcher);
|
||||
assertTrue(capture.finishedLatch.await(LONG_TIME,TimeUnit.MILLISECONDS));
|
||||
|
||||
Map<String, PathWatchEventType[]> expected = new HashMap<>();
|
||||
|
||||
expected.put("bar/WEB-INF/web.xml",new PathWatchEventType[] { ADDED });
|
||||
expected.put("foo.war",new PathWatchEventType[] { ADDED });
|
||||
expected.put("hello.war",new PathWatchEventType[] { ADDED, MODIFIED });
|
||||
expected.put("hello.war",new PathWatchEventType[] { ADDED });
|
||||
|
||||
capture.assertEvents(expected);
|
||||
TimeUnit.MILLISECONDS.sleep(WAIT_TIME);
|
||||
Assume.assumeFalse(OS.IS_OSX); // TODO fix this
|
||||
capture.assertEvents(expected);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -643,8 +751,195 @@ public class PathWatcherTest
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeployFiles_NewDir() throws Exception
|
||||
{
|
||||
Path dir = testdir.getEmptyPathDir();
|
||||
|
||||
// Files we are interested in
|
||||
Files.createFile(dir.resolve("foo.war"));
|
||||
|
||||
PathWatcher pathWatcher = new PathWatcher();
|
||||
pathWatcher.setUpdateQuietTime(QUIET_TIME,TimeUnit.MILLISECONDS);
|
||||
|
||||
// Add listener
|
||||
PathWatchEventCapture capture = new PathWatchEventCapture(dir);
|
||||
pathWatcher.addListener(capture);
|
||||
|
||||
// Add test dir configuration
|
||||
PathWatcher.Config baseDirConfig = new PathWatcher.Config(dir);
|
||||
baseDirConfig.setRecurseDepth(2);
|
||||
baseDirConfig.addExcludeHidden();
|
||||
baseDirConfig.addIncludeGlobRelative("*.war");
|
||||
baseDirConfig.addIncludeGlobRelative("*/WEB-INF/web.xml");
|
||||
pathWatcher.watch(baseDirConfig);
|
||||
|
||||
try
|
||||
{
|
||||
capture.setFinishTrigger(1);
|
||||
pathWatcher.start();
|
||||
|
||||
// Pretend that startup occurred
|
||||
assertTrue(capture.finishedLatch.await(LONG_TIME,TimeUnit.MILLISECONDS));
|
||||
|
||||
// New war added
|
||||
capture.setFinishTrigger(1);
|
||||
|
||||
Files.createDirectories(dir.resolve("bar/WEB-INF"));
|
||||
Thread.sleep(QUIET_TIME/2);
|
||||
Files.createFile(dir.resolve("bar/WEB-INF/web.xml"));
|
||||
Thread.sleep(QUIET_TIME/2);
|
||||
updateFile(dir.resolve("bar/WEB-INF/web.xml"),"Update");
|
||||
Thread.sleep(QUIET_TIME/2);
|
||||
updateFile(dir.resolve("bar/WEB-INF/web.xml"),"Update web.xml");
|
||||
|
||||
// Let capture finish
|
||||
assertTrue(capture.finishedLatch.await(LONG_TIME,TimeUnit.MILLISECONDS));
|
||||
|
||||
Map<String, PathWatchEventType[]> expected = new HashMap<>();
|
||||
|
||||
expected.put("bar/WEB-INF/web.xml",new PathWatchEventType[] { ADDED });
|
||||
expected.put("foo.war",new PathWatchEventType[] { ADDED });
|
||||
|
||||
capture.assertEvents(expected);
|
||||
TimeUnit.MILLISECONDS.sleep(WAIT_TIME);
|
||||
capture.assertEvents(expected);
|
||||
}
|
||||
finally
|
||||
{
|
||||
pathWatcher.stop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testDeployFilesBeyondDepthLimit() throws Exception
|
||||
{
|
||||
Path dir = testdir.getEmptyPathDir();
|
||||
|
||||
// Files we are interested in
|
||||
Files.createDirectories(dir.resolve("foo/WEB-INF/lib"));
|
||||
Files.createDirectories(dir.resolve("bar/WEB-INF/lib"));
|
||||
|
||||
PathWatcher pathWatcher = new PathWatcher();
|
||||
pathWatcher.setUpdateQuietTime(QUIET_TIME,TimeUnit.MILLISECONDS);
|
||||
|
||||
// Add listener
|
||||
PathWatchEventCapture capture = new PathWatchEventCapture(dir);
|
||||
pathWatcher.addListener(capture);
|
||||
|
||||
// Add test dir configuration
|
||||
PathWatcher.Config baseDirConfig = new PathWatcher.Config(dir);
|
||||
baseDirConfig.setRecurseDepth(0);
|
||||
pathWatcher.watch(baseDirConfig);
|
||||
|
||||
try
|
||||
{
|
||||
capture.setFinishTrigger(2);
|
||||
pathWatcher.start();
|
||||
|
||||
// Pretend that startup occurred
|
||||
assertTrue(capture.finishedLatch.await(LONG_TIME,TimeUnit.MILLISECONDS));
|
||||
|
||||
Map<String, PathWatchEventType[]> expected = new HashMap<>();
|
||||
expected.put("foo",new PathWatchEventType[] { ADDED });
|
||||
expected.put("bar",new PathWatchEventType[] { ADDED });
|
||||
|
||||
capture.assertEvents(expected);
|
||||
|
||||
capture.reset(1);
|
||||
expected.clear();
|
||||
expected.put("bar",new PathWatchEventType[] { MODIFIED });
|
||||
Files.createFile(dir.resolve("bar/index.html"));
|
||||
assertTrue(capture.finishedLatch.await(LONG_TIME,TimeUnit.MILLISECONDS));
|
||||
|
||||
capture.assertEvents(expected);
|
||||
TimeUnit.MILLISECONDS.sleep(WAIT_TIME);
|
||||
capture.assertEvents(expected);
|
||||
|
||||
capture.reset(1);
|
||||
expected.clear();
|
||||
expected.put("bob",new PathWatchEventType[] { ADDED });
|
||||
Files.createFile(dir.resolve("bar/WEB-INF/lib/ignored"));
|
||||
PathWatcher.LOG.debug("create bob");
|
||||
Files.createDirectories(dir.resolve("bob/WEB-INF/lib"));
|
||||
Thread.sleep(QUIET_TIME/2);
|
||||
PathWatcher.LOG.debug("create bob/index.html");
|
||||
Files.createFile(dir.resolve("bob/index.html"));
|
||||
Thread.sleep(QUIET_TIME/2);
|
||||
PathWatcher.LOG.debug("update bob/index.html");
|
||||
updateFile(dir.resolve("bob/index.html"),"Update");
|
||||
Thread.sleep(QUIET_TIME/2);
|
||||
PathWatcher.LOG.debug("update bob/index.html");
|
||||
updateFile(dir.resolve("bob/index.html"),"Update index.html");
|
||||
|
||||
assertTrue(capture.finishedLatch.await(LONG_TIME,TimeUnit.MILLISECONDS));
|
||||
capture.assertEvents(expected);
|
||||
TimeUnit.MILLISECONDS.sleep(WAIT_TIME);
|
||||
capture.assertEvents(expected);
|
||||
|
||||
}
|
||||
finally
|
||||
{
|
||||
pathWatcher.stop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testWatchFile() throws Exception
|
||||
{
|
||||
Path dir = testdir.getEmptyPathDir();
|
||||
|
||||
// Files we are interested in
|
||||
Files.createDirectories(dir.resolve("bar/WEB-INF"));
|
||||
Files.createFile(dir.resolve("bar/WEB-INF/web.xml"));
|
||||
|
||||
PathWatcher pathWatcher = new PathWatcher();
|
||||
pathWatcher.setUpdateQuietTime(QUIET_TIME,TimeUnit.MILLISECONDS);
|
||||
|
||||
// Add listener
|
||||
PathWatchEventCapture capture = new PathWatchEventCapture(dir);
|
||||
pathWatcher.addListener(capture);
|
||||
|
||||
// Add test configuration
|
||||
pathWatcher.watch(dir.resolve("bar/WEB-INF/web.xml"));
|
||||
pathWatcher.setNotifyExistingOnStart(false);
|
||||
|
||||
try
|
||||
{
|
||||
pathWatcher.start();
|
||||
Thread.sleep(WAIT_TIME);
|
||||
assertThat(capture.events.size(),is(0));
|
||||
|
||||
Files.createFile(dir.resolve("bar/index.htnl"));
|
||||
Files.createFile(dir.resolve("bar/WEB-INF/other.xml"));
|
||||
Files.createDirectories(dir.resolve("bar/WEB-INF/lib"));
|
||||
|
||||
Thread.sleep(WAIT_TIME);
|
||||
assertThat(capture.events.size(),is(0));
|
||||
|
||||
capture.setFinishTrigger(1);
|
||||
updateFile(dir.resolve("bar/WEB-INF/web.xml"),"Update web.xml");
|
||||
assertTrue(capture.finishedLatch.await(LONG_TIME,TimeUnit.MILLISECONDS));
|
||||
|
||||
Map<String, PathWatchEventType[]> expected = new HashMap<>();
|
||||
|
||||
expected.put("bar/WEB-INF/web.xml",new PathWatchEventType[] { MODIFIED });
|
||||
|
||||
capture.assertEvents(expected);
|
||||
TimeUnit.MILLISECONDS.sleep(WAIT_TIME);
|
||||
capture.assertEvents(expected);
|
||||
}
|
||||
finally
|
||||
{
|
||||
pathWatcher.stop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Pretend to add a new war file that is large, and being copied into place
|
||||
* Pretend to modify a new war file that is large, and being copied into place
|
||||
* using some sort of technique that is slow enough that it takes a while for
|
||||
* the entire war file to exist in place.
|
||||
* <p>
|
||||
|
@ -654,17 +949,18 @@ public class PathWatcherTest
|
|||
* on test failure
|
||||
*/
|
||||
@Test
|
||||
public void testDeployFiles_NewWar_LargeSlowCopy() throws Exception
|
||||
public void testDeployFiles_ModifyWar_LargeSlowCopy() throws Exception
|
||||
{
|
||||
Path dir = testdir.getEmptyPathDir();
|
||||
|
||||
// Files we are interested in
|
||||
Files.createFile(dir.resolve("foo.war"));
|
||||
Files.createFile(dir.resolve("hello.war"));
|
||||
Files.createDirectories(dir.resolve("bar/WEB-INF"));
|
||||
Files.createFile(dir.resolve("bar/WEB-INF/web.xml"));
|
||||
|
||||
PathWatcher pathWatcher = new PathWatcher();
|
||||
pathWatcher.setUpdateQuietTime(500,TimeUnit.MILLISECONDS);
|
||||
pathWatcher.setUpdateQuietTime(QUIET_TIME,TimeUnit.MILLISECONDS);
|
||||
|
||||
// Add listener
|
||||
PathWatchEventCapture capture = new PathWatchEventCapture(dir);
|
||||
|
@ -680,26 +976,35 @@ public class PathWatcherTest
|
|||
|
||||
try
|
||||
{
|
||||
capture.setFinishTrigger(3);
|
||||
pathWatcher.start();
|
||||
|
||||
// Pretend that startup occurred
|
||||
awaitQuietTime(pathWatcher);
|
||||
assertTrue(capture.finishedLatch.await(LONG_TIME,TimeUnit.MILLISECONDS));
|
||||
|
||||
|
||||
// New war added (slowly)
|
||||
capture.setFinishTrigger(1);
|
||||
Path warFile = dir.resolve("hello.war");
|
||||
capture.setFinishTrigger(warFile,MODIFIED);
|
||||
updateFileOverTime(warFile,50 * MB,3,TimeUnit.SECONDS);
|
||||
|
||||
// Let capture finish
|
||||
capture.awaitFinish(pathWatcher);
|
||||
long start = System.nanoTime();
|
||||
new Thread(()->
|
||||
{
|
||||
updateFileOverTime(warFile,2*QUIET_TIME,TimeUnit.MILLISECONDS);
|
||||
}).start();
|
||||
|
||||
assertTrue(capture.finishedLatch.await(4*QUIET_TIME,TimeUnit.MILLISECONDS));
|
||||
long end = System.nanoTime();
|
||||
assertThat(end-start,greaterThan(TimeUnit.MILLISECONDS.toNanos(2*QUIET_TIME)));
|
||||
|
||||
|
||||
Map<String, PathWatchEventType[]> expected = new HashMap<>();
|
||||
|
||||
expected.put("bar/WEB-INF/web.xml",new PathWatchEventType[] { ADDED });
|
||||
expected.put("foo.war",new PathWatchEventType[] { ADDED });
|
||||
expected.put("hello.war",new PathWatchEventType[] { ADDED, MODIFIED });
|
||||
|
||||
capture.assertEvents(expected);
|
||||
TimeUnit.MILLISECONDS.sleep(WAIT_TIME);
|
||||
capture.assertEvents(expected);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
# Setup default logging implementation for during testing
|
||||
org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
|
||||
#org.eclipse.jetty.util.LEVEL=DEBUG
|
||||
#org.eclipse.jetty.util.PathWatcher.LEVEL=DEBUG
|
Loading…
Reference in New Issue