diff --git a/bramble-api/src/test/java/org/briarproject/bramble/test/TestUtils.java b/bramble-api/src/test/java/org/briarproject/bramble/test/TestUtils.java index d33304dd0..4c4d77ae6 100644 --- a/bramble-api/src/test/java/org/briarproject/bramble/test/TestUtils.java +++ b/bramble-api/src/test/java/org/briarproject/bramble/test/TestUtils.java @@ -1,6 +1,8 @@ package org.briarproject.bramble.test; import org.briarproject.bramble.api.UniqueId; +import org.briarproject.bramble.api.contact.PendingContact; +import org.briarproject.bramble.api.contact.PendingContactId; import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.AuthorId; @@ -25,6 +27,7 @@ import java.util.Random; import java.util.concurrent.atomic.AtomicInteger; import static java.util.Arrays.asList; +import static org.briarproject.bramble.api.contact.PendingContactState.WAITING_FOR_CONNECTION; import static org.briarproject.bramble.api.identity.Author.FORMAT_VERSION; import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH; import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH; @@ -140,6 +143,16 @@ public class TestUtils { return new Message(id, groupId, timestamp, body); } + public static PendingContact getPendingContact() { + return getPendingContact(1 + random.nextInt(MAX_AUTHOR_NAME_LENGTH)); + } + + public static PendingContact getPendingContact(int nameLength) { + PendingContactId id = new PendingContactId(getRandomId()); + String alias = getRandomString(nameLength); + return new PendingContact(id, alias, WAITING_FOR_CONNECTION, timestamp); + } + public static double getMedian(Collection samples) { int size = samples.size(); if (size == 0) throw new IllegalArgumentException(); diff --git a/bramble-core/src/test/java/org/briarproject/bramble/db/JdbcDatabaseTest.java b/bramble-core/src/test/java/org/briarproject/bramble/db/JdbcDatabaseTest.java index 0fe39b79b..a37c6fb94 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/db/JdbcDatabaseTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/db/JdbcDatabaseTest.java @@ -2,6 +2,7 @@ package org.briarproject.bramble.db; import org.briarproject.bramble.api.contact.Contact; import org.briarproject.bramble.api.contact.ContactId; +import org.briarproject.bramble.api.contact.PendingContact; import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.db.DatabaseConfig; import org.briarproject.bramble.api.db.DbException; @@ -55,6 +56,7 @@ import static java.util.Collections.emptyMap; import static java.util.Collections.singletonList; import static java.util.Collections.singletonMap; import static java.util.concurrent.TimeUnit.SECONDS; +import static org.briarproject.bramble.api.contact.PendingContactState.FAILED; import static org.briarproject.bramble.api.db.Metadata.REMOVE; import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH; import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE; @@ -73,6 +75,7 @@ import static org.briarproject.bramble.test.TestUtils.getClientId; import static org.briarproject.bramble.test.TestUtils.getGroup; import static org.briarproject.bramble.test.TestUtils.getLocalAuthor; import static org.briarproject.bramble.test.TestUtils.getMessage; +import static org.briarproject.bramble.test.TestUtils.getPendingContact; import static org.briarproject.bramble.test.TestUtils.getRandomId; import static org.briarproject.bramble.test.TestUtils.getSecretKey; import static org.briarproject.bramble.test.TestUtils.getTestDirectory; @@ -107,6 +110,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { private final ContactId contactId; private final TransportKeySetId keySetId, keySetId1; private final StaticTransportKeySetId staticKeySetId, staticKeySetId1; + private final PendingContact pendingContact; private final Random random = new Random(); JdbcDatabaseTest() { @@ -124,6 +128,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { keySetId1 = new TransportKeySetId(2); staticKeySetId = new StaticTransportKeySetId(1); staticKeySetId1 = new StaticTransportKeySetId(2); + pendingContact = getPendingContact(); } protected abstract JdbcDatabase createDatabase(DatabaseConfig config, @@ -788,6 +793,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { assertEquals(2, allKeys.size()); for (StaticTransportKeySet ks : allKeys) { assertEquals(contactId, ks.getContactId()); + assertNull(ks.getPendingContactId()); if (ks.getKeySetId().equals(staticKeySetId)) { assertKeysEquals(keys, ks.getKeys()); } else { @@ -811,6 +817,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { assertEquals(2, allKeys.size()); for (StaticTransportKeySet ks : allKeys) { assertEquals(contactId, ks.getContactId()); + assertNull(ks.getPendingContactId()); if (ks.getKeySetId().equals(staticKeySetId)) { assertKeysEquals(updated, ks.getKeys()); } else { @@ -844,6 +851,78 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { actual.getCurrentOutgoingKeys()); } + @Test + public void testStaticTransportKeysForPendingContact() throws Exception { + long timePeriod = 123, timePeriod1 = 234; + boolean alice = random.nextBoolean(); + SecretKey rootKey = getSecretKey(); + SecretKey rootKey1 = getSecretKey(); + StaticTransportKeys keys = + createStaticTransportKeys(timePeriod, rootKey, alice); + StaticTransportKeys keys1 = + createStaticTransportKeys(timePeriod1, rootKey1, alice); + + Database db = open(false); + Connection txn = db.startTransaction(); + + // Initially there should be no static transport keys in the database + assertEquals(emptyList(), db.getStaticTransportKeys(txn, transportId)); + + // Add the pending contact, the transport and the static transport keys + db.addPendingContact(txn, pendingContact); + db.addTransport(txn, transportId, 123); + assertEquals(staticKeySetId, + db.addStaticTransportKeys(txn, pendingContact.getId(), keys)); + assertEquals(staticKeySetId1, + db.addStaticTransportKeys(txn, pendingContact.getId(), keys1)); + + // Retrieve the static transport keys + Collection allKeys = + db.getStaticTransportKeys(txn, transportId); + assertEquals(2, allKeys.size()); + for (StaticTransportKeySet ks : allKeys) { + assertNull(ks.getContactId()); + assertEquals(pendingContact.getId(), ks.getPendingContactId()); + if (ks.getKeySetId().equals(staticKeySetId)) { + assertKeysEquals(keys, ks.getKeys()); + } else { + assertEquals(staticKeySetId1, ks.getKeySetId()); + assertKeysEquals(keys1, ks.getKeys()); + } + } + + // Update the transport keys + StaticTransportKeys updated = + createStaticTransportKeys(timePeriod + 1, rootKey, alice); + StaticTransportKeys updated1 = + createStaticTransportKeys(timePeriod1 + 1, rootKey1, alice); + db.updateStaticTransportKeys(txn, new StaticTransportKeySet( + staticKeySetId, pendingContact.getId(), updated)); + db.updateStaticTransportKeys(txn, new StaticTransportKeySet( + staticKeySetId1, pendingContact.getId(), updated1)); + + // Retrieve the static transport keys again + allKeys = db.getStaticTransportKeys(txn, transportId); + assertEquals(2, allKeys.size()); + for (StaticTransportKeySet ks : allKeys) { + assertNull(ks.getContactId()); + assertEquals(pendingContact.getId(), ks.getPendingContactId()); + if (ks.getKeySetId().equals(staticKeySetId)) { + assertKeysEquals(updated, ks.getKeys()); + } else { + assertEquals(staticKeySetId1, ks.getKeySetId()); + assertKeysEquals(updated1, ks.getKeys()); + } + } + + // Removing the pending contact should remove the static transport keys + db.removePendingContact(txn, pendingContact.getId()); + assertEquals(emptyList(), db.getStaticTransportKeys(txn, transportId)); + + db.commitTransaction(txn); + db.close(); + } + @Test public void testIncrementStreamCounter() throws Exception { long timePeriod = 123; @@ -2163,6 +2242,39 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { db.close(); } + @Test + public void testPendingContacts() throws Exception { + Database db = open(false); + Connection txn = db.startTransaction(); + + assertEquals(emptyList(), db.getPendingContacts(txn)); + + db.addPendingContact(txn, pendingContact); + Collection pendingContacts = + db.getPendingContacts(txn); + assertEquals(1, pendingContacts.size()); + PendingContact retrieved = pendingContacts.iterator().next(); + assertEquals(pendingContact.getId(), retrieved.getId()); + assertEquals(pendingContact.getAlias(), retrieved.getAlias()); + assertEquals(pendingContact.getState(), retrieved.getState()); + assertEquals(pendingContact.getTimestamp(), retrieved.getTimestamp()); + + db.setPendingContactState(txn, pendingContact.getId(), FAILED); + pendingContacts = db.getPendingContacts(txn); + assertEquals(1, pendingContacts.size()); + retrieved = pendingContacts.iterator().next(); + assertEquals(pendingContact.getId(), retrieved.getId()); + assertEquals(pendingContact.getAlias(), retrieved.getAlias()); + assertEquals(FAILED, retrieved.getState()); + assertEquals(pendingContact.getTimestamp(), retrieved.getTimestamp()); + + db.removePendingContact(txn, pendingContact.getId()); + assertEquals(emptyList(), db.getPendingContacts(txn)); + + db.commitTransaction(txn); + db.close(); + } + private Database open(boolean resume) throws Exception { return open(resume, new TestMessageFactory(), new SystemClock()); }