Skip to content
Snippets Groups Projects
Verified Commit a720501f authored by Torsten Grote's avatar Torsten Grote
Browse files

First integration test for mailbox with two contacts

one private message gets send via mailbox from one contact to the other
parent 648911b3
No related branches found
No related tags found
No related merge requests found
Showing
with 253 additions and 54 deletions
......@@ -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();
......
......@@ -8,13 +8,17 @@ apply from: '../dagger.gradle'
dependencies {
testImplementation project(path: ':bramble-api', configuration: 'default')
testImplementation project(path: ':bramble-core', configuration: 'default')
testImplementation project(path: ':briar-api', configuration: 'default')
testImplementation project(path: ':briar-core', configuration: 'default')
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 project(path: ':briar-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"
}
package org.briarproject.bramble.mailbox;
import org.briarproject.bramble.BrambleCoreIntegrationTestEagerSingletons;
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.test.BrambleTestCase;
import org.briarproject.bramble.api.mailbox.MailboxUpdateWithMailbox;
import org.briarproject.bramble.api.plugin.Plugin;
import org.briarproject.bramble.api.plugin.PluginException;
import org.briarproject.bramble.api.plugin.TorConstants;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.test.BrambleIntegrationTest;
import org.briarproject.bramble.test.TestDatabaseConfigModule;
import org.briarproject.briar.api.messaging.PrivateMessage;
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.concurrent.CountDownLatch;
import static java.util.Collections.emptyList;
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.test.TestUtils.getTestDirectory;
import static org.briarproject.briar.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
abstract class AbstractMailboxIntegrationTest extends BrambleTestCase {
abstract class AbstractMailboxIntegrationTest
extends BrambleIntegrationTest<MailboxIntegrationTestComponent> {
static final String URL_BASE = "http://127.0.0.1:8000";
private final File testDir = getTestDirectory();
final File dir1 = new File(testDir, "alice");
final File dir2 = new File(testDir, "bob");
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);
}
MailboxIntegrationTestComponent startTestComponent(
File databaseDir, String name) throws Exception {
TestDatabaseConfigModule dbModule =
new TestDatabaseConfigModule(databaseDir);
MailboxIntegrationTestComponent component =
DaggerMailboxIntegrationTestComponent
.builder()
.testDatabaseConfigModule(
new TestDatabaseConfigModule(databaseDir))
.testDatabaseConfigModule(dbModule)
.build();
BrambleCoreIntegrationTestEagerSingletons.Helper
.injectEagerSingletons(component);
injectEagerSingletons(component);
component.getPluginManager().setPluginEnabled(TorConstants.ID, false);
setUp(component, name);
return component;
}
......@@ -56,6 +102,7 @@ abstract class AbstractMailboxIntegrationTest extends BrambleTestCase {
LifecycleManager lifecycleManager = device.getLifecycleManager();
lifecycleManager.startServices(getSecretKey());
lifecycleManager.waitForStartup();
addEventListener(device);
}
MailboxProperties pair(MailboxIntegrationTestComponent c,
......@@ -81,4 +128,83 @@ abstract class AbstractMailboxIntegrationTest extends BrambleTestCase {
);
}
void addContacts() throws Exception {
LocalAuthor author1 = c1.getIdentityManager().getLocalAuthor();
LocalAuthor author2 = c2.getIdentityManager().getLocalAuthor();
ContactId contactId1 = c1.getContactManager().addContact(author2,
author1.getId(), rootKey, c1.getClock().currentTimeMillis(),
true, true, true);
ContactId contactId2 = c2.getContactManager().addContact(author1,
author2.getId(), rootKey, c2.getClock().currentTimeMillis(),
false, true, true);
contact2From1 = c1.getContactManager().getContact(contactId2);
contact1From2 = c2.getContactManager().getContact(contactId1);
// Sync client versioning update from 0 to 1
sync1To2(1, true);
// Sync client versioning update and ack from 1 to 0
sync2To1(1, true);
// Sync second client versioning update, mailbox properties and ack
// from 0 to 1
sync1To2(2, true);
// Sync mailbox properties and ack from 1 to 0
sync2To1(1, true);
// Sync final ack from 0 to 1
ack1To2(1);
}
<T> T getFromDb(MailboxIntegrationTestComponent device,
DbCallable<T, ?> callable) throws Exception {
return device.getDatabaseComponent()
.transactionWithResult(true, callable::call);
}
void restartTor(MailboxIntegrationTestComponent device)
throws PluginException {
Plugin torPlugin = device.getPluginManager().getPlugin(TorConstants.ID);
assertNotNull(torPlugin);
torPlugin.stop();
torPlugin.start();
}
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 sendMessage(MailboxIntegrationTestComponent from,
ContactId toContactId, String text) throws Exception {
GroupId g = from.getMessagingManager().getConversationId(toContactId);
PrivateMessage m = from.getPrivateMessageFactory().createPrivateMessage(
g, from.getClock().currentTimeMillis(), text, emptyList(),
NO_AUTO_DELETE_TIMER);
from.getMessagingManager().addLocalMessage(m);
}
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);
}
}
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 static org.briarproject.bramble.mailbox.MailboxIntegrationTestUtils.retryUntilSuccessOrTimeout;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
public class MailboxIntegrationTest extends AbstractMailboxIntegrationTest {
@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
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());
// send message and wait for it to arrive via mailbox
sendMessage(c1, contact2From1.getId(), "test");
// restart Tor for c1 to cause an immediate upload
// and wait until file arrived on mailbox
restartTor(c1);
retryUntilSuccessOrTimeout(5_000, 100, () -> {
List<MailboxFile> files = api.getFiles(props2, props2.getInboxId());
return files.size() > 0;
});
// restart Tor for c2 to cause an immediate download
// and wait for message to arrive
restartTor(c2);
awaitPendingMessageDelivery(1, 5_000);
// private message arrived for c2
int size = getFromDb(c2, txn -> c2.getMessagingManager()
.getMessageHeaders(txn, contact1From2.getId()).size());
assertEquals(1, size);
// all files were deleted from mailbox
assertEquals(0, api.getFiles(props2, props2.getInboxId()).size());
}
}
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.db.DatabaseComponent;
import org.briarproject.bramble.api.identity.AuthorFactory;
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.api.mailbox.MailboxManager;
import org.briarproject.bramble.api.mailbox.MailboxSettingsManager;
import org.briarproject.bramble.mailbox.MailboxIntegrationTestUtils.TestUrlConverterModule;
import org.briarproject.bramble.api.mailbox.MailboxUpdateManager;
import org.briarproject.bramble.api.plugin.PluginManager;
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;
import org.briarproject.briar.BriarCoreModule;
import org.briarproject.briar.identity.IdentityModule;
import org.briarproject.briar.messaging.MessagingModule;
import org.briarproject.briar.test.BriarIntegrationTestComponent;
import javax.inject.Singleton;
......@@ -22,23 +23,30 @@ import dagger.Component;
@Component(modules = {
BrambleCoreIntegrationTestModule.class,
BrambleCoreModule.class,
BriarCoreModule.class,
TestUrlConverterModule.class,
FakeTorPluginConfigModule.class,
MailboxTestPluginConfigModule.class,
TestSocksModule.class,
TestDnsModule.class,
})
interface MailboxIntegrationTestComponent extends
BrambleIntegrationTestComponent {
DatabaseComponent getDatabaseComponent();
BriarIntegrationTestComponent {
MailboxManager getMailboxManager();
MailboxSettingsManager getMailboxSettingsManager();
LifecycleManager getLifecycleManager();
MailboxUpdateManager getMailboxUpdateManager();
ContactManager getContactManager();
PluginManager getPluginManager();
AuthorFactory getAuthorFactory();
class Helper {
static void injectEagerSingletons(
MailboxIntegrationTestComponent c) {
BrambleCoreIntegrationTestEagerSingletons.Helper
.injectEagerSingletons(c);
c.inject(new IdentityModule.EagerSingletons());
c.inject(new MessagingModule.EagerSingletons());
}
}
}
......@@ -8,12 +8,8 @@ import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorFactory;
import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.mailbox.MailboxProperties;
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.util.ArrayList;
import java.util.Collection;
......@@ -27,11 +23,6 @@ import static org.junit.Assert.assertEquals;
public class OwnMailboxContactListWorkerIntegrationTest
extends AbstractMailboxIntegrationTest {
@Rule
public TemporaryFolder mailboxDataDirectory = new TemporaryFolder();
private TestMailbox mailbox;
private final MailboxApi api = createMailboxApi();
private MailboxProperties ownerProperties;
......@@ -42,21 +33,13 @@ public class OwnMailboxContactListWorkerIntegrationTest
private final long timestamp = System.currentTimeMillis();
@Before
@Override
public void setUp() throws Exception {
mailbox = new TestMailbox(mailboxDataDirectory.getRoot());
mailbox.startLifecycle();
c1 = startTestComponent(dir1, "Alice");
super.setUp();
localAuthor1 = c1.getIdentityManager().getLocalAuthor();
ownerProperties = pair(c1, mailbox);
}
@After
public void tearDown() {
mailbox.stopLifecycle(true);
}
@Test
public void testUploadContacts() throws Exception {
// Check the initial conditions
......
......@@ -4,6 +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.PluginCallback;
import org.briarproject.bramble.api.plugin.TorConstants;
import org.briarproject.bramble.api.plugin.TransportId;
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
......@@ -20,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
......@@ -28,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;
......@@ -50,12 +55,14 @@ public class FakeTorPlugin implements DuplexPlugin {
public void start() {
LOG.info("Starting plugin");
state = ACTIVE;
callback.pluginStateChanged(state);
}
@Override
public void stop() {
LOG.info("Stopping plugin");
state = DISABLED;
state = INACTIVE;
callback.pluginStateChanged(state);
}
@Override
......
......@@ -32,6 +32,6 @@ public class FakeTorPluginFactory implements DuplexPluginFactory {
@Nullable
@Override
public DuplexPlugin createPlugin(PluginCallback callback) {
return new FakeTorPlugin();
return new FakeTorPlugin(callback);
}
}
......@@ -6,6 +6,7 @@ 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;
......@@ -17,14 +18,14 @@ import javax.annotation.Nullable;
import dagger.Module;
import dagger.Provides;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyMap;
import static java.util.Collections.singletonList;
import static org.briarproject.bramble.test.TestUtils.getTransportId;
import static org.briarproject.bramble.test.TestPluginConfigModule.SIMPLEX_TRANSPORT_ID;
@Module
public class FakeTorPluginConfigModule {
public class MailboxTestPluginConfigModule {
public static final TransportId SIMPLEX_TRANSPORT_ID = getTransportId();
private static final int MAX_LATENCY = 30_000; // 30 seconds
@NotNullByDefault
......@@ -48,7 +49,8 @@ public class FakeTorPluginConfigModule {
};
@Provides
PluginConfig providePluginConfig(FakeTorPluginFactory tor) {
PluginConfig providePluginConfig(FakeTorPluginFactory tor,
MailboxPluginFactory mailboxPluginFactory) {
@NotNullByDefault
PluginConfig pluginConfig = new PluginConfig() {
......@@ -59,7 +61,7 @@ public class FakeTorPluginConfigModule {
@Override
public Collection<SimplexPluginFactory> getSimplexFactories() {
return singletonList(simplex);
return asList(simplex, mailboxPluginFactory);
}
@Override
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment