Merge branch '1580-offline-state' into 'master'

Add offline state for pending contacts

Closes #1580

See merge request briar/briar!1138
This commit is contained in:
Torsten Grote
2019-06-17 13:10:41 +00:00
8 changed files with 77 additions and 30 deletions

View File

@@ -6,11 +6,15 @@ import org.briarproject.bramble.api.contact.ContactManager;
import org.briarproject.bramble.api.contact.PendingContact;
import org.briarproject.bramble.api.contact.PendingContactState;
import org.briarproject.bramble.api.contact.event.ContactAddedEvent;
import org.briarproject.bramble.api.contact.event.PendingContactStateChangedEvent;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.event.EventListener;
import org.briarproject.bramble.api.identity.Identity;
import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.test.BrambleTestCase;
import org.briarproject.bramble.test.TestDatabaseConfigModule;
import org.briarproject.bramble.test.TestDuplexTransportConnection;
@@ -27,7 +31,7 @@ import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static junit.framework.TestCase.assertNotNull;
import static junit.framework.TestCase.assertNull;
import static junit.framework.TestCase.fail;
import static org.briarproject.bramble.api.contact.PendingContactState.WAITING_FOR_CONNECTION;
import static org.briarproject.bramble.api.contact.PendingContactState.OFFLINE;
import static org.briarproject.bramble.test.TestDuplexTransportConnection.createPair;
import static org.briarproject.bramble.test.TestPluginConfigModule.DUPLEX_TRANSPORT_ID;
import static org.briarproject.bramble.test.TestUtils.deleteTestDirectory;
@@ -188,9 +192,14 @@ public class ContactExchangeIntegrationTest extends BrambleTestCase {
private PendingContact addPendingContact(
ContactExchangeIntegrationTestComponent local,
ContactExchangeIntegrationTestComponent remote) throws Exception {
EventWaiter waiter = new EventWaiter();
local.getEventBus().addListener(waiter);
String link = remote.getContactManager().getHandshakeLink();
String alias = remote.getIdentityManager().getLocalAuthor().getName();
return local.getContactManager().addPendingContact(link, alias);
PendingContact pendingContact =
local.getContactManager().addPendingContact(link, alias);
waiter.latch.await(TIMEOUT, MILLISECONDS);
return pendingContact;
}
private void assertContacts(boolean verified,
@@ -237,7 +246,7 @@ public class ContactExchangeIntegrationTest extends BrambleTestCase {
assertEquals(1, pairs.size());
Pair<PendingContact, PendingContactState> pair =
pairs.iterator().next();
assertEquals(WAITING_FOR_CONNECTION, pair.getSecond());
assertEquals(OFFLINE, pair.getSecond());
PendingContact pendingContact = pair.getFirst();
assertEquals(expectedIdentity.getLocalAuthor().getName(),
pendingContact.getAlias());
@@ -261,4 +270,19 @@ public class ContactExchangeIntegrationTest extends BrambleTestCase {
tearDown(bob);
deleteTestDirectory(testDir);
}
@NotNullByDefault
private static class EventWaiter implements EventListener {
private final CountDownLatch latch = new CountDownLatch(1);
@Override
public void eventOccurred(Event e) {
if (e instanceof PendingContactStateChangedEvent) {
PendingContactStateChangedEvent p =
(PendingContactStateChangedEvent) e;
if (p.getPendingContactState() == OFFLINE) latch.countDown();
}
}
}
}

View File

@@ -45,6 +45,7 @@ import static java.util.Collections.singletonList;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static org.briarproject.bramble.api.contact.PendingContactState.ADDING_CONTACT;
import static org.briarproject.bramble.api.contact.PendingContactState.FAILED;
import static org.briarproject.bramble.api.contact.PendingContactState.OFFLINE;
import static org.briarproject.bramble.api.contact.PendingContactState.WAITING_FOR_CONNECTION;
import static org.briarproject.bramble.rendezvous.RendezvousConstants.POLLING_INTERVAL_MS;
import static org.briarproject.bramble.rendezvous.RendezvousConstants.RENDEZVOUS_TIMEOUT_MS;
@@ -120,7 +121,7 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
will(returnValue(beforeExpiry));
oneOf(eventBus).broadcast(with(new PredicateMatcher<>(
PendingContactStateChangedEvent.class, e ->
e.getPendingContactState() == WAITING_FOR_CONNECTION)));
e.getPendingContactState() == OFFLINE)));
// Capture the poll task
oneOf(scheduler).scheduleAtFixedRate(with(any(Runnable.class)),
with(POLLING_INTERVAL_MS), with(POLLING_INTERVAL_MS),
@@ -184,7 +185,7 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
context.assertIsSatisfied();
// Add the pending contact - endpoint should be created and polled
expectAddUnexpiredPendingContact(beforeExpiry);
expectAddPendingContact(beforeExpiry, WAITING_FOR_CONNECTION);
expectDeriveRendezvousKey();
expectCreateEndpoint();
@@ -205,9 +206,7 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
context.assertIsSatisfied();
// Remove the pending contact - endpoint should be closed
context.checking(new Expectations() {{
oneOf(rendezvousEndpoint).close();
}});
expectCloseEndpoint();
rendezvousPoller.eventOccurred(
new PendingContactRemovedEvent(pendingContact.getId()));
@@ -238,7 +237,7 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
context.assertIsSatisfied();
// Add the pending contact - endpoint should be created and polled
expectAddUnexpiredPendingContact(beforeExpiry);
expectAddPendingContact(beforeExpiry, WAITING_FOR_CONNECTION);
expectDeriveRendezvousKey();
expectCreateEndpoint();
@@ -260,10 +259,7 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
// Run the poll task - pending contact expires, endpoint is closed
expectPendingContactExpires(afterExpiry);
context.checking(new Expectations() {{
oneOf(rendezvousEndpoint).close();
}});
expectCloseEndpoint();
capturePollTask.get().run();
context.assertIsSatisfied();
@@ -289,7 +285,7 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
context.assertIsSatisfied();
// Add the pending contact - no endpoints should be created yet
expectAddUnexpiredPendingContact(beforeExpiry);
expectAddPendingContact(beforeExpiry, OFFLINE);
expectDeriveRendezvousKey();
rendezvousPoller.eventOccurred(
@@ -299,14 +295,14 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
// Enable the transport - endpoint should be created
expectGetPlugin();
expectCreateEndpoint();
expectStateChangedEvent(WAITING_FOR_CONNECTION);
rendezvousPoller.eventOccurred(new TransportEnabledEvent(transportId));
context.assertIsSatisfied();
// Disable the transport - endpoint should be closed
context.checking(new Expectations() {{
oneOf(rendezvousEndpoint).close();
}});
expectCloseEndpoint();
expectStateChangedEvent(OFFLINE);
rendezvousPoller.eventOccurred(new TransportDisabledEvent(transportId));
context.assertIsSatisfied();
@@ -482,13 +478,14 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
return capturePollTask;
}
private void expectAddUnexpiredPendingContact(long now) {
private void expectAddPendingContact(long now,
PendingContactState initialState) {
context.checking(new Expectations() {{
oneOf(clock).currentTimeMillis();
will(returnValue(now));
oneOf(eventBus).broadcast(with(new PredicateMatcher<>(
PendingContactStateChangedEvent.class, e ->
e.getPendingContactState() == WAITING_FOR_CONNECTION)));
e.getPendingContactState() == initialState)));
}});
}
@@ -546,7 +543,7 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
will(returnValue(now));
oneOf(eventBus).broadcast(with(new PredicateMatcher<>(
PendingContactStateChangedEvent.class, e ->
e.getPendingContactState() == WAITING_FOR_CONNECTION)));
e.getPendingContactState() == OFFLINE)));
// Capture the poll task
oneOf(scheduler).scheduleAtFixedRate(with(any(Runnable.class)),
with(POLLING_INTERVAL_MS), with(POLLING_INTERVAL_MS),
@@ -576,4 +573,10 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
e.getPendingContactState() == state)));
}});
}
private void expectCloseEndpoint() throws Exception {
context.checking(new Expectations() {{
oneOf(rendezvousEndpoint).close();
}});
}
}