mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-19 06:09:55 +01:00
Refactored PollingRemovableDriveMonitor, fixed test.
This commit is contained in:
@@ -12,7 +12,7 @@ import net.sf.briar.api.plugins.PluginExecutor;
|
|||||||
class PollingRemovableDriveMonitor implements RemovableDriveMonitor, Runnable {
|
class PollingRemovableDriveMonitor implements RemovableDriveMonitor, Runnable {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
Logger.getLogger(PollingRemovableDriveMonitor.class.getName());
|
Logger.getLogger(PollingRemovableDriveMonitor.class.getName());
|
||||||
|
|
||||||
private final Executor pluginExecutor;
|
private final Executor pluginExecutor;
|
||||||
private final RemovableDriveFinder finder;
|
private final RemovableDriveFinder finder;
|
||||||
@@ -21,7 +21,6 @@ class PollingRemovableDriveMonitor implements RemovableDriveMonitor, Runnable {
|
|||||||
|
|
||||||
private volatile boolean running = false;
|
private volatile boolean running = false;
|
||||||
private volatile Callback callback = null;
|
private volatile Callback callback = null;
|
||||||
private volatile IOException exception = null;
|
|
||||||
|
|
||||||
public PollingRemovableDriveMonitor(@PluginExecutor Executor pluginExecutor,
|
public PollingRemovableDriveMonitor(@PluginExecutor Executor pluginExecutor,
|
||||||
RemovableDriveFinder finder, long pollingInterval) {
|
RemovableDriveFinder finder, long pollingInterval) {
|
||||||
@@ -34,7 +33,6 @@ class PollingRemovableDriveMonitor implements RemovableDriveMonitor, Runnable {
|
|||||||
synchronized(this) {
|
synchronized(this) {
|
||||||
assert !running;
|
assert !running;
|
||||||
assert this.callback == null;
|
assert this.callback == null;
|
||||||
assert exception == null;
|
|
||||||
running = true;
|
running = true;
|
||||||
this.callback = callback;
|
this.callback = callback;
|
||||||
}
|
}
|
||||||
@@ -42,19 +40,15 @@ class PollingRemovableDriveMonitor implements RemovableDriveMonitor, Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void stop() throws IOException {
|
public void stop() throws IOException {
|
||||||
IOException e;
|
|
||||||
synchronized(this) {
|
synchronized(this) {
|
||||||
assert running;
|
assert running;
|
||||||
assert callback != null;
|
assert callback != null;
|
||||||
running = false;
|
running = false;
|
||||||
callback = null;
|
callback = null;
|
||||||
e = exception;
|
|
||||||
exception = null;
|
|
||||||
}
|
}
|
||||||
synchronized(pollingLock) {
|
synchronized(pollingLock) {
|
||||||
pollingLock.notifyAll();
|
pollingLock.notifyAll();
|
||||||
}
|
}
|
||||||
if(e != null) throw e;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
@@ -76,7 +70,7 @@ class PollingRemovableDriveMonitor implements RemovableDriveMonitor, Runnable {
|
|||||||
LOG.info("Interrupted while waiting to poll");
|
LOG.info("Interrupted while waiting to poll");
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
} catch(IOException e) {
|
} catch(IOException e) {
|
||||||
exception = e;
|
callback.exceptionThrown(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,5 +12,7 @@ interface RemovableDriveMonitor {
|
|||||||
interface Callback {
|
interface Callback {
|
||||||
|
|
||||||
void driveInserted(File root);
|
void driveInserted(File root);
|
||||||
|
|
||||||
|
void exceptionThrown(IOException e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -123,4 +123,8 @@ implements RemovableDriveMonitor.Callback {
|
|||||||
for(File f : files) if(f.isFile()) createReaderFromFile(f);
|
for(File f : files) if(f.isFile()) createReaderFromFile(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void exceptionThrown(IOException e) {
|
||||||
|
if(LOG.isLoggable(Level.WARNING)) LOG.warning(e.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,90 +3,92 @@ package net.sf.briar.plugins.file;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import net.sf.briar.BriarTestCase;
|
import net.sf.briar.BriarTestCase;
|
||||||
import net.sf.briar.plugins.file.RemovableDriveMonitor.Callback;
|
import net.sf.briar.plugins.file.RemovableDriveMonitor.Callback;
|
||||||
|
|
||||||
import org.jmock.Expectations;
|
|
||||||
import org.jmock.Mockery;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class PollingRemovableDriveMonitorTest extends BriarTestCase {
|
public class PollingRemovableDriveMonitorTest extends BriarTestCase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOneCallbackPerFile() throws Exception {
|
public void testOneCallbackPerFile() throws Exception {
|
||||||
|
// Create a finder that returns no files the first time, then two files
|
||||||
final File file1 = new File("foo");
|
final File file1 = new File("foo");
|
||||||
final File file2 = new File("bar");
|
final File file2 = new File("bar");
|
||||||
// Create a finder that returns no files the first time, then two files
|
final RemovableDriveFinder finder = new RemovableDriveFinder() {
|
||||||
final List<File> noDrives = Collections.emptyList();
|
|
||||||
final List<File> twoDrives = new ArrayList<File>();
|
private AtomicBoolean firstCall = new AtomicBoolean(true);
|
||||||
twoDrives.add(file1);
|
|
||||||
twoDrives.add(file2);
|
public Collection<File> findRemovableDrives() throws IOException {
|
||||||
Mockery context = new Mockery();
|
if(firstCall.getAndSet(false)) return Collections.emptyList();
|
||||||
final RemovableDriveFinder finder =
|
else return Arrays.asList(new File[] {file1, file2});
|
||||||
context.mock(RemovableDriveFinder.class);
|
}
|
||||||
context.checking(new Expectations() {{
|
};
|
||||||
oneOf(finder).findRemovableDrives();
|
// Create a callback that waits for two files
|
||||||
will(returnValue(noDrives));
|
|
||||||
oneOf(finder).findRemovableDrives();
|
|
||||||
will(returnValue(twoDrives));
|
|
||||||
}});
|
|
||||||
// Create a callback that will wait for two files before stopping
|
|
||||||
final List<File> detected = new ArrayList<File>();
|
|
||||||
final CountDownLatch latch = new CountDownLatch(2);
|
final CountDownLatch latch = new CountDownLatch(2);
|
||||||
final Callback callback = new Callback() {
|
final List<File> detected = new ArrayList<File>();
|
||||||
|
Callback callback = new Callback() {
|
||||||
|
|
||||||
public void driveInserted(File f) {
|
public void driveInserted(File f) {
|
||||||
detected.add(f);
|
detected.add(f);
|
||||||
latch.countDown();
|
latch.countDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void exceptionThrown(IOException e) {
|
||||||
|
fail();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
// Create the monitor and start it
|
// Create the monitor and start it
|
||||||
final RemovableDriveMonitor monitor = new PollingRemovableDriveMonitor(
|
final RemovableDriveMonitor monitor = new PollingRemovableDriveMonitor(
|
||||||
Executors.newCachedThreadPool(), finder, 10);
|
Executors.newCachedThreadPool(), finder, 1);
|
||||||
monitor.start(callback);
|
monitor.start(callback);
|
||||||
// Wait for the monitor to detect the files
|
// Wait for the monitor to detect the files
|
||||||
assertTrue(latch.await(5, TimeUnit.SECONDS));
|
assertTrue(latch.await(10, TimeUnit.SECONDS));
|
||||||
monitor.stop();
|
monitor.stop();
|
||||||
// Check that both files were detected
|
// Check that both files were detected
|
||||||
assertEquals(2, detected.size());
|
assertEquals(2, detected.size());
|
||||||
assertTrue(detected.contains(file1));
|
assertTrue(detected.contains(file1));
|
||||||
assertTrue(detected.contains(file2));
|
assertTrue(detected.contains(file2));
|
||||||
// Check that the finder was polled twice
|
|
||||||
context.assertIsSatisfied();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testExceptionRethrownWhenStopping() throws Exception {
|
public void testExceptionCallback() throws Exception {
|
||||||
final List<File> noDrives = Collections.emptyList();
|
|
||||||
// Create a finder that throws an exception the second time it's polled
|
// Create a finder that throws an exception the second time it's polled
|
||||||
Mockery context = new Mockery();
|
final RemovableDriveFinder finder = new RemovableDriveFinder() {
|
||||||
final RemovableDriveFinder finder =
|
|
||||||
context.mock(RemovableDriveFinder.class);
|
private AtomicBoolean firstCall = new AtomicBoolean(true);
|
||||||
context.checking(new Expectations() {{
|
|
||||||
oneOf(finder).findRemovableDrives();
|
public Collection<File> findRemovableDrives() throws IOException {
|
||||||
will(returnValue(noDrives));
|
if(firstCall.getAndSet(false)) return Collections.emptyList();
|
||||||
oneOf(finder).findRemovableDrives();
|
else throw new IOException();
|
||||||
will(throwException(new IOException()));
|
}
|
||||||
}});
|
};
|
||||||
// Create the monitor, start it, and give it some time to run
|
// Create a callback that waits for an exception
|
||||||
final RemovableDriveMonitor monitor = new PollingRemovableDriveMonitor(
|
final CountDownLatch latch = new CountDownLatch(1);
|
||||||
Executors.newCachedThreadPool(), finder, 10);
|
Callback callback = new Callback() {
|
||||||
monitor.start(new Callback() {
|
|
||||||
public void driveInserted(File root) {
|
public void driveInserted(File root) {
|
||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
});
|
|
||||||
Thread.sleep(100);
|
public void exceptionThrown(IOException e) {
|
||||||
// The monitor should rethrow the exception when it stops
|
latch.countDown();
|
||||||
try {
|
}
|
||||||
monitor.stop();
|
};
|
||||||
fail();
|
// Create the monitor and start it
|
||||||
} catch(IOException expected) {}
|
final RemovableDriveMonitor monitor = new PollingRemovableDriveMonitor(
|
||||||
context.assertIsSatisfied();
|
Executors.newCachedThreadPool(), finder, 1);
|
||||||
|
monitor.start(callback);
|
||||||
|
assertTrue(latch.await(10, TimeUnit.SECONDS));
|
||||||
|
monitor.stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package net.sf.briar.plugins.file;
|
package net.sf.briar.plugins.file;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
@@ -33,9 +34,14 @@ public class UnixRemovableDriveMonitorTest extends BriarTestCase {
|
|||||||
File doesNotExist = new File(testDir, "doesNotExist");
|
File doesNotExist = new File(testDir, "doesNotExist");
|
||||||
RemovableDriveMonitor monitor = createMonitor(doesNotExist);
|
RemovableDriveMonitor monitor = createMonitor(doesNotExist);
|
||||||
monitor.start(new Callback() {
|
monitor.start(new Callback() {
|
||||||
|
|
||||||
public void driveInserted(File root) {
|
public void driveInserted(File root) {
|
||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void exceptionThrown(IOException e) {
|
||||||
|
fail();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
monitor.stop();
|
monitor.stop();
|
||||||
}
|
}
|
||||||
@@ -50,10 +56,15 @@ public class UnixRemovableDriveMonitorTest extends BriarTestCase {
|
|||||||
final List<File> detected = new ArrayList<File>();
|
final List<File> detected = new ArrayList<File>();
|
||||||
final CountDownLatch latch = new CountDownLatch(2);
|
final CountDownLatch latch = new CountDownLatch(2);
|
||||||
final Callback callback = new Callback() {
|
final Callback callback = new Callback() {
|
||||||
|
|
||||||
public void driveInserted(File f) {
|
public void driveInserted(File f) {
|
||||||
detected.add(f);
|
detected.add(f);
|
||||||
latch.countDown();
|
latch.countDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void exceptionThrown(IOException e) {
|
||||||
|
fail();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
// Create the monitor and start it
|
// Create the monitor and start it
|
||||||
RemovableDriveMonitor monitor = createMonitor(testDir);
|
RemovableDriveMonitor monitor = createMonitor(testDir);
|
||||||
|
|||||||
Reference in New Issue
Block a user