mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-17 13:19:52 +01:00
When our mailbox's API versions change, send them to contacts.
This commit is contained in:
@@ -46,7 +46,7 @@ public interface MailboxSettingsManager {
|
|||||||
|
|
||||||
interface MailboxHook {
|
interface MailboxHook {
|
||||||
/**
|
/**
|
||||||
* Called when Briar is paired with a mailbox
|
* Called when Briar is paired with a mailbox.
|
||||||
*
|
*
|
||||||
* @param txn A read-write transaction
|
* @param txn A read-write transaction
|
||||||
*/
|
*/
|
||||||
@@ -54,10 +54,18 @@ public interface MailboxSettingsManager {
|
|||||||
throws DbException;
|
throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the mailbox is unpaired
|
* Called when the mailbox is unpaired.
|
||||||
*
|
*
|
||||||
* @param txn A read-write transaction
|
* @param txn A read-write transaction
|
||||||
*/
|
*/
|
||||||
void mailboxUnpaired(Transaction txn) throws DbException;
|
void mailboxUnpaired(Transaction txn) throws DbException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when we receive our mailbox's server-supported API versions.
|
||||||
|
*
|
||||||
|
* @param txn A read-write transaction
|
||||||
|
*/
|
||||||
|
void serverSupportedVersionsReceived(Transaction txn,
|
||||||
|
List<MailboxVersion> serverSupports) throws DbException;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,6 +79,12 @@ public interface MailboxUpdateManager {
|
|||||||
*/
|
*/
|
||||||
String GROUP_KEY_SENT_CLIENT_SUPPORTS = "sentClientSupports";
|
String GROUP_KEY_SENT_CLIENT_SUPPORTS = "sentClientSupports";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key in the client's local group for storing the serverSupports list that
|
||||||
|
* was last sent out, if any.
|
||||||
|
*/
|
||||||
|
String GROUP_KEY_SENT_SERVER_SUPPORTS = "sentServerSupports";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the latest {@link MailboxUpdate} sent to the given contact.
|
* Returns the latest {@link MailboxUpdate} sent to the given contact.
|
||||||
* <p>
|
* <p>
|
||||||
|
|||||||
@@ -119,6 +119,12 @@ class MailboxSettingsManagerImpl implements MailboxSettingsManager {
|
|||||||
@Override
|
@Override
|
||||||
public void recordSuccessfulConnection(Transaction txn, long now,
|
public void recordSuccessfulConnection(Transaction txn, long now,
|
||||||
List<MailboxVersion> versions) throws DbException {
|
List<MailboxVersion> versions) throws DbException {
|
||||||
|
// if we no longer have a paired mailbox, return
|
||||||
|
Settings oldSettings =
|
||||||
|
settingsManager.getSettings(txn, SETTINGS_NAMESPACE);
|
||||||
|
String onion = oldSettings.get(SETTINGS_KEY_ONION);
|
||||||
|
String token = oldSettings.get(SETTINGS_KEY_TOKEN);
|
||||||
|
if (isNullOrEmpty(onion) || isNullOrEmpty(token)) return;
|
||||||
Settings s = new Settings();
|
Settings s = new Settings();
|
||||||
// record the successful connection
|
// record the successful connection
|
||||||
s.putLong(SETTINGS_KEY_LAST_ATTEMPT, now);
|
s.putLong(SETTINGS_KEY_LAST_ATTEMPT, now);
|
||||||
@@ -126,6 +132,9 @@ class MailboxSettingsManagerImpl implements MailboxSettingsManager {
|
|||||||
s.putInt(SETTINGS_KEY_ATTEMPTS, 0);
|
s.putInt(SETTINGS_KEY_ATTEMPTS, 0);
|
||||||
encodeServerSupports(versions, s);
|
encodeServerSupports(versions, s);
|
||||||
settingsManager.mergeSettings(txn, s, SETTINGS_NAMESPACE);
|
settingsManager.mergeSettings(txn, s, SETTINGS_NAMESPACE);
|
||||||
|
for (MailboxHook hook : hooks) {
|
||||||
|
hook.serverSupportedVersionsReceived(txn, versions);
|
||||||
|
}
|
||||||
// broadcast status event
|
// broadcast status event
|
||||||
MailboxStatus status = new MailboxStatus(now, now, 0, versions);
|
MailboxStatus status = new MailboxStatus(now, now, 0, versions);
|
||||||
txn.attach(new OwnMailboxConnectionStatusEvent(status));
|
txn.attach(new OwnMailboxConnectionStatusEvent(status));
|
||||||
@@ -134,8 +143,12 @@ class MailboxSettingsManagerImpl implements MailboxSettingsManager {
|
|||||||
@Override
|
@Override
|
||||||
public void recordFailedConnectionAttempt(Transaction txn, long now)
|
public void recordFailedConnectionAttempt(Transaction txn, long now)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
|
// if we no longer have a paired mailbox, return
|
||||||
Settings oldSettings =
|
Settings oldSettings =
|
||||||
settingsManager.getSettings(txn, SETTINGS_NAMESPACE);
|
settingsManager.getSettings(txn, SETTINGS_NAMESPACE);
|
||||||
|
String onion = oldSettings.get(SETTINGS_KEY_ONION);
|
||||||
|
String token = oldSettings.get(SETTINGS_KEY_TOKEN);
|
||||||
|
if (isNullOrEmpty(onion) || isNullOrEmpty(token)) return;
|
||||||
int newAttempts = 1 + oldSettings.getInt(SETTINGS_KEY_ATTEMPTS, 0);
|
int newAttempts = 1 + oldSettings.getInt(SETTINGS_KEY_ATTEMPTS, 0);
|
||||||
long lastSuccess = oldSettings.getLong(SETTINGS_KEY_LAST_SUCCESS, 0);
|
long lastSuccess = oldSettings.getLong(SETTINGS_KEY_LAST_SUCCESS, 0);
|
||||||
Settings newSettings = new Settings();
|
Settings newSettings = new Settings();
|
||||||
|
|||||||
@@ -49,6 +49,9 @@ import java.util.Map.Entry;
|
|||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import static java.util.Collections.emptyList;
|
||||||
|
import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE;
|
||||||
|
import static org.briarproject.bramble.api.nullsafety.NullSafety.requireNonNull;
|
||||||
import static org.briarproject.bramble.api.sync.validation.IncomingMessageHook.DeliveryAction.ACCEPT_DO_NOT_SHARE;
|
import static org.briarproject.bramble.api.sync.validation.IncomingMessageHook.DeliveryAction.ACCEPT_DO_NOT_SHARE;
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
@@ -175,6 +178,12 @@ class MailboxUpdateManagerImpl implements MailboxUpdateManager,
|
|||||||
localUpdates.put(c.getId(), u);
|
localUpdates.put(c.getId(), u);
|
||||||
}
|
}
|
||||||
txn.attach(new MailboxPairedEvent(p, localUpdates));
|
txn.attach(new MailboxPairedEvent(p, localUpdates));
|
||||||
|
// Store the list of server-supported versions
|
||||||
|
try {
|
||||||
|
storeSentServerSupports(txn, p.getServerSupports());
|
||||||
|
} catch (FormatException e) {
|
||||||
|
throw new DbException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -185,6 +194,76 @@ class MailboxUpdateManagerImpl implements MailboxUpdateManager,
|
|||||||
localUpdates.put(c.getId(), u);
|
localUpdates.put(c.getId(), u);
|
||||||
}
|
}
|
||||||
txn.attach(new MailboxUnpairedEvent(localUpdates));
|
txn.attach(new MailboxUnpairedEvent(localUpdates));
|
||||||
|
// Remove the list of server-supported versions
|
||||||
|
try {
|
||||||
|
BdfDictionary meta = BdfDictionary.of(new BdfEntry(
|
||||||
|
GROUP_KEY_SENT_SERVER_SUPPORTS, NULL_VALUE));
|
||||||
|
clientHelper.mergeGroupMetadata(txn, localGroup.getId(), meta);
|
||||||
|
} catch (FormatException e) {
|
||||||
|
throw new DbException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void serverSupportedVersionsReceived(Transaction txn,
|
||||||
|
List<MailboxVersion> serverSupports) throws DbException {
|
||||||
|
try {
|
||||||
|
List<MailboxVersion> oldServerSupports =
|
||||||
|
loadSentServerSupports(txn);
|
||||||
|
if (serverSupports.equals(oldServerSupports)) return;
|
||||||
|
storeSentServerSupports(txn, serverSupports);
|
||||||
|
for (Contact c : db.getContacts(txn)) {
|
||||||
|
Group contactGroup = getContactGroup(c);
|
||||||
|
LatestUpdate latest =
|
||||||
|
findLatest(txn, contactGroup.getId(), true);
|
||||||
|
// This method should only be called when we have a mailbox
|
||||||
|
if (latest == null) throw new DbException();
|
||||||
|
BdfList body =
|
||||||
|
clientHelper.getMessageAsList(txn, latest.messageId);
|
||||||
|
MailboxUpdate oldUpdate = parseUpdate(body);
|
||||||
|
if (!oldUpdate.hasMailbox()) throw new DbException();
|
||||||
|
MailboxUpdateWithMailbox newUpdate = updateServerSupports(
|
||||||
|
(MailboxUpdateWithMailbox) oldUpdate, serverSupports);
|
||||||
|
storeMessageReplaceLatest(txn, contactGroup.getId(), newUpdate,
|
||||||
|
latest);
|
||||||
|
}
|
||||||
|
} catch (FormatException e) {
|
||||||
|
throw new DbException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void storeSentServerSupports(Transaction txn,
|
||||||
|
List<MailboxVersion> serverSupports)
|
||||||
|
throws DbException, FormatException {
|
||||||
|
BdfDictionary meta = BdfDictionary.of(new BdfEntry(
|
||||||
|
GROUP_KEY_SENT_SERVER_SUPPORTS,
|
||||||
|
encodeSupportsList(serverSupports)));
|
||||||
|
clientHelper.mergeGroupMetadata(txn, localGroup.getId(), meta);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<MailboxVersion> loadSentServerSupports(Transaction txn)
|
||||||
|
throws DbException, FormatException {
|
||||||
|
BdfDictionary meta = clientHelper.getGroupMetadataAsDictionary(txn,
|
||||||
|
localGroup.getId());
|
||||||
|
BdfList serverSupports =
|
||||||
|
meta.getOptionalList(GROUP_KEY_SENT_SERVER_SUPPORTS);
|
||||||
|
if (serverSupports == null) return emptyList();
|
||||||
|
return clientHelper.parseMailboxVersionList(serverSupports);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a new {@link MailboxUpdateWithMailbox} that updates the list
|
||||||
|
* of server-supported API versions in the given
|
||||||
|
* {@link MailboxUpdateWithMailbox}.
|
||||||
|
*/
|
||||||
|
private MailboxUpdateWithMailbox updateServerSupports(
|
||||||
|
MailboxUpdateWithMailbox old, List<MailboxVersion> serverSupports) {
|
||||||
|
MailboxProperties oldProps = old.getMailboxProperties();
|
||||||
|
MailboxProperties newProps = new MailboxProperties(oldProps.getOnion(),
|
||||||
|
oldProps.getAuthToken(), serverSupports,
|
||||||
|
requireNonNull(oldProps.getInboxId()),
|
||||||
|
requireNonNull(oldProps.getOutboxId()));
|
||||||
|
return new MailboxUpdateWithMailbox(old.getClientSupports(), newProps);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -304,21 +383,27 @@ class MailboxUpdateManagerImpl implements MailboxUpdateManager,
|
|||||||
MailboxUpdate u) throws DbException {
|
MailboxUpdate u) throws DbException {
|
||||||
try {
|
try {
|
||||||
LatestUpdate latest = findLatest(txn, g, true);
|
LatestUpdate latest = findLatest(txn, g, true);
|
||||||
long version = latest == null ? 1 : latest.version + 1;
|
storeMessageReplaceLatest(txn, g, u, latest);
|
||||||
Message m = clientHelper.createMessage(g, clock.currentTimeMillis(),
|
|
||||||
encodeProperties(version, u));
|
|
||||||
BdfDictionary meta = new BdfDictionary();
|
|
||||||
meta.put(MSG_KEY_VERSION, version);
|
|
||||||
meta.put(MSG_KEY_LOCAL, true);
|
|
||||||
clientHelper.addLocalMessage(txn, m, meta, true, false);
|
|
||||||
if (latest != null) {
|
|
||||||
db.removeMessage(txn, latest.messageId);
|
|
||||||
}
|
|
||||||
} catch (FormatException e) {
|
} catch (FormatException e) {
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void storeMessageReplaceLatest(Transaction txn, GroupId g,
|
||||||
|
MailboxUpdate u, @Nullable LatestUpdate latest)
|
||||||
|
throws DbException, FormatException {
|
||||||
|
long version = latest == null ? 1 : latest.version + 1;
|
||||||
|
Message m = clientHelper.createMessage(g, clock.currentTimeMillis(),
|
||||||
|
encodeProperties(version, u));
|
||||||
|
BdfDictionary meta = new BdfDictionary();
|
||||||
|
meta.put(MSG_KEY_VERSION, version);
|
||||||
|
meta.put(MSG_KEY_LOCAL, true);
|
||||||
|
clientHelper.addLocalMessage(txn, m, meta, true, false);
|
||||||
|
if (latest != null) {
|
||||||
|
db.removeMessage(txn, latest.messageId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private LatestUpdate findLatest(Transaction txn, GroupId g, boolean local)
|
private LatestUpdate findLatest(Transaction txn, GroupId g, boolean local)
|
||||||
throws DbException, FormatException {
|
throws DbException, FormatException {
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import static org.briarproject.bramble.mailbox.MailboxSettingsManagerImpl.SETTIN
|
|||||||
import static org.briarproject.bramble.mailbox.MailboxSettingsManagerImpl.SETTINGS_UPLOADS_NAMESPACE;
|
import static org.briarproject.bramble.mailbox.MailboxSettingsManagerImpl.SETTINGS_UPLOADS_NAMESPACE;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getEvent;
|
import static org.briarproject.bramble.test.TestUtils.getEvent;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
||||||
|
import static org.briarproject.bramble.test.TestUtils.hasEvent;
|
||||||
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
@@ -52,6 +53,7 @@ public class MailboxSettingsManagerImplTest extends BrambleMockTestCase {
|
|||||||
private final MailboxProperties properties = new MailboxProperties(onion,
|
private final MailboxProperties properties = new MailboxProperties(onion,
|
||||||
token, serverSupports);
|
token, serverSupports);
|
||||||
private final int[] serverSupportsInts = {1, 0, 1, 1};
|
private final int[] serverSupportsInts = {1, 0, 1, 1};
|
||||||
|
private final Settings pairedSettings;
|
||||||
private final ContactId contactId1 = new ContactId(random.nextInt());
|
private final ContactId contactId1 = new ContactId(random.nextInt());
|
||||||
private final ContactId contactId2 = new ContactId(random.nextInt());
|
private final ContactId contactId2 = new ContactId(random.nextInt());
|
||||||
private final ContactId contactId3 = new ContactId(random.nextInt());
|
private final ContactId contactId3 = new ContactId(random.nextInt());
|
||||||
@@ -60,6 +62,14 @@ public class MailboxSettingsManagerImplTest extends BrambleMockTestCase {
|
|||||||
private final long lastSuccess = now - 2345;
|
private final long lastSuccess = now - 2345;
|
||||||
private final int attempts = 123;
|
private final int attempts = 123;
|
||||||
|
|
||||||
|
public MailboxSettingsManagerImplTest() {
|
||||||
|
pairedSettings = new Settings();
|
||||||
|
pairedSettings.put(SETTINGS_KEY_ONION, onion);
|
||||||
|
pairedSettings.put(SETTINGS_KEY_TOKEN, token.toString());
|
||||||
|
pairedSettings.putIntArray(SETTINGS_KEY_SERVER_SUPPORTS,
|
||||||
|
serverSupportsInts);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReturnsNullPropertiesIfSettingsAreEmpty() throws Exception {
|
public void testReturnsNullPropertiesIfSettingsAreEmpty() throws Exception {
|
||||||
Transaction txn = new Transaction(null, true);
|
Transaction txn = new Transaction(null, true);
|
||||||
@@ -76,14 +86,10 @@ public class MailboxSettingsManagerImplTest extends BrambleMockTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testReturnsProperties() throws Exception {
|
public void testReturnsProperties() throws Exception {
|
||||||
Transaction txn = new Transaction(null, true);
|
Transaction txn = new Transaction(null, true);
|
||||||
Settings settings = new Settings();
|
|
||||||
settings.put(SETTINGS_KEY_ONION, onion);
|
|
||||||
settings.put(SETTINGS_KEY_TOKEN, token.toString());
|
|
||||||
settings.putIntArray(SETTINGS_KEY_SERVER_SUPPORTS, serverSupportsInts);
|
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
oneOf(settingsManager).getSettings(txn, SETTINGS_NAMESPACE);
|
oneOf(settingsManager).getSettings(txn, SETTINGS_NAMESPACE);
|
||||||
will(returnValue(settings));
|
will(returnValue(pairedSettings));
|
||||||
}});
|
}});
|
||||||
|
|
||||||
MailboxProperties properties = manager.getOwnMailboxProperties(txn);
|
MailboxProperties properties = manager.getOwnMailboxProperties(txn);
|
||||||
@@ -97,16 +103,11 @@ public class MailboxSettingsManagerImplTest extends BrambleMockTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testStoresProperties() throws Exception {
|
public void testStoresProperties() throws Exception {
|
||||||
Transaction txn = new Transaction(null, false);
|
Transaction txn = new Transaction(null, false);
|
||||||
Settings expectedSettings = new Settings();
|
|
||||||
expectedSettings.put(SETTINGS_KEY_ONION, onion);
|
|
||||||
expectedSettings.put(SETTINGS_KEY_TOKEN, token.toString());
|
|
||||||
expectedSettings.putIntArray(SETTINGS_KEY_SERVER_SUPPORTS,
|
|
||||||
serverSupportsInts);
|
|
||||||
|
|
||||||
manager.registerMailboxHook(hook);
|
manager.registerMailboxHook(hook);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
oneOf(settingsManager).mergeSettings(txn, expectedSettings,
|
oneOf(settingsManager).mergeSettings(txn, pairedSettings,
|
||||||
SETTINGS_NAMESPACE);
|
SETTINGS_NAMESPACE);
|
||||||
oneOf(hook).mailboxPaired(txn, properties);
|
oneOf(hook).mailboxPaired(txn, properties);
|
||||||
}});
|
}});
|
||||||
@@ -182,6 +183,8 @@ public class MailboxSettingsManagerImplTest extends BrambleMockTestCase {
|
|||||||
serverSupportsInts);
|
serverSupportsInts);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
|
oneOf(settingsManager).getSettings(txn, SETTINGS_NAMESPACE);
|
||||||
|
will(returnValue(pairedSettings));
|
||||||
oneOf(settingsManager).mergeSettings(txn, expectedSettings,
|
oneOf(settingsManager).mergeSettings(txn, expectedSettings,
|
||||||
SETTINGS_NAMESPACE);
|
SETTINGS_NAMESPACE);
|
||||||
}});
|
}});
|
||||||
@@ -196,22 +199,36 @@ public class MailboxSettingsManagerImplTest extends BrambleMockTestCase {
|
|||||||
assertFalse(status.hasProblem(now));
|
assertFalse(status.hasProblem(now));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDoesNotRecordSuccessIfNotPaired() throws Exception {
|
||||||
|
Transaction txn = new Transaction(null, false);
|
||||||
|
|
||||||
|
context.checking(new Expectations() {{
|
||||||
|
oneOf(settingsManager).getSettings(txn, SETTINGS_NAMESPACE);
|
||||||
|
will(returnValue(new Settings()));
|
||||||
|
}});
|
||||||
|
|
||||||
|
manager.recordSuccessfulConnection(txn, now, serverSupports);
|
||||||
|
assertFalse(hasEvent(txn, OwnMailboxConnectionStatusEvent.class));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRecordsFailureOnFirstAttempt() throws Exception {
|
public void testRecordsFailureOnFirstAttempt() throws Exception {
|
||||||
testRecordsFailure(new Settings(), 0);
|
testRecordsFailure(pairedSettings, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRecordsFailureOnLaterAttempt() throws Exception {
|
public void testRecordsFailureOnLaterAttempt() throws Exception {
|
||||||
Settings oldSettings = new Settings();
|
Settings oldSettings = new Settings();
|
||||||
|
oldSettings.putAll(pairedSettings);
|
||||||
oldSettings.putLong(SETTINGS_KEY_LAST_ATTEMPT, lastAttempt);
|
oldSettings.putLong(SETTINGS_KEY_LAST_ATTEMPT, lastAttempt);
|
||||||
oldSettings.putLong(SETTINGS_KEY_LAST_SUCCESS, lastSuccess);
|
oldSettings.putLong(SETTINGS_KEY_LAST_SUCCESS, lastSuccess);
|
||||||
oldSettings.putInt(SETTINGS_KEY_ATTEMPTS, attempts);
|
oldSettings.putInt(SETTINGS_KEY_ATTEMPTS, attempts);
|
||||||
testRecordsFailure(oldSettings, attempts);
|
testRecordsFailure(oldSettings, attempts, lastSuccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void testRecordsFailure(Settings oldSettings, int oldAttempts)
|
private void testRecordsFailure(Settings oldSettings, int oldAttempts,
|
||||||
throws Exception {
|
long lastSuccess) throws Exception {
|
||||||
Transaction txn = new Transaction(null, false);
|
Transaction txn = new Transaction(null, false);
|
||||||
Settings expectedSettings = new Settings();
|
Settings expectedSettings = new Settings();
|
||||||
expectedSettings.putLong(SETTINGS_KEY_LAST_ATTEMPT, now);
|
expectedSettings.putLong(SETTINGS_KEY_LAST_ATTEMPT, now);
|
||||||
@@ -225,6 +242,25 @@ public class MailboxSettingsManagerImplTest extends BrambleMockTestCase {
|
|||||||
}});
|
}});
|
||||||
|
|
||||||
manager.recordFailedConnectionAttempt(txn, now);
|
manager.recordFailedConnectionAttempt(txn, now);
|
||||||
|
OwnMailboxConnectionStatusEvent e =
|
||||||
|
getEvent(txn, OwnMailboxConnectionStatusEvent.class);
|
||||||
|
MailboxStatus status = e.getStatus();
|
||||||
|
assertEquals(now, status.getTimeOfLastAttempt());
|
||||||
|
assertEquals(lastSuccess, status.getTimeOfLastSuccess());
|
||||||
|
assertEquals(oldAttempts + 1, status.getAttemptsSinceSuccess());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDoesNotRecordFailureIfNotPaired() throws Exception {
|
||||||
|
Transaction txn = new Transaction(null, false);
|
||||||
|
|
||||||
|
context.checking(new Expectations() {{
|
||||||
|
oneOf(settingsManager).getSettings(txn, SETTINGS_NAMESPACE);
|
||||||
|
will(returnValue(new Settings()));
|
||||||
|
}});
|
||||||
|
|
||||||
|
manager.recordFailedConnectionAttempt(txn, now);
|
||||||
|
assertFalse(hasEvent(txn, OwnMailboxConnectionStatusEvent.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -38,8 +38,10 @@ import java.util.Random;
|
|||||||
|
|
||||||
import static java.util.Collections.singleton;
|
import static java.util.Collections.singleton;
|
||||||
import static java.util.Collections.singletonList;
|
import static java.util.Collections.singletonList;
|
||||||
|
import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE;
|
||||||
import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.CLIENT_ID;
|
import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.CLIENT_ID;
|
||||||
import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.GROUP_KEY_SENT_CLIENT_SUPPORTS;
|
import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.GROUP_KEY_SENT_CLIENT_SUPPORTS;
|
||||||
|
import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.GROUP_KEY_SENT_SERVER_SUPPORTS;
|
||||||
import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.MAJOR_VERSION;
|
import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.MAJOR_VERSION;
|
||||||
import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.MSG_KEY_LOCAL;
|
import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.MSG_KEY_LOCAL;
|
||||||
import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.MSG_KEY_VERSION;
|
import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.MSG_KEY_VERSION;
|
||||||
@@ -89,7 +91,10 @@ public class MailboxUpdateManagerImplTest extends BrambleMockTestCase {
|
|||||||
private final BdfList someClientSupports;
|
private final BdfList someClientSupports;
|
||||||
private final List<MailboxVersion> newerClientSupportsList;
|
private final List<MailboxVersion> newerClientSupportsList;
|
||||||
private final BdfList newerClientSupports;
|
private final BdfList newerClientSupports;
|
||||||
|
private final List<MailboxVersion> someServerSupportsList;
|
||||||
private final BdfList someServerSupports;
|
private final BdfList someServerSupports;
|
||||||
|
private final List<MailboxVersion> newerServerSupportsList;
|
||||||
|
private final BdfList newerServerSupports;
|
||||||
private final BdfList emptyServerSupports = new BdfList();
|
private final BdfList emptyServerSupports = new BdfList();
|
||||||
private final MailboxProperties updateProps;
|
private final MailboxProperties updateProps;
|
||||||
private final MailboxUpdateWithMailbox updateWithMailbox;
|
private final MailboxUpdateWithMailbox updateWithMailbox;
|
||||||
@@ -110,11 +115,17 @@ public class MailboxUpdateManagerImplTest extends BrambleMockTestCase {
|
|||||||
newerClientSupportsList.get(0).getMajor(),
|
newerClientSupportsList.get(0).getMajor(),
|
||||||
newerClientSupportsList.get(0).getMinor()));
|
newerClientSupportsList.get(0).getMinor()));
|
||||||
|
|
||||||
List<MailboxVersion> someServerSupportsList =
|
someServerSupportsList = singletonList(new MailboxVersion(
|
||||||
singletonList(new MailboxVersion(rnd.nextInt(), rnd.nextInt()));
|
rnd.nextInt(), rnd.nextInt()));
|
||||||
someServerSupports = BdfList.of(BdfList.of(
|
someServerSupports = BdfList.of(BdfList.of(
|
||||||
someServerSupportsList.get(0).getMajor(),
|
someServerSupportsList.get(0).getMajor(),
|
||||||
someServerSupportsList.get(0).getMinor()));
|
someServerSupportsList.get(0).getMinor()));
|
||||||
|
newerServerSupportsList = singletonList(new MailboxVersion(
|
||||||
|
someServerSupportsList.get(0).getMajor(),
|
||||||
|
someServerSupportsList.get(0).getMinor() + 1));
|
||||||
|
newerServerSupports = BdfList.of(BdfList.of(
|
||||||
|
newerServerSupportsList.get(0).getMajor(),
|
||||||
|
newerServerSupportsList.get(0).getMinor()));
|
||||||
|
|
||||||
updateNoMailbox = new MailboxUpdate(someClientSupportsList);
|
updateNoMailbox = new MailboxUpdate(someClientSupportsList);
|
||||||
|
|
||||||
@@ -687,25 +698,33 @@ public class MailboxUpdateManagerImplTest extends BrambleMockTestCase {
|
|||||||
new BdfEntry(MSG_KEY_VERSION, 3),
|
new BdfEntry(MSG_KEY_VERSION, 3),
|
||||||
new BdfEntry(MSG_KEY_LOCAL, false)
|
new BdfEntry(MSG_KEY_LOCAL, false)
|
||||||
));
|
));
|
||||||
|
BdfDictionary groupMetadata = new BdfDictionary();
|
||||||
|
groupMetadata.put(GROUP_KEY_SENT_SERVER_SUPPORTS, someServerSupports);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
oneOf(db).getContacts(txn);
|
oneOf(db).getContacts(txn);
|
||||||
will(returnValue(contacts));
|
will(returnValue(contacts));
|
||||||
|
// Generate mailbox properties for contact
|
||||||
oneOf(crypto).generateUniqueId();
|
oneOf(crypto).generateUniqueId();
|
||||||
will(returnValue(updateProps.getAuthToken()));
|
will(returnValue(updateProps.getAuthToken()));
|
||||||
oneOf(crypto).generateUniqueId();
|
oneOf(crypto).generateUniqueId();
|
||||||
will(returnValue(updateProps.getInboxId()));
|
will(returnValue(updateProps.getInboxId()));
|
||||||
oneOf(crypto).generateUniqueId();
|
oneOf(crypto).generateUniqueId();
|
||||||
will(returnValue(updateProps.getOutboxId()));
|
will(returnValue(updateProps.getOutboxId()));
|
||||||
|
// Find latest update
|
||||||
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
|
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
|
||||||
MAJOR_VERSION, contact);
|
MAJOR_VERSION, contact);
|
||||||
will(returnValue(contactGroup));
|
will(returnValue(contactGroup));
|
||||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
||||||
contactGroupId);
|
contactGroupId);
|
||||||
will(returnValue(messageMetadata));
|
will(returnValue(messageMetadata));
|
||||||
|
// Replace latest update with new update
|
||||||
expectStoreMessage(txn, contactGroupId, 2, someClientSupports,
|
expectStoreMessage(txn, contactGroupId, 2, someClientSupports,
|
||||||
someServerSupports, propsDict);
|
someServerSupports, propsDict);
|
||||||
oneOf(db).removeMessage(txn, latestId);
|
oneOf(db).removeMessage(txn, latestId);
|
||||||
|
// Store sent server-supported versions
|
||||||
|
oneOf(clientHelper).mergeGroupMetadata(txn, localGroup.getId(),
|
||||||
|
groupMetadata);
|
||||||
}});
|
}});
|
||||||
|
|
||||||
MailboxUpdateManagerImpl t = createInstance(someClientSupportsList);
|
MailboxUpdateManagerImpl t = createInstance(someClientSupportsList);
|
||||||
@@ -741,19 +760,26 @@ public class MailboxUpdateManagerImplTest extends BrambleMockTestCase {
|
|||||||
new BdfEntry(MSG_KEY_VERSION, 3),
|
new BdfEntry(MSG_KEY_VERSION, 3),
|
||||||
new BdfEntry(MSG_KEY_LOCAL, false)
|
new BdfEntry(MSG_KEY_LOCAL, false)
|
||||||
));
|
));
|
||||||
|
BdfDictionary groupMetadata = new BdfDictionary();
|
||||||
|
groupMetadata.put(GROUP_KEY_SENT_SERVER_SUPPORTS, NULL_VALUE);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
oneOf(db).getContacts(txn);
|
oneOf(db).getContacts(txn);
|
||||||
will(returnValue(contacts));
|
will(returnValue(contacts));
|
||||||
|
// Find latest update
|
||||||
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
|
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
|
||||||
MAJOR_VERSION, contact);
|
MAJOR_VERSION, contact);
|
||||||
will(returnValue(contactGroup));
|
will(returnValue(contactGroup));
|
||||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
||||||
contactGroupId);
|
contactGroupId);
|
||||||
will(returnValue(messageMetadata));
|
will(returnValue(messageMetadata));
|
||||||
|
// Replace latest update with new update
|
||||||
expectStoreMessage(txn, contactGroupId, 2, someClientSupports,
|
expectStoreMessage(txn, contactGroupId, 2, someClientSupports,
|
||||||
emptyServerSupports, emptyPropsDict);
|
emptyServerSupports, emptyPropsDict);
|
||||||
oneOf(db).removeMessage(txn, latestId);
|
oneOf(db).removeMessage(txn, latestId);
|
||||||
|
// Remove sent server-supported versions
|
||||||
|
oneOf(clientHelper).mergeGroupMetadata(txn, localGroup.getId(),
|
||||||
|
groupMetadata);
|
||||||
}});
|
}});
|
||||||
|
|
||||||
MailboxUpdateManagerImpl t = createInstance(someClientSupportsList);
|
MailboxUpdateManagerImpl t = createInstance(someClientSupportsList);
|
||||||
@@ -768,6 +794,80 @@ public class MailboxUpdateManagerImplTest extends BrambleMockTestCase {
|
|||||||
assertFalse(hasEvent(txn, MailboxUpdateSentEvent.class));
|
assertFalse(hasEvent(txn, MailboxUpdateSentEvent.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStoresLocalUpdateWhenServerSupportsChange()
|
||||||
|
throws Exception {
|
||||||
|
Transaction txn = new Transaction(null, false);
|
||||||
|
Map<MessageId, BdfDictionary> messageMetadata = new LinkedHashMap<>();
|
||||||
|
MessageId latestId = new MessageId(getRandomId());
|
||||||
|
messageMetadata.put(latestId, BdfDictionary.of(
|
||||||
|
new BdfEntry(MSG_KEY_VERSION, 1),
|
||||||
|
new BdfEntry(MSG_KEY_LOCAL, true)
|
||||||
|
));
|
||||||
|
BdfList body = BdfList.of(1, someClientSupports, someServerSupports,
|
||||||
|
propsDict);
|
||||||
|
BdfDictionary oldGroupMetadata = new BdfDictionary();
|
||||||
|
oldGroupMetadata.put(GROUP_KEY_SENT_SERVER_SUPPORTS,
|
||||||
|
someServerSupports);
|
||||||
|
BdfDictionary newGroupMetadata = new BdfDictionary();
|
||||||
|
newGroupMetadata.put(GROUP_KEY_SENT_SERVER_SUPPORTS,
|
||||||
|
newerServerSupports);
|
||||||
|
|
||||||
|
context.checking(new Expectations() {{
|
||||||
|
// Load sent server-supported versions
|
||||||
|
oneOf(clientHelper).getGroupMetadataAsDictionary(txn,
|
||||||
|
localGroup.getId());
|
||||||
|
will(returnValue(oldGroupMetadata));
|
||||||
|
oneOf(clientHelper).parseMailboxVersionList(someServerSupports);
|
||||||
|
will(returnValue(someServerSupportsList));
|
||||||
|
// Update sent server-supported versions
|
||||||
|
oneOf(clientHelper).mergeGroupMetadata(txn, localGroup.getId(),
|
||||||
|
newGroupMetadata);
|
||||||
|
oneOf(db).getContacts(txn);
|
||||||
|
will(returnValue(contacts));
|
||||||
|
// Find latest update
|
||||||
|
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
|
||||||
|
MAJOR_VERSION, contact);
|
||||||
|
will(returnValue(contactGroup));
|
||||||
|
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
||||||
|
contactGroupId);
|
||||||
|
will(returnValue(messageMetadata));
|
||||||
|
// Load and parse latest update
|
||||||
|
oneOf(clientHelper).getMessageAsList(txn, latestId);
|
||||||
|
will(returnValue(body));
|
||||||
|
oneOf(clientHelper).parseAndValidateMailboxUpdate(
|
||||||
|
someClientSupports, someServerSupports, propsDict);
|
||||||
|
will(returnValue(updateWithMailbox));
|
||||||
|
// Replace latest update with new update
|
||||||
|
expectStoreMessage(txn, contactGroupId, 2, someClientSupports,
|
||||||
|
newerServerSupports, propsDict);
|
||||||
|
oneOf(db).removeMessage(txn, latestId);
|
||||||
|
}});
|
||||||
|
|
||||||
|
MailboxUpdateManagerImpl t = createInstance(someClientSupportsList);
|
||||||
|
t.serverSupportedVersionsReceived(txn, newerServerSupportsList);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDoesNotStoreLocalUpdateWhenServerSupportsAreUnchanged()
|
||||||
|
throws Exception {
|
||||||
|
Transaction txn = new Transaction(null, false);
|
||||||
|
BdfDictionary groupMetadata = new BdfDictionary();
|
||||||
|
groupMetadata.put(GROUP_KEY_SENT_SERVER_SUPPORTS, someServerSupports);
|
||||||
|
|
||||||
|
context.checking(new Expectations() {{
|
||||||
|
// Load sent server-supported versions
|
||||||
|
oneOf(clientHelper).getGroupMetadataAsDictionary(txn,
|
||||||
|
localGroup.getId());
|
||||||
|
will(returnValue(groupMetadata));
|
||||||
|
oneOf(clientHelper).parseMailboxVersionList(someServerSupports);
|
||||||
|
will(returnValue(someServerSupportsList));
|
||||||
|
}});
|
||||||
|
|
||||||
|
MailboxUpdateManagerImpl t = createInstance(someClientSupportsList);
|
||||||
|
t.serverSupportedVersionsReceived(txn, someServerSupportsList);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetRemoteUpdate() throws Exception {
|
public void testGetRemoteUpdate() throws Exception {
|
||||||
Transaction txn = new Transaction(null, false);
|
Transaction txn = new Transaction(null, false);
|
||||||
|
|||||||
Reference in New Issue
Block a user