From 57a6c8cb3ac2b8416b447a711578f52d07ecc93e Mon Sep 17 00:00:00 2001
From: akwizgran <michael@briarproject.org>
Date: Tue, 17 Apr 2018 12:13:02 +0100
Subject: [PATCH] Separate the crypto executor into its own module.

This allows it to be replaced for testing.
---
 .../bramble/BrambleCoreEagerSingletons.java   |   4 +-
 .../bramble/BrambleCoreModule.java            |   4 +-
 .../bramble/crypto/CryptoExecutorModule.java  |  67 ++++++++
 .../bramble/crypto/CryptoModule.java          |  55 ------
 .../test/TestCryptoExecutorModule.java        |  21 +++
 .../feed/FeedManagerIntegrationTest.java      |   6 +-
 .../FeedManagerIntegrationTestComponent.java  |  10 +-
 .../IntroductionIntegrationTestComponent.java |   2 +
 .../messaging/MessageSizeIntegrationTest.java |  13 ++
 .../MessageSizeIntegrationTestComponent.java  |  24 ++-
 .../SimplexMessagingIntegrationTest.java      | 156 ++++++++++--------
 ...plexMessagingIntegrationTestComponent.java |  12 ++
 .../briar/test/BriarIntegrationTest.java      |   4 +-
 .../test/BriarIntegrationTestComponent.java   |   4 +-
 14 files changed, 241 insertions(+), 141 deletions(-)
 create mode 100644 bramble-core/src/main/java/org/briarproject/bramble/crypto/CryptoExecutorModule.java
 create mode 100644 bramble-core/src/test/java/org/briarproject/bramble/test/TestCryptoExecutorModule.java

diff --git a/bramble-core/src/main/java/org/briarproject/bramble/BrambleCoreEagerSingletons.java b/bramble-core/src/main/java/org/briarproject/bramble/BrambleCoreEagerSingletons.java
index e7a211e294..b57869fb12 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/BrambleCoreEagerSingletons.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/BrambleCoreEagerSingletons.java
@@ -1,7 +1,7 @@
 package org.briarproject.bramble;
 
 import org.briarproject.bramble.contact.ContactModule;
-import org.briarproject.bramble.crypto.CryptoModule;
+import org.briarproject.bramble.crypto.CryptoExecutorModule;
 import org.briarproject.bramble.db.DatabaseExecutorModule;
 import org.briarproject.bramble.identity.IdentityModule;
 import org.briarproject.bramble.lifecycle.LifecycleModule;
@@ -15,7 +15,7 @@ public interface BrambleCoreEagerSingletons {
 
 	void inject(ContactModule.EagerSingletons init);
 
-	void inject(CryptoModule.EagerSingletons init);
+	void inject(CryptoExecutorModule.EagerSingletons init);
 
 	void inject(DatabaseExecutorModule.EagerSingletons init);
 
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/BrambleCoreModule.java b/bramble-core/src/main/java/org/briarproject/bramble/BrambleCoreModule.java
index 365b50de91..771776c26a 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/BrambleCoreModule.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/BrambleCoreModule.java
@@ -2,6 +2,7 @@ package org.briarproject.bramble;
 
 import org.briarproject.bramble.client.ClientModule;
 import org.briarproject.bramble.contact.ContactModule;
+import org.briarproject.bramble.crypto.CryptoExecutorModule;
 import org.briarproject.bramble.crypto.CryptoModule;
 import org.briarproject.bramble.data.DataModule;
 import org.briarproject.bramble.db.DatabaseExecutorModule;
@@ -26,6 +27,7 @@ import dagger.Module;
 		ClientModule.class,
 		ContactModule.class,
 		CryptoModule.class,
+		CryptoExecutorModule.class,
 		DataModule.class,
 		DatabaseModule.class,
 		DatabaseExecutorModule.class,
@@ -47,7 +49,7 @@ public class BrambleCoreModule {
 
 	public static void initEagerSingletons(BrambleCoreEagerSingletons c) {
 		c.inject(new ContactModule.EagerSingletons());
-		c.inject(new CryptoModule.EagerSingletons());
+		c.inject(new CryptoExecutorModule.EagerSingletons());
 		c.inject(new DatabaseExecutorModule.EagerSingletons());
 		c.inject(new IdentityModule.EagerSingletons());
 		c.inject(new LifecycleModule.EagerSingletons());
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/crypto/CryptoExecutorModule.java b/bramble-core/src/main/java/org/briarproject/bramble/crypto/CryptoExecutorModule.java
new file mode 100644
index 0000000000..ab0e4114f5
--- /dev/null
+++ b/bramble-core/src/main/java/org/briarproject/bramble/crypto/CryptoExecutorModule.java
@@ -0,0 +1,67 @@
+package org.briarproject.bramble.crypto;
+
+import org.briarproject.bramble.TimeLoggingExecutor;
+import org.briarproject.bramble.api.crypto.CryptoExecutor;
+import org.briarproject.bramble.api.lifecycle.LifecycleManager;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.RejectedExecutionHandler;
+import java.util.concurrent.ThreadPoolExecutor;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import dagger.Module;
+import dagger.Provides;
+
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+@Module
+public class CryptoExecutorModule {
+
+	public static class EagerSingletons {
+		@Inject
+		@CryptoExecutor
+		ExecutorService cryptoExecutor;
+	}
+
+	/**
+	 * The maximum number of executor threads.
+	 * <p>
+	 * The number of available processors can change during the lifetime of the
+	 * JVM, so this is just a reasonable guess.
+	 */
+	private static final int MAX_EXECUTOR_THREADS =
+			Math.max(1, Runtime.getRuntime().availableProcessors() - 1);
+
+	private final ExecutorService cryptoExecutor;
+
+	public CryptoExecutorModule() {
+		// Use an unbounded queue
+		BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>();
+		// Discard tasks that are submitted during shutdown
+		RejectedExecutionHandler policy =
+				new ThreadPoolExecutor.DiscardPolicy();
+		// Create a limited # of threads and keep them in the pool for 60 secs
+		cryptoExecutor = new TimeLoggingExecutor("CryptoExecutor", 0,
+				MAX_EXECUTOR_THREADS, 60, SECONDS, queue, policy);
+	}
+
+	@Provides
+	@Singleton
+	@CryptoExecutor
+	ExecutorService provideCryptoExecutorService(
+			LifecycleManager lifecycleManager) {
+		lifecycleManager.registerForShutdown(cryptoExecutor);
+		return cryptoExecutor;
+	}
+
+	@Provides
+	@CryptoExecutor
+	Executor provideCryptoExecutor() {
+		return cryptoExecutor;
+	}
+}
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/crypto/CryptoModule.java b/bramble-core/src/main/java/org/briarproject/bramble/crypto/CryptoModule.java
index 25d24995d5..680391bd00 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/crypto/CryptoModule.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/crypto/CryptoModule.java
@@ -1,64 +1,24 @@
 package org.briarproject.bramble.crypto;
 
-import org.briarproject.bramble.TimeLoggingExecutor;
 import org.briarproject.bramble.api.crypto.CryptoComponent;
-import org.briarproject.bramble.api.crypto.CryptoExecutor;
 import org.briarproject.bramble.api.crypto.KeyAgreementCrypto;
 import org.briarproject.bramble.api.crypto.PasswordStrengthEstimator;
 import org.briarproject.bramble.api.crypto.StreamDecrypterFactory;
 import org.briarproject.bramble.api.crypto.StreamEncrypterFactory;
 import org.briarproject.bramble.api.crypto.TransportCrypto;
-import org.briarproject.bramble.api.lifecycle.LifecycleManager;
 import org.briarproject.bramble.api.system.SecureRandomProvider;
 
 import java.security.SecureRandom;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.Executor;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.RejectedExecutionHandler;
-import java.util.concurrent.ThreadPoolExecutor;
 
-import javax.inject.Inject;
 import javax.inject.Provider;
 import javax.inject.Singleton;
 
 import dagger.Module;
 import dagger.Provides;
 
-import static java.util.concurrent.TimeUnit.SECONDS;
-
 @Module
 public class CryptoModule {
 
-	public static class EagerSingletons {
-		@Inject
-		@CryptoExecutor
-		ExecutorService cryptoExecutor;
-	}
-
-	/**
-	 * The maximum number of executor threads.
-	 * <p>
-	 * The number of available processors can change during the lifetime of the
-	 * JVM, so this is just a reasonable guess.
-	 */
-	private static final int MAX_EXECUTOR_THREADS =
-			Math.max(1, Runtime.getRuntime().availableProcessors() - 1);
-
-	private final ExecutorService cryptoExecutor;
-
-	public CryptoModule() {
-		// Use an unbounded queue
-		BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>();
-		// Discard tasks that are submitted during shutdown
-		RejectedExecutionHandler policy =
-				new ThreadPoolExecutor.DiscardPolicy();
-		// Create a limited # of threads and keep them in the pool for 60 secs
-		cryptoExecutor = new TimeLoggingExecutor("CryptoExecutor", 0,
-				MAX_EXECUTOR_THREADS, 60, SECONDS, queue, policy);
-	}
-
 	@Provides
 	AuthenticatedCipher provideAuthenticatedCipher() {
 		return new XSalsa20Poly1305AuthenticatedCipher();
@@ -103,21 +63,6 @@ public class CryptoModule {
 		return keyAgreementCrypto;
 	}
 
-	@Provides
-	@Singleton
-	@CryptoExecutor
-	ExecutorService getCryptoExecutorService(
-			LifecycleManager lifecycleManager) {
-		lifecycleManager.registerForShutdown(cryptoExecutor);
-		return cryptoExecutor;
-	}
-
-	@Provides
-	@CryptoExecutor
-	Executor getCryptoExecutor() {
-		return cryptoExecutor;
-	}
-
 	@Provides
 	SecureRandom getSecureRandom(CryptoComponent crypto) {
 		return crypto.getSecureRandom();
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/test/TestCryptoExecutorModule.java b/bramble-core/src/test/java/org/briarproject/bramble/test/TestCryptoExecutorModule.java
new file mode 100644
index 0000000000..3fabc08d5a
--- /dev/null
+++ b/bramble-core/src/test/java/org/briarproject/bramble/test/TestCryptoExecutorModule.java
@@ -0,0 +1,21 @@
+package org.briarproject.bramble.test;
+
+import org.briarproject.bramble.api.crypto.CryptoExecutor;
+
+import java.util.concurrent.Executor;
+
+import javax.inject.Singleton;
+
+import dagger.Module;
+import dagger.Provides;
+
+@Module
+public class TestCryptoExecutorModule {
+
+	@Provides
+	@Singleton
+	@CryptoExecutor
+	Executor provideCryptoExecutor() {
+		return new ImmediateExecutor();
+	}
+}
diff --git a/briar-core/src/test/java/org/briarproject/briar/feed/FeedManagerIntegrationTest.java b/briar-core/src/test/java/org/briarproject/briar/feed/FeedManagerIntegrationTest.java
index 2fc24aae58..ea8448ed40 100644
--- a/briar-core/src/test/java/org/briarproject/briar/feed/FeedManagerIntegrationTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/feed/FeedManagerIntegrationTest.java
@@ -2,7 +2,7 @@ package org.briarproject.briar.feed;
 
 import org.briarproject.bramble.api.lifecycle.LifecycleManager;
 import org.briarproject.bramble.contact.ContactModule;
-import org.briarproject.bramble.crypto.CryptoModule;
+import org.briarproject.bramble.crypto.CryptoExecutorModule;
 import org.briarproject.bramble.identity.IdentityModule;
 import org.briarproject.bramble.lifecycle.LifecycleModule;
 import org.briarproject.bramble.sync.SyncModule;
@@ -113,10 +113,10 @@ public class FeedManagerIntegrationTest extends BriarTestCase {
 
 	protected void injectEagerSingletons(
 			FeedManagerIntegrationTestComponent component) {
-		component.inject(new FeedModule.EagerSingletons());
 		component.inject(new BlogModule.EagerSingletons());
 		component.inject(new ContactModule.EagerSingletons());
-		component.inject(new CryptoModule.EagerSingletons());
+		component.inject(new CryptoExecutorModule.EagerSingletons());
+		component.inject(new FeedModule.EagerSingletons());
 		component.inject(new IdentityModule.EagerSingletons());
 		component.inject(new LifecycleModule.EagerSingletons());
 		component.inject(new SyncModule.EagerSingletons());
diff --git a/briar-core/src/test/java/org/briarproject/briar/feed/FeedManagerIntegrationTestComponent.java b/briar-core/src/test/java/org/briarproject/briar/feed/FeedManagerIntegrationTestComponent.java
index 0a8fbfbe62..6de06bc283 100644
--- a/briar-core/src/test/java/org/briarproject/briar/feed/FeedManagerIntegrationTestComponent.java
+++ b/briar-core/src/test/java/org/briarproject/briar/feed/FeedManagerIntegrationTestComponent.java
@@ -3,6 +3,7 @@ package org.briarproject.briar.feed;
 import org.briarproject.bramble.api.lifecycle.LifecycleManager;
 import org.briarproject.bramble.client.ClientModule;
 import org.briarproject.bramble.contact.ContactModule;
+import org.briarproject.bramble.crypto.CryptoExecutorModule;
 import org.briarproject.bramble.crypto.CryptoModule;
 import org.briarproject.bramble.data.DataModule;
 import org.briarproject.bramble.db.DatabaseModule;
@@ -33,17 +34,18 @@ import dagger.Component;
 		TestSecureRandomModule.class,
 		TestSocksModule.class,
 		TestDnsModule.class,
-		LifecycleModule.class,
 		BriarClientModule.class,
 		ClientModule.class,
 		ContactModule.class,
 		CryptoModule.class,
+		CryptoExecutorModule.class,
 		BlogModule.class,
 		FeedModule.class,
 		DataModule.class,
 		DatabaseModule.class,
 		EventModule.class,
 		IdentityModule.class,
+		LifecycleModule.class,
 		SyncModule.class,
 		SystemModule.class,
 		TransportModule.class
@@ -52,13 +54,13 @@ interface FeedManagerIntegrationTestComponent {
 
 	void inject(FeedManagerIntegrationTest testCase);
 
-	void inject(FeedModule.EagerSingletons init);
-
 	void inject(BlogModule.EagerSingletons init);
 
 	void inject(ContactModule.EagerSingletons init);
 
-	void inject(CryptoModule.EagerSingletons init);
+	void inject(CryptoExecutorModule.EagerSingletons init);
+
+	void inject(FeedModule.EagerSingletons init);
 
 	void inject(IdentityModule.EagerSingletons init);
 
diff --git a/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionIntegrationTestComponent.java b/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionIntegrationTestComponent.java
index 3a90d7d148..d3367296f3 100644
--- a/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionIntegrationTestComponent.java
+++ b/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionIntegrationTestComponent.java
@@ -2,6 +2,7 @@ package org.briarproject.briar.introduction;
 
 import org.briarproject.bramble.client.ClientModule;
 import org.briarproject.bramble.contact.ContactModule;
+import org.briarproject.bramble.crypto.CryptoExecutorModule;
 import org.briarproject.bramble.crypto.CryptoModule;
 import org.briarproject.bramble.data.DataModule;
 import org.briarproject.bramble.db.DatabaseModule;
@@ -38,6 +39,7 @@ import dagger.Component;
 		ClientModule.class,
 		ContactModule.class,
 		CryptoModule.class,
+		CryptoExecutorModule.class,
 		DataModule.class,
 		DatabaseModule.class,
 		EventModule.class,
diff --git a/briar-core/src/test/java/org/briarproject/briar/messaging/MessageSizeIntegrationTest.java b/briar-core/src/test/java/org/briarproject/briar/messaging/MessageSizeIntegrationTest.java
index b56d42d7fa..d2b19c89f1 100644
--- a/briar-core/src/test/java/org/briarproject/briar/messaging/MessageSizeIntegrationTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/messaging/MessageSizeIntegrationTest.java
@@ -7,11 +7,17 @@ import org.briarproject.bramble.api.identity.AuthorFactory;
 import org.briarproject.bramble.api.identity.LocalAuthor;
 import org.briarproject.bramble.api.sync.GroupId;
 import org.briarproject.bramble.api.sync.MessageId;
+import org.briarproject.bramble.contact.ContactModule;
+import org.briarproject.bramble.crypto.CryptoExecutorModule;
+import org.briarproject.bramble.identity.IdentityModule;
+import org.briarproject.bramble.sync.SyncModule;
 import org.briarproject.bramble.system.SystemModule;
+import org.briarproject.bramble.transport.TransportModule;
 import org.briarproject.briar.api.forum.ForumPost;
 import org.briarproject.briar.api.forum.ForumPostFactory;
 import org.briarproject.briar.api.messaging.PrivateMessage;
 import org.briarproject.briar.api.messaging.PrivateMessageFactory;
+import org.briarproject.briar.forum.ForumModule;
 import org.briarproject.briar.test.BriarTestCase;
 import org.junit.Test;
 
@@ -85,6 +91,13 @@ public class MessageSizeIntegrationTest extends BriarTestCase {
 
 	private static void injectEagerSingletons(
 			MessageSizeIntegrationTestComponent component) {
+		component.inject(new ContactModule.EagerSingletons());
+		component.inject(new CryptoExecutorModule.EagerSingletons());
+		component.inject(new ForumModule.EagerSingletons());
+		component.inject(new IdentityModule.EagerSingletons());
+		component.inject(new MessagingModule.EagerSingletons());
+		component.inject(new SyncModule.EagerSingletons());
 		component.inject(new SystemModule.EagerSingletons());
+		component.inject(new TransportModule.EagerSingletons());
 	}
 }
diff --git a/briar-core/src/test/java/org/briarproject/briar/messaging/MessageSizeIntegrationTestComponent.java b/briar-core/src/test/java/org/briarproject/briar/messaging/MessageSizeIntegrationTestComponent.java
index 42b27da6f3..2ac7f469b5 100644
--- a/briar-core/src/test/java/org/briarproject/briar/messaging/MessageSizeIntegrationTestComponent.java
+++ b/briar-core/src/test/java/org/briarproject/briar/messaging/MessageSizeIntegrationTestComponent.java
@@ -1,6 +1,8 @@
 package org.briarproject.briar.messaging;
 
 import org.briarproject.bramble.client.ClientModule;
+import org.briarproject.bramble.contact.ContactModule;
+import org.briarproject.bramble.crypto.CryptoExecutorModule;
 import org.briarproject.bramble.crypto.CryptoModule;
 import org.briarproject.bramble.data.DataModule;
 import org.briarproject.bramble.db.DatabaseModule;
@@ -10,7 +12,9 @@ import org.briarproject.bramble.sync.SyncModule;
 import org.briarproject.bramble.system.SystemModule;
 import org.briarproject.bramble.test.TestDatabaseModule;
 import org.briarproject.bramble.test.TestLifecycleModule;
+import org.briarproject.bramble.test.TestPluginConfigModule;
 import org.briarproject.bramble.test.TestSecureRandomModule;
+import org.briarproject.bramble.transport.TransportModule;
 import org.briarproject.briar.client.BriarClientModule;
 import org.briarproject.briar.forum.ForumModule;
 
@@ -22,10 +26,13 @@ import dagger.Component;
 @Component(modules = {
 		TestDatabaseModule.class,
 		TestLifecycleModule.class,
+		TestPluginConfigModule.class,
 		TestSecureRandomModule.class,
 		BriarClientModule.class,
 		ClientModule.class,
+		ContactModule.class,
 		CryptoModule.class,
+		CryptoExecutorModule.class,
 		DataModule.class,
 		DatabaseModule.class,
 		EventModule.class,
@@ -33,11 +40,26 @@ import dagger.Component;
 		IdentityModule.class,
 		MessagingModule.class,
 		SyncModule.class,
-		SystemModule.class
+		SystemModule.class,
+		TransportModule.class
 })
 interface MessageSizeIntegrationTestComponent {
 
 	void inject(MessageSizeIntegrationTest testCase);
 
+	void inject(ContactModule.EagerSingletons init);
+
+	void inject(CryptoExecutorModule.EagerSingletons init);
+
+	void inject(ForumModule.EagerSingletons init);
+
+	void inject(IdentityModule.EagerSingletons init);
+
+	void inject(MessagingModule.EagerSingletons init);
+
+	void inject(SyncModule.EagerSingletons init);
+
 	void inject(SystemModule.EagerSingletons init);
+
+	void inject(TransportModule.EagerSingletons init);
 }
diff --git a/briar-core/src/test/java/org/briarproject/briar/messaging/SimplexMessagingIntegrationTest.java b/briar-core/src/test/java/org/briarproject/briar/messaging/SimplexMessagingIntegrationTest.java
index 8967961cee..df9754d53d 100644
--- a/briar-core/src/test/java/org/briarproject/briar/messaging/SimplexMessagingIntegrationTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/messaging/SimplexMessagingIntegrationTest.java
@@ -5,6 +5,7 @@ import org.briarproject.bramble.api.contact.ContactManager;
 import org.briarproject.bramble.api.crypto.SecretKey;
 import org.briarproject.bramble.api.event.Event;
 import org.briarproject.bramble.api.event.EventListener;
+import org.briarproject.bramble.api.identity.Author;
 import org.briarproject.bramble.api.identity.IdentityManager;
 import org.briarproject.bramble.api.identity.LocalAuthor;
 import org.briarproject.bramble.api.lifecycle.LifecycleManager;
@@ -12,17 +13,22 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
 import org.briarproject.bramble.api.sync.GroupId;
 import org.briarproject.bramble.api.sync.SyncSession;
 import org.briarproject.bramble.api.sync.SyncSessionFactory;
-import org.briarproject.bramble.api.sync.event.MessageAddedEvent;
 import org.briarproject.bramble.api.transport.KeyManager;
 import org.briarproject.bramble.api.transport.StreamContext;
 import org.briarproject.bramble.api.transport.StreamReaderFactory;
 import org.briarproject.bramble.api.transport.StreamWriterFactory;
+import org.briarproject.bramble.contact.ContactModule;
+import org.briarproject.bramble.identity.IdentityModule;
+import org.briarproject.bramble.lifecycle.LifecycleModule;
+import org.briarproject.bramble.sync.SyncModule;
 import org.briarproject.bramble.system.SystemModule;
 import org.briarproject.bramble.test.TestDatabaseModule;
 import org.briarproject.bramble.test.TestUtils;
+import org.briarproject.bramble.transport.TransportModule;
 import org.briarproject.briar.api.messaging.MessagingManager;
 import org.briarproject.briar.api.messaging.PrivateMessage;
 import org.briarproject.briar.api.messaging.PrivateMessageFactory;
+import org.briarproject.briar.api.messaging.event.PrivateMessageReceivedEvent;
 import org.briarproject.briar.test.BriarTestCase;
 import org.junit.After;
 import org.junit.Before;
@@ -41,7 +47,6 @@ import static org.briarproject.bramble.test.TestUtils.getLocalAuthor;
 import static org.briarproject.bramble.test.TestUtils.getSecretKey;
 import static org.briarproject.bramble.test.TestUtils.getTestDirectory;
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
@@ -71,103 +76,105 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
 
 	@Test
 	public void testWriteAndRead() throws Exception {
-		read(write());
+		// Set up the devices and get the contact IDs
+		ContactId bobId = setUp(alice, aliceAuthor, bobAuthor, true);
+		ContactId aliceId = setUp(bob, bobAuthor, aliceAuthor, false);
+		// Add a private message listener
+		PrivateMessageListener listener = new PrivateMessageListener();
+		bob.getEventBus().addListener(listener);
+		// Alice sends a private message to Bob
+		sendMessage(alice, bobId);
+		// Send three simplex streams to exchange client versions and the
+		// private message
+		read(bob, aliceId, write(alice, bobId));
+		read(alice, bobId, write(bob, aliceId));
+		read(bob, aliceId, write(alice, bobId));
+		// Tear down the devices
+		tearDown(alice);
+		tearDown(bob);
+		// Bob should have received the private message
+		assertTrue(listener.messageAdded);
 	}
 
-
-	private byte[] write() throws Exception {
-		// Instantiate Alice's services
-		LifecycleManager lifecycleManager = alice.getLifecycleManager();
-		IdentityManager identityManager = alice.getIdentityManager();
-		ContactManager contactManager = alice.getContactManager();
-		MessagingManager messagingManager = alice.getMessagingManager();
-		KeyManager keyManager = alice.getKeyManager();
-		PrivateMessageFactory privateMessageFactory =
-				alice.getPrivateMessageFactory();
-		StreamWriterFactory streamWriterFactory =
-				alice.getStreamWriterFactory();
-		SyncSessionFactory syncSessionFactory = alice.getSyncSessionFactory();
-
+	private ContactId setUp(SimplexMessagingIntegrationTestComponent device,
+			LocalAuthor local, Author remote, boolean alice) throws Exception {
 		// Start the lifecycle manager
+		LifecycleManager lifecycleManager = device.getLifecycleManager();
 		lifecycleManager.startServices(null);
 		lifecycleManager.waitForStartup();
-		// Add an identity for Alice
-		identityManager.registerLocalAuthor(aliceAuthor);
-		// Add Bob as a contact
-		ContactId contactId = contactManager.addContact(bobAuthor,
-				aliceAuthor.getId(), master, timestamp, true, true, true);
+		// Add an identity for the user
+		IdentityManager identityManager = device.getIdentityManager();
+		identityManager.registerLocalAuthor(local);
+		// Add the other user as a contact
+		ContactManager contactManager = device.getContactManager();
+		return contactManager.addContact(remote, local.getId(), master,
+				timestamp, alice, true, true);
+	}
 
+	private void sendMessage(SimplexMessagingIntegrationTestComponent device,
+			ContactId contactId) throws Exception {
 		// Send Bob a message
+		MessagingManager messagingManager = device.getMessagingManager();
 		GroupId groupId = messagingManager.getConversationId(contactId);
-		String body = "Hi Bob!";
+		PrivateMessageFactory privateMessageFactory =
+				device.getPrivateMessageFactory();
 		PrivateMessage message = privateMessageFactory.createPrivateMessage(
-				groupId, timestamp, body);
+				groupId, System.currentTimeMillis(), "Hi!");
 		messagingManager.addLocalMessage(message);
-		// Get a stream context
-		StreamContext ctx = keyManager.getStreamContext(contactId,
-				TRANSPORT_ID);
-		assertNotNull(ctx);
-		// Create a stream writer
-		ByteArrayOutputStream out = new ByteArrayOutputStream();
-		OutputStream streamWriter = streamWriterFactory.createStreamWriter(
-				out, ctx);
-		// Create an outgoing sync session
-		SyncSession session = syncSessionFactory.createSimplexOutgoingSession(
-				contactId, MAX_LATENCY, streamWriter);
-		// Write whatever needs to be written
-		session.run();
-		streamWriter.close();
-
-		// Clean up
-		lifecycleManager.stopServices();
-		lifecycleManager.waitForShutdown();
-
-		// Return the contents of the stream
-		return out.toByteArray();
 	}
 
-	private void read(byte[] stream) throws Exception {
-		// Instantiate Bob's services
-		LifecycleManager lifecycleManager = bob.getLifecycleManager();
-		IdentityManager identityManager = bob.getIdentityManager();
-		ContactManager contactManager = bob.getContactManager();
-		KeyManager keyManager = bob.getKeyManager();
-		StreamReaderFactory streamReaderFactory = bob.getStreamReaderFactory();
-		SyncSessionFactory syncSessionFactory = bob.getSyncSessionFactory();
-
-		// Start the lifecyle manager
-		lifecycleManager.startServices(null);
-		lifecycleManager.waitForStartup();
-		// Add an identity for Bob
-		identityManager.registerLocalAuthor(bobAuthor);
-		// Add Alice as a contact
-		ContactId contactId = contactManager.addContact(aliceAuthor,
-				bobAuthor.getId(), master, timestamp, false, true, true);
-		// Set up an event listener
-		MessageListener listener = new MessageListener();
-		bob.getEventBus().addListener(listener);
+	private void read(SimplexMessagingIntegrationTestComponent device,
+			ContactId contactId, byte[] stream) throws Exception {
 		// Read and recognise the tag
 		ByteArrayInputStream in = new ByteArrayInputStream(stream);
 		byte[] tag = new byte[TAG_LENGTH];
 		int read = in.read(tag);
 		assertEquals(tag.length, read);
+		KeyManager keyManager = device.getKeyManager();
 		StreamContext ctx = keyManager.getStreamContext(TRANSPORT_ID, tag);
 		assertNotNull(ctx);
 		// Create a stream reader
+		StreamReaderFactory streamReaderFactory =
+				device.getStreamReaderFactory();
 		InputStream streamReader = streamReaderFactory.createStreamReader(
 				in, ctx);
 		// Create an incoming sync session
+		SyncSessionFactory syncSessionFactory = device.getSyncSessionFactory();
 		SyncSession session = syncSessionFactory.createIncomingSession(
 				contactId, streamReader);
-		// No messages should have been added yet
-		assertFalse(listener.messageAdded);
 		// Read whatever needs to be read
 		session.run();
 		streamReader.close();
-		// The private message from Alice should have been added
-		assertTrue(listener.messageAdded);
+	}
+
+	private byte[] write(SimplexMessagingIntegrationTestComponent device,
+			ContactId contactId) throws Exception {
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		// Get a stream context
+		KeyManager keyManager = device.getKeyManager();
+		StreamContext ctx = keyManager.getStreamContext(contactId,
+				TRANSPORT_ID);
+		assertNotNull(ctx);
+		// Create a stream writer
+		StreamWriterFactory streamWriterFactory =
+				device.getStreamWriterFactory();
+		OutputStream streamWriter =
+				streamWriterFactory.createStreamWriter(out, ctx);
+		// Create an outgoing sync session
+		SyncSessionFactory syncSessionFactory = device.getSyncSessionFactory();
+		SyncSession session = syncSessionFactory.createSimplexOutgoingSession(
+				contactId, MAX_LATENCY, streamWriter);
+		// Write whatever needs to be written
+		session.run();
+		streamWriter.close();
+		// Return the contents of the stream
+		return out.toByteArray();
+	}
 
-		// Clean up
+	private void tearDown(SimplexMessagingIntegrationTestComponent device)
+			throws Exception {
+		// Stop the lifecycle manager
+		LifecycleManager lifecycleManager = device.getLifecycleManager();
 		lifecycleManager.stopServices();
 		lifecycleManager.waitForShutdown();
 	}
@@ -179,18 +186,23 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
 
 	private static void injectEagerSingletons(
 			SimplexMessagingIntegrationTestComponent component) {
+		component.inject(new ContactModule.EagerSingletons());
+		component.inject(new IdentityModule.EagerSingletons());
+		component.inject(new LifecycleModule.EagerSingletons());
 		component.inject(new MessagingModule.EagerSingletons());
+		component.inject(new SyncModule.EagerSingletons());
 		component.inject(new SystemModule.EagerSingletons());
+		component.inject(new TransportModule.EagerSingletons());
 	}
 
 	@NotNullByDefault
-	private static class MessageListener implements EventListener {
+	private static class PrivateMessageListener implements EventListener {
 
 		private volatile boolean messageAdded = false;
 
 		@Override
 		public void eventOccurred(Event e) {
-			if (e instanceof MessageAddedEvent) messageAdded = true;
+			if (e instanceof PrivateMessageReceivedEvent) messageAdded = true;
 		}
 	}
 }
diff --git a/briar-core/src/test/java/org/briarproject/briar/messaging/SimplexMessagingIntegrationTestComponent.java b/briar-core/src/test/java/org/briarproject/briar/messaging/SimplexMessagingIntegrationTestComponent.java
index d740859aa1..7fc608a554 100644
--- a/briar-core/src/test/java/org/briarproject/briar/messaging/SimplexMessagingIntegrationTestComponent.java
+++ b/briar-core/src/test/java/org/briarproject/briar/messaging/SimplexMessagingIntegrationTestComponent.java
@@ -18,6 +18,7 @@ import org.briarproject.bramble.identity.IdentityModule;
 import org.briarproject.bramble.lifecycle.LifecycleModule;
 import org.briarproject.bramble.sync.SyncModule;
 import org.briarproject.bramble.system.SystemModule;
+import org.briarproject.bramble.test.TestCryptoExecutorModule;
 import org.briarproject.bramble.test.TestDatabaseModule;
 import org.briarproject.bramble.test.TestPluginConfigModule;
 import org.briarproject.bramble.test.TestSecureRandomModule;
@@ -32,6 +33,7 @@ import dagger.Component;
 
 @Singleton
 @Component(modules = {
+		TestCryptoExecutorModule.class,
 		TestDatabaseModule.class,
 		TestPluginConfigModule.class,
 		TestSecureRandomModule.class,
@@ -51,10 +53,20 @@ import dagger.Component;
 })
 interface SimplexMessagingIntegrationTestComponent {
 
+	void inject(ContactModule.EagerSingletons init);
+
+	void inject(IdentityModule.EagerSingletons init);
+
+	void inject(LifecycleModule.EagerSingletons init);
+
 	void inject(MessagingModule.EagerSingletons init);
 
+	void inject(SyncModule.EagerSingletons init);
+
 	void inject(SystemModule.EagerSingletons init);
 
+	void inject(TransportModule.EagerSingletons init);
+
 	LifecycleManager getLifecycleManager();
 
 	IdentityManager getIdentityManager();
diff --git a/briar-core/src/test/java/org/briarproject/briar/test/BriarIntegrationTest.java b/briar-core/src/test/java/org/briarproject/briar/test/BriarIntegrationTest.java
index bb955313b5..18d00ee060 100644
--- a/briar-core/src/test/java/org/briarproject/briar/test/BriarIntegrationTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/test/BriarIntegrationTest.java
@@ -24,7 +24,7 @@ import org.briarproject.bramble.api.sync.SyncSessionFactory;
 import org.briarproject.bramble.api.sync.event.MessageStateChangedEvent;
 import org.briarproject.bramble.api.system.Clock;
 import org.briarproject.bramble.contact.ContactModule;
-import org.briarproject.bramble.crypto.CryptoModule;
+import org.briarproject.bramble.crypto.CryptoExecutorModule;
 import org.briarproject.bramble.identity.IdentityModule;
 import org.briarproject.bramble.lifecycle.LifecycleModule;
 import org.briarproject.bramble.properties.PropertiesModule;
@@ -170,7 +170,7 @@ public abstract class BriarIntegrationTest<C extends BriarIntegrationTestCompone
 			BriarIntegrationTestComponent component) {
 		component.inject(new BlogModule.EagerSingletons());
 		component.inject(new ContactModule.EagerSingletons());
-		component.inject(new CryptoModule.EagerSingletons());
+		component.inject(new CryptoExecutorModule.EagerSingletons());
 		component.inject(new ForumModule.EagerSingletons());
 		component.inject(new GroupInvitationModule.EagerSingletons());
 		component.inject(new IdentityModule.EagerSingletons());
diff --git a/briar-core/src/test/java/org/briarproject/briar/test/BriarIntegrationTestComponent.java b/briar-core/src/test/java/org/briarproject/briar/test/BriarIntegrationTestComponent.java
index ecaf60d1b9..ddf22cafac 100644
--- a/briar-core/src/test/java/org/briarproject/briar/test/BriarIntegrationTestComponent.java
+++ b/briar-core/src/test/java/org/briarproject/briar/test/BriarIntegrationTestComponent.java
@@ -11,6 +11,7 @@ import org.briarproject.bramble.api.properties.TransportPropertyManager;
 import org.briarproject.bramble.api.sync.SyncSessionFactory;
 import org.briarproject.bramble.client.ClientModule;
 import org.briarproject.bramble.contact.ContactModule;
+import org.briarproject.bramble.crypto.CryptoExecutorModule;
 import org.briarproject.bramble.crypto.CryptoModule;
 import org.briarproject.bramble.data.DataModule;
 import org.briarproject.bramble.db.DatabaseModule;
@@ -59,6 +60,7 @@ import dagger.Component;
 		ClientModule.class,
 		ContactModule.class,
 		CryptoModule.class,
+		CryptoExecutorModule.class,
 		DataModule.class,
 		DatabaseModule.class,
 		EventModule.class,
@@ -83,7 +85,7 @@ public interface BriarIntegrationTestComponent {
 
 	void inject(ContactModule.EagerSingletons init);
 
-	void inject(CryptoModule.EagerSingletons init);
+	void inject(CryptoExecutorModule.EagerSingletons init);
 
 	void inject(ForumModule.EagerSingletons init);
 
-- 
GitLab