File watcher test: wait/notify instead of delays

This commit is contained in:
Roman Shevchenko
2012-05-07 15:07:42 +04:00
parent 3cf4c21d51
commit a74e742e89
2 changed files with 53 additions and 14 deletions
@@ -316,7 +316,7 @@ public class FileWatcher {
}
@TestOnly
public void startup() throws IOException {
public void startup(@Nullable final Runnable notifier) throws IOException {
final Application app = ApplicationManager.getApplication();
assert app != null && app.isUnitTestMode() : app;
@@ -327,6 +327,8 @@ public class FileWatcher {
if (notifierProcess != null) {
new WatchForChangesThread().start();
}
myNotifier = notifier;
}
@TestOnly
@@ -334,6 +336,8 @@ public class FileWatcher {
final Application app = ApplicationManager.getApplication();
assert app != null && app.isUnitTestMode() : app;
myNotifier = null;
final Process process = notifierProcess;
if (process != null) {
shutdownProcess();
@@ -341,6 +345,15 @@ public class FileWatcher {
}
}
private volatile Runnable myNotifier = null;
private void notifyOnEvent() {
final Runnable notifier = myNotifier;
if (notifier != null) {
notifier.run();
}
}
private class WatchForChangesThread extends Thread {
public WatchForChangesThread() {
//noinspection HardCodedStringLiteral
@@ -381,6 +394,8 @@ public class FileWatcher {
synchronized (LOCK) {
myManualWatchRoots = roots;
}
notifyOnEvent();
}
else if (MESSAGE_COMMAND.equals(command)) {
final String message = readLine();
@@ -570,6 +585,8 @@ public class FileWatcher {
reset();
break;
}
notifyOnEvent();
}
private void reset() {
@@ -19,6 +19,7 @@ import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.idea.Bombed;
import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.*;
@@ -30,8 +31,8 @@ import com.intellij.openapi.vfs.newvfs.events.VFileDeleteEvent;
import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
import com.intellij.openapi.vfs.newvfs.impl.VirtualDirectoryImpl;
import com.intellij.testFramework.PlatformLangTestCase;
import com.intellij.util.Alarm;
import com.intellij.util.Function;
import com.intellij.util.TimeoutUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.messages.MessageBusConnection;
import org.jetbrains.annotations.NotNull;
@@ -46,16 +47,36 @@ public class FileWatcherTest extends PlatformLangTestCase {
private FileWatcher myWatcher;
private LocalFileSystem myFileSystem;
private MessageBusConnection myConnection;
private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD);
private final Runnable myNotifier = new Runnable() {
@Override
public void run() {
synchronized (myAlarm) {
myAlarm.cancelAllRequests();
myAlarm.addRequest(new Runnable() {
@Override
public void run() {
synchronized (myWaiter) {
myWaiter.notifyAll();
}
}
}, NATIVE_PROCESS_DELAY);
}
}
};
private final Object myWaiter = new Object();
private final List<VFileEvent> myEvents = new ArrayList<VFileEvent>();
@Override
protected void setUp() throws Exception {
super.setUp();
Disposer.register(getProject(), myAlarm);
myWatcher = FileWatcher.getInstance();
assertNotNull(myWatcher);
assertFalse(myWatcher.isOperational());
myWatcher.startup();
myWatcher.startup(myNotifier);
assertTrue(myWatcher.isOperational());
myFileSystem = LocalFileSystem.getInstance();
@@ -69,10 +90,7 @@ public class FileWatcherTest extends PlatformLangTestCase {
@Override
public void after(@NotNull List<? extends VFileEvent> events) {
synchronized (myEvents) {
myEvents.addAll(events);
myEvents.notifyAll();
}
myEvents.addAll(events);
}
});
}
@@ -377,13 +395,17 @@ public class FileWatcherTest extends PlatformLangTestCase {
private List<VFileEvent> getEvents() throws InterruptedException {
TimeoutUtil.sleep(NATIVE_PROCESS_DELAY);
waitForResponse();
myFileSystem.refresh(false);
final ArrayList<VFileEvent> result = new ArrayList<VFileEvent>(myEvents);
myEvents.clear();
return result;
}
synchronized (myEvents) {
final ArrayList<VFileEvent> result = new ArrayList<VFileEvent>(myEvents);
myEvents.clear();
return result;
private void waitForResponse() throws InterruptedException {
synchronized (myWaiter) {
//noinspection WaitNotInLoop
myWaiter.wait(NATIVE_PROCESS_DELAY);
}
}
@@ -403,14 +425,14 @@ public class FileWatcherTest extends PlatformLangTestCase {
private LocalFileSystem.WatchRequest watch(final File watchFile, final boolean recursive) throws InterruptedException {
final LocalFileSystem.WatchRequest request = myFileSystem.addRootToWatch(watchFile.getAbsolutePath(), recursive);
assertNotNull(request);
TimeoutUtil.sleep(NATIVE_PROCESS_DELAY);
waitForResponse();
clearEvents();
return request;
}
private void unwatch(final LocalFileSystem.WatchRequest request) throws InterruptedException {
myFileSystem.removeWatchedRoot(request);
TimeoutUtil.sleep(NATIVE_PROCESS_DELAY);
waitForResponse();
clearEvents();
}