Replaced Timer with ScheduledExecutorService. #258

This commit is contained in:
akwizgran
2016-05-05 11:07:58 +01:00
parent 036c5d6753
commit ff8301521c
26 changed files with 201 additions and 212 deletions

View File

@@ -42,6 +42,7 @@ import org.briarproject.introduction.MessageSender;
import org.briarproject.lifecycle.LifecycleModule;
import org.briarproject.properties.PropertiesModule;
import org.briarproject.sync.SyncModule;
import org.briarproject.system.SystemModule;
import org.briarproject.transport.TransportModule;
import org.junit.After;
import org.junit.Before;
@@ -944,6 +945,7 @@ public class IntroductionIntegrationTest extends BriarTestCase {
this.accept = accept;
}
@Override
public void eventOccurred(Event e) {
if (e instanceof MessageValidatedEvent) {
MessageValidatedEvent event = (MessageValidatedEvent) e;
@@ -1010,6 +1012,7 @@ public class IntroductionIntegrationTest extends BriarTestCase {
public volatile boolean response2Received = false;
public volatile boolean aborted = false;
@Override
public void eventOccurred(Event e) {
if (e instanceof MessageValidatedEvent) {
MessageValidatedEvent event = (MessageValidatedEvent) e;
@@ -1050,7 +1053,7 @@ public class IntroductionIntegrationTest extends BriarTestCase {
component.inject(new ContactModule.EagerSingletons());
component.inject(new TransportModule.EagerSingletons());
component.inject(new SyncModule.EagerSingletons());
component.inject(new SystemModule.EagerSingletons());
component.inject(new PropertiesModule.EagerSingletons());
}
}

View File

@@ -21,6 +21,7 @@ import org.briarproject.introduction.MessageSender;
import org.briarproject.lifecycle.LifecycleModule;
import org.briarproject.properties.PropertiesModule;
import org.briarproject.sync.SyncModule;
import org.briarproject.system.SystemModule;
import org.briarproject.transport.TransportModule;
import javax.inject.Singleton;
@@ -29,9 +30,9 @@ import dagger.Component;
@Singleton
@Component(modules = {
TestSystemModule.class,
TestDatabaseModule.class,
TestPluginsModule.class,
TestSeedProviderModule.class,
LifecycleModule.class,
IntroductionModule.class,
DatabaseModule.class,
@@ -42,6 +43,7 @@ import dagger.Component;
TransportModule.class,
ClientsModule.class,
SyncModule.class,
SystemModule.class,
DataModule.class,
PropertiesModule.class
})
@@ -61,6 +63,8 @@ public interface IntroductionIntegrationTestComponent {
void inject(SyncModule.EagerSingletons init);
void inject(SystemModule.EagerSingletons init);
void inject(TransportModule.EagerSingletons init);
LifecycleManager getLifecycleManager();
@@ -84,5 +88,4 @@ public interface IntroductionIntegrationTestComponent {
MessageSender getMessageSender();
IntroductionGroupFactory getIntroductionGroupFactory();
}

View File

@@ -13,6 +13,7 @@ import org.briarproject.api.messaging.PrivateMessage;
import org.briarproject.api.messaging.PrivateMessageFactory;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.MessageId;
import org.briarproject.system.SystemModule;
import org.junit.Test;
import javax.inject.Inject;
@@ -39,6 +40,7 @@ public class MessageSizeIntegrationTest extends BriarTestCase {
MessageSizeIntegrationTestComponent component =
DaggerMessageSizeIntegrationTestComponent.builder().build();
component.inject(this);
component.inject(new SystemModule.EagerSingletons());
}
@Test

View File

@@ -9,6 +9,7 @@ import org.briarproject.forum.ForumModule;
import org.briarproject.identity.IdentityModule;
import org.briarproject.messaging.MessagingModule;
import org.briarproject.sync.SyncModule;
import org.briarproject.system.SystemModule;
import javax.inject.Singleton;
@@ -18,7 +19,7 @@ import dagger.Component;
@Component(modules = {
TestDatabaseModule.class,
TestLifecycleModule.class,
TestSystemModule.class,
TestSeedProviderModule.class,
ClientsModule.class,
CryptoModule.class,
DataModule.class,
@@ -27,8 +28,12 @@ import dagger.Component;
ForumModule.class,
IdentityModule.class,
MessagingModule.class,
SyncModule.class
SyncModule.class,
SystemModule.class
})
public interface MessageSizeIntegrationTestComponent {
void inject(MessageSizeIntegrationTest testCase);
void inject(SystemModule.EagerSingletons init);
}

View File

@@ -21,6 +21,7 @@ import org.briarproject.api.transport.KeyManager;
import org.briarproject.api.transport.StreamContext;
import org.briarproject.api.transport.StreamReaderFactory;
import org.briarproject.api.transport.StreamWriterFactory;
import org.briarproject.system.SystemModule;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -57,8 +58,10 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
assertTrue(testDir.mkdirs());
alice = DaggerSimplexMessagingIntegrationTestComponent.builder()
.testDatabaseModule(new TestDatabaseModule(aliceDir)).build();
alice.inject(new SystemModule.EagerSingletons());
bob = DaggerSimplexMessagingIntegrationTestComponent.builder()
.testDatabaseModule(new TestDatabaseModule(bobDir)).build();
bob.inject(new SystemModule.EagerSingletons());
}
@Test
@@ -183,6 +186,7 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
private volatile boolean messageAdded = false;
@Override
public void eventOccurred(Event e) {
if (e instanceof MessageAddedEvent) messageAdded = true;
}

View File

@@ -21,6 +21,7 @@ import org.briarproject.lifecycle.LifecycleModule;
import org.briarproject.messaging.MessagingModule;
import org.briarproject.plugins.PluginsModule;
import org.briarproject.sync.SyncModule;
import org.briarproject.system.SystemModule;
import org.briarproject.transport.TransportModule;
import javax.inject.Singleton;
@@ -31,7 +32,7 @@ import dagger.Component;
@Component(modules = {
TestDatabaseModule.class,
TestPluginsModule.class,
TestSystemModule.class,
TestSeedProviderModule.class,
ClientsModule.class,
ContactModule.class,
CryptoModule.class,
@@ -43,11 +44,12 @@ import dagger.Component;
MessagingModule.class,
PluginsModule.class,
SyncModule.class,
SystemModule.class,
TransportModule.class
})
public interface SimplexMessagingIntegrationTestComponent {
void inject(SimplexMessagingIntegrationTest testCase);
void inject(SystemModule.EagerSingletons init);
LifecycleManager getLifecycleManager();

View File

@@ -10,7 +10,7 @@ import dagger.Component;
@Singleton
@Component(modules = {
TestSystemModule.class,
TestSeedProviderModule.class,
CryptoModule.class,
SyncModule.class,
TransportModule.class

View File

@@ -15,6 +15,7 @@ import dagger.Provides;
public class AndroidSystemModule {
@Provides
@Singleton
public SeedProvider provideSeedProvider(Application app) {
return new AndroidSeedProvider(app);
}

View File

@@ -1,27 +0,0 @@
package org.briarproject.api.system;
import java.util.TimerTask;
/**
* A wrapper around a {@link java.util.Timer} that allows it to be replaced for
* testing.
*/
public interface Timer {
/** @see {@link java.util.Timer#cancel()} */
void cancel();
/** @see {@link java.util.Timer#purge()} */
int purge();
/** @see {@link java.util.Timer#schedule(TimerTask, long)} */
void schedule(TimerTask task, long delay);
/** @see {@link java.util.Timer#schedule(TimerTask, long, long)} */
void schedule(TimerTask task, long delay, long period);
/**
* @see {@link java.util.Timer#scheduleAtFixedRate(TimerTask, long, long)}
*/
void scheduleAtFixedRate(TimerTask task, long delay, long period);
}

View File

@@ -10,6 +10,7 @@ import org.briarproject.messaging.MessagingModule;
import org.briarproject.plugins.PluginsModule;
import org.briarproject.properties.PropertiesModule;
import org.briarproject.sync.SyncModule;
import org.briarproject.system.SystemModule;
import org.briarproject.transport.TransportModule;
public interface CoreEagerSingletons {
@@ -34,5 +35,7 @@ public interface CoreEagerSingletons {
void inject(SyncModule.EagerSingletons init);
void inject(SystemModule.EagerSingletons init);
void inject(TransportModule.EagerSingletons init);
}

View File

@@ -61,6 +61,7 @@ public class CoreModule {
c.inject(new PluginsModule.EagerSingletons());
c.inject(new PropertiesModule.EagerSingletons());
c.inject(new SyncModule.EagerSingletons());
c.inject(new SystemModule.EagerSingletons());
c.inject(new TransportModule.EagerSingletons());
c.inject(new IntroductionModule.EagerSingletons());
}

View File

@@ -122,9 +122,6 @@ class PluginManagerImpl implements PluginManager, Service, EventListener {
public void stopService() throws ServiceException {
// Stop listening for events
eventBus.removeListener(this);
// Stop the poller
LOG.info("Stopping poller");
poller.stop();
final CountDownLatch latch = new CountDownLatch(plugins.size());
// Stop the simplex plugins
LOG.info("Stopping simplex plugins");
@@ -432,7 +429,7 @@ class PluginManagerImpl implements PluginManager, Service, EventListener {
public void transportEnabled() {
eventBus.broadcast(new TransportEnabledEvent(id));
Plugin p = plugins.get(id);
if (p != null) poller.pollNow(p);
if (p != null && p.shouldPoll()) poller.pollNow(p);
}
@Override

View File

@@ -8,12 +8,10 @@ import org.briarproject.api.plugins.ConnectionManager;
import org.briarproject.api.plugins.ConnectionRegistry;
import org.briarproject.api.plugins.PluginManager;
import org.briarproject.api.sync.SyncSessionFactory;
import org.briarproject.api.system.Timer;
import org.briarproject.api.transport.KeyManager;
import org.briarproject.api.transport.StreamReaderFactory;
import org.briarproject.api.transport.StreamWriterFactory;
import java.security.SecureRandom;
import java.util.concurrent.Executor;
import javax.inject.Inject;
@@ -36,10 +34,9 @@ public class PluginsModule {
}
@Provides
Poller providePoller(@IoExecutor Executor ioExecutor,
ConnectionRegistry connectionRegistry, SecureRandom random,
Timer timer) {
return new PollerImpl(ioExecutor, connectionRegistry, random, timer);
@Singleton
Poller providePoller(PollerImpl poller) {
return poller;
}
@Provides

View File

@@ -6,7 +6,4 @@ interface Poller {
/** Tells the poller to poll the given plugin immediately. */
void pollNow(Plugin p);
/** Stops the poller. */
void stop();
}

View File

@@ -4,17 +4,17 @@ import org.briarproject.api.TransportId;
import org.briarproject.api.lifecycle.IoExecutor;
import org.briarproject.api.plugins.ConnectionRegistry;
import org.briarproject.api.plugins.Plugin;
import org.briarproject.api.system.Timer;
import java.security.SecureRandom;
import java.util.Map;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledExecutorService;
import java.util.logging.Logger;
import javax.inject.Inject;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.logging.Level.INFO;
class PollerImpl implements Poller {
@@ -23,31 +23,26 @@ class PollerImpl implements Poller {
Logger.getLogger(PollerImpl.class.getName());
private final Executor ioExecutor;
private final ScheduledExecutorService scheduler;
private final ConnectionRegistry connectionRegistry;
private final SecureRandom random;
private final Timer timer;
private final Map<TransportId, PollTask> tasks;
@Inject
PollerImpl(@IoExecutor Executor ioExecutor,
ConnectionRegistry connectionRegistry, SecureRandom random,
Timer timer) {
ScheduledExecutorService scheduler,
ConnectionRegistry connectionRegistry, SecureRandom random) {
this.ioExecutor = ioExecutor;
this.connectionRegistry = connectionRegistry;
this.random = random;
this.timer = timer;
this.scheduler = scheduler;
tasks = new ConcurrentHashMap<TransportId, PollTask>();
}
@Override
public void stop() {
timer.cancel();
}
@Override
public void pollNow(Plugin p) {
// Randomise next polling interval
if (p.shouldPoll()) schedule(p, 0, true);
schedule(p, 0, true);
}
private void schedule(Plugin p, int interval, boolean randomiseNext) {
@@ -55,7 +50,7 @@ class PollerImpl implements Poller {
PollTask task = new PollTask(p, randomiseNext);
PollTask replaced = tasks.put(p.getId(), task);
if (replaced != null) replaced.cancel();
timer.schedule(task, interval);
scheduler.schedule(task, interval, MILLISECONDS);
}
private void poll(final Plugin p) {
@@ -69,18 +64,25 @@ class PollerImpl implements Poller {
});
}
private class PollTask extends TimerTask {
private class PollTask implements Runnable {
private final Plugin plugin;
private final boolean randomiseNext;
private volatile boolean cancelled = false;
private PollTask(Plugin plugin, boolean randomiseNext) {
this.plugin = plugin;
this.randomiseNext = randomiseNext;
}
private void cancel() {
cancelled = true;
}
@Override
public void run() {
if (cancelled) return;
tasks.remove(plugin.getId());
int interval = plugin.getPollingInterval();
if (randomiseNext)

View File

@@ -1,23 +1,41 @@
package org.briarproject.system;
import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.system.Clock;
import org.briarproject.api.system.LocationUtils;
import org.briarproject.api.system.SeedProvider;
import org.briarproject.api.system.Timer;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import javax.inject.Inject;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
@Module
public class SystemModule {
public static class EagerSingletons {
@Inject
ScheduledExecutorService scheduledExecutorService;
}
private final ScheduledExecutorService scheduler;
public SystemModule() {
scheduler = Executors.newSingleThreadScheduledExecutor();
}
@Provides
Clock provideClock() {
return new SystemClock();
}
@Provides
Timer provideTimer() {
return new SystemTimer();
@Singleton
ScheduledExecutorService provideScheduledExecutorService(
LifecycleManager lifecycleManager) {
lifecycleManager.registerForShutdown(scheduler);
return scheduler;
}
}

View File

@@ -1,31 +0,0 @@
package org.briarproject.system;
import java.util.TimerTask;
import org.briarproject.api.system.Timer;
/** Default timer implementation. */
public class SystemTimer implements Timer {
private final java.util.Timer timer = new java.util.Timer(true);
public void cancel() {
timer.cancel();
}
public int purge() {
return timer.purge();
}
public void schedule(TimerTask task, long delay) {
timer.schedule(task, delay);
}
public void schedule(TimerTask task, long delay, long period) {
timer.schedule(task, delay, period);
}
public void scheduleAtFixedRate(TimerTask task, long delay, long period) {
timer.scheduleAtFixedRate(task, delay, period);
}
}

View File

@@ -19,7 +19,6 @@ import org.briarproject.api.plugins.PluginConfig;
import org.briarproject.api.plugins.duplex.DuplexPluginFactory;
import org.briarproject.api.plugins.simplex.SimplexPluginFactory;
import org.briarproject.api.system.Clock;
import org.briarproject.api.system.Timer;
import org.briarproject.api.transport.KeyManager;
import org.briarproject.api.transport.StreamContext;
@@ -28,6 +27,7 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledExecutorService;
import java.util.logging.Logger;
import javax.inject.Inject;
@@ -42,21 +42,22 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
private final DatabaseComponent db;
private final CryptoComponent crypto;
private final Executor dbExecutor;
private final ScheduledExecutorService scheduler;
private final PluginConfig pluginConfig;
private final Timer timer;
private final Clock clock;
private final Map<ContactId, Boolean> activeContacts;
private final ConcurrentHashMap<TransportId, TransportKeyManager> managers;
@Inject
KeyManagerImpl(DatabaseComponent db, CryptoComponent crypto,
@DatabaseExecutor Executor dbExecutor, PluginConfig pluginConfig,
Timer timer, Clock clock) {
@DatabaseExecutor Executor dbExecutor,
ScheduledExecutorService scheduler, PluginConfig pluginConfig,
Clock clock) {
this.db = db;
this.crypto = crypto;
this.dbExecutor = dbExecutor;
this.scheduler = scheduler;
this.pluginConfig = pluginConfig;
this.timer = timer;
this.clock = clock;
// Use a ConcurrentHashMap as a thread-safe set
activeContacts = new ConcurrentHashMap<ContactId, Boolean>();
@@ -80,7 +81,8 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
db.addTransport(txn, e.getKey(), e.getValue());
for (Entry<TransportId, Integer> e : transports.entrySet()) {
TransportKeyManager m = new TransportKeyManager(db, crypto,
timer, clock, e.getKey(), e.getValue());
dbExecutor, scheduler, clock, e.getKey(),
e.getValue());
managers.put(e.getKey(), m);
m.start(txn);
}
@@ -97,12 +99,14 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
public void stopService() {
}
@Override
public void addContact(Transaction txn, ContactId c, SecretKey master,
long timestamp, boolean alice) throws DbException {
for (TransportKeyManager m : managers.values())
m.addContact(txn, c, master, timestamp, alice);
}
@Override
public StreamContext getStreamContext(ContactId c, TransportId t)
throws DbException {
// Don't allow outgoing streams to inactive contacts
@@ -123,6 +127,7 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
return ctx;
}
@Override
public StreamContext getStreamContext(TransportId t, byte[] tag)
throws DbException {
TransportKeyManager m = managers.get(t);
@@ -141,6 +146,7 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
return ctx;
}
@Override
public void eventOccurred(Event e) {
if (e instanceof ContactRemovedEvent) {
removeContact(((ContactRemovedEvent) e).getContactId());
@@ -154,6 +160,7 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
private void removeContact(final ContactId c) {
activeContacts.remove(c);
dbExecutor.execute(new Runnable() {
@Override
public void run() {
for (TransportKeyManager m : managers.values())
m.removeContact(c);

View File

@@ -9,7 +9,6 @@ import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException;
import org.briarproject.api.db.Transaction;
import org.briarproject.api.system.Clock;
import org.briarproject.api.system.Timer;
import org.briarproject.api.transport.StreamContext;
import org.briarproject.api.transport.TransportKeys;
import org.briarproject.transport.ReorderingWindow.Change;
@@ -18,10 +17,12 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TimerTask;
import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Logger;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.logging.Level.WARNING;
import static org.briarproject.api.transport.TransportConstants.MAX_CLOCK_DIFFERENCE;
import static org.briarproject.api.transport.TransportConstants.TAG_LENGTH;
@@ -34,7 +35,8 @@ class TransportKeyManager {
private final DatabaseComponent db;
private final CryptoComponent crypto;
private final Timer timer;
private final Executor dbExecutor;
private final ScheduledExecutorService scheduler;
private final Clock clock;
private final TransportId transportId;
private final long rotationPeriodLength;
@@ -46,11 +48,12 @@ class TransportKeyManager {
private final Map<ContactId, MutableTransportKeys> keys;
TransportKeyManager(DatabaseComponent db, CryptoComponent crypto,
Timer timer, Clock clock, TransportId transportId,
long maxLatency) {
Executor dbExecutor, ScheduledExecutorService scheduler,
Clock clock, TransportId transportId, long maxLatency) {
this.db = db;
this.crypto = crypto;
this.timer = timer;
this.dbExecutor = dbExecutor;
this.scheduler = scheduler;
this.clock = clock;
this.transportId = transportId;
rotationPeriodLength = maxLatency + MAX_CLOCK_DIFFERENCE;
@@ -122,7 +125,19 @@ class TransportKeyManager {
}
private void scheduleKeyRotation(long now) {
TimerTask task = new TimerTask() {
Runnable task = new Runnable() {
@Override
public void run() {
rotateKeys();
}
};
long delay = rotationPeriodLength - now % rotationPeriodLength;
scheduler.schedule(task, delay, MILLISECONDS);
}
private void rotateKeys() {
dbExecutor.execute(new Runnable() {
@Override
public void run() {
try {
Transaction txn = db.startTransaction(false);
@@ -137,9 +152,7 @@ class TransportKeyManager {
LOG.log(WARNING, e.toString(), e);
}
}
};
long delay = rotationPeriodLength - now % rotationPeriodLength;
timer.schedule(task, delay);
});
}
void addContact(Transaction txn, ContactId c, SecretKey master,

View File

@@ -18,7 +18,8 @@ import dagger.Provides;
public class TransportModule {
public static class EagerSingletons {
@Inject KeyManager keyManager;
@Inject
KeyManager keyManager;
}
@Provides
@@ -35,7 +36,7 @@ public class TransportModule {
@Provides
@Singleton
KeyManager getKeyManager(LifecycleManager lifecycleManager,
KeyManager provideKeyManager(LifecycleManager lifecycleManager,
EventBus eventBus, KeyManagerImpl keyManager) {
lifecycleManager.registerService(keyManager);
eventBus.addListener(keyManager);

View File

@@ -0,0 +1,19 @@
package org.briarproject.system;
import org.briarproject.api.system.SeedProvider;
import org.briarproject.util.OsUtils;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
@Module
public class DesktopSeedProviderModule {
@Provides
@Singleton
SeedProvider provideSeedProvider() {
return OsUtils.isLinux() ? new LinuxSeedProvider() : null;
}
}

View File

@@ -1,31 +0,0 @@
package org.briarproject.system;
import org.briarproject.api.system.Clock;
import org.briarproject.api.system.SeedProvider;
import org.briarproject.api.system.Timer;
import org.briarproject.util.OsUtils;
import dagger.Module;
import dagger.Provides;
@Module
public class DesktopSystemModule {
@Provides
Clock provideClock() {
return new SystemClock();
}
@Provides
Timer provideTimer() {
return new SystemTimer();
}
@Provides
SeedProvider provideSeedProvider() {
if (OsUtils.isLinux()) {
return new LinuxSeedProvider();
}
return null;
}
}

View File

@@ -0,0 +1,18 @@
package org.briarproject;
import org.briarproject.api.system.SeedProvider;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
@Module
public class TestSeedProviderModule {
@Provides
@Singleton
SeedProvider provideSeedProvider() {
return new TestSeedProvider();
}
}

View File

@@ -1,29 +0,0 @@
package org.briarproject;
import org.briarproject.api.system.Clock;
import org.briarproject.api.system.SeedProvider;
import org.briarproject.api.system.Timer;
import org.briarproject.system.SystemClock;
import org.briarproject.system.SystemTimer;
import dagger.Module;
import dagger.Provides;
@Module
public class TestSystemModule {
@Provides
Clock provideClock() {
return new SystemClock();
}
@Provides
Timer provideSystemTimer() {
return new SystemTimer();
}
@Provides
SeedProvider provideSeedProvider() {
return new TestSeedProvider();
}
}

View File

@@ -113,8 +113,6 @@ public class PluginManagerImplTest extends BriarTestCase {
// stop()
// Stop listening for events
oneOf(eventBus).removeListener(with(any(EventListener.class)));
// Stop the poller
oneOf(poller).stop();
// Stop the plugins
oneOf(simplexPlugin).stop();
oneOf(duplexPlugin).stop();
@@ -248,8 +246,6 @@ public class PluginManagerImplTest extends BriarTestCase {
// stop()
// Stop listening for events
oneOf(eventBus).removeListener(with(any(EventListener.class)));
// Stop the poller
oneOf(poller).stop();
// Stop the plugins
oneOf(simplexPlugin).stop();
oneOf(simplexPlugin1).stop();

View File

@@ -9,7 +9,6 @@ import org.briarproject.api.crypto.SecretKey;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.Transaction;
import org.briarproject.api.system.Clock;
import org.briarproject.api.system.Timer;
import org.briarproject.api.transport.IncomingKeys;
import org.briarproject.api.transport.OutgoingKeys;
import org.briarproject.api.transport.StreamContext;
@@ -28,8 +27,10 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.TimerTask;
import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledExecutorService;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static org.briarproject.api.transport.TransportConstants.MAX_CLOCK_DIFFERENCE;
import static org.briarproject.api.transport.TransportConstants.REORDERING_WINDOW_SIZE;
import static org.briarproject.api.transport.TransportConstants.TAG_LENGTH;
@@ -56,11 +57,12 @@ public class TransportKeyManagerTest extends BriarTestCase {
Mockery context = new Mockery();
final DatabaseComponent db = context.mock(DatabaseComponent.class);
final CryptoComponent crypto = context.mock(CryptoComponent.class);
final Timer timer = context.mock(Timer.class);
final Executor dbExecutor = context.mock(Executor.class);
final ScheduledExecutorService scheduler =
context.mock(ScheduledExecutorService.class);
final Clock clock = context.mock(Clock.class);
final Map<ContactId, TransportKeys> loaded =
new LinkedHashMap<ContactId, TransportKeys>();
final Map<ContactId, TransportKeys> loaded = new LinkedHashMap<>();
final TransportKeys shouldRotate = createTransportKeys(900, 0);
final TransportKeys shouldNotRotate = createTransportKeys(1000, 0);
loaded.put(contactId, shouldRotate);
@@ -90,12 +92,12 @@ public class TransportKeyManagerTest extends BriarTestCase {
oneOf(db).updateTransportKeys(txn,
Collections.singletonMap(contactId, rotated));
// Schedule key rotation at the start of the next rotation period
oneOf(timer).schedule(with(any(TimerTask.class)),
with(rotationPeriodLength - 1));
oneOf(scheduler).schedule(with(any(Runnable.class)),
with(rotationPeriodLength - 1), with(MILLISECONDS));
}});
TransportKeyManager transportKeyManager = new TransportKeyManager(db,
crypto, timer, clock, transportId, maxLatency);
crypto, dbExecutor, scheduler, clock, transportId, maxLatency);
transportKeyManager.start(txn);
context.assertIsSatisfied();
@@ -106,7 +108,9 @@ public class TransportKeyManagerTest extends BriarTestCase {
Mockery context = new Mockery();
final DatabaseComponent db = context.mock(DatabaseComponent.class);
final CryptoComponent crypto = context.mock(CryptoComponent.class);
final Timer timer = context.mock(Timer.class);
final Executor dbExecutor = context.mock(Executor.class);
final ScheduledExecutorService scheduler =
context.mock(ScheduledExecutorService.class);
final Clock clock = context.mock(Clock.class);
final boolean alice = true;
@@ -135,7 +139,7 @@ public class TransportKeyManagerTest extends BriarTestCase {
}});
TransportKeyManager transportKeyManager = new TransportKeyManager(db,
crypto, timer, clock, transportId, maxLatency);
crypto, dbExecutor, scheduler, clock, transportId, maxLatency);
// The timestamp is 1 ms before the start of rotation period 1000
long timestamp = rotationPeriodLength * 1000 - 1;
transportKeyManager.addContact(txn, contactId, masterKey, timestamp,
@@ -150,13 +154,15 @@ public class TransportKeyManagerTest extends BriarTestCase {
Mockery context = new Mockery();
final DatabaseComponent db = context.mock(DatabaseComponent.class);
final CryptoComponent crypto = context.mock(CryptoComponent.class);
final Timer timer = context.mock(Timer.class);
final Executor dbExecutor = context.mock(Executor.class);
final ScheduledExecutorService scheduler =
context.mock(ScheduledExecutorService.class);
final Clock clock = context.mock(Clock.class);
final Transaction txn = new Transaction(null, false);
TransportKeyManager transportKeyManager = new TransportKeyManager(db,
crypto, timer, clock, transportId, maxLatency);
crypto, dbExecutor, scheduler, clock, transportId, maxLatency);
assertNull(transportKeyManager.getStreamContext(txn, contactId));
context.assertIsSatisfied();
@@ -168,7 +174,9 @@ public class TransportKeyManagerTest extends BriarTestCase {
Mockery context = new Mockery();
final DatabaseComponent db = context.mock(DatabaseComponent.class);
final CryptoComponent crypto = context.mock(CryptoComponent.class);
final Timer timer = context.mock(Timer.class);
final Executor dbExecutor = context.mock(Executor.class);
final ScheduledExecutorService scheduler =
context.mock(ScheduledExecutorService.class);
final Clock clock = context.mock(Clock.class);
final boolean alice = true;
@@ -198,7 +206,7 @@ public class TransportKeyManagerTest extends BriarTestCase {
}});
TransportKeyManager transportKeyManager = new TransportKeyManager(db,
crypto, timer, clock, transportId, maxLatency);
crypto, dbExecutor, scheduler, clock, transportId, maxLatency);
// The timestamp is at the start of rotation period 1000
long timestamp = rotationPeriodLength * 1000;
transportKeyManager.addContact(txn, contactId, masterKey, timestamp,
@@ -213,7 +221,9 @@ public class TransportKeyManagerTest extends BriarTestCase {
Mockery context = new Mockery();
final DatabaseComponent db = context.mock(DatabaseComponent.class);
final CryptoComponent crypto = context.mock(CryptoComponent.class);
final Timer timer = context.mock(Timer.class);
final Executor dbExecutor = context.mock(Executor.class);
final ScheduledExecutorService scheduler =
context.mock(ScheduledExecutorService.class);
final Clock clock = context.mock(Clock.class);
final boolean alice = true;
@@ -245,7 +255,7 @@ public class TransportKeyManagerTest extends BriarTestCase {
}});
TransportKeyManager transportKeyManager = new TransportKeyManager(db,
crypto, timer, clock, transportId, maxLatency);
crypto, dbExecutor, scheduler, clock, transportId, maxLatency);
// The timestamp is at the start of rotation period 1000
long timestamp = rotationPeriodLength * 1000;
transportKeyManager.addContact(txn, contactId, masterKey, timestamp,
@@ -271,7 +281,9 @@ public class TransportKeyManagerTest extends BriarTestCase {
Mockery context = new Mockery();
final DatabaseComponent db = context.mock(DatabaseComponent.class);
final CryptoComponent crypto = context.mock(CryptoComponent.class);
final Timer timer = context.mock(Timer.class);
final Executor dbExecutor = context.mock(Executor.class);
final ScheduledExecutorService scheduler =
context.mock(ScheduledExecutorService.class);
final Clock clock = context.mock(Clock.class);
final boolean alice = true;
@@ -299,7 +311,7 @@ public class TransportKeyManagerTest extends BriarTestCase {
}});
TransportKeyManager transportKeyManager = new TransportKeyManager(db,
crypto, timer, clock, transportId, maxLatency);
crypto, dbExecutor, scheduler, clock, transportId, maxLatency);
// The timestamp is at the start of rotation period 1000
long timestamp = rotationPeriodLength * 1000;
transportKeyManager.addContact(txn, contactId, masterKey, timestamp,
@@ -315,13 +327,15 @@ public class TransportKeyManagerTest extends BriarTestCase {
Mockery context = new Mockery();
final DatabaseComponent db = context.mock(DatabaseComponent.class);
final CryptoComponent crypto = context.mock(CryptoComponent.class);
final Timer timer = context.mock(Timer.class);
final Executor dbExecutor = context.mock(Executor.class);
final ScheduledExecutorService scheduler =
context.mock(ScheduledExecutorService.class);
final Clock clock = context.mock(Clock.class);
final boolean alice = true;
final TransportKeys transportKeys = createTransportKeys(1000, 0);
// Keep a copy of the tags
final List<byte[]> tags = new ArrayList<byte[]>();
final List<byte[]> tags = new ArrayList<>();
final Transaction txn = new Transaction(null, false);
context.checking(new Expectations() {{
@@ -352,7 +366,7 @@ public class TransportKeyManagerTest extends BriarTestCase {
}});
TransportKeyManager transportKeyManager = new TransportKeyManager(db,
crypto, timer, clock, transportId, maxLatency);
crypto, dbExecutor, scheduler, clock, transportId, maxLatency);
// The timestamp is at the start of rotation period 1000
long timestamp = rotationPeriodLength * 1000;
transportKeyManager.addContact(txn, contactId, masterKey, timestamp,
@@ -381,7 +395,9 @@ public class TransportKeyManagerTest extends BriarTestCase {
Mockery context = new Mockery();
final DatabaseComponent db = context.mock(DatabaseComponent.class);
final CryptoComponent crypto = context.mock(CryptoComponent.class);
final Timer timer = context.mock(Timer.class);
final Executor dbExecutor = context.mock(Executor.class);
final ScheduledExecutorService scheduler =
context.mock(ScheduledExecutorService.class);
final Clock clock = context.mock(Clock.class);
final TransportKeys transportKeys = createTransportKeys(1000, 0);
@@ -408,9 +424,11 @@ public class TransportKeyManagerTest extends BriarTestCase {
will(new EncodeTagAction());
}
// Schedule key rotation at the start of the next rotation period
oneOf(timer).schedule(with(any(TimerTask.class)),
with(rotationPeriodLength));
will(new RunTimerTaskAction());
oneOf(scheduler).schedule(with(any(Runnable.class)),
with(rotationPeriodLength), with(MILLISECONDS));
will(new RunAction());
oneOf(dbExecutor).execute(with(any(Runnable.class)));
will(new RunAction());
// Start a transaction for key rotation
oneOf(db).startTransaction(false);
will(returnValue(txn1));
@@ -431,14 +449,14 @@ public class TransportKeyManagerTest extends BriarTestCase {
oneOf(db).updateTransportKeys(txn1,
Collections.singletonMap(contactId, rotated));
// Schedule key rotation at the start of the next rotation period
oneOf(timer).schedule(with(any(TimerTask.class)),
with(rotationPeriodLength));
oneOf(scheduler).schedule(with(any(Runnable.class)),
with(rotationPeriodLength), with(MILLISECONDS));
// Commit the key rotation transaction
oneOf(db).endTransaction(txn1);
}});
TransportKeyManager transportKeyManager = new TransportKeyManager(db,
crypto, timer, clock, transportId, maxLatency);
crypto, dbExecutor, scheduler, clock, transportId, maxLatency);
transportKeyManager.start(txn);
assertTrue(txn1.isComplete());
@@ -484,18 +502,18 @@ public class TransportKeyManagerTest extends BriarTestCase {
}
}
private static class RunTimerTaskAction implements Action {
private static class RunAction implements Action {
@Override
public Object invoke(Invocation invocation) throws Throwable {
TimerTask task = (TimerTask) invocation.getParameter(0);
Runnable task = (Runnable) invocation.getParameter(0);
task.run();
return null;
}
@Override
public void describeTo(Description description) {
description.appendText("schedules a timer task");
description.appendText("runs a runnable");
}
}
}