diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 966457e8e253cafba47123a364439f9d2ae1a433..2f93054bf0210af5af70e361c69fba1b86ea7dfa 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -107,6 +107,10 @@ bridge test: mailbox integration test: extends: .optional_tests rules: + - changes: + - mailbox-integration-tests/**/* + when: on_success + allow_failure: false - if: '$CI_PIPELINE_SOURCE == "schedule"' when: on_success - if: '$CI_COMMIT_TAG == null' diff --git a/bramble-android/src/main/java/org/briarproject/bramble/BrambleAndroidModule.java b/bramble-android/src/main/java/org/briarproject/bramble/BrambleAndroidModule.java index 5be846f61c66d139770efa17e45dcaae70a74dda..7859bd6521091bb87ddb981f08e603e15b9503b4 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/BrambleAndroidModule.java +++ b/bramble-android/src/main/java/org/briarproject/bramble/BrambleAndroidModule.java @@ -9,6 +9,7 @@ import org.briarproject.bramble.socks.SocksModule; import org.briarproject.bramble.system.AndroidSystemModule; import org.briarproject.bramble.system.AndroidTaskSchedulerModule; import org.briarproject.bramble.system.AndroidWakefulIoExecutorModule; +import org.briarproject.bramble.system.DefaultThreadFactoryModule; import dagger.Module; @@ -18,6 +19,7 @@ import dagger.Module; AndroidSystemModule.class, AndroidTaskSchedulerModule.class, AndroidWakefulIoExecutorModule.class, + DefaultThreadFactoryModule.class, CircumventionModule.class, DnsModule.class, ReportingModule.class, diff --git a/bramble-core/src/main/java/org/briarproject/bramble/TimeLoggingExecutor.java b/bramble-core/src/main/java/org/briarproject/bramble/TimeLoggingExecutor.java index dc0b96d3d487b28ee9faea453b510dfc3d219b72..3513b5f540a948575a38298332df2f5fc7358023 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/TimeLoggingExecutor.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/TimeLoggingExecutor.java @@ -4,6 +4,7 @@ import org.briarproject.nullsafety.NotNullByDefault; import java.util.concurrent.BlockingQueue; import java.util.concurrent.RejectedExecutionHandler; +import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.logging.Logger; @@ -19,9 +20,10 @@ public class TimeLoggingExecutor extends ThreadPoolExecutor { public TimeLoggingExecutor(String tag, int corePoolSize, int maxPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, + ThreadFactory threadFactory, RejectedExecutionHandler handler) { super(corePoolSize, maxPoolSize, keepAliveTime, unit, workQueue, - handler); + threadFactory, handler); log = Logger.getLogger(tag); } 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 index ab0e4114f5672469fd0c26b8061389c1e1b7172c..7a069b2eb817cbfd0d1943e4b5cf01b27ec59192 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/crypto/CryptoExecutorModule.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/crypto/CryptoExecutorModule.java @@ -9,6 +9,7 @@ import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.RejectedExecutionHandler; +import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import javax.inject.Inject; @@ -37,31 +38,31 @@ public class CryptoExecutorModule { 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 lifecycleManager, ThreadFactory threadFactory) { + // 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 + ExecutorService cryptoExecutor = new TimeLoggingExecutor( + "CryptoExecutor", 0, MAX_EXECUTOR_THREADS, 60, SECONDS, queue, + threadFactory, policy); lifecycleManager.registerForShutdown(cryptoExecutor); return cryptoExecutor; } @Provides @CryptoExecutor - Executor provideCryptoExecutor() { + Executor provideCryptoExecutor( + @CryptoExecutor ExecutorService cryptoExecutor) { return cryptoExecutor; } } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/db/DatabaseExecutorModule.java b/bramble-core/src/main/java/org/briarproject/bramble/db/DatabaseExecutorModule.java index a65feef89da60c3f967fb891906ee1a13c14a3d8..73b26710a4b323dc36380728ae38eb13b85ec59e 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/db/DatabaseExecutorModule.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/db/DatabaseExecutorModule.java @@ -9,6 +9,7 @@ import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.RejectedExecutionHandler; +import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import javax.inject.Inject; @@ -28,24 +29,20 @@ public class DatabaseExecutorModule { ExecutorService executorService; } - private final ExecutorService databaseExecutor; - - public DatabaseExecutorModule() { + @Provides + @Singleton + @DatabaseExecutor + ExecutorService provideDatabaseExecutorService( + LifecycleManager lifecycleManager, ThreadFactory threadFactory) { // Use an unbounded queue BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>(); // Discard tasks that are submitted during shutdown RejectedExecutionHandler policy = new ThreadPoolExecutor.DiscardPolicy(); // Use a single thread and keep it in the pool for 60 secs - databaseExecutor = new TimeLoggingExecutor("DatabaseExecutor", 0, 1, - 60, SECONDS, queue, policy); - } - - @Provides - @Singleton - @DatabaseExecutor - ExecutorService provideDatabaseExecutorService( - LifecycleManager lifecycleManager) { + ExecutorService databaseExecutor = new TimeLoggingExecutor( + "DatabaseExecutor", 0, 1, 60, SECONDS, queue, threadFactory, + policy); lifecycleManager.registerForShutdown(databaseExecutor); return databaseExecutor; } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/event/DefaultEventExecutorModule.java b/bramble-core/src/main/java/org/briarproject/bramble/event/DefaultEventExecutorModule.java index 5fc21cc86a3142a3f2c1ff5f07188dc2c3e1c7c7..2d43800c174ff48ccd7dfc941e2802c115c60f18 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/event/DefaultEventExecutorModule.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/event/DefaultEventExecutorModule.java @@ -3,6 +3,7 @@ package org.briarproject.bramble.event; import org.briarproject.bramble.api.event.EventExecutor; import java.util.concurrent.Executor; +import java.util.concurrent.ThreadFactory; import javax.inject.Singleton; @@ -22,10 +23,11 @@ public class DefaultEventExecutorModule { @Provides @Singleton @EventExecutor - Executor provideEventExecutor() { + Executor provideEventExecutor(ThreadFactory threadFactory) { return newSingleThreadExecutor(r -> { - Thread t = new Thread(r); + Thread t = threadFactory.newThread(r); t.setDaemon(true); + t.setName(t.getName() + "-Event"); return t; }); } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/lifecycle/LifecycleModule.java b/bramble-core/src/main/java/org/briarproject/bramble/lifecycle/LifecycleModule.java index 43db266efb188d5b3a3c2bbe90d48e194f7b1990..b38f79b1c5933f731b1a13c62255be94f3336e0d 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/lifecycle/LifecycleModule.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/lifecycle/LifecycleModule.java @@ -9,6 +9,7 @@ import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import javax.inject.Inject; @@ -28,19 +29,6 @@ public class LifecycleModule { Executor executor; } - private final ExecutorService ioExecutor; - - public LifecycleModule() { - // The thread pool is unbounded, so use direct handoff - BlockingQueue<Runnable> queue = new SynchronousQueue<>(); - // Discard tasks that are submitted during shutdown - RejectedExecutionHandler policy = - new ThreadPoolExecutor.DiscardPolicy(); - // Create threads as required and keep them in the pool for 60 seconds - ioExecutor = new ThreadPoolExecutor(0, Integer.MAX_VALUE, - 60, SECONDS, queue, policy); - } - @Provides @Singleton ShutdownManager provideShutdownManager() { @@ -57,7 +45,16 @@ public class LifecycleModule { @Provides @Singleton @IoExecutor - Executor provideIoExecutor(LifecycleManager lifecycleManager) { + Executor provideIoExecutor(LifecycleManager lifecycleManager, + ThreadFactory threadFactory) { + // The thread pool is unbounded, so use direct handoff + BlockingQueue<Runnable> queue = new SynchronousQueue<>(); + // Discard tasks that are submitted during shutdown + RejectedExecutionHandler policy = + new ThreadPoolExecutor.DiscardPolicy(); + // Create threads as required and keep them in the pool for 60 seconds + ExecutorService ioExecutor = new ThreadPoolExecutor(0, + Integer.MAX_VALUE, 60, SECONDS, queue, threadFactory, policy); lifecycleManager.registerForShutdown(ioExecutor); return ioExecutor; } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxApiCallerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxApiCallerImpl.java index ce08b2f2522019587ba56132ed6e990334c9abdf..368c7ed7c67647d315ac0bbd58b1bbce72976d9d 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxApiCallerImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxApiCallerImpl.java @@ -20,12 +20,15 @@ import static java.util.concurrent.TimeUnit.MILLISECONDS; class MailboxApiCallerImpl implements MailboxApiCaller { private final TaskScheduler taskScheduler; + private final MailboxConfig mailboxConfig; private final Executor ioExecutor; @Inject MailboxApiCallerImpl(TaskScheduler taskScheduler, + MailboxConfig mailboxConfig, @IoExecutor Executor ioExecutor) { this.taskScheduler = taskScheduler; + this.mailboxConfig = mailboxConfig; this.ioExecutor = ioExecutor; } @@ -49,7 +52,8 @@ class MailboxApiCallerImpl implements MailboxApiCaller { private boolean cancelled = false; @GuardedBy("lock") - private long retryIntervalMs = MIN_RETRY_INTERVAL_MS; + private long retryIntervalMs = + mailboxConfig.getApiCallerMinRetryInterval(); private Task(ApiCall apiCall) { this.apiCall = apiCall; @@ -74,8 +78,9 @@ class MailboxApiCallerImpl implements MailboxApiCaller { scheduledTask = taskScheduler.schedule(this::callApi, ioExecutor, retryIntervalMs, MILLISECONDS); // Increase the retry interval each time we retry - retryIntervalMs = - min(MAX_RETRY_INTERVAL_MS, retryIntervalMs * 2); + retryIntervalMs = min( + mailboxConfig.getApiCallerMaxRetryInterval(), + retryIntervalMs * 2); } } else { synchronized (lock) { diff --git a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxConfig.java b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..7f03dff6dd35712799377a1243b4a4bc80b52fb3 --- /dev/null +++ b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxConfig.java @@ -0,0 +1,24 @@ +package org.briarproject.bramble.mailbox; + +import org.briarproject.bramble.api.plugin.Plugin; + +interface MailboxConfig { + + /** + * The minimum interval between API call retries in milliseconds. + */ + long getApiCallerMinRetryInterval(); + + /** + * The maximum interval between API call retries in milliseconds. + */ + long getApiCallerMaxRetryInterval(); + + /** + * How long (in milliseconds) the Tor plugin needs to be continuously + * {@link Plugin.State#ACTIVE active} before we assume our contacts can + * reach our hidden service. + */ + long getTorReachabilityPeriod(); + +} diff --git a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxConfigImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxConfigImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..fa6a1f528b9357fd973af5cdac763af26b69f95d --- /dev/null +++ b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxConfigImpl.java @@ -0,0 +1,30 @@ +package org.briarproject.bramble.mailbox; + +import org.briarproject.nullsafety.NotNullByDefault; + +import javax.annotation.concurrent.Immutable; +import javax.inject.Inject; + +@Immutable +@NotNullByDefault +class MailboxConfigImpl implements MailboxConfig { + + @Inject + MailboxConfigImpl() { + } + + @Override + public long getApiCallerMinRetryInterval() { + return MailboxApiCaller.MIN_RETRY_INTERVAL_MS; + } + + @Override + public long getApiCallerMaxRetryInterval() { + return MailboxApiCaller.MAX_RETRY_INTERVAL_MS; + } + + @Override + public long getTorReachabilityPeriod() { + return TorReachabilityMonitor.REACHABILITY_PERIOD_MS; + } +} diff --git a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/UrlConverterModule.java b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/ModularMailboxModule.java similarity index 58% rename from bramble-core/src/main/java/org/briarproject/bramble/mailbox/UrlConverterModule.java rename to bramble-core/src/main/java/org/briarproject/bramble/mailbox/ModularMailboxModule.java index cc9d4469875b2674696a0f6e56dd8d3ae32be79d..8ddbd782466cb56cc60ee3edf9793ec4b40cfdab 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/UrlConverterModule.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/ModularMailboxModule.java @@ -4,7 +4,11 @@ import dagger.Module; import dagger.Provides; @Module -public class UrlConverterModule { +public class ModularMailboxModule { + @Provides + MailboxConfig provideMailboxConfig(MailboxConfigImpl mailboxConfig) { + return mailboxConfig; + } @Provides UrlConverter provideUrlConverter(UrlConverterImpl urlConverter) { diff --git a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/TorReachabilityMonitorImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/TorReachabilityMonitorImpl.java index 359e70460538cc8eb0fb29ad8bad8d439ed7feea..20afebe30f2862b230d66c3bc7e175b81f5e7dc2 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/TorReachabilityMonitorImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/TorReachabilityMonitorImpl.java @@ -32,6 +32,7 @@ class TorReachabilityMonitorImpl private final Executor ioExecutor; private final TaskScheduler taskScheduler; + private final MailboxConfig mailboxConfig; private final PluginManager pluginManager; private final EventBus eventBus; private final Object lock = new Object(); @@ -50,10 +51,12 @@ class TorReachabilityMonitorImpl TorReachabilityMonitorImpl( @IoExecutor Executor ioExecutor, TaskScheduler taskScheduler, + MailboxConfig mailboxConfig, PluginManager pluginManager, EventBus eventBus) { this.ioExecutor = ioExecutor; this.taskScheduler = taskScheduler; + this.mailboxConfig = mailboxConfig; this.pluginManager = pluginManager; this.eventBus = eventBus; } @@ -110,7 +113,7 @@ class TorReachabilityMonitorImpl synchronized (lock) { if (destroyed || task != null) return; task = taskScheduler.schedule(this::onTorReachable, ioExecutor, - REACHABILITY_PERIOD_MS, MILLISECONDS); + mailboxConfig.getTorReachabilityPeriod(), MILLISECONDS); } } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/system/DefaultTaskSchedulerModule.java b/bramble-core/src/main/java/org/briarproject/bramble/system/DefaultTaskSchedulerModule.java index 3e36faff275884f76df2e001d8b3c4ac2f9709f7..30e4732370db1c4abe8e7717021d6755248c5628 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/system/DefaultTaskSchedulerModule.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/system/DefaultTaskSchedulerModule.java @@ -6,6 +6,7 @@ import org.briarproject.bramble.api.system.TaskScheduler; import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.ThreadFactory; import javax.inject.Inject; import javax.inject.Singleton; @@ -21,18 +22,15 @@ public class DefaultTaskSchedulerModule { TaskScheduler scheduler; } - private final ScheduledExecutorService scheduledExecutorService; - - public DefaultTaskSchedulerModule() { + @Provides + @Singleton + TaskScheduler provideTaskScheduler(LifecycleManager lifecycleManager, + ThreadFactory threadFactory) { // Discard tasks that are submitted during shutdown RejectedExecutionHandler policy = new ScheduledThreadPoolExecutor.DiscardPolicy(); - scheduledExecutorService = new ScheduledThreadPoolExecutor(1, policy); - } - - @Provides - @Singleton - TaskScheduler provideTaskScheduler(LifecycleManager lifecycleManager) { + ScheduledExecutorService scheduledExecutorService = + new ScheduledThreadPoolExecutor(1, threadFactory, policy); lifecycleManager.registerForShutdown(scheduledExecutorService); return new TaskSchedulerImpl(scheduledExecutorService); } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/system/DefaultThreadFactoryModule.java b/bramble-core/src/main/java/org/briarproject/bramble/system/DefaultThreadFactoryModule.java new file mode 100644 index 0000000000000000000000000000000000000000..d2ea5f976dd022bed1dafa285e0a46eb2e91aed7 --- /dev/null +++ b/bramble-core/src/main/java/org/briarproject/bramble/system/DefaultThreadFactoryModule.java @@ -0,0 +1,18 @@ +package org.briarproject.bramble.system; + +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; + +import javax.inject.Singleton; + +import dagger.Module; +import dagger.Provides; + +@Module +public class DefaultThreadFactoryModule { + @Provides + @Singleton + ThreadFactory provideThreadFactory() { + return Executors.defaultThreadFactory(); + } +} diff --git a/bramble-core/src/test/java/org/briarproject/bramble/contact/ContactExchangeIntegrationTestComponent.java b/bramble-core/src/test/java/org/briarproject/bramble/contact/ContactExchangeIntegrationTestComponent.java index becb74db811a8b8cf2b57b0b656bf7fecb85c0ed..f01e365f1dda5f503d0a9ab8ffcf239c0888a08b 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/contact/ContactExchangeIntegrationTestComponent.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/contact/ContactExchangeIntegrationTestComponent.java @@ -9,7 +9,7 @@ import org.briarproject.bramble.api.event.EventBus; import org.briarproject.bramble.api.identity.IdentityManager; import org.briarproject.bramble.api.lifecycle.IoExecutor; import org.briarproject.bramble.api.lifecycle.LifecycleManager; -import org.briarproject.bramble.mailbox.UrlConverterModule; +import org.briarproject.bramble.mailbox.ModularMailboxModule; import org.briarproject.bramble.test.BrambleCoreIntegrationTestModule; import org.briarproject.bramble.test.TestDnsModule; import org.briarproject.bramble.test.TestPluginConfigModule; @@ -25,7 +25,7 @@ import dagger.Component; @Component(modules = { BrambleCoreIntegrationTestModule.class, BrambleCoreModule.class, - UrlConverterModule.class, + ModularMailboxModule.class, TestDnsModule.class, TestSocksModule.class, TestPluginConfigModule.class, diff --git a/bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxApiCallerImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxApiCallerImplTest.java index 2612fe16abcbc21aaf8beddf19bdf5f411d77f64..b625a94a8e65e95ced4e593da5f63e5ac754af1e 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxApiCallerImplTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxApiCallerImplTest.java @@ -21,12 +21,13 @@ public class MailboxApiCallerImplTest extends BrambleMockTestCase { private final TaskScheduler taskScheduler = context.mock(TaskScheduler.class); + private final MailboxConfig mailboxConfig = new MailboxConfigImpl(); private final Executor ioExecutor = context.mock(Executor.class); private final ApiCall apiCall = context.mock(ApiCall.class); private final Cancellable scheduledTask = context.mock(Cancellable.class); private final MailboxApiCallerImpl caller = - new MailboxApiCallerImpl(taskScheduler, ioExecutor); + new MailboxApiCallerImpl(taskScheduler, mailboxConfig, ioExecutor); @Test public void testSubmitsTaskImmediately() { diff --git a/bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxApiTest.java b/bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxApiTest.java index 3b46320c8830c0845f2f3b087a06c3e6fee2a1d8..aeaaccbafd5a4da7f394aa0cc314f846d5d4ba1c 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxApiTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxApiTest.java @@ -24,9 +24,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import javax.annotation.Nonnull; -import javax.net.SocketFactory; - import okhttp3.OkHttpClient; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; @@ -34,8 +31,8 @@ import okhttp3.mockwebserver.RecordedRequest; import okio.Buffer; import static java.util.Collections.singletonList; -import static java.util.concurrent.TimeUnit.MILLISECONDS; import static org.briarproject.bramble.api.mailbox.MailboxConstants.CLIENT_SUPPORTS; +import static org.briarproject.bramble.mailbox.MailboxTestUtils.createHttpClientProvider; import static org.briarproject.bramble.test.TestUtils.getContactId; import static org.briarproject.bramble.test.TestUtils.getMailboxProperties; import static org.briarproject.bramble.test.TestUtils.getRandomBytes; @@ -56,18 +53,8 @@ public class MailboxApiTest extends BrambleTestCase { @Rule public TemporaryFolder folder = new TemporaryFolder(); - private final OkHttpClient client = new OkHttpClient.Builder() - .socketFactory(SocketFactory.getDefault()) - .connectTimeout(60_000, MILLISECONDS) - .build(); private final WeakSingletonProvider<OkHttpClient> httpClientProvider = - new WeakSingletonProvider<OkHttpClient>() { - @Override - @Nonnull - public OkHttpClient createInstance() { - return client; - } - }; + createHttpClientProvider(); // We aren't using a real onion address, so use the given address verbatim private final UrlConverter urlConverter = onion -> onion; private final MailboxApiImpl api = new MailboxApiImpl(httpClientProvider, diff --git a/bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxPairingTaskImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxPairingTaskImplTest.java index 6a3e312ed1716865dccdd71a40cd0f86b9ef3c98..fbc817d3f7f86882f69bd0106f6f3b5593ac2326 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxPairingTaskImplTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxPairingTaskImplTest.java @@ -22,13 +22,12 @@ import org.jmock.Expectations; import org.junit.Test; import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.charset.Charset; import java.util.ArrayList; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicInteger; import static java.util.Collections.singletonList; +import static org.briarproject.bramble.mailbox.MailboxTestUtils.getQrCodePayload; import static org.briarproject.bramble.test.TestUtils.getContact; import static org.briarproject.bramble.test.TestUtils.getRandomBytes; import static org.briarproject.bramble.test.TestUtils.getRandomId; @@ -59,7 +58,8 @@ public class MailboxPairingTaskImplTest extends BrambleMockTestCase { new MailboxAuthToken(getRandomId()); private final MailboxAuthToken ownerToken = new MailboxAuthToken(getRandomId()); - private final String validPayload = getValidPayload(); + private final String validPayload = + getQrCodePayload(onionBytes, setupToken.getBytes()); private final long time = System.currentTimeMillis(); private final MailboxProperties setupProperties = new MailboxProperties( onion, setupToken, new ArrayList<>()); @@ -194,16 +194,6 @@ public class MailboxPairingTaskImplTest extends BrambleMockTestCase { MailboxPairingState.UnexpectedError.class)); } - private String getValidPayload() { - byte[] payloadBytes = ByteBuffer.allocate(65) - .put((byte) 32) // 1 - .put(onionBytes) // 32 - .put(setupToken.getBytes()) // 32 - .array(); - //noinspection CharsetObjectCanBeUsed - return new String(payloadBytes, Charset.forName("ISO-8859-1")); - } - private PredicateMatcher<MailboxProperties> matches(MailboxProperties p2) { return new PredicateMatcher<>(MailboxProperties.class, p1 -> p1.getAuthToken().equals(p2.getAuthToken()) && diff --git a/bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxTestUtils.java b/bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxTestUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..4795fb739b5f484fc88e29a286b79bdd4355debf --- /dev/null +++ b/bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxTestUtils.java @@ -0,0 +1,44 @@ +package org.briarproject.bramble.mailbox; + +import org.briarproject.bramble.api.WeakSingletonProvider; + +import java.nio.ByteBuffer; +import java.nio.charset.Charset; + +import javax.annotation.Nonnull; +import javax.net.SocketFactory; + +import okhttp3.OkHttpClient; + +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static org.briarproject.bramble.test.TestUtils.getRandomId; + +class MailboxTestUtils { + + static String getQrCodePayload(byte[] onionBytes, byte[] setupToken) { + byte[] payloadBytes = ByteBuffer.allocate(65) + .put((byte) 32) // 1 + .put(onionBytes) // 32 + .put(setupToken) // 32 + .array(); + //noinspection CharsetObjectCanBeUsed + return new String(payloadBytes, Charset.forName("ISO-8859-1")); + } + + static String getQrCodePayload(byte[] setupToken) { + return getQrCodePayload(getRandomId(), setupToken); + } + + static WeakSingletonProvider<OkHttpClient> createHttpClientProvider() { + return new WeakSingletonProvider<OkHttpClient>() { + @Override + @Nonnull + public OkHttpClient createInstance() { + return new OkHttpClient.Builder() + .socketFactory(SocketFactory.getDefault()) + .connectTimeout(60_000, MILLISECONDS) + .build(); + } + }; + } +} diff --git a/bramble-core/src/test/java/org/briarproject/bramble/mailbox/TorReachabilityMonitorImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/mailbox/TorReachabilityMonitorImplTest.java index 032095cd6bd798ab4246bf7df48fe94de5bb5b51..547041a1f2538a22c13ce040f46c3aa62bb9e163 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/mailbox/TorReachabilityMonitorImplTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/mailbox/TorReachabilityMonitorImplTest.java @@ -29,6 +29,7 @@ public class TorReachabilityMonitorImplTest extends BrambleMockTestCase { private final Executor ioExecutor = context.mock(Executor.class); private final TaskScheduler taskScheduler = context.mock(TaskScheduler.class); + private final MailboxConfig mailboxConfig = new MailboxConfigImpl(); private final PluginManager pluginManager = context.mock(PluginManager.class); private final EventBus eventBus = context.mock(EventBus.class); @@ -39,7 +40,7 @@ public class TorReachabilityMonitorImplTest extends BrambleMockTestCase { private final TorReachabilityMonitorImpl monitor = new TorReachabilityMonitorImpl(ioExecutor, taskScheduler, - pluginManager, eventBus); + mailboxConfig, pluginManager, eventBus); @Test public void testSchedulesTaskWhenStartedIfTorIsActive() { diff --git a/bramble-core/src/test/java/org/briarproject/bramble/plugin/file/RemovableDriveIntegrationTestComponent.java b/bramble-core/src/test/java/org/briarproject/bramble/plugin/file/RemovableDriveIntegrationTestComponent.java index 59435bdb0fe248beb76a0acf6c77868aa8e0ea0a..6a071e2deb17225fb3ee4d6cbf4f6be80844a430 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/plugin/file/RemovableDriveIntegrationTestComponent.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/plugin/file/RemovableDriveIntegrationTestComponent.java @@ -9,7 +9,8 @@ import org.briarproject.bramble.api.lifecycle.LifecycleManager; import org.briarproject.bramble.api.plugin.file.RemovableDriveManager; import org.briarproject.bramble.battery.DefaultBatteryManagerModule; import org.briarproject.bramble.event.DefaultEventExecutorModule; -import org.briarproject.bramble.mailbox.UrlConverterModule; +import org.briarproject.bramble.mailbox.ModularMailboxModule; +import org.briarproject.bramble.system.DefaultThreadFactoryModule; import org.briarproject.bramble.system.DefaultWakefulIoExecutorModule; import org.briarproject.bramble.system.TimeTravelModule; import org.briarproject.bramble.test.TestDatabaseConfigModule; @@ -29,13 +30,14 @@ import dagger.Component; DefaultBatteryManagerModule.class, DefaultEventExecutorModule.class, DefaultWakefulIoExecutorModule.class, + DefaultThreadFactoryModule.class, TestDatabaseConfigModule.class, TestDnsModule.class, TestFeatureFlagModule.class, TestMailboxDirectoryModule.class, RemovableDriveIntegrationTestModule.class, RemovableDriveModule.class, - UrlConverterModule.class, + ModularMailboxModule.class, TestSecureRandomModule.class, TimeTravelModule.class, TestSocksModule.class, diff --git a/bramble-core/src/test/java/org/briarproject/bramble/sync/SyncIntegrationTestComponent.java b/bramble-core/src/test/java/org/briarproject/bramble/sync/SyncIntegrationTestComponent.java index d6571298e3af75d67320e4bed974a848d14216a4..8a4cda6548753b2020e210c6885e986ae0d87539 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/sync/SyncIntegrationTestComponent.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/sync/SyncIntegrationTestComponent.java @@ -2,7 +2,7 @@ package org.briarproject.bramble.sync; import org.briarproject.bramble.BrambleCoreIntegrationTestEagerSingletons; import org.briarproject.bramble.BrambleCoreModule; -import org.briarproject.bramble.mailbox.UrlConverterModule; +import org.briarproject.bramble.mailbox.ModularMailboxModule; import org.briarproject.bramble.test.BrambleCoreIntegrationTestModule; import org.briarproject.bramble.test.TestDnsModule; import org.briarproject.bramble.test.TestPluginConfigModule; @@ -16,7 +16,7 @@ import dagger.Component; @Component(modules = { BrambleCoreIntegrationTestModule.class, BrambleCoreModule.class, - UrlConverterModule.class, + ModularMailboxModule.class, TestDnsModule.class, TestSocksModule.class, TestPluginConfigModule.class, diff --git a/bramble-core/src/test/java/org/briarproject/bramble/test/BrambleCoreIntegrationTestModule.java b/bramble-core/src/test/java/org/briarproject/bramble/test/BrambleCoreIntegrationTestModule.java index 8d4224df6ccc561d82dcc4b356e3ee09f770725b..e2ddb2fa94e99e9f4ce1cb4d4e6e43b5d1fede7f 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/test/BrambleCoreIntegrationTestModule.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/test/BrambleCoreIntegrationTestModule.java @@ -11,6 +11,7 @@ import dagger.Module; DefaultBatteryManagerModule.class, DefaultEventExecutorModule.class, DefaultWakefulIoExecutorModule.class, + TestThreadFactoryModule.class, TestDatabaseConfigModule.class, TestFeatureFlagModule.class, TestMailboxDirectoryModule.class, diff --git a/bramble-core/src/test/java/org/briarproject/bramble/test/BrambleIntegrationTest.java b/bramble-core/src/test/java/org/briarproject/bramble/test/BrambleIntegrationTest.java index e4cd5182696b1bf59c339acbc4ba93d414cd5ab3..9e6c41ab6bdda192310fae6c216bc1cfd75ac441 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/test/BrambleIntegrationTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/test/BrambleIntegrationTest.java @@ -235,11 +235,16 @@ public abstract class BrambleIntegrationTest<C extends BrambleIntegrationTestCom protected void awaitPendingMessageDelivery(int num) throws TimeoutException { - deliveryWaiter.await(TIMEOUT, num); + awaitPendingMessageDelivery(num, TIMEOUT); + } + + protected void awaitPendingMessageDelivery(int num, long timeout) + throws TimeoutException { + deliveryWaiter.await(timeout, num); assertEquals("Messages delivered", num, deliveryCounter.getAndSet(0)); try { - messageSemaphore.tryAcquire(num, TIMEOUT, MILLISECONDS); + messageSemaphore.tryAcquire(num, timeout, MILLISECONDS); } catch (InterruptedException e) { LOG.info("Interrupted while waiting for messages"); Thread.currentThread().interrupt(); diff --git a/bramble-core/src/test/java/org/briarproject/bramble/test/BrambleIntegrationTestComponent.java b/bramble-core/src/test/java/org/briarproject/bramble/test/BrambleIntegrationTestComponent.java index db5ef337be3c0d30d1bf5a109aec60cfc4082acc..9544d7e9bfc732405c9d447737cb5cf5d7d88f0e 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/test/BrambleIntegrationTestComponent.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/test/BrambleIntegrationTestComponent.java @@ -6,7 +6,7 @@ import org.briarproject.bramble.api.client.ClientHelper; import org.briarproject.bramble.api.connection.ConnectionManager; import org.briarproject.bramble.api.event.EventBus; import org.briarproject.bramble.api.identity.IdentityManager; -import org.briarproject.bramble.mailbox.UrlConverterModule; +import org.briarproject.bramble.mailbox.ModularMailboxModule; import javax.inject.Singleton; @@ -16,7 +16,7 @@ import dagger.Component; @Component(modules = { BrambleCoreIntegrationTestModule.class, BrambleCoreModule.class, - UrlConverterModule.class, + ModularMailboxModule.class, TestDnsModule.class, TestSocksModule.class, TestPluginConfigModule.class, diff --git a/bramble-core/src/test/java/org/briarproject/bramble/test/TestThreadFactoryModule.java b/bramble-core/src/test/java/org/briarproject/bramble/test/TestThreadFactoryModule.java new file mode 100644 index 0000000000000000000000000000000000000000..fd8432d98495a3d90c661c9b0c602a061d7dd2a7 --- /dev/null +++ b/bramble-core/src/test/java/org/briarproject/bramble/test/TestThreadFactoryModule.java @@ -0,0 +1,66 @@ +package org.briarproject.bramble.test; + +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.atomic.AtomicInteger; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import dagger.Module; +import dagger.Provides; + +@Module +public class TestThreadFactoryModule { + + @Nullable + private final String prefix; + + public TestThreadFactoryModule() { + this(null); + } + + public TestThreadFactoryModule(@Nullable String prefix) { + this.prefix = prefix; + } + + @Provides + ThreadFactory provideThreadFactory() { + if (prefix == null) return Executors.defaultThreadFactory(); + return new TestThreadFactory(prefix); + } + + /** + * This class is mostly copied from + * {@link Executors#defaultThreadFactory()} only adds a given prefix. + */ + static class TestThreadFactory implements ThreadFactory { + private static final AtomicInteger poolNumber = new AtomicInteger(1); + private final ThreadGroup group; + private final AtomicInteger threadNumber = new AtomicInteger(1); + private final String namePrefix; + + private TestThreadFactory(String prefix) { + SecurityManager s = System.getSecurityManager(); + this.group = s != null ? s.getThreadGroup() : + Thread.currentThread().getThreadGroup(); + this.namePrefix = + prefix + "-p-" + poolNumber.getAndIncrement() + "-t-"; + } + + @Override + public Thread newThread(@Nonnull Runnable r) { + Thread t = new Thread(this.group, r, + this.namePrefix + this.threadNumber.getAndIncrement(), 0L); + if (t.isDaemon()) { + t.setDaemon(false); + } + + if (t.getPriority() != 5) { + t.setPriority(5); + } + + return t; + } + } +} diff --git a/bramble-core/src/test/java/org/briarproject/bramble/transport/agreement/TransportKeyAgreementTestComponent.java b/bramble-core/src/test/java/org/briarproject/bramble/transport/agreement/TransportKeyAgreementTestComponent.java index 88a4747a2137d4479eb904e905c9a5e8fd835452..64dfa6f2caa542555a820f90c750337437b5efa9 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/transport/agreement/TransportKeyAgreementTestComponent.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/transport/agreement/TransportKeyAgreementTestComponent.java @@ -7,7 +7,7 @@ import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.lifecycle.LifecycleManager; import org.briarproject.bramble.api.properties.TransportPropertyManager; import org.briarproject.bramble.api.transport.KeyManager; -import org.briarproject.bramble.mailbox.UrlConverterModule; +import org.briarproject.bramble.mailbox.ModularMailboxModule; import org.briarproject.bramble.test.BrambleCoreIntegrationTestModule; import org.briarproject.bramble.test.BrambleIntegrationTestComponent; import org.briarproject.bramble.test.TestDnsModule; @@ -22,7 +22,7 @@ import dagger.Component; @Component(modules = { BrambleCoreIntegrationTestModule.class, BrambleCoreModule.class, - UrlConverterModule.class, + ModularMailboxModule.class, TestDnsModule.class, TestSocksModule.class, TestPluginConfigModule.class, diff --git a/bramble-java/src/main/java/org/briarproject/bramble/BrambleJavaModule.java b/bramble-java/src/main/java/org/briarproject/bramble/BrambleJavaModule.java index 001c44d634f367ec42a3b0dd13abf417a39d24b0..d627025ab616d509d852161c06c880bf27d26a77 100644 --- a/bramble-java/src/main/java/org/briarproject/bramble/BrambleJavaModule.java +++ b/bramble-java/src/main/java/org/briarproject/bramble/BrambleJavaModule.java @@ -1,7 +1,7 @@ package org.briarproject.bramble; import org.briarproject.bramble.io.DnsModule; -import org.briarproject.bramble.mailbox.UrlConverterModule; +import org.briarproject.bramble.mailbox.ModularMailboxModule; import org.briarproject.bramble.network.JavaNetworkModule; import org.briarproject.bramble.plugin.tor.CircumventionModule; import org.briarproject.bramble.socks.SocksModule; @@ -14,7 +14,7 @@ import dagger.Module; DnsModule.class, JavaNetworkModule.class, JavaSystemModule.class, - UrlConverterModule.class, + ModularMailboxModule.class, SocksModule.class }) public class BrambleJavaModule { diff --git a/bramble-java/src/test/java/org/briarproject/bramble/test/BrambleJavaIntegrationTestComponent.java b/bramble-java/src/test/java/org/briarproject/bramble/test/BrambleJavaIntegrationTestComponent.java index 8003bb7e55dae1743be26e4b2bedf518b6395855..3f47a3541cf8bfab23440048b13777db29bf860b 100644 --- a/bramble-java/src/test/java/org/briarproject/bramble/test/BrambleJavaIntegrationTestComponent.java +++ b/bramble-java/src/test/java/org/briarproject/bramble/test/BrambleJavaIntegrationTestComponent.java @@ -3,7 +3,7 @@ package org.briarproject.bramble.test; import org.briarproject.bramble.BrambleCoreIntegrationTestEagerSingletons; import org.briarproject.bramble.BrambleCoreModule; import org.briarproject.bramble.BrambleJavaModule; -import org.briarproject.bramble.mailbox.UrlConverterModule; +import org.briarproject.bramble.mailbox.ModularMailboxModule; import org.briarproject.bramble.plugin.tor.BridgeTest; import org.briarproject.bramble.plugin.tor.CircumventionProvider; @@ -16,7 +16,7 @@ import dagger.Component; BrambleCoreIntegrationTestModule.class, BrambleCoreModule.class, BrambleJavaModule.class, - UrlConverterModule.class, + ModularMailboxModule.class, TestTorPortsModule.class, TestPluginConfigModule.class, }) diff --git a/briar-android/src/androidTestOfficial/java/org/briarproject/briar/android/BriarUiTestComponent.java b/briar-android/src/androidTestOfficial/java/org/briarproject/briar/android/BriarUiTestComponent.java index 6216e241a2a846ebbff311eac68ab30b4d073336..df1d043c34d4e285861a5119239f365130969f70 100644 --- a/briar-android/src/androidTestOfficial/java/org/briarproject/briar/android/BriarUiTestComponent.java +++ b/briar-android/src/androidTestOfficial/java/org/briarproject/briar/android/BriarUiTestComponent.java @@ -3,7 +3,7 @@ package org.briarproject.briar.android; import org.briarproject.bramble.BrambleAndroidModule; import org.briarproject.bramble.BrambleCoreModule; import org.briarproject.bramble.account.BriarAccountModule; -import org.briarproject.bramble.mailbox.UrlConverterModule; +import org.briarproject.bramble.mailbox.ModularMailboxModule; import org.briarproject.bramble.plugin.file.RemovableDriveModule; import org.briarproject.bramble.system.ClockModule; import org.briarproject.briar.BriarCoreModule; @@ -28,7 +28,7 @@ import dagger.Component; BrambleAndroidModule.class, BriarAccountModule.class, BrambleCoreModule.class, - UrlConverterModule.class + ModularMailboxModule.class }) public interface BriarUiTestComponent extends AndroidComponent { diff --git a/briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/BriarUiTestComponent.java b/briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/BriarUiTestComponent.java index a12e480d23d59457201b785aa2b95339fc093b12..e597363786151ffb0485c668b077f088d83b2242 100644 --- a/briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/BriarUiTestComponent.java +++ b/briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/BriarUiTestComponent.java @@ -3,7 +3,7 @@ package org.briarproject.briar.android; import org.briarproject.bramble.BrambleAndroidModule; import org.briarproject.bramble.BrambleCoreModule; import org.briarproject.bramble.account.BriarAccountModule; -import org.briarproject.bramble.mailbox.UrlConverterModule; +import org.briarproject.bramble.mailbox.ModularMailboxModule; import org.briarproject.bramble.plugin.file.RemovableDriveModule; import org.briarproject.bramble.system.ClockModule; import org.briarproject.briar.BriarCoreModule; @@ -27,7 +27,7 @@ import dagger.Component; BrambleAndroidModule.class, BriarAccountModule.class, BrambleCoreModule.class, - UrlConverterModule.class + ModularMailboxModule.class }) public interface BriarUiTestComponent extends AndroidComponent { diff --git a/briar-android/src/main/java/org/briarproject/briar/android/AndroidComponent.java b/briar-android/src/main/java/org/briarproject/briar/android/AndroidComponent.java index c1ec805a6220505c598174473449b3c3034f4d3f..468782cd495bd79397cb3e080033664c1bd0fbd2 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/AndroidComponent.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/AndroidComponent.java @@ -28,7 +28,7 @@ import org.briarproject.bramble.api.system.AndroidExecutor; import org.briarproject.bramble.api.system.AndroidWakeLockManager; import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.LocationUtils; -import org.briarproject.bramble.mailbox.UrlConverterModule; +import org.briarproject.bramble.mailbox.ModularMailboxModule; import org.briarproject.bramble.plugin.file.RemovableDriveModule; import org.briarproject.bramble.plugin.tor.CircumventionProvider; import org.briarproject.bramble.system.ClockModule; @@ -102,7 +102,7 @@ import dagger.Component; AttachmentModule.class, ClockModule.class, MediaModule.class, - UrlConverterModule.class, + ModularMailboxModule.class, RemovableDriveModule.class }) public interface AndroidComponent 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 fe4afa241cfac6197354ce131680a0d4a4127cbd..896df814abc2d6acf79e635a560f9981e3b7eca6 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 @@ -4,7 +4,7 @@ import org.briarproject.bramble.BrambleCoreIntegrationTestEagerSingletons; import org.briarproject.bramble.BrambleCoreModule; import org.briarproject.bramble.api.identity.IdentityManager; import org.briarproject.bramble.api.lifecycle.LifecycleManager; -import org.briarproject.bramble.mailbox.UrlConverterModule; +import org.briarproject.bramble.mailbox.ModularMailboxModule; import org.briarproject.bramble.test.BrambleCoreIntegrationTestModule; import org.briarproject.bramble.test.TestDnsModule; import org.briarproject.bramble.test.TestPluginConfigModule; @@ -29,7 +29,7 @@ import dagger.Component; BriarClientModule.class, FeedModule.class, IdentityModule.class, - UrlConverterModule.class, + ModularMailboxModule.class, TestDnsModule.class, TestSocksModule.class, TestPluginConfigModule.class, 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 69f7bdc4d1a253453bee24725a9b61d40ef3b364..f054a55cb3c7605279f0fcf69caba0bbb08929ab 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 @@ -1,7 +1,7 @@ package org.briarproject.briar.introduction; import org.briarproject.bramble.BrambleCoreModule; -import org.briarproject.bramble.mailbox.UrlConverterModule; +import org.briarproject.bramble.mailbox.ModularMailboxModule; import org.briarproject.bramble.test.BrambleCoreIntegrationTestModule; import org.briarproject.bramble.test.TestDnsModule; import org.briarproject.bramble.test.TestPluginConfigModule; @@ -41,7 +41,7 @@ import dagger.Component; MessagingModule.class, PrivateGroupModule.class, SharingModule.class, - UrlConverterModule.class, + ModularMailboxModule.class, TestDnsModule.class, TestSocksModule.class, TestPluginConfigModule.class, 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 6b4083adef945972385f5f658da36410c5a40bd1..c01400b8206e041713a4d315ee4be1f3a4da0d99 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 @@ -2,7 +2,7 @@ package org.briarproject.briar.messaging; import org.briarproject.bramble.BrambleCoreIntegrationTestEagerSingletons; import org.briarproject.bramble.BrambleCoreModule; -import org.briarproject.bramble.mailbox.UrlConverterModule; +import org.briarproject.bramble.mailbox.ModularMailboxModule; import org.briarproject.bramble.test.BrambleCoreIntegrationTestModule; import org.briarproject.bramble.test.TestDnsModule; import org.briarproject.bramble.test.TestPluginConfigModule; @@ -29,7 +29,7 @@ import dagger.Component; ForumModule.class, IdentityModule.class, MessagingModule.class, - UrlConverterModule.class, + ModularMailboxModule.class, TestDnsModule.class, TestSocksModule.class, TestPluginConfigModule.class, 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 e3498608dd18b0127640266f772ffb68d4fb26a0..f929bab690aa355c811665caa16d11f4b88a83a2 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 @@ -7,7 +7,7 @@ import org.briarproject.bramble.api.contact.ContactManager; import org.briarproject.bramble.api.event.EventBus; import org.briarproject.bramble.api.identity.IdentityManager; import org.briarproject.bramble.api.lifecycle.LifecycleManager; -import org.briarproject.bramble.mailbox.UrlConverterModule; +import org.briarproject.bramble.mailbox.ModularMailboxModule; import org.briarproject.bramble.test.BrambleCoreIntegrationTestModule; import org.briarproject.bramble.test.TestDnsModule; import org.briarproject.bramble.test.TestPluginConfigModule; @@ -30,7 +30,7 @@ import dagger.Component; BriarClientModule.class, ConversationModule.class, MessagingModule.class, - UrlConverterModule.class, + ModularMailboxModule.class, TestDnsModule.class, TestSocksModule.class, TestPluginConfigModule.class, 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 a2486c3470255e8f2b7993f69912e990f47932e0..c2010c345894c5e3c903b9dc98225e5b183dce83 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 @@ -8,7 +8,7 @@ import org.briarproject.bramble.api.identity.AuthorFactory; import org.briarproject.bramble.api.lifecycle.LifecycleManager; import org.briarproject.bramble.api.properties.TransportPropertyManager; import org.briarproject.bramble.api.system.Clock; -import org.briarproject.bramble.mailbox.UrlConverterModule; +import org.briarproject.bramble.mailbox.ModularMailboxModule; import org.briarproject.bramble.test.BrambleCoreIntegrationTestModule; import org.briarproject.bramble.test.BrambleIntegrationTestComponent; import org.briarproject.bramble.test.TestDnsModule; @@ -66,7 +66,7 @@ import dagger.Component; MessagingModule.class, PrivateGroupModule.class, SharingModule.class, - UrlConverterModule.class, + ModularMailboxModule.class, TestDnsModule.class, TestSocksModule.class, TestPluginConfigModule.class, diff --git a/briar-headless/src/main/java/org/briarproject/briar/headless/HeadlessModule.kt b/briar-headless/src/main/java/org/briarproject/briar/headless/HeadlessModule.kt index a841f9913289d4aeed8afdecd6229ed9e5b1649f..d15db40dd92716270eacb8dab8de80e33a859ca7 100644 --- a/briar-headless/src/main/java/org/briarproject/briar/headless/HeadlessModule.kt +++ b/briar-headless/src/main/java/org/briarproject/briar/headless/HeadlessModule.kt @@ -22,6 +22,7 @@ import org.briarproject.bramble.plugin.tor.UnixTorPluginFactory import org.briarproject.bramble.plugin.tor.WindowsTorPluginFactory import org.briarproject.bramble.system.ClockModule import org.briarproject.bramble.system.DefaultTaskSchedulerModule +import org.briarproject.bramble.system.DefaultThreadFactoryModule import org.briarproject.bramble.system.DefaultWakefulIoExecutorModule import org.briarproject.bramble.system.DesktopSecureRandomModule import org.briarproject.bramble.util.OsUtils.isLinux @@ -44,6 +45,7 @@ import javax.inject.Singleton DefaultEventExecutorModule::class, DefaultTaskSchedulerModule::class, DefaultWakefulIoExecutorModule::class, + DefaultThreadFactoryModule::class, DesktopSecureRandomModule::class, HeadlessBlogModule::class, HeadlessContactModule::class, diff --git a/briar-headless/src/test/java/org/briarproject/briar/headless/HeadlessTestModule.kt b/briar-headless/src/test/java/org/briarproject/briar/headless/HeadlessTestModule.kt index 2725b70a5195a3f5bf72529b53baaa41aa6558fd..219051d16cb67aa984f47963cb9e9f3ec4faa4b8 100644 --- a/briar-headless/src/test/java/org/briarproject/briar/headless/HeadlessTestModule.kt +++ b/briar-headless/src/test/java/org/briarproject/briar/headless/HeadlessTestModule.kt @@ -17,6 +17,7 @@ import org.briarproject.bramble.api.plugin.simplex.SimplexPluginFactory import org.briarproject.bramble.event.DefaultEventExecutorModule import org.briarproject.bramble.system.ClockModule import org.briarproject.bramble.system.DefaultTaskSchedulerModule +import org.briarproject.bramble.system.DefaultThreadFactoryModule import org.briarproject.bramble.system.DefaultWakefulIoExecutorModule import org.briarproject.bramble.test.TestFeatureFlagModule import org.briarproject.bramble.test.TestSecureRandomModule @@ -37,6 +38,7 @@ import javax.inject.Singleton DefaultEventExecutorModule::class, DefaultTaskSchedulerModule::class, DefaultWakefulIoExecutorModule::class, + DefaultThreadFactoryModule::class, TestFeatureFlagModule::class, TestSecureRandomModule::class, HeadlessBlogModule::class, diff --git a/mailbox-integration-tests/build.gradle b/mailbox-integration-tests/build.gradle index cd2f67fde05be2bb016316dd4494e1d4d9b5e5b1..3b833cc2bb6089d57991cfd722854179714ea9e4 100644 --- a/mailbox-integration-tests/build.gradle +++ b/mailbox-integration-tests/build.gradle @@ -7,14 +7,15 @@ apply from: '../dagger.gradle' dependencies { testImplementation project(path: ':bramble-api', configuration: 'default') + testImplementation project(path: ':bramble-api', configuration: 'testOutput') testImplementation project(path: ':bramble-core', configuration: 'default') + testImplementation project(path: ':bramble-core', configuration: 'testOutput') testImplementation project(path: ':mailbox-core', configuration: 'default') testImplementation project(path: ':mailbox-lib', configuration: 'default') - testImplementation project(path: ':bramble-api', configuration: 'testOutput') - testImplementation project(path: ':bramble-core', configuration: 'testOutput') testImplementation "junit:junit:$junit_version" testImplementation "ch.qos.logback:logback-classic:1.2.11" + testImplementation 'net.jodah:concurrentunit:0.4.6' testAnnotationProcessor "com.google.dagger:dagger-compiler:$dagger_version" } diff --git a/mailbox-integration-tests/src/test/java/org/briarproject/bramble/mailbox/AbstractMailboxIntegrationTest.java b/mailbox-integration-tests/src/test/java/org/briarproject/bramble/mailbox/AbstractMailboxIntegrationTest.java new file mode 100644 index 0000000000000000000000000000000000000000..2eb0eef4fa5a0aaede9fe687c88da04436fe16b8 --- /dev/null +++ b/mailbox-integration-tests/src/test/java/org/briarproject/bramble/mailbox/AbstractMailboxIntegrationTest.java @@ -0,0 +1,221 @@ +package org.briarproject.bramble.mailbox; + +import org.briarproject.bramble.api.contact.Contact; +import org.briarproject.bramble.api.contact.ContactId; +import org.briarproject.bramble.api.crypto.SecretKey; +import org.briarproject.bramble.api.db.DatabaseComponent; +import org.briarproject.bramble.api.db.DbCallable; +import org.briarproject.bramble.api.db.DbException; +import org.briarproject.bramble.api.identity.Identity; +import org.briarproject.bramble.api.identity.IdentityManager; +import org.briarproject.bramble.api.identity.LocalAuthor; +import org.briarproject.bramble.api.lifecycle.LifecycleManager; +import org.briarproject.bramble.api.mailbox.MailboxAuthToken; +import org.briarproject.bramble.api.mailbox.MailboxPairingState; +import org.briarproject.bramble.api.mailbox.MailboxPairingTask; +import org.briarproject.bramble.api.mailbox.MailboxProperties; +import org.briarproject.bramble.api.mailbox.MailboxUpdateWithMailbox; +import org.briarproject.bramble.api.plugin.TransportId; +import org.briarproject.bramble.api.properties.TransportProperties; +import org.briarproject.bramble.test.BrambleIntegrationTest; +import org.briarproject.bramble.test.TestDatabaseConfigModule; +import org.briarproject.bramble.test.TestLogFormatter; +import org.briarproject.bramble.test.TestThreadFactoryModule; +import org.briarproject.mailbox.lib.AbstractMailbox; +import org.briarproject.mailbox.lib.TestMailbox; +import org.junit.After; +import org.junit.Before; + +import java.io.File; +import java.util.Map; +import java.util.concurrent.CountDownLatch; + +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.briarproject.bramble.api.mailbox.MailboxAuthToken.fromString; +import static org.briarproject.bramble.mailbox.MailboxIntegrationTestComponent.Helper.injectEagerSingletons; +import static org.briarproject.bramble.mailbox.MailboxIntegrationTestUtils.createMailboxApi; +import static org.briarproject.bramble.mailbox.MailboxTestUtils.getQrCodePayload; +import static org.briarproject.bramble.test.TestUtils.getSecretKey; +import static org.briarproject.bramble.util.StringUtils.getRandomString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + +abstract class AbstractMailboxIntegrationTest + extends BrambleIntegrationTest<MailboxIntegrationTestComponent> { + + static final String URL_BASE = "http://127.0.0.1:8000"; + + AbstractMailboxIntegrationTest() { + TestLogFormatter.use(); + } + + private final TransportId transportId = new TransportId(getRandomString(4)); + private final File dir1 = new File(testDir, "alice"); + private final File dir2 = new File(testDir, "bob"); + private final SecretKey rootKey = getSecretKey(); + + MailboxIntegrationTestComponent c1, c2; + Contact contact1From2, contact2From1; + TestMailbox mailbox; + MailboxApi api = createMailboxApi(); + + @Before + @Override + public void setUp() throws Exception { + super.setUp(); + c1 = startTestComponent(dir1, "Alice"); + c2 = startTestComponent(dir2, "Bob"); + mailbox = new TestMailbox(new File(testDir, "mailbox")); + mailbox.startLifecycle(); + } + + @After + @Override + public void tearDown() throws Exception { + super.tearDown(); + c1.getLifecycleManager().stopServices(); + c2.getLifecycleManager().stopServices(); + c1.getLifecycleManager().waitForShutdown(); + c2.getLifecycleManager().waitForShutdown(); + mailbox.stopLifecycle(true); + } + + private MailboxIntegrationTestComponent startTestComponent( + File databaseDir, String name) throws Exception { + TestThreadFactoryModule threadFactoryModule = + new TestThreadFactoryModule(name); + TestDatabaseConfigModule dbModule = + new TestDatabaseConfigModule(databaseDir); + MailboxIntegrationTestComponent component = + DaggerMailboxIntegrationTestComponent + .builder() + .testThreadFactoryModule(threadFactoryModule) + .testDatabaseConfigModule(dbModule) + .build(); + injectEagerSingletons(component); + + setUp(component, name); + return component; + } + + private void setUp(MailboxIntegrationTestComponent device, + String name) throws Exception { + // Add an identity for the user + IdentityManager identityManager = device.getIdentityManager(); + Identity identity = identityManager.createIdentity(name); + identityManager.registerIdentity(identity); + // Start the lifecycle manager + LifecycleManager lifecycleManager = device.getLifecycleManager(); + lifecycleManager.startServices(getSecretKey()); + lifecycleManager.waitForStartup(); + addEventListener(device); + } + + MailboxProperties pair(MailboxIntegrationTestComponent c, + AbstractMailbox mailbox) throws Exception { + MailboxAuthToken setupToken = fromString(mailbox.getSetupToken()); + + MailboxPairingTask pairingTask = c.getMailboxManager() + .startPairingTask(getQrCodePayload(setupToken.getBytes())); + + CountDownLatch latch = new CountDownLatch(1); + pairingTask.addObserver((state) -> { + if (state instanceof MailboxPairingState.Paired) { + latch.countDown(); + } + }); + if (!latch.await(10, SECONDS)) { + fail("Timeout reached when waiting for pairing."); + } + MailboxProperties properties = c.getDatabaseComponent() + .transactionWithNullableResult(true, txn -> + c.getMailboxSettingsManager() + .getOwnMailboxProperties(txn) + ); + assertNotNull(properties); + return properties; + } + + void addContacts() throws Exception { + LocalAuthor author1 = c1.getIdentityManager().getLocalAuthor(); + LocalAuthor author2 = c2.getIdentityManager().getLocalAuthor(); + + ContactId contactId2From1 = + c1.getContactManager().addContact(author2, + author1.getId(), rootKey, + c1.getClock().currentTimeMillis(), + true, true, true); + ContactId contactId1From2 = + c2.getContactManager().addContact(author1, + author2.getId(), rootKey, + c2.getClock().currentTimeMillis(), + false, true, true); + + contact2From1 = c1.getContactManager().getContact(contactId2From1); + contact1From2 = c2.getContactManager().getContact(contactId1From2); + + // Sync client versioning update from 1 to 2 + sync1To2(1, true); + // Sync client versioning update and ack from 2 to 1 + sync2To1(1, true); + // Sync second client versioning update, mailbox properties and ack + // from 1 to 2 + sync1To2(2, true); + // Sync mailbox properties and ack from 2 to 1 + sync2To1(1, true); + // Sync final ack from 1 to 2 + ack1To2(1); + } + + <T> T getFromDb(MailboxIntegrationTestComponent device, + DbCallable<T, ?> callable) throws Exception { + return device.getDatabaseComponent() + .transactionWithResult(true, callable::call); + } + + MailboxProperties getMailboxProperties( + MailboxIntegrationTestComponent device, ContactId contactId) + throws DbException { + DatabaseComponent db = device.getDatabaseComponent(); + MailboxUpdateWithMailbox update = (MailboxUpdateWithMailbox) + db.transactionWithNullableResult(true, txn -> + device.getMailboxUpdateManager() + .getRemoteUpdate(txn, contactId) + ); + if (update == null) fail(); + return update.getMailboxProperties(); + } + + void broadcastMessage(MailboxIntegrationTestComponent from) + throws Exception { + TransportProperties p = from.getTransportPropertyManager() + .getLocalProperties(transportId); + p.put(getRandomString(23), getRandomString(8)); + from.getTransportPropertyManager().mergeLocalProperties(transportId, p); + } + + void sync1To2(int num, boolean valid) throws Exception { + syncMessage(c1, c2, contact2From1.getId(), num, valid); + } + + void sync2To1(int num, boolean valid) throws Exception { + syncMessage(c2, c1, contact1From2.getId(), num, valid); + } + + void ack1To2(int num) throws Exception { + sendAcks(c1, c2, contact2From1.getId(), num); + } + + void ack2To1(int num) throws Exception { + sendAcks(c2, c1, contact1From2.getId(), num); + } + + void assertNumMessages(MailboxIntegrationTestComponent c, + ContactId contactId, int num) throws DbException { + Map<ContactId, TransportProperties> p = c.getTransportPropertyManager() + .getRemoteProperties(transportId); + assertEquals(num, p.get(contactId).size()); + } + +} diff --git a/mailbox-integration-tests/src/test/java/org/briarproject/bramble/mailbox/MailboxApiIntegrationTest.java b/mailbox-integration-tests/src/test/java/org/briarproject/bramble/mailbox/MailboxApiIntegrationTest.java index e6ab681216f9f8cbdbcb0d59435953363c776701..d196d180dcff07c8af9e5f836bf26bf881e01263 100644 --- a/mailbox-integration-tests/src/test/java/org/briarproject/bramble/mailbox/MailboxApiIntegrationTest.java +++ b/mailbox-integration-tests/src/test/java/org/briarproject/bramble/mailbox/MailboxApiIntegrationTest.java @@ -26,7 +26,7 @@ import java.util.List; import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; -import static org.briarproject.bramble.mailbox.MailboxIntegrationTestUtils.URL_BASE; +import static org.briarproject.bramble.mailbox.AbstractMailboxIntegrationTest.URL_BASE; import static org.briarproject.bramble.mailbox.MailboxIntegrationTestUtils.createMailboxApi; import static org.briarproject.bramble.test.TestUtils.getRandomBytes; import static org.briarproject.bramble.test.TestUtils.getRandomId; diff --git a/mailbox-integration-tests/src/test/java/org/briarproject/bramble/mailbox/MailboxIntegrationTest.java b/mailbox-integration-tests/src/test/java/org/briarproject/bramble/mailbox/MailboxIntegrationTest.java new file mode 100644 index 0000000000000000000000000000000000000000..043257eaf5367d6aacb27e651e73000490868eb0 --- /dev/null +++ b/mailbox-integration-tests/src/test/java/org/briarproject/bramble/mailbox/MailboxIntegrationTest.java @@ -0,0 +1,70 @@ +package org.briarproject.bramble.mailbox; + +import org.briarproject.bramble.api.contact.ContactId; +import org.briarproject.bramble.api.mailbox.MailboxProperties; +import org.briarproject.bramble.mailbox.MailboxApi.MailboxFile; +import org.junit.Test; + +import java.util.Collection; +import java.util.List; +import java.util.logging.Logger; + +import static java.util.logging.Logger.getLogger; +import static org.briarproject.bramble.mailbox.MailboxIntegrationTestUtils.retryUntilSuccessOrTimeout; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class MailboxIntegrationTest extends AbstractMailboxIntegrationTest { + + private static final Logger LOG = + getLogger(MailboxIntegrationTest.class.getSimpleName()); + + @Test + public void testSendMessageViaMailbox() throws Exception { + addContacts(); + + // c1 one pairs the mailbox + MailboxProperties props1 = pair(c1, mailbox); + + // Check for number of contacts on mailbox via API every 100ms. + // This should be quick and will succeed with first call. + retryUntilSuccessOrTimeout(1_000, 100, () -> { + Collection<ContactId> contacts = api.getContacts(props1); + return contacts.size() == 1; + }); + + // tell contact about mailbox + sync1To2(1, true); + ack2To1(1); + + // contact should have received their MailboxProperties + MailboxProperties props2 = + getMailboxProperties(c2, contact1From2.getId()); + assertNotNull(props2.getInboxId()); + + // wait until file containing mailbox properties arrived on mailbox + retryUntilSuccessOrTimeout(5_000, 500, () -> { + List<MailboxFile> files = api.getFiles(props2, props2.getInboxId()); + return files.size() == 1; + }); + LOG.info("Mailbox properties uploaded"); + + // send message and wait for it to arrive via mailbox + broadcastMessage(c1); + + // we don't check for two messages now, because 2 (Bob) might have + // download the first message still in their 1st download cycle. + + // wait for message to arrive + // this might require 2nd download cycle after Tor reachability period + LOG.info("Waiting for delivery of broadcast message"); + awaitPendingMessageDelivery(1); + + // assert that message arrived for c2 + assertNumMessages(c2, contact1From2.getId(), 1); + + // all files were deleted from mailbox + assertEquals(0, api.getFiles(props2, props2.getInboxId()).size()); + } + +} diff --git a/mailbox-integration-tests/src/test/java/org/briarproject/bramble/mailbox/MailboxIntegrationTestComponent.java b/mailbox-integration-tests/src/test/java/org/briarproject/bramble/mailbox/MailboxIntegrationTestComponent.java index a4fc1adb57bc559f8e0c3eca12e291964bc03743..c6c7fd9318f30871bf029070970fbf7b69ec1bcf 100644 --- a/mailbox-integration-tests/src/test/java/org/briarproject/bramble/mailbox/MailboxIntegrationTestComponent.java +++ b/mailbox-integration-tests/src/test/java/org/briarproject/bramble/mailbox/MailboxIntegrationTestComponent.java @@ -1,8 +1,8 @@ package org.briarproject.bramble.mailbox; +import org.briarproject.bramble.BrambleCoreIntegrationTestEagerSingletons; import org.briarproject.bramble.BrambleCoreModule; import org.briarproject.bramble.api.contact.ContactManager; -import org.briarproject.bramble.api.crypto.CryptoComponent; import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.identity.AuthorFactory; import org.briarproject.bramble.api.lifecycle.LifecycleManager; @@ -11,10 +11,9 @@ import org.briarproject.bramble.api.mailbox.MailboxSettingsManager; import org.briarproject.bramble.api.mailbox.MailboxUpdateManager; import org.briarproject.bramble.api.properties.TransportPropertyManager; import org.briarproject.bramble.api.system.Clock; -import org.briarproject.bramble.mailbox.MailboxIntegrationTestUtils.TestUrlConverterModule; import org.briarproject.bramble.test.BrambleCoreIntegrationTestModule; import org.briarproject.bramble.test.BrambleIntegrationTestComponent; -import org.briarproject.bramble.test.FakeTorPluginConfigModule; +import org.briarproject.bramble.test.MailboxTestPluginConfigModule; import org.briarproject.bramble.test.TestDnsModule; import org.briarproject.bramble.test.TestSocksModule; @@ -26,31 +25,37 @@ import dagger.Component; @Component(modules = { BrambleCoreIntegrationTestModule.class, BrambleCoreModule.class, - TestUrlConverterModule.class, - FakeTorPluginConfigModule.class, + TestModularMailboxModule.class, + MailboxTestPluginConfigModule.class, TestSocksModule.class, TestDnsModule.class, }) interface MailboxIntegrationTestComponent extends BrambleIntegrationTestComponent { + LifecycleManager getLifecycleManager(); + DatabaseComponent getDatabaseComponent(); - MailboxManager getMailboxManager(); + ContactManager getContactManager(); - MailboxUpdateManager getMailboxUpdateManager(); + AuthorFactory getAuthorFactory(); - MailboxSettingsManager getMailboxSettingsManager(); + Clock getClock(); - LifecycleManager getLifecycleManager(); + MailboxManager getMailboxManager(); - ContactManager getContactManager(); + MailboxSettingsManager getMailboxSettingsManager(); - Clock getClock(); + MailboxUpdateManager getMailboxUpdateManager(); TransportPropertyManager getTransportPropertyManager(); - AuthorFactory getAuthorFactory(); - - CryptoComponent getCrypto(); + class Helper { + static void injectEagerSingletons( + MailboxIntegrationTestComponent c) { + BrambleCoreIntegrationTestEagerSingletons.Helper + .injectEagerSingletons(c); + } + } } diff --git a/mailbox-integration-tests/src/test/java/org/briarproject/bramble/mailbox/MailboxIntegrationTestUtils.java b/mailbox-integration-tests/src/test/java/org/briarproject/bramble/mailbox/MailboxIntegrationTestUtils.java index 3f27c648dc0bb703be017fc5a1b34a720c8c981a..bcea13ea363ddc4c4830879724ab455f842bd056 100644 --- a/mailbox-integration-tests/src/test/java/org/briarproject/bramble/mailbox/MailboxIntegrationTestUtils.java +++ b/mailbox-integration-tests/src/test/java/org/briarproject/bramble/mailbox/MailboxIntegrationTestUtils.java @@ -1,89 +1,16 @@ package org.briarproject.bramble.mailbox; -import org.briarproject.bramble.BrambleCoreIntegrationTestEagerSingletons; -import org.briarproject.bramble.api.WeakSingletonProvider; -import org.briarproject.bramble.api.mailbox.MailboxAuthToken; -import org.briarproject.bramble.test.TestDatabaseConfigModule; - -import java.io.File; -import java.nio.ByteBuffer; -import java.nio.charset.Charset; -import java.util.Arrays; import java.util.concurrent.atomic.AtomicBoolean; -import javax.annotation.Nonnull; -import javax.net.SocketFactory; - -import dagger.Module; -import dagger.Provides; -import okhttp3.OkHttpClient; - import static java.lang.System.currentTimeMillis; -import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static org.briarproject.bramble.mailbox.MailboxTestUtils.createHttpClientProvider; +import static org.briarproject.bramble.mailbox.TestModularMailboxModule.urlConverter; import static org.junit.Assert.fail; class MailboxIntegrationTestUtils { - static final String URL_BASE = "http://127.0.0.1:8000"; - - static String getQrCodePayload(MailboxAuthToken setupToken) { - byte[] bytes = getQrCodeBytes(setupToken); - Charset charset = Charset.forName("ISO-8859-1"); - return new String(bytes, charset); - } - - private static byte[] getQrCodeBytes(MailboxAuthToken setupToken) { - byte[] hiddenServiceBytes = getHiddenServiceBytes(); - byte[] setupTokenBytes = setupToken.getBytes(); - return ByteBuffer.allocate(65).put((byte) 32) - .put(hiddenServiceBytes).put(setupTokenBytes).array(); - } - - private static byte[] getHiddenServiceBytes() { - byte[] data = new byte[32]; - Arrays.fill(data, (byte) 'a'); - return data; - } - - private static WeakSingletonProvider<OkHttpClient> createHttpClientProvider() { - OkHttpClient client = new OkHttpClient.Builder() - .socketFactory(SocketFactory.getDefault()) - .connectTimeout(60_000, MILLISECONDS) - .build(); - return new WeakSingletonProvider<OkHttpClient>() { - @Override - @Nonnull - public OkHttpClient createInstance() { - return client; - } - }; - } - static MailboxApi createMailboxApi() { - return new MailboxApiImpl(createHttpClientProvider(), - new TestUrlConverter()); - } - - static MailboxIntegrationTestComponent createTestComponent( - File databaseDir) { - MailboxIntegrationTestComponent component = - DaggerMailboxIntegrationTestComponent - .builder() - .testDatabaseConfigModule( - new TestDatabaseConfigModule(databaseDir)) - .build(); - BrambleCoreIntegrationTestEagerSingletons.Helper - .injectEagerSingletons(component); - return component; - } - - @Module - static class TestUrlConverterModule { - - @Provides - UrlConverter provideUrlConverter() { - return new TestUrlConverter(); - } + return new MailboxApiImpl(createHttpClientProvider(), urlConverter); } interface Check { @@ -126,6 +53,7 @@ class MailboxIntegrationTestUtils { return; } try { + //noinspection BusyWait Thread.sleep(step); } catch (InterruptedException ignore) { // continue diff --git a/mailbox-integration-tests/src/test/java/org/briarproject/bramble/mailbox/OwnMailboxContactListWorkerIntegrationTest.java b/mailbox-integration-tests/src/test/java/org/briarproject/bramble/mailbox/OwnMailboxContactListWorkerIntegrationTest.java index d91ca40a085dabe83cd977f8c694c23c3941d6e7..40b12ffc52627ee11ab8fb66d63f82ff44eb680a 100644 --- a/mailbox-integration-tests/src/test/java/org/briarproject/bramble/mailbox/OwnMailboxContactListWorkerIntegrationTest.java +++ b/mailbox-integration-tests/src/test/java/org/briarproject/bramble/mailbox/OwnMailboxContactListWorkerIntegrationTest.java @@ -6,112 +6,49 @@ import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.AuthorFactory; -import org.briarproject.bramble.api.identity.Identity; -import org.briarproject.bramble.api.identity.IdentityManager; -import org.briarproject.bramble.api.lifecycle.LifecycleManager; -import org.briarproject.bramble.api.mailbox.MailboxAuthToken; -import org.briarproject.bramble.api.mailbox.MailboxPairingState.Paired; -import org.briarproject.bramble.api.mailbox.MailboxPairingTask; +import org.briarproject.bramble.api.identity.LocalAuthor; import org.briarproject.bramble.api.mailbox.MailboxProperties; -import org.briarproject.bramble.test.BrambleTestCase; -import org.briarproject.mailbox.lib.TestMailbox; -import org.junit.After; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.List; -import java.util.concurrent.CountDownLatch; -import static org.briarproject.bramble.api.mailbox.MailboxAuthToken.fromString; import static org.briarproject.bramble.mailbox.MailboxIntegrationTestUtils.createMailboxApi; -import static org.briarproject.bramble.mailbox.MailboxIntegrationTestUtils.createTestComponent; -import static org.briarproject.bramble.mailbox.MailboxIntegrationTestUtils.getQrCodePayload; import static org.briarproject.bramble.mailbox.MailboxIntegrationTestUtils.retryUntilSuccessOrTimeout; import static org.briarproject.bramble.test.TestUtils.getSecretKey; -import static org.briarproject.bramble.test.TestUtils.getTestDirectory; import static org.junit.Assert.assertEquals; public class OwnMailboxContactListWorkerIntegrationTest - extends BrambleTestCase { - - @Rule - public TemporaryFolder mailboxDataDirectory = new TemporaryFolder(); - - private TestMailbox mailbox; + extends AbstractMailboxIntegrationTest { private final MailboxApi api = createMailboxApi(); private MailboxProperties ownerProperties; - private final File testDir = getTestDirectory(); - private final File aliceDir = new File(testDir, "alice"); - - private MailboxIntegrationTestComponent component; - private Identity identity; + private LocalAuthor localAuthor1; private final SecretKey rootKey = getSecretKey(); private final long timestamp = System.currentTimeMillis(); @Before + @Override public void setUp() throws Exception { - mailbox = new TestMailbox(mailboxDataDirectory.getRoot()); - mailbox.startLifecycle(); - - MailboxAuthToken setupToken = fromString(mailbox.getSetupToken()); - - component = createTestComponent(aliceDir); - identity = setUp(component, "Alice"); - - MailboxPairingTask pairingTask = component.getMailboxManager() - .startPairingTask(getQrCodePayload(setupToken)); - - CountDownLatch latch = new CountDownLatch(1); - pairingTask.addObserver((state) -> { - if (state instanceof Paired) { - latch.countDown(); - } - }); - latch.await(); - - ownerProperties = component.getDatabaseComponent() - .transactionWithNullableResult(false, txn -> - component.getMailboxSettingsManager() - .getOwnMailboxProperties(txn) - ); - } - - @After - public void tearDown() { - mailbox.stopLifecycle(true); + super.setUp(); + localAuthor1 = c1.getIdentityManager().getLocalAuthor(); + ownerProperties = pair(c1, mailbox); } - private Identity setUp(MailboxIntegrationTestComponent device, String name) - throws Exception { - // Add an identity for the user - IdentityManager identityManager = device.getIdentityManager(); - Identity identity = identityManager.createIdentity(name); - identityManager.registerIdentity(identity); - // Start the lifecycle manager - LifecycleManager lifecycleManager = device.getLifecycleManager(); - lifecycleManager.startServices(getSecretKey()); - lifecycleManager.waitForStartup(); + @Test + public void testUploadContacts() throws Exception { // Check the initial conditions - ContactManager contactManager = device.getContactManager(); + ContactManager contactManager = c1.getContactManager(); assertEquals(0, contactManager.getPendingContacts().size()); assertEquals(0, contactManager.getContacts().size()); - return identity; - } - @Test - public void testUploadContacts() throws Exception { int numContactsToAdd = 5; - List<ContactId> expectedContacts = - createContacts(component, identity, numContactsToAdd); + List<ContactId> expectedContacts = createContacts(c1, numContactsToAdd); // Check for number of contacts on mailbox via API every 100ms retryUntilSuccessOrTimeout(1000, 100, () -> { @@ -125,15 +62,16 @@ public class OwnMailboxContactListWorkerIntegrationTest } private List<ContactId> createContacts( - MailboxIntegrationTestComponent component, Identity local, - int numContacts) throws DbException { + MailboxIntegrationTestComponent component, int numContacts) + throws DbException { List<ContactId> contactIds = new ArrayList<>(); ContactManager contactManager = component.getContactManager(); AuthorFactory authorFactory = component.getAuthorFactory(); for (int i = 0; i < numContacts; i++) { Author remote = authorFactory.createLocalAuthor("Bob " + i); - contactIds.add(contactManager.addContact(remote, local.getId(), - rootKey, timestamp, true, true, true)); + ContactId c = contactManager.addContact(remote, + localAuthor1.getId(), rootKey, timestamp, true, true, true); + contactIds.add(c); } return contactIds; } diff --git a/mailbox-integration-tests/src/test/java/org/briarproject/bramble/mailbox/TestMailboxConfigImpl.java b/mailbox-integration-tests/src/test/java/org/briarproject/bramble/mailbox/TestMailboxConfigImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..2552fca776fb63baf8f7bf249fad800095a4fe58 --- /dev/null +++ b/mailbox-integration-tests/src/test/java/org/briarproject/bramble/mailbox/TestMailboxConfigImpl.java @@ -0,0 +1,30 @@ +package org.briarproject.bramble.mailbox; + +import org.briarproject.nullsafety.NotNullByDefault; + +import javax.annotation.concurrent.Immutable; +import javax.inject.Inject; + +@Immutable +@NotNullByDefault +class TestMailboxConfigImpl implements MailboxConfig { + + @Inject + TestMailboxConfigImpl() { + } + + @Override + public long getApiCallerMinRetryInterval() { + return 1000; + } + + @Override + public long getApiCallerMaxRetryInterval() { + return 2000; + } + + @Override + public long getTorReachabilityPeriod() { + return 10_000; + } +} diff --git a/mailbox-integration-tests/src/test/java/org/briarproject/bramble/mailbox/TestModularMailboxModule.java b/mailbox-integration-tests/src/test/java/org/briarproject/bramble/mailbox/TestModularMailboxModule.java new file mode 100644 index 0000000000000000000000000000000000000000..22e001bae8d17375c2eeedc7f573e26b207c92f4 --- /dev/null +++ b/mailbox-integration-tests/src/test/java/org/briarproject/bramble/mailbox/TestModularMailboxModule.java @@ -0,0 +1,25 @@ +package org.briarproject.bramble.mailbox; + +import org.briarproject.nullsafety.NotNullByDefault; + +import dagger.Module; +import dagger.Provides; + +import static org.briarproject.bramble.mailbox.AbstractMailboxIntegrationTest.URL_BASE; + +@Module +@NotNullByDefault +class TestModularMailboxModule { + + @Provides + MailboxConfig provideMailboxConfig(TestMailboxConfigImpl mailboxConfig) { + return mailboxConfig; + } + + static UrlConverter urlConverter = onion -> URL_BASE; + + @Provides + UrlConverter provideUrlConverter() { + return urlConverter; + } +} diff --git a/mailbox-integration-tests/src/test/java/org/briarproject/bramble/mailbox/TestUrlConverter.java b/mailbox-integration-tests/src/test/java/org/briarproject/bramble/mailbox/TestUrlConverter.java deleted file mode 100644 index 5841e7cc97d9b26f0977a04b7fdd33ef700db4e2..0000000000000000000000000000000000000000 --- a/mailbox-integration-tests/src/test/java/org/briarproject/bramble/mailbox/TestUrlConverter.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.briarproject.bramble.mailbox; - -import org.briarproject.nullsafety.NotNullByDefault; - -import static org.briarproject.bramble.mailbox.MailboxIntegrationTestUtils.URL_BASE; - -@NotNullByDefault -class TestUrlConverter implements UrlConverter { - - @Override - public String convertOnionToBaseUrl(String onion) { - return URL_BASE; - } -} diff --git a/bramble-core/src/test/java/org/briarproject/bramble/test/FakeTorPlugin.java b/mailbox-integration-tests/src/test/java/org/briarproject/bramble/test/FakeTorPlugin.java similarity index 89% rename from bramble-core/src/test/java/org/briarproject/bramble/test/FakeTorPlugin.java rename to mailbox-integration-tests/src/test/java/org/briarproject/bramble/test/FakeTorPlugin.java index 8e68f4f35ad601dea92a0323105c052f0eeaf606..fd702cb3c5b0c2e4727753fa8666da941f6906a1 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/test/FakeTorPlugin.java +++ b/mailbox-integration-tests/src/test/java/org/briarproject/bramble/test/FakeTorPlugin.java @@ -4,7 +4,7 @@ import org.briarproject.bramble.api.Pair; import org.briarproject.bramble.api.data.BdfList; import org.briarproject.bramble.api.keyagreement.KeyAgreementListener; import org.briarproject.bramble.api.plugin.ConnectionHandler; -import org.briarproject.bramble.api.plugin.PluginException; +import org.briarproject.bramble.api.plugin.PluginCallback; import org.briarproject.bramble.api.plugin.TorConstants; import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin; @@ -21,7 +21,6 @@ import javax.annotation.Nullable; import static java.util.logging.Logger.getLogger; import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE; -import static org.briarproject.bramble.api.plugin.Plugin.State.DISABLED; import static org.briarproject.bramble.api.plugin.Plugin.State.INACTIVE; @NotNullByDefault @@ -29,9 +28,14 @@ public class FakeTorPlugin implements DuplexPlugin { private static final Logger LOG = getLogger(FakeTorPlugin.class.getName()); + private final PluginCallback callback; private State state = INACTIVE; + FakeTorPlugin(PluginCallback callback) { + this.callback = callback; + } + @Override public TransportId getId() { return TorConstants.ID; @@ -48,15 +52,17 @@ public class FakeTorPlugin implements DuplexPlugin { } @Override - public void start() throws PluginException { + public void start() { LOG.info("Starting plugin"); state = ACTIVE; + callback.pluginStateChanged(state); } @Override - public void stop() throws PluginException { + public void stop() { LOG.info("Stopping plugin"); - state = DISABLED; + state = INACTIVE; + callback.pluginStateChanged(state); } @Override diff --git a/bramble-core/src/test/java/org/briarproject/bramble/test/FakeTorPluginFactory.java b/mailbox-integration-tests/src/test/java/org/briarproject/bramble/test/FakeTorPluginFactory.java similarity index 95% rename from bramble-core/src/test/java/org/briarproject/bramble/test/FakeTorPluginFactory.java rename to mailbox-integration-tests/src/test/java/org/briarproject/bramble/test/FakeTorPluginFactory.java index 32ea3139d4706a02c0f52ab74bbff66e19aea03f..9e718991b04c670a543bdc4ee3da7d36ab699142 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/test/FakeTorPluginFactory.java +++ b/mailbox-integration-tests/src/test/java/org/briarproject/bramble/test/FakeTorPluginFactory.java @@ -32,6 +32,6 @@ public class FakeTorPluginFactory implements DuplexPluginFactory { @Nullable @Override public DuplexPlugin createPlugin(PluginCallback callback) { - return new FakeTorPlugin(); + return new FakeTorPlugin(callback); } } diff --git a/bramble-core/src/test/java/org/briarproject/bramble/test/FakeTorPluginConfigModule.java b/mailbox-integration-tests/src/test/java/org/briarproject/bramble/test/MailboxTestPluginConfigModule.java similarity index 52% rename from bramble-core/src/test/java/org/briarproject/bramble/test/FakeTorPluginConfigModule.java rename to mailbox-integration-tests/src/test/java/org/briarproject/bramble/test/MailboxTestPluginConfigModule.java index 49b9048ad8827f4ff96deb9af431329379f8eeeb..a8c681bd2292b5c450b0d1f1220bfdab68a667f5 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/test/FakeTorPluginConfigModule.java +++ b/mailbox-integration-tests/src/test/java/org/briarproject/bramble/test/MailboxTestPluginConfigModule.java @@ -1,27 +1,56 @@ package org.briarproject.bramble.test; +import org.briarproject.bramble.api.plugin.PluginCallback; import org.briarproject.bramble.api.plugin.PluginConfig; import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory; +import org.briarproject.bramble.api.plugin.simplex.SimplexPlugin; import org.briarproject.bramble.api.plugin.simplex.SimplexPluginFactory; +import org.briarproject.bramble.plugin.file.MailboxPluginFactory; import org.briarproject.nullsafety.NotNullByDefault; import java.util.Collection; import java.util.List; import java.util.Map; +import javax.annotation.Nullable; + import dagger.Module; import dagger.Provides; -import static java.util.Collections.emptyList; +import static java.util.Arrays.asList; import static java.util.Collections.emptyMap; import static java.util.Collections.singletonList; +import static org.briarproject.bramble.test.TestPluginConfigModule.SIMPLEX_TRANSPORT_ID; @Module -public class FakeTorPluginConfigModule { +public class MailboxTestPluginConfigModule { + + private static final int MAX_LATENCY = 30_000; // 30 seconds + + @NotNullByDefault + private final SimplexPluginFactory simplex = new SimplexPluginFactory() { + + @Override + public TransportId getId() { + return SIMPLEX_TRANSPORT_ID; + } + + @Override + public long getMaxLatency() { + return MAX_LATENCY; + } + + @Override + @Nullable + public SimplexPlugin createPlugin(PluginCallback callback) { + return null; + } + }; @Provides - PluginConfig providePluginConfig(FakeTorPluginFactory tor) { + PluginConfig providePluginConfig(FakeTorPluginFactory tor, + MailboxPluginFactory mailboxPluginFactory) { @NotNullByDefault PluginConfig pluginConfig = new PluginConfig() { @@ -32,7 +61,7 @@ public class FakeTorPluginConfigModule { @Override public Collection<SimplexPluginFactory> getSimplexFactories() { - return emptyList(); + return asList(simplex, mailboxPluginFactory); } @Override diff --git a/mailbox-integration-tests/src/test/java/org/briarproject/bramble/test/TestLogFormatter.java b/mailbox-integration-tests/src/test/java/org/briarproject/bramble/test/TestLogFormatter.java new file mode 100644 index 0000000000000000000000000000000000000000..b5b819d15ff828cf9bf9d984cf37019d5aebd560 --- /dev/null +++ b/mailbox-integration-tests/src/test/java/org/briarproject/bramble/test/TestLogFormatter.java @@ -0,0 +1,57 @@ +package org.briarproject.bramble.test; + +import org.briarproject.nullsafety.NotNullByDefault; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.logging.ConsoleHandler; +import java.util.logging.LogManager; +import java.util.logging.LogRecord; +import java.util.logging.Logger; +import java.util.logging.SimpleFormatter; + +import javax.annotation.concurrent.ThreadSafe; + +@ThreadSafe +@NotNullByDefault +public class TestLogFormatter extends SimpleFormatter { + + private final Object lock = new Object(); + private final DateFormat dateFormat; // Locking: lock + private final Date date; // Locking: lock + + public static void use() { + LogManager.getLogManager().reset(); + Logger rootLogger = LogManager.getLogManager().getLogger(""); + ConsoleHandler handler = new ConsoleHandler(); + handler.setFormatter(new TestLogFormatter()); + rootLogger.addHandler(handler); + } + + private TestLogFormatter() { + synchronized (lock) { + dateFormat = new SimpleDateFormat("HH:mm:ss.SSS"); + date = new Date(); + } + } + + @Override + public String format(LogRecord rec) { + if (rec.getThrown() == null) { + String dateString; + synchronized (lock) { + date.setTime(rec.getMillis()); + dateString = dateFormat.format(date); + } + return String.format("%s [%s] %s %s - %s\n", + dateString, + Thread.currentThread().getName(), + rec.getLevel().getName(), + rec.getLoggerName(), + rec.getMessage()); + } else { + return super.format(rec); + } + } +}