mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-13 03:09:04 +01:00
Refactor ValidationManager and fix some bugs. #619
This commit is contained in:
@@ -292,7 +292,7 @@ public class BlogManagerImplTest extends BriarTestCase {
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn));
|
||||
oneOf(clientHelper)
|
||||
.addLocalMessage(txn, message, CLIENT_ID, meta, true);
|
||||
.addLocalMessage(txn, message, meta, true);
|
||||
oneOf(identityManager)
|
||||
.getAuthorStatus(txn, blog1.getAuthor().getId());
|
||||
will(returnValue(VERIFIED));
|
||||
|
||||
@@ -16,11 +16,11 @@ import org.briarproject.api.sync.ClientId;
|
||||
import org.briarproject.api.sync.Group;
|
||||
import org.briarproject.api.sync.GroupId;
|
||||
import org.briarproject.api.sync.Message;
|
||||
import org.briarproject.api.sync.MessageContext;
|
||||
import org.briarproject.api.sync.MessageId;
|
||||
import org.briarproject.api.sync.ValidationManager;
|
||||
import org.briarproject.api.sync.ValidationManager.IncomingMessageHook;
|
||||
import org.briarproject.api.sync.ValidationManager.MessageValidator;
|
||||
import org.briarproject.api.sync.MessageContext;
|
||||
import org.briarproject.util.ByteUtils;
|
||||
import org.hamcrest.Description;
|
||||
import org.jmock.Expectations;
|
||||
@@ -77,7 +77,7 @@ public class MessageQueueManagerImplTest extends BriarTestCase {
|
||||
body);
|
||||
will(new CreateMessageAction());
|
||||
oneOf(db).addLocalMessage(with(txn), with(any(QueueMessage.class)),
|
||||
with(clientId), with(messageMetadata), with(true));
|
||||
with(messageMetadata), with(true));
|
||||
// Second message: queue state exists
|
||||
oneOf(db).getGroupMetadata(txn, groupId);
|
||||
will(returnValue(groupMetadata1));
|
||||
@@ -91,7 +91,7 @@ public class MessageQueueManagerImplTest extends BriarTestCase {
|
||||
body);
|
||||
will(new CreateMessageAction());
|
||||
oneOf(db).addLocalMessage(with(txn), with(any(QueueMessage.class)),
|
||||
with(clientId), with(messageMetadata), with(true));
|
||||
with(messageMetadata), with(true));
|
||||
}});
|
||||
|
||||
MessageQueueManagerImpl mqm = new MessageQueueManagerImpl(db,
|
||||
|
||||
@@ -27,9 +27,9 @@ import org.briarproject.api.event.LocalAuthorRemovedEvent;
|
||||
import org.briarproject.api.event.MessageAddedEvent;
|
||||
import org.briarproject.api.event.MessageRequestedEvent;
|
||||
import org.briarproject.api.event.MessageSharedEvent;
|
||||
import org.briarproject.api.event.MessageStateChangedEvent;
|
||||
import org.briarproject.api.event.MessageToAckEvent;
|
||||
import org.briarproject.api.event.MessageToRequestEvent;
|
||||
import org.briarproject.api.event.MessageStateChangedEvent;
|
||||
import org.briarproject.api.event.MessagesAckedEvent;
|
||||
import org.briarproject.api.event.MessagesSentEvent;
|
||||
import org.briarproject.api.event.SettingsUpdatedEvent;
|
||||
@@ -62,7 +62,6 @@ import java.util.Map;
|
||||
import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
||||
import static org.briarproject.api.sync.ValidationManager.State.DELIVERED;
|
||||
import static org.briarproject.api.sync.ValidationManager.State.UNKNOWN;
|
||||
import static org.briarproject.api.sync.ValidationManager.State.VALID;
|
||||
import static org.briarproject.api.transport.TransportConstants.REORDERING_WINDOW_SIZE;
|
||||
import static org.briarproject.db.DatabaseConstants.MAX_OFFERED_MESSAGES;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
@@ -241,7 +240,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
|
||||
|
||||
Transaction transaction = db.startTransaction(false);
|
||||
try {
|
||||
db.addLocalMessage(transaction, message, clientId, metadata, true);
|
||||
db.addLocalMessage(transaction, message, metadata, true);
|
||||
fail();
|
||||
} catch (NoSuchGroupException expected) {
|
||||
// Expected
|
||||
@@ -284,7 +283,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
|
||||
|
||||
Transaction transaction = db.startTransaction(false);
|
||||
try {
|
||||
db.addLocalMessage(transaction, message, clientId, metadata, true);
|
||||
db.addLocalMessage(transaction, message, metadata, true);
|
||||
transaction.setComplete();
|
||||
} finally {
|
||||
db.endTransaction(transaction);
|
||||
@@ -677,11 +676,11 @@ public class DatabaseComponentImplTest extends BriarTestCase {
|
||||
final EventBus eventBus = context.mock(EventBus.class);
|
||||
context.checking(new Expectations() {{
|
||||
// Check whether the message is in the DB (which it's not)
|
||||
exactly(10).of(database).startTransaction();
|
||||
exactly(11).of(database).startTransaction();
|
||||
will(returnValue(txn));
|
||||
exactly(10).of(database).containsMessage(txn, messageId);
|
||||
exactly(11).of(database).containsMessage(txn, messageId);
|
||||
will(returnValue(false));
|
||||
exactly(10).of(database).abortTransaction(txn);
|
||||
exactly(11).of(database).abortTransaction(txn);
|
||||
// This is needed for getMessageStatus() to proceed
|
||||
exactly(1).of(database).containsContact(txn, contactId);
|
||||
will(returnValue(true));
|
||||
@@ -729,6 +728,16 @@ public class DatabaseComponentImplTest extends BriarTestCase {
|
||||
db.endTransaction(transaction);
|
||||
}
|
||||
|
||||
transaction = db.startTransaction(false);
|
||||
try {
|
||||
db.getMessageState(transaction, messageId);
|
||||
fail();
|
||||
} catch (NoSuchMessageException expected) {
|
||||
// Expected
|
||||
} finally {
|
||||
db.endTransaction(transaction);
|
||||
}
|
||||
|
||||
transaction = db.startTransaction(false);
|
||||
try {
|
||||
db.getMessageStatus(transaction, contactId, messageId);
|
||||
@@ -761,7 +770,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
|
||||
|
||||
transaction = db.startTransaction(false);
|
||||
try {
|
||||
db.setMessageState(transaction, message, clientId, VALID);
|
||||
db.setMessageState(transaction, messageId, DELIVERED);
|
||||
fail();
|
||||
} catch (NoSuchMessageException expected) {
|
||||
// Expected
|
||||
@@ -1652,8 +1661,10 @@ public class DatabaseComponentImplTest extends BriarTestCase {
|
||||
// addMessageDependencies()
|
||||
oneOf(database).containsMessage(txn, messageId);
|
||||
will(returnValue(true));
|
||||
oneOf(database).addMessageDependency(txn, messageId, messageId1);
|
||||
oneOf(database).addMessageDependency(txn, messageId, messageId2);
|
||||
oneOf(database).addMessageDependency(txn, groupId, messageId,
|
||||
messageId1);
|
||||
oneOf(database).addMessageDependency(txn, groupId, messageId,
|
||||
messageId2);
|
||||
// getMessageDependencies()
|
||||
oneOf(database).containsMessage(txn, messageId);
|
||||
will(returnValue(true));
|
||||
@@ -1664,7 +1675,8 @@ public class DatabaseComponentImplTest extends BriarTestCase {
|
||||
oneOf(database).getMessageDependents(txn, messageId);
|
||||
// broadcast for message added event
|
||||
oneOf(eventBus).broadcast(with(any(MessageAddedEvent.class)));
|
||||
oneOf(eventBus).broadcast(with(any(MessageStateChangedEvent.class)));
|
||||
oneOf(eventBus).broadcast(with(any(
|
||||
MessageStateChangedEvent.class)));
|
||||
oneOf(eventBus).broadcast(with(any(MessageSharedEvent.class)));
|
||||
// endTransaction()
|
||||
oneOf(database).commitTransaction(txn);
|
||||
@@ -1678,7 +1690,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
|
||||
assertFalse(db.open());
|
||||
Transaction transaction = db.startTransaction(false);
|
||||
try {
|
||||
db.addLocalMessage(transaction, message, clientId, metadata, true);
|
||||
db.addLocalMessage(transaction, message, metadata, true);
|
||||
Collection<MessageId> dependencies = new ArrayList<>(2);
|
||||
dependencies.add(messageId1);
|
||||
dependencies.add(messageId2);
|
||||
|
||||
@@ -50,7 +50,6 @@ import static org.briarproject.api.sync.ValidationManager.State.DELIVERED;
|
||||
import static org.briarproject.api.sync.ValidationManager.State.INVALID;
|
||||
import static org.briarproject.api.sync.ValidationManager.State.PENDING;
|
||||
import static org.briarproject.api.sync.ValidationManager.State.UNKNOWN;
|
||||
import static org.briarproject.api.sync.ValidationManager.State.VALID;
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
@@ -67,6 +66,7 @@ public class H2DatabaseTest extends BriarTestCase {
|
||||
|
||||
private final File testDir = TestUtils.getTestDirectory();
|
||||
private final GroupId groupId;
|
||||
private final ClientId clientId;
|
||||
private final Group group;
|
||||
private final Author author;
|
||||
private final AuthorId localAuthorId;
|
||||
@@ -81,7 +81,7 @@ public class H2DatabaseTest extends BriarTestCase {
|
||||
|
||||
public H2DatabaseTest() throws Exception {
|
||||
groupId = new GroupId(TestUtils.getRandomId());
|
||||
ClientId clientId = new ClientId(TestUtils.getRandomId());
|
||||
clientId = new ClientId(TestUtils.getRandomId());
|
||||
byte[] descriptor = new byte[0];
|
||||
group = new Group(groupId, clientId, descriptor);
|
||||
AuthorId authorId = new AuthorId(TestUtils.getRandomId());
|
||||
@@ -239,16 +239,7 @@ public class H2DatabaseTest extends BriarTestCase {
|
||||
ids = db.getMessagesToOffer(txn, contactId, 100);
|
||||
assertTrue(ids.isEmpty());
|
||||
|
||||
// Marking the message valid should make it unsendable
|
||||
// TODO do we maybe want to already send valid messages? If we do, we need also to call db.setMessageShared() earlier.
|
||||
db.setMessageState(txn, messageId, VALID);
|
||||
ids = db.getMessagesToSend(txn, contactId, ONE_MEGABYTE);
|
||||
assertTrue(ids.isEmpty());
|
||||
ids = db.getMessagesToOffer(txn, contactId, 100);
|
||||
assertTrue(ids.isEmpty());
|
||||
|
||||
// Marking the message pending should make it unsendable
|
||||
// TODO do we maybe want to already send pending messages? If we do, we need also to call db.setMessageShared() earlier.
|
||||
db.setMessageState(txn, messageId, PENDING);
|
||||
ids = db.getMessagesToSend(txn, contactId, ONE_MEGABYTE);
|
||||
assertTrue(ids.isEmpty());
|
||||
@@ -1019,13 +1010,6 @@ public class H2DatabaseTest extends BriarTestCase {
|
||||
map = db.getMessageMetadata(txn, groupId);
|
||||
assertTrue(map.isEmpty());
|
||||
|
||||
// No metadata for valid messages
|
||||
db.setMessageState(txn, messageId, VALID);
|
||||
retrieved = db.getMessageMetadata(txn, messageId);
|
||||
assertTrue(retrieved.isEmpty());
|
||||
map = db.getMessageMetadata(txn, groupId);
|
||||
assertTrue(map.isEmpty());
|
||||
|
||||
// No metadata for pending messages
|
||||
db.setMessageState(txn, messageId, PENDING);
|
||||
retrieved = db.getMessageMetadata(txn, messageId);
|
||||
@@ -1033,7 +1017,7 @@ public class H2DatabaseTest extends BriarTestCase {
|
||||
map = db.getMessageMetadata(txn, groupId);
|
||||
assertTrue(map.isEmpty());
|
||||
|
||||
// validator gets also metadata for pending messages
|
||||
// Validator can get metadata for pending messages
|
||||
retrieved = db.getMessageMetadataForValidator(txn, messageId);
|
||||
assertFalse(retrieved.isEmpty());
|
||||
|
||||
@@ -1198,12 +1182,6 @@ public class H2DatabaseTest extends BriarTestCase {
|
||||
all = db.getMessageMetadata(txn, groupId, query);
|
||||
assertTrue(all.isEmpty());
|
||||
|
||||
// No metadata for valid messages
|
||||
db.setMessageState(txn, messageId, VALID);
|
||||
db.setMessageState(txn, messageId1, VALID);
|
||||
all = db.getMessageMetadata(txn, groupId, query);
|
||||
assertTrue(all.isEmpty());
|
||||
|
||||
// No metadata for pending messages
|
||||
db.setMessageState(txn, messageId, PENDING);
|
||||
db.setMessageState(txn, messageId1, PENDING);
|
||||
@@ -1217,149 +1195,139 @@ public class H2DatabaseTest extends BriarTestCase {
|
||||
|
||||
@Test
|
||||
public void testMessageDependencies() throws Exception {
|
||||
MessageId messageId1 = new MessageId(TestUtils.getRandomId());
|
||||
MessageId messageId2 = new MessageId(TestUtils.getRandomId());
|
||||
MessageId messageId3 = new MessageId(TestUtils.getRandomId());
|
||||
MessageId messageId4 = new MessageId(TestUtils.getRandomId());
|
||||
Message message1 = new Message(messageId1, groupId, timestamp, raw);
|
||||
Message message2 = new Message(messageId2, groupId, timestamp, raw);
|
||||
|
||||
Database<Connection> db = open(false);
|
||||
Connection txn = db.startTransaction();
|
||||
|
||||
// Add a group and a message
|
||||
// Add a group and some messages
|
||||
db.addGroup(txn, group);
|
||||
db.addMessage(txn, message, VALID, true);
|
||||
|
||||
// Create more messages
|
||||
MessageId mId1 = new MessageId(TestUtils.getRandomId());
|
||||
MessageId mId2 = new MessageId(TestUtils.getRandomId());
|
||||
MessageId dId1 = new MessageId(TestUtils.getRandomId());
|
||||
MessageId dId2 = new MessageId(TestUtils.getRandomId());
|
||||
Message m1 = new Message(mId1, groupId, timestamp, raw);
|
||||
Message m2 = new Message(mId2, groupId, timestamp, raw);
|
||||
|
||||
// Add new messages
|
||||
db.addMessage(txn, m1, VALID, true);
|
||||
db.addMessage(txn, m2, INVALID, true);
|
||||
db.addMessage(txn, message, PENDING, true);
|
||||
db.addMessage(txn, message1, DELIVERED, true);
|
||||
db.addMessage(txn, message2, INVALID, true);
|
||||
|
||||
// Add dependencies
|
||||
db.addMessageDependency(txn, messageId, mId1);
|
||||
db.addMessageDependency(txn, messageId, mId2);
|
||||
db.addMessageDependency(txn, mId1, dId1);
|
||||
db.addMessageDependency(txn, mId2, dId2);
|
||||
db.addMessageDependency(txn, groupId, messageId, messageId1);
|
||||
db.addMessageDependency(txn, groupId, messageId, messageId2);
|
||||
db.addMessageDependency(txn, groupId, messageId1, messageId3);
|
||||
db.addMessageDependency(txn, groupId, messageId2, messageId4);
|
||||
|
||||
Map<MessageId, State> dependencies;
|
||||
|
||||
// Retrieve dependencies for root
|
||||
dependencies = db.getMessageDependencies(txn, messageId);
|
||||
assertEquals(2, dependencies.size());
|
||||
assertEquals(VALID, dependencies.get(mId1));
|
||||
assertEquals(INVALID, dependencies.get(mId2));
|
||||
assertEquals(DELIVERED, dependencies.get(messageId1));
|
||||
assertEquals(INVALID, dependencies.get(messageId2));
|
||||
|
||||
// Retrieve dependencies for m1
|
||||
dependencies = db.getMessageDependencies(txn, mId1);
|
||||
// Retrieve dependencies for message 1
|
||||
dependencies = db.getMessageDependencies(txn, messageId1);
|
||||
assertEquals(1, dependencies.size());
|
||||
assertEquals(UNKNOWN, dependencies.get(dId1));
|
||||
assertEquals(UNKNOWN, dependencies.get(messageId3)); // Missing
|
||||
|
||||
// Retrieve dependencies for m2
|
||||
dependencies = db.getMessageDependencies(txn, mId2);
|
||||
// Retrieve dependencies for message 2
|
||||
dependencies = db.getMessageDependencies(txn, messageId2);
|
||||
assertEquals(1, dependencies.size());
|
||||
assertEquals(UNKNOWN, dependencies.get(dId2));
|
||||
assertEquals(UNKNOWN, dependencies.get(messageId4)); // Missing
|
||||
|
||||
// Make sure d's have no dependencies
|
||||
dependencies = db.getMessageDependencies(txn, dId1);
|
||||
assertTrue(dependencies.isEmpty());
|
||||
dependencies = db.getMessageDependencies(txn, dId2);
|
||||
assertTrue(dependencies.isEmpty());
|
||||
// Make sure leaves have no dependencies
|
||||
dependencies = db.getMessageDependencies(txn, messageId3);
|
||||
assertEquals(0, dependencies.size());
|
||||
dependencies = db.getMessageDependencies(txn, messageId4);
|
||||
assertEquals(0, dependencies.size());
|
||||
|
||||
Map<MessageId, State> dependents;
|
||||
|
||||
// Root message does not have dependents
|
||||
dependents = db.getMessageDependents(txn, messageId);
|
||||
assertTrue(dependents.isEmpty());
|
||||
assertEquals(0, dependents.size());
|
||||
|
||||
// The root message depends on both m's
|
||||
dependents = db.getMessageDependents(txn, mId1);
|
||||
// Messages 1 and 2 have the root as a dependent
|
||||
dependents = db.getMessageDependents(txn, messageId1);
|
||||
assertEquals(1, dependents.size());
|
||||
assertEquals(VALID, dependents.get(messageId));
|
||||
dependents = db.getMessageDependents(txn, mId2);
|
||||
assertEquals(PENDING, dependents.get(messageId));
|
||||
dependents = db.getMessageDependents(txn, messageId2);
|
||||
assertEquals(1, dependents.size());
|
||||
assertEquals(VALID, dependents.get(messageId));
|
||||
assertEquals(PENDING, dependents.get(messageId));
|
||||
|
||||
// Both m's depend on the d's
|
||||
dependents = db.getMessageDependents(txn, dId1);
|
||||
// Message 3 has message 1 as a dependent
|
||||
dependents = db.getMessageDependents(txn, messageId3);
|
||||
assertEquals(1, dependents.size());
|
||||
assertEquals(VALID, dependents.get(mId1));
|
||||
dependents = db.getMessageDependents(txn, dId2);
|
||||
assertEquals(DELIVERED, dependents.get(messageId1));
|
||||
|
||||
// Message 4 has message 2 as a dependent
|
||||
dependents = db.getMessageDependents(txn, messageId4);
|
||||
assertEquals(1, dependents.size());
|
||||
assertEquals(INVALID, dependents.get(mId2));
|
||||
assertEquals(INVALID, dependents.get(messageId2));
|
||||
|
||||
db.commitTransaction(txn);
|
||||
db.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMessageDependenciesInSameGroup() throws Exception {
|
||||
public void testMessageDependenciesAcrossGroups() throws Exception {
|
||||
Database<Connection> db = open(false);
|
||||
Connection txn = db.startTransaction();
|
||||
|
||||
// Add a group and a message
|
||||
db.addGroup(txn, group);
|
||||
db.addMessage(txn, message, DELIVERED, true);
|
||||
db.addMessage(txn, message, PENDING, true);
|
||||
|
||||
// Add a second group
|
||||
GroupId groupId1 = new GroupId(TestUtils.getRandomId());
|
||||
Group group1 = new Group(groupId1, group.getClientId(),
|
||||
Group group1 = new Group(groupId1, clientId,
|
||||
TestUtils.getRandomBytes(42));
|
||||
db.addGroup(txn, group1);
|
||||
|
||||
// Add a message to the second group
|
||||
MessageId mId1 = new MessageId(TestUtils.getRandomId());
|
||||
Message m1 = new Message(mId1, groupId1, timestamp, raw);
|
||||
db.addMessage(txn, m1, DELIVERED, true);
|
||||
MessageId messageId1 = new MessageId(TestUtils.getRandomId());
|
||||
Message message1 = new Message(messageId1, groupId1, timestamp, raw);
|
||||
db.addMessage(txn, message1, DELIVERED, true);
|
||||
|
||||
// Create a fake dependency as well
|
||||
MessageId mId2 = new MessageId(TestUtils.getRandomId());
|
||||
// Create an ID for a missing message
|
||||
MessageId messageId2 = new MessageId(TestUtils.getRandomId());
|
||||
|
||||
// Create and add a real and proper dependency
|
||||
MessageId mId3 = new MessageId(TestUtils.getRandomId());
|
||||
Message m3 = new Message(mId3, groupId, timestamp, raw);
|
||||
db.addMessage(txn, m3, PENDING, true);
|
||||
// Add another message to the first group
|
||||
MessageId messageId3 = new MessageId(TestUtils.getRandomId());
|
||||
Message message3 = new Message(messageId3, groupId, timestamp, raw);
|
||||
db.addMessage(txn, message3, DELIVERED, true);
|
||||
|
||||
// Add dependencies
|
||||
db.addMessageDependency(txn, messageId, mId1);
|
||||
db.addMessageDependency(txn, messageId, mId2);
|
||||
db.addMessageDependency(txn, messageId, mId3);
|
||||
// Add dependencies between the messages
|
||||
db.addMessageDependency(txn, groupId, messageId, messageId1);
|
||||
db.addMessageDependency(txn, groupId, messageId, messageId2);
|
||||
db.addMessageDependency(txn, groupId, messageId, messageId3);
|
||||
|
||||
// Return invalid dependencies for delivered message m1
|
||||
// Retrieve the dependencies for the root
|
||||
Map<MessageId, State> dependencies;
|
||||
dependencies = db.getMessageDependencies(txn, messageId);
|
||||
assertEquals(INVALID, dependencies.get(mId1));
|
||||
assertEquals(UNKNOWN, dependencies.get(mId2));
|
||||
assertEquals(PENDING, dependencies.get(mId3));
|
||||
|
||||
// Return invalid dependencies for valid message m1
|
||||
db.setMessageState(txn, mId1, VALID);
|
||||
dependencies = db.getMessageDependencies(txn, messageId);
|
||||
assertEquals(INVALID, dependencies.get(mId1));
|
||||
assertEquals(UNKNOWN, dependencies.get(mId2));
|
||||
assertEquals(PENDING, dependencies.get(mId3));
|
||||
// The cross-group dependency should have state INVALID
|
||||
assertEquals(INVALID, dependencies.get(messageId1));
|
||||
|
||||
// Return invalid dependencies for pending message m1
|
||||
db.setMessageState(txn, mId1, PENDING);
|
||||
dependencies = db.getMessageDependencies(txn, messageId);
|
||||
assertEquals(INVALID, dependencies.get(mId1));
|
||||
assertEquals(UNKNOWN, dependencies.get(mId2));
|
||||
assertEquals(PENDING, dependencies.get(mId3));
|
||||
// The missing dependency should have state UNKNOWN
|
||||
assertEquals(UNKNOWN, dependencies.get(messageId2));
|
||||
|
||||
// The valid dependency should have its real state
|
||||
assertEquals(DELIVERED, dependencies.get(messageId3));
|
||||
|
||||
// Retrieve the dependents for the message in the second group
|
||||
Map<MessageId, State> dependents;
|
||||
dependents = db.getMessageDependents(txn, messageId1);
|
||||
|
||||
// The cross-group dependent should have its real state
|
||||
assertEquals(PENDING, dependents.get(messageId));
|
||||
|
||||
db.commitTransaction(txn);
|
||||
db.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMessagesForValidationAndDelivery() throws Exception {
|
||||
Database<Connection> db = open(false);
|
||||
Connection txn = db.startTransaction();
|
||||
|
||||
// Add a group and a message
|
||||
db.addGroup(txn, group);
|
||||
db.addMessage(txn, message, VALID, true);
|
||||
|
||||
// Create more messages
|
||||
public void testGetPendingMessagesForDelivery() throws Exception {
|
||||
MessageId mId1 = new MessageId(TestUtils.getRandomId());
|
||||
MessageId mId2 = new MessageId(TestUtils.getRandomId());
|
||||
MessageId mId3 = new MessageId(TestUtils.getRandomId());
|
||||
@@ -1369,7 +1337,11 @@ public class H2DatabaseTest extends BriarTestCase {
|
||||
Message m3 = new Message(mId3, groupId, timestamp, raw);
|
||||
Message m4 = new Message(mId4, groupId, timestamp, raw);
|
||||
|
||||
// Add new messages with different states
|
||||
Database<Connection> db = open(false);
|
||||
Connection txn = db.startTransaction();
|
||||
|
||||
// Add a group and some messages with different states
|
||||
db.addGroup(txn, group);
|
||||
db.addMessage(txn, m1, UNKNOWN, true);
|
||||
db.addMessage(txn, m2, INVALID, true);
|
||||
db.addMessage(txn, m3, PENDING, true);
|
||||
@@ -1378,17 +1350,12 @@ public class H2DatabaseTest extends BriarTestCase {
|
||||
Collection<MessageId> result;
|
||||
|
||||
// Retrieve messages to be validated
|
||||
result = db.getMessagesToValidate(txn, group.getClientId());
|
||||
result = db.getMessagesToValidate(txn, clientId);
|
||||
assertEquals(1, result.size());
|
||||
assertTrue(result.contains(mId1));
|
||||
|
||||
// Retrieve messages to be delivered
|
||||
result = db.getMessagesToDeliver(txn, group.getClientId());
|
||||
assertEquals(1, result.size());
|
||||
assertTrue(result.contains(messageId));
|
||||
|
||||
// Retrieve pending messages
|
||||
result = db.getPendingMessages(txn, group.getClientId());
|
||||
result = db.getPendingMessages(txn, clientId);
|
||||
assertEquals(1, result.size());
|
||||
assertTrue(result.contains(mId3));
|
||||
|
||||
@@ -1607,6 +1574,29 @@ public class H2DatabaseTest extends BriarTestCase {
|
||||
db.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetMessageState() throws Exception {
|
||||
|
||||
Database<Connection> db = open(false);
|
||||
Connection txn = db.startTransaction();
|
||||
|
||||
// Add a group and a message
|
||||
db.addGroup(txn, group);
|
||||
db.addMessage(txn, message, UNKNOWN, false);
|
||||
|
||||
// Walk the message through the validation and delivery states
|
||||
assertEquals(UNKNOWN, db.getMessageState(txn, messageId));
|
||||
db.setMessageState(txn, messageId, INVALID);
|
||||
assertEquals(INVALID, db.getMessageState(txn, messageId));
|
||||
db.setMessageState(txn, messageId, PENDING);
|
||||
assertEquals(PENDING, db.getMessageState(txn, messageId));
|
||||
db.setMessageState(txn, messageId, DELIVERED);
|
||||
assertEquals(DELIVERED, db.getMessageState(txn, messageId));
|
||||
|
||||
db.commitTransaction(txn);
|
||||
db.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExceptionHandling() throws Exception {
|
||||
Database<Connection> db = open(false);
|
||||
|
||||
@@ -279,8 +279,7 @@ public class IntroduceeManagerTest extends BriarTestCase {
|
||||
|
||||
// store session state
|
||||
oneOf(clientHelper)
|
||||
.addLocalMessage(txn, localStateMessage, clientId, state,
|
||||
false);
|
||||
.addLocalMessage(txn, localStateMessage, state, false);
|
||||
}});
|
||||
|
||||
BdfDictionary result = introduceeManager.initialize(txn, groupId, msg);
|
||||
|
||||
@@ -167,8 +167,7 @@ public class IntroducerManagerTest extends BriarTestCase {
|
||||
oneOf(introductionGroupFactory)
|
||||
.createIntroductionGroup(introducee2);
|
||||
will(returnValue(introductionGroup2));
|
||||
oneOf(clientHelper).addLocalMessage(txn, msg, getClientId(), state,
|
||||
false);
|
||||
oneOf(clientHelper).addLocalMessage(txn, msg, state, false);
|
||||
|
||||
// send message
|
||||
oneOf(clientHelper).mergeMessageMetadata(txn, msg.getId(), state2);
|
||||
|
||||
@@ -26,11 +26,9 @@ import org.jmock.Expectations;
|
||||
import org.jmock.Mockery;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
@@ -38,7 +36,7 @@ import static org.briarproject.api.sync.ValidationManager.State.DELIVERED;
|
||||
import static org.briarproject.api.sync.ValidationManager.State.INVALID;
|
||||
import static org.briarproject.api.sync.ValidationManager.State.PENDING;
|
||||
import static org.briarproject.api.sync.ValidationManager.State.UNKNOWN;
|
||||
import static org.briarproject.api.sync.ValidationManager.State.VALID;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class ValidationManagerImplTest extends BriarTestCase {
|
||||
@@ -58,21 +56,17 @@ public class ValidationManagerImplTest extends BriarTestCase {
|
||||
raw);
|
||||
private final Message message2 = new Message(messageId2, groupId, timestamp,
|
||||
raw);
|
||||
|
||||
private final Metadata metadata = new Metadata();
|
||||
private final MessageContext validResult = new MessageContext(metadata);
|
||||
private final ContactId contactId = new ContactId(234);
|
||||
private final Collection<MessageId> dependencies = new ArrayList<>();
|
||||
private final MessageContext validResultWithDependencies =
|
||||
new MessageContext(metadata, dependencies);
|
||||
private final Map<MessageId, State> states = new HashMap<>();
|
||||
new MessageContext(metadata, Collections.singletonList(messageId1));
|
||||
|
||||
public ValidationManagerImplTest() {
|
||||
// Encode the messages
|
||||
System.arraycopy(groupId.getBytes(), 0, raw, 0, UniqueId.LENGTH);
|
||||
ByteUtils.writeUint64(timestamp, raw, UniqueId.LENGTH);
|
||||
|
||||
dependencies.add(messageId1);
|
||||
states.put(messageId1, INVALID);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -84,11 +78,10 @@ public class ValidationManagerImplTest extends BriarTestCase {
|
||||
final MessageValidator validator = context.mock(MessageValidator.class);
|
||||
final IncomingMessageHook hook =
|
||||
context.mock(IncomingMessageHook.class);
|
||||
final Transaction txn = new Transaction(null, false);
|
||||
final Transaction txn1 = new Transaction(null, false);
|
||||
final Transaction txn = new Transaction(null, true);
|
||||
final Transaction txn1 = new Transaction(null, true);
|
||||
final Transaction txn2 = new Transaction(null, false);
|
||||
final Transaction txn2b = new Transaction(null, false);
|
||||
final Transaction txn3 = new Transaction(null, false);
|
||||
final Transaction txn3 = new Transaction(null, true);
|
||||
final Transaction txn4 = new Transaction(null, false);
|
||||
final Transaction txn5 = new Transaction(null, true);
|
||||
context.checking(new Expectations() {{
|
||||
@@ -112,21 +105,16 @@ public class ValidationManagerImplTest extends BriarTestCase {
|
||||
// Store the validation result for the first message
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn2));
|
||||
oneOf(db).getMessageDependencies(txn2, messageId);
|
||||
oneOf(db).mergeMessageMetadata(txn2, messageId, metadata);
|
||||
oneOf(db).setMessageState(txn2, message, clientId, VALID);
|
||||
oneOf(db).endTransaction(txn2);
|
||||
// Async delivery
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn2b));
|
||||
// Call the hook for the first message
|
||||
oneOf(hook).incomingMessage(txn2b, message, metadata);
|
||||
oneOf(db).getRawMessage(txn2b, messageId);
|
||||
// Deliver the first message
|
||||
oneOf(hook).incomingMessage(txn2, message, metadata);
|
||||
oneOf(db).getRawMessage(txn2, messageId);
|
||||
will(returnValue(raw));
|
||||
oneOf(db).setMessageState(txn2b, message, clientId, DELIVERED);
|
||||
oneOf(db).getMessageDependents(txn2b, messageId);
|
||||
oneOf(db).setMessageState(txn2, messageId, DELIVERED);
|
||||
// Get any pending dependents
|
||||
oneOf(db).getMessageDependents(txn2, messageId);
|
||||
will(returnValue(Collections.emptyMap()));
|
||||
oneOf(db).endTransaction(txn2b);
|
||||
oneOf(db).endTransaction(txn2);
|
||||
// Load the second raw message and group
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn3));
|
||||
@@ -141,101 +129,20 @@ public class ValidationManagerImplTest extends BriarTestCase {
|
||||
// Store the validation result for the second message
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn4));
|
||||
oneOf(db).setMessageState(txn4, message1, clientId, INVALID);
|
||||
// Recursively invalidate dependents
|
||||
oneOf(db).getMessageDependents(txn4, messageId1);
|
||||
oneOf(db).getMessageState(txn4, messageId1);
|
||||
will(returnValue(UNKNOWN));
|
||||
oneOf(db).setMessageState(txn4, messageId1, INVALID);
|
||||
oneOf(db).deleteMessage(txn4, messageId1);
|
||||
oneOf(db).deleteMessageMetadata(txn4, messageId1);
|
||||
// Recursively invalidate any dependents
|
||||
oneOf(db).getMessageDependents(txn4, messageId1);
|
||||
will(returnValue(Collections.emptyMap()));
|
||||
oneOf(db).endTransaction(txn4);
|
||||
// Get other messages to deliver
|
||||
// Get pending messages to deliver
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn5));
|
||||
oneOf(db).getMessagesToDeliver(txn5, clientId);
|
||||
oneOf(db).getPendingMessages(txn5, clientId);
|
||||
oneOf(db).endTransaction(txn5);
|
||||
}});
|
||||
|
||||
ValidationManagerImpl vm = new ValidationManagerImpl(db, dbExecutor,
|
||||
cryptoExecutor);
|
||||
vm.registerMessageValidator(clientId, validator);
|
||||
vm.registerIncomingMessageHook(clientId, hook);
|
||||
vm.startService();
|
||||
|
||||
context.assertIsSatisfied();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMessagesAreDeliveredAtStartup() throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
final DatabaseComponent db = context.mock(DatabaseComponent.class);
|
||||
final Executor dbExecutor = new ImmediateExecutor();
|
||||
final Executor cryptoExecutor = new ImmediateExecutor();
|
||||
final MessageValidator validator = context.mock(MessageValidator.class);
|
||||
final IncomingMessageHook hook =
|
||||
context.mock(IncomingMessageHook.class);
|
||||
final Transaction txn = new Transaction(null, true);
|
||||
final Transaction txn1 = new Transaction(null, true);
|
||||
final Transaction txn2 = new Transaction(null, true);
|
||||
final Transaction txn3 = new Transaction(null, false);
|
||||
final Transaction txn4 = new Transaction(null, true);
|
||||
final Transaction txn5 = new Transaction(null, false);
|
||||
|
||||
states.put(messageId1, PENDING);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
// Get messages to validate
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
oneOf(db).getMessagesToValidate(txn, clientId);
|
||||
oneOf(db).endTransaction(txn);
|
||||
// Get IDs of messages to deliver
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn1));
|
||||
oneOf(db).getMessagesToDeliver(txn1, clientId);
|
||||
will(returnValue(Collections.singletonList(messageId)));
|
||||
oneOf(db).getPendingMessages(txn1, clientId);
|
||||
oneOf(db).endTransaction(txn1);
|
||||
// Get message and its metadata to deliver
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn2));
|
||||
oneOf(db).getRawMessage(txn2, messageId);
|
||||
will(returnValue(message.getRaw()));
|
||||
oneOf(db).getGroup(txn2, message.getGroupId());
|
||||
will(returnValue(group));
|
||||
oneOf(db).getMessageMetadataForValidator(txn2, messageId);
|
||||
will(returnValue(metadata));
|
||||
oneOf(db).endTransaction(txn2);
|
||||
// Deliver message in a new transaction
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn3));
|
||||
oneOf(db).setMessageState(txn3, message, clientId, DELIVERED);
|
||||
oneOf(hook).incomingMessage(txn3, message, metadata);
|
||||
oneOf(db).getRawMessage(txn3, messageId);
|
||||
will(returnValue(message.getRaw()));
|
||||
// Try to also deliver pending dependents
|
||||
oneOf(db).getMessageDependents(txn3, messageId);
|
||||
will(returnValue(states));
|
||||
oneOf(db).getMessageDependencies(txn3, messageId1);
|
||||
will(returnValue(Collections.singletonMap(messageId2, DELIVERED)));
|
||||
oneOf(db).endTransaction(txn3);
|
||||
// Get the dependent to deliver
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn4));
|
||||
oneOf(db).getRawMessage(txn4, messageId1);
|
||||
will(returnValue(message1.getRaw()));
|
||||
oneOf(db).getGroup(txn4, message.getGroupId());
|
||||
will(returnValue(group));
|
||||
oneOf(db).getMessageMetadataForValidator(txn4, messageId1);
|
||||
will(returnValue(metadata));
|
||||
oneOf(db).endTransaction(txn4);
|
||||
// Deliver the dependent in a new transaction
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn5));
|
||||
oneOf(db).setMessageState(txn5, message1, clientId, DELIVERED);
|
||||
oneOf(hook).incomingMessage(txn5, message1, metadata);
|
||||
oneOf(db).getRawMessage(txn5, messageId1);
|
||||
will(returnValue(message1.getRaw()));
|
||||
oneOf(db).getMessageDependents(txn5, messageId1);
|
||||
will(returnValue(Collections.emptyList()));
|
||||
oneOf(db).endTransaction(txn5);
|
||||
}});
|
||||
|
||||
@@ -266,7 +173,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
|
||||
context.mock(IncomingMessageHook.class);
|
||||
final Transaction txn = new Transaction(null, true);
|
||||
final Transaction txn1 = new Transaction(null, true);
|
||||
final Transaction txn2 = new Transaction(null, true);
|
||||
final Transaction txn2 = new Transaction(null, false);
|
||||
final Transaction txn3 = new Transaction(null, false);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
@@ -274,33 +181,59 @@ public class ValidationManagerImplTest extends BriarTestCase {
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
oneOf(db).getMessagesToValidate(txn, clientId);
|
||||
will(returnValue(Collections.emptyList()));
|
||||
oneOf(db).endTransaction(txn);
|
||||
// Get IDs of messages to deliver
|
||||
// Get pending messages to deliver
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn1));
|
||||
oneOf(db).getMessagesToDeliver(txn1, clientId);
|
||||
oneOf(db).getPendingMessages(txn1, clientId);
|
||||
will(returnValue(Collections.singletonList(messageId)));
|
||||
oneOf(db).endTransaction(txn1);
|
||||
// Get message and its metadata to deliver
|
||||
oneOf(db).startTransaction(true);
|
||||
// Check whether the message is ready to deliver
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn2));
|
||||
oneOf(db).getRawMessage(txn2, messageId);
|
||||
will(returnValue(message.getRaw()));
|
||||
oneOf(db).getGroup(txn2, message.getGroupId());
|
||||
will(returnValue(group));
|
||||
oneOf(db).getMessageState(txn2, messageId);
|
||||
will(returnValue(PENDING));
|
||||
oneOf(db).getMessageDependencies(txn2, messageId);
|
||||
will(returnValue(Collections.singletonMap(messageId1, DELIVERED)));
|
||||
// Get the message and its metadata to deliver
|
||||
oneOf(db).getRawMessage(txn2, messageId);
|
||||
will(returnValue(raw));
|
||||
oneOf(db).getGroup(txn2, groupId);
|
||||
will(returnValue(group));
|
||||
oneOf(db).getMessageMetadataForValidator(txn2, messageId);
|
||||
will(returnValue(new Metadata()));
|
||||
// Deliver the message
|
||||
oneOf(hook).incomingMessage(txn2, message, metadata);
|
||||
oneOf(db).getRawMessage(txn2, messageId);
|
||||
will(returnValue(raw));
|
||||
oneOf(db).setMessageState(txn2, messageId, DELIVERED);
|
||||
// Get any pending dependents
|
||||
oneOf(db).getMessageDependents(txn2, messageId);
|
||||
will(returnValue(Collections.singletonMap(messageId2, PENDING)));
|
||||
oneOf(db).endTransaction(txn2);
|
||||
// Deliver the pending message
|
||||
// Check whether the dependent is ready to deliver
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn3));
|
||||
oneOf(db).setMessageState(txn3, message, clientId, DELIVERED);
|
||||
oneOf(hook).incomingMessage(txn3, message, metadata);
|
||||
oneOf(db).getRawMessage(txn3, messageId);
|
||||
will(returnValue(message.getRaw()));
|
||||
oneOf(db).getMessageDependents(txn3, messageId);
|
||||
oneOf(db).getMessageState(txn3, messageId2);
|
||||
will(returnValue(PENDING));
|
||||
oneOf(db).getMessageDependencies(txn3, messageId2);
|
||||
will(returnValue(Collections.singletonMap(messageId1, DELIVERED)));
|
||||
// Get the dependent and its metadata to deliver
|
||||
oneOf(db).getRawMessage(txn3, messageId2);
|
||||
will(returnValue(raw));
|
||||
oneOf(db).getGroup(txn3, groupId);
|
||||
will(returnValue(group));
|
||||
oneOf(db).getMessageMetadataForValidator(txn3, messageId2);
|
||||
will(returnValue(metadata));
|
||||
// Deliver the dependent
|
||||
oneOf(hook).incomingMessage(txn3, message2, metadata);
|
||||
oneOf(db).getRawMessage(txn3, messageId2);
|
||||
will(returnValue(raw));
|
||||
oneOf(db).setMessageState(txn3, messageId2, DELIVERED);
|
||||
// Get any pending dependents
|
||||
oneOf(db).getMessageDependents(txn3, messageId2);
|
||||
will(returnValue(Collections.emptyMap()));
|
||||
oneOf(db).endTransaction(txn3);
|
||||
}});
|
||||
|
||||
@@ -357,20 +290,23 @@ public class ValidationManagerImplTest extends BriarTestCase {
|
||||
// Validate the second message: invalid
|
||||
oneOf(validator).validateMessage(message1, group);
|
||||
will(throwException(new InvalidMessageException()));
|
||||
// Store the validation result for the second message
|
||||
// Invalidate the second message
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn3));
|
||||
oneOf(db).setMessageState(txn3, message1, clientId, INVALID);
|
||||
// recursively invalidate dependents
|
||||
oneOf(db).getMessageDependents(txn3, messageId1);
|
||||
oneOf(db).getMessageState(txn3, messageId1);
|
||||
will(returnValue(UNKNOWN));
|
||||
oneOf(db).setMessageState(txn3, messageId1, INVALID);
|
||||
oneOf(db).deleteMessage(txn3, messageId1);
|
||||
oneOf(db).deleteMessageMetadata(txn3, messageId1);
|
||||
// Recursively invalidate dependents
|
||||
oneOf(db).getMessageDependents(txn3, messageId1);
|
||||
will(returnValue(Collections.emptyMap()));
|
||||
oneOf(db).endTransaction(txn3);
|
||||
// Get other messages to deliver
|
||||
// Get pending messages to deliver
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn4));
|
||||
oneOf(db).getMessagesToDeliver(txn4, clientId);
|
||||
oneOf(db).getPendingMessages(txn4, clientId);
|
||||
will(returnValue(Collections.emptyList()));
|
||||
oneOf(db).endTransaction(txn4);
|
||||
}});
|
||||
|
||||
@@ -383,7 +319,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
|
||||
context.assertIsSatisfied();
|
||||
|
||||
assertTrue(txn.isComplete());
|
||||
assertTrue(txn1.isComplete());
|
||||
assertFalse(txn1.isComplete()); // Aborted due to NoSuchMessageException
|
||||
assertTrue(txn2.isComplete());
|
||||
assertTrue(txn3.isComplete());
|
||||
assertTrue(txn4.isComplete());
|
||||
@@ -434,17 +370,20 @@ public class ValidationManagerImplTest extends BriarTestCase {
|
||||
// Store the validation result for the second message
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn3));
|
||||
oneOf(db).setMessageState(txn3, message1, clientId, INVALID);
|
||||
// recursively invalidate dependents
|
||||
oneOf(db).getMessageDependents(txn3, messageId1);
|
||||
oneOf(db).getMessageState(txn3, messageId1);
|
||||
will(returnValue(UNKNOWN));
|
||||
oneOf(db).setMessageState(txn3, messageId1, INVALID);
|
||||
oneOf(db).deleteMessage(txn3, messageId1);
|
||||
oneOf(db).deleteMessageMetadata(txn3, messageId1);
|
||||
// Recursively invalidate dependents
|
||||
oneOf(db).getMessageDependents(txn3, messageId1);
|
||||
will(returnValue(Collections.emptyMap()));
|
||||
oneOf(db).endTransaction(txn3);
|
||||
// Get other messages to deliver
|
||||
// Get pending messages to deliver
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn4));
|
||||
oneOf(db).getMessagesToDeliver(txn4, clientId);
|
||||
oneOf(db).getPendingMessages(txn4, clientId);
|
||||
will(returnValue(Collections.emptyList()));
|
||||
oneOf(db).endTransaction(txn4);
|
||||
}});
|
||||
|
||||
@@ -457,7 +396,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
|
||||
context.assertIsSatisfied();
|
||||
|
||||
assertTrue(txn.isComplete());
|
||||
assertTrue(txn1.isComplete());
|
||||
assertFalse(txn1.isComplete()); // Aborted due to NoSuchGroupException
|
||||
assertTrue(txn2.isComplete());
|
||||
assertTrue(txn3.isComplete());
|
||||
assertTrue(txn4.isComplete());
|
||||
@@ -474,7 +413,6 @@ public class ValidationManagerImplTest extends BriarTestCase {
|
||||
context.mock(IncomingMessageHook.class);
|
||||
final Transaction txn = new Transaction(null, true);
|
||||
final Transaction txn1 = new Transaction(null, false);
|
||||
final Transaction txn2 = new Transaction(null, false);
|
||||
context.checking(new Expectations() {{
|
||||
// Load the group
|
||||
oneOf(db).startTransaction(true);
|
||||
@@ -488,20 +426,16 @@ public class ValidationManagerImplTest extends BriarTestCase {
|
||||
// Store the validation result
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn1));
|
||||
oneOf(db).getMessageDependencies(txn1, messageId);
|
||||
oneOf(db).mergeMessageMetadata(txn1, messageId, metadata);
|
||||
oneOf(db).setMessageState(txn1, message, clientId, VALID);
|
||||
oneOf(db).endTransaction(txn1);
|
||||
// async delivery
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn2));
|
||||
// Call the hook
|
||||
oneOf(hook).incomingMessage(txn2, message, metadata);
|
||||
oneOf(db).getRawMessage(txn2, messageId);
|
||||
// Deliver the message
|
||||
oneOf(hook).incomingMessage(txn1, message, metadata);
|
||||
oneOf(db).getRawMessage(txn1, messageId);
|
||||
will(returnValue(raw));
|
||||
oneOf(db).setMessageState(txn2, message, clientId, DELIVERED);
|
||||
oneOf(db).getMessageDependents(txn2, messageId);
|
||||
oneOf(db).endTransaction(txn2);
|
||||
oneOf(db).setMessageState(txn1, messageId, DELIVERED);
|
||||
// Get any pending dependents
|
||||
oneOf(db).getMessageDependents(txn1, messageId);
|
||||
will(returnValue(Collections.emptyMap()));
|
||||
oneOf(db).endTransaction(txn1);
|
||||
}});
|
||||
|
||||
ValidationManagerImpl vm = new ValidationManagerImpl(db, dbExecutor,
|
||||
@@ -514,7 +448,6 @@ public class ValidationManagerImplTest extends BriarTestCase {
|
||||
|
||||
assertTrue(txn.isComplete());
|
||||
assertTrue(txn1.isComplete());
|
||||
assertTrue(txn2.isComplete());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -537,10 +470,9 @@ public class ValidationManagerImplTest extends BriarTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMessagesWithNonDeliveredDependenciesArePending()
|
||||
public void testMessagesWithUndeliveredDependenciesArePending()
|
||||
throws Exception {
|
||||
|
||||
states.put(messageId1, UNKNOWN);
|
||||
Mockery context = new Mockery();
|
||||
final DatabaseComponent db = context.mock(DatabaseComponent.class);
|
||||
final Executor dbExecutor = new ImmediateExecutor();
|
||||
@@ -566,9 +498,9 @@ public class ValidationManagerImplTest extends BriarTestCase {
|
||||
oneOf(db).addMessageDependencies(txn1, message,
|
||||
validResultWithDependencies.getDependencies());
|
||||
oneOf(db).getMessageDependencies(txn1, messageId);
|
||||
will(returnValue(states));
|
||||
will(returnValue(Collections.singletonMap(messageId1, UNKNOWN)));
|
||||
oneOf(db).mergeMessageMetadata(txn1, messageId, metadata);
|
||||
oneOf(db).setMessageState(txn1, message, clientId, PENDING);
|
||||
oneOf(db).setMessageState(txn1, messageId, PENDING);
|
||||
oneOf(db).endTransaction(txn1);
|
||||
}});
|
||||
|
||||
@@ -587,8 +519,6 @@ public class ValidationManagerImplTest extends BriarTestCase {
|
||||
@Test
|
||||
public void testMessagesWithDeliveredDependenciesGetDelivered()
|
||||
throws Exception {
|
||||
|
||||
states.put(messageId1, DELIVERED);
|
||||
Mockery context = new Mockery();
|
||||
final DatabaseComponent db = context.mock(DatabaseComponent.class);
|
||||
final Executor dbExecutor = new ImmediateExecutor();
|
||||
@@ -598,7 +528,6 @@ public class ValidationManagerImplTest extends BriarTestCase {
|
||||
context.mock(IncomingMessageHook.class);
|
||||
final Transaction txn = new Transaction(null, true);
|
||||
final Transaction txn1 = new Transaction(null, false);
|
||||
final Transaction txn2 = new Transaction(null, false);
|
||||
context.checking(new Expectations() {{
|
||||
// Load the group
|
||||
oneOf(db).startTransaction(true);
|
||||
@@ -615,20 +544,17 @@ public class ValidationManagerImplTest extends BriarTestCase {
|
||||
oneOf(db).addMessageDependencies(txn1, message,
|
||||
validResultWithDependencies.getDependencies());
|
||||
oneOf(db).getMessageDependencies(txn1, messageId);
|
||||
will(returnValue(states));
|
||||
will(returnValue(Collections.singletonMap(messageId1, DELIVERED)));
|
||||
oneOf(db).mergeMessageMetadata(txn1, messageId, metadata);
|
||||
oneOf(db).setMessageState(txn1, message, clientId, VALID);
|
||||
oneOf(db).endTransaction(txn1);
|
||||
// async delivery
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn2));
|
||||
// Call the hook
|
||||
oneOf(hook).incomingMessage(txn2, message, metadata);
|
||||
oneOf(db).getRawMessage(txn2, messageId);
|
||||
// Deliver the message
|
||||
oneOf(hook).incomingMessage(txn1, message, metadata);
|
||||
oneOf(db).getRawMessage(txn1, messageId);
|
||||
will(returnValue(raw));
|
||||
oneOf(db).setMessageState(txn2, message, clientId, DELIVERED);
|
||||
oneOf(db).getMessageDependents(txn2, messageId);
|
||||
oneOf(db).endTransaction(txn2);
|
||||
oneOf(db).setMessageState(txn1, messageId, DELIVERED);
|
||||
// Get any pending dependents
|
||||
oneOf(db).getMessageDependents(txn1, messageId);
|
||||
will(returnValue(Collections.emptyMap()));
|
||||
oneOf(db).endTransaction(txn1);
|
||||
}});
|
||||
|
||||
ValidationManagerImpl vm = new ValidationManagerImpl(db, dbExecutor,
|
||||
@@ -641,7 +567,6 @@ public class ValidationManagerImplTest extends BriarTestCase {
|
||||
|
||||
assertTrue(txn.isComplete());
|
||||
assertTrue(txn1.isComplete());
|
||||
assertTrue(txn2.isComplete());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -657,8 +582,6 @@ public class ValidationManagerImplTest extends BriarTestCase {
|
||||
final Transaction txn = new Transaction(null, true);
|
||||
final Transaction txn1 = new Transaction(null, false);
|
||||
final Transaction txn2 = new Transaction(null, false);
|
||||
final Transaction txn3 = new Transaction(null, true);
|
||||
final Transaction txn4 = new Transaction(null, false);
|
||||
context.checking(new Expectations() {{
|
||||
// Load the group
|
||||
oneOf(db).startTransaction(true);
|
||||
@@ -674,35 +597,142 @@ public class ValidationManagerImplTest extends BriarTestCase {
|
||||
will(returnValue(txn1));
|
||||
oneOf(db).addMessageDependencies(txn1, message,
|
||||
validResultWithDependencies.getDependencies());
|
||||
// Check for invalid dependencies
|
||||
oneOf(db).getMessageDependencies(txn1, messageId);
|
||||
will(returnValue(states));
|
||||
will(returnValue(Collections.singletonMap(messageId1, INVALID)));
|
||||
// Invalidate message
|
||||
oneOf(db).getMessageState(txn1, messageId);
|
||||
will(returnValue(UNKNOWN));
|
||||
oneOf(db).setMessageState(txn1, messageId, INVALID);
|
||||
oneOf(db).deleteMessage(txn1, messageId);
|
||||
oneOf(db).deleteMessageMetadata(txn1, messageId);
|
||||
// Recursively invalidate dependents
|
||||
oneOf(db).getMessageDependents(txn1, messageId);
|
||||
will(returnValue(Collections.singletonMap(messageId2, UNKNOWN)));
|
||||
oneOf(db).endTransaction(txn1);
|
||||
// Invalidate message in a new transaction
|
||||
// Invalidate dependent in a new transaction
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn2));
|
||||
oneOf(db).getMessageDependents(txn2, messageId);
|
||||
will(returnValue(Collections.singletonMap(messageId2, UNKNOWN)));
|
||||
oneOf(db).setMessageState(txn2, message, clientId, INVALID);
|
||||
oneOf(db).deleteMessage(txn2, messageId);
|
||||
oneOf(db).deleteMessageMetadata(txn2, messageId);
|
||||
oneOf(db).endTransaction(txn2);
|
||||
// Get message to invalidate in a new transaction
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn3));
|
||||
oneOf(db).getRawMessage(txn3, messageId2);
|
||||
will(returnValue(message2.getRaw()));
|
||||
oneOf(db).getGroup(txn3, message2.getGroupId());
|
||||
will(returnValue(group));
|
||||
oneOf(db).endTransaction(txn3);
|
||||
// Invalidate dependent message in a new transaction
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn4));
|
||||
oneOf(db).getMessageDependents(txn4, messageId2);
|
||||
oneOf(db).getMessageState(txn2, messageId2);
|
||||
will(returnValue(UNKNOWN));
|
||||
oneOf(db).setMessageState(txn2, messageId2, INVALID);
|
||||
oneOf(db).deleteMessage(txn2, messageId2);
|
||||
oneOf(db).deleteMessageMetadata(txn2, messageId2);
|
||||
oneOf(db).getMessageDependents(txn2, messageId2);
|
||||
will(returnValue(Collections.emptyMap()));
|
||||
oneOf(db).setMessageState(txn4, message2, clientId, INVALID);
|
||||
oneOf(db).deleteMessage(txn4, messageId2);
|
||||
oneOf(db).deleteMessageMetadata(txn4, messageId2);
|
||||
oneOf(db).endTransaction(txn4);
|
||||
oneOf(db).endTransaction(txn2);
|
||||
}});
|
||||
|
||||
ValidationManagerImpl vm = new ValidationManagerImpl(db, dbExecutor,
|
||||
cryptoExecutor);
|
||||
vm.registerMessageValidator(clientId, validator);
|
||||
vm.registerIncomingMessageHook(clientId, hook);
|
||||
vm.eventOccurred(new MessageAddedEvent(message, contactId));
|
||||
|
||||
context.assertIsSatisfied();
|
||||
|
||||
assertTrue(txn.isComplete());
|
||||
assertTrue(txn1.isComplete());
|
||||
assertTrue(txn2.isComplete());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRecursiveInvalidation() throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
final DatabaseComponent db = context.mock(DatabaseComponent.class);
|
||||
final Executor dbExecutor = new ImmediateExecutor();
|
||||
final Executor cryptoExecutor = new ImmediateExecutor();
|
||||
final MessageValidator validator = context.mock(MessageValidator.class);
|
||||
final IncomingMessageHook hook =
|
||||
context.mock(IncomingMessageHook.class);
|
||||
final MessageId messageId3 = new MessageId(TestUtils.getRandomId());
|
||||
final MessageId messageId4 = new MessageId(TestUtils.getRandomId());
|
||||
final Map<MessageId, State> twoDependents = new LinkedHashMap<>();
|
||||
twoDependents.put(messageId1, PENDING);
|
||||
twoDependents.put(messageId2, PENDING);
|
||||
final Transaction txn = new Transaction(null, true);
|
||||
final Transaction txn1 = new Transaction(null, false);
|
||||
final Transaction txn2 = new Transaction(null, false);
|
||||
final Transaction txn3 = new Transaction(null, false);
|
||||
final Transaction txn4 = new Transaction(null, false);
|
||||
final Transaction txn5 = new Transaction(null, false);
|
||||
final Transaction txn6 = new Transaction(null, false);
|
||||
context.checking(new Expectations() {{
|
||||
// Load the group
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
oneOf(db).getGroup(txn, groupId);
|
||||
will(returnValue(group));
|
||||
oneOf(db).endTransaction(txn);
|
||||
// Validate the message: invalid
|
||||
oneOf(validator).validateMessage(message, group);
|
||||
will(throwException(new InvalidMessageException()));
|
||||
// Invalidate the message
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn1));
|
||||
oneOf(db).getMessageState(txn1, messageId);
|
||||
will(returnValue(UNKNOWN));
|
||||
oneOf(db).setMessageState(txn1, messageId, INVALID);
|
||||
oneOf(db).deleteMessage(txn1, messageId);
|
||||
oneOf(db).deleteMessageMetadata(txn1, messageId);
|
||||
// The message has two dependents: 1 and 2
|
||||
oneOf(db).getMessageDependents(txn1, messageId);
|
||||
will(returnValue(twoDependents));
|
||||
oneOf(db).endTransaction(txn1);
|
||||
// Invalidate message 1
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn2));
|
||||
oneOf(db).getMessageState(txn2, messageId1);
|
||||
will(returnValue(PENDING));
|
||||
oneOf(db).setMessageState(txn2, messageId1, INVALID);
|
||||
oneOf(db).deleteMessage(txn2, messageId1);
|
||||
oneOf(db).deleteMessageMetadata(txn2, messageId1);
|
||||
// Message 1 has one dependent: 3
|
||||
oneOf(db).getMessageDependents(txn2, messageId1);
|
||||
will(returnValue(Collections.singletonMap(messageId3, PENDING)));
|
||||
oneOf(db).endTransaction(txn2);
|
||||
// Invalidate message 2
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn3));
|
||||
oneOf(db).getMessageState(txn3, messageId2);
|
||||
will(returnValue(PENDING));
|
||||
oneOf(db).setMessageState(txn3, messageId2, INVALID);
|
||||
oneOf(db).deleteMessage(txn3, messageId2);
|
||||
oneOf(db).deleteMessageMetadata(txn3, messageId2);
|
||||
// Message 2 has one dependent: 3 (same dependent as 1)
|
||||
oneOf(db).getMessageDependents(txn3, messageId2);
|
||||
will(returnValue(Collections.singletonMap(messageId3, PENDING)));
|
||||
oneOf(db).endTransaction(txn3);
|
||||
// Invalidate message 3 (via 1)
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn4));
|
||||
oneOf(db).getMessageState(txn4, messageId3);
|
||||
will(returnValue(PENDING));
|
||||
oneOf(db).setMessageState(txn4, messageId3, INVALID);
|
||||
oneOf(db).deleteMessage(txn4, messageId3);
|
||||
oneOf(db).deleteMessageMetadata(txn4, messageId3);
|
||||
// Message 3 has one dependent: 4
|
||||
oneOf(db).getMessageDependents(txn4, messageId3);
|
||||
will(returnValue(Collections.singletonMap(messageId4, PENDING)));
|
||||
oneOf(db).endTransaction(txn4);
|
||||
// Invalidate message 3 (again, via 2)
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn5));
|
||||
oneOf(db).getMessageState(txn5, messageId3);
|
||||
will(returnValue(INVALID)); // Already invalidated
|
||||
oneOf(db).endTransaction(txn5);
|
||||
// Invalidate message 4 (via 1 and 3)
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn6));
|
||||
oneOf(db).getMessageState(txn6, messageId4);
|
||||
will(returnValue(PENDING));
|
||||
oneOf(db).setMessageState(txn6, messageId4, INVALID);
|
||||
oneOf(db).deleteMessage(txn6, messageId4);
|
||||
oneOf(db).deleteMessageMetadata(txn6, messageId4);
|
||||
// Message 4 has no dependents
|
||||
oneOf(db).getMessageDependents(txn6, messageId4);
|
||||
will(returnValue(Collections.emptyMap()));
|
||||
oneOf(db).endTransaction(txn6);
|
||||
}});
|
||||
|
||||
ValidationManagerImpl vm = new ValidationManagerImpl(db, dbExecutor,
|
||||
@@ -716,8 +746,6 @@ public class ValidationManagerImplTest extends BriarTestCase {
|
||||
assertTrue(txn.isComplete());
|
||||
assertTrue(txn1.isComplete());
|
||||
assertTrue(txn2.isComplete());
|
||||
assertTrue(txn3.isComplete());
|
||||
assertTrue(txn4.isComplete());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -729,11 +757,25 @@ public class ValidationManagerImplTest extends BriarTestCase {
|
||||
final MessageValidator validator = context.mock(MessageValidator.class);
|
||||
final IncomingMessageHook hook =
|
||||
context.mock(IncomingMessageHook.class);
|
||||
final MessageId messageId3 = new MessageId(TestUtils.getRandomId());
|
||||
final MessageId messageId4 = new MessageId(TestUtils.getRandomId());
|
||||
final Message message3 = new Message(messageId3, groupId, timestamp,
|
||||
raw);
|
||||
final Message message4 = new Message(messageId4, groupId, timestamp,
|
||||
raw);
|
||||
final Map<MessageId, State> twoDependents = new LinkedHashMap<>();
|
||||
twoDependents.put(messageId1, PENDING);
|
||||
twoDependents.put(messageId2, PENDING);
|
||||
final Map<MessageId, State> twoDependencies = new LinkedHashMap<>();
|
||||
twoDependencies.put(messageId1, DELIVERED);
|
||||
twoDependencies.put(messageId2, DELIVERED);
|
||||
final Transaction txn = new Transaction(null, true);
|
||||
final Transaction txn1 = new Transaction(null, false);
|
||||
final Transaction txn2 = new Transaction(null, false);
|
||||
final Transaction txn3 = new Transaction(null, true);
|
||||
final Transaction txn3 = new Transaction(null, false);
|
||||
final Transaction txn4 = new Transaction(null, false);
|
||||
final Transaction txn5 = new Transaction(null, false);
|
||||
final Transaction txn6 = new Transaction(null, false);
|
||||
context.checking(new Expectations() {{
|
||||
// Load the group
|
||||
oneOf(db).startTransaction(true);
|
||||
@@ -747,43 +789,114 @@ public class ValidationManagerImplTest extends BriarTestCase {
|
||||
// Store the validation result
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn1));
|
||||
oneOf(db).getMessageDependencies(txn1, messageId);
|
||||
will(returnValue(Collections.emptyMap()));
|
||||
oneOf(db).mergeMessageMetadata(txn1, messageId, metadata);
|
||||
oneOf(db).setMessageState(txn1, message, clientId, VALID);
|
||||
// Deliver the message
|
||||
oneOf(hook).incomingMessage(txn1, message, metadata);
|
||||
oneOf(db).getRawMessage(txn1, messageId);
|
||||
will(returnValue(raw));
|
||||
oneOf(db).setMessageState(txn1, messageId, DELIVERED);
|
||||
// The message has two pending dependents: 1 and 2
|
||||
oneOf(db).getMessageDependents(txn1, messageId);
|
||||
will(returnValue(twoDependents));
|
||||
oneOf(db).endTransaction(txn1);
|
||||
// Deliver first message
|
||||
// Check whether message 1 is ready to be delivered
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn2));
|
||||
oneOf(hook).incomingMessage(txn2, message, metadata);
|
||||
oneOf(db).getRawMessage(txn2, messageId);
|
||||
will(returnValue(raw));
|
||||
oneOf(db).setMessageState(txn2, message, clientId, DELIVERED);
|
||||
oneOf(db).getMessageDependents(txn2, messageId);
|
||||
will(returnValue(Collections.singletonMap(messageId1, PENDING)));
|
||||
oneOf(db).getMessageState(txn2, messageId1);
|
||||
will(returnValue(PENDING));
|
||||
oneOf(db).getMessageDependencies(txn2, messageId1);
|
||||
will(returnValue(Collections.singletonMap(messageId2, DELIVERED)));
|
||||
oneOf(db).endTransaction(txn2);
|
||||
// Also get the pending message for delivery
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn3));
|
||||
oneOf(db).getRawMessage(txn3, messageId1);
|
||||
will(returnValue(message1.getRaw()));
|
||||
oneOf(db).getGroup(txn3, message1.getGroupId());
|
||||
will(returnValue(Collections.singletonMap(messageId, DELIVERED)));
|
||||
// Get message 1 and its metadata
|
||||
oneOf(db).getRawMessage(txn2, messageId1);
|
||||
will(returnValue(raw));
|
||||
oneOf(db).getGroup(txn2, groupId);
|
||||
will(returnValue(group));
|
||||
oneOf(db).getMessageMetadataForValidator(txn3, messageId1);
|
||||
oneOf(db).getMessageMetadataForValidator(txn2, messageId1);
|
||||
will(returnValue(metadata));
|
||||
// Deliver message 1
|
||||
oneOf(hook).incomingMessage(txn2, message1, metadata);
|
||||
oneOf(db).getRawMessage(txn2, messageId1);
|
||||
will(returnValue(raw));
|
||||
oneOf(db).setMessageState(txn2, messageId1, DELIVERED);
|
||||
// Message 1 has one pending dependent: 3
|
||||
oneOf(db).getMessageDependents(txn2, messageId1);
|
||||
will(returnValue(Collections.singletonMap(messageId3, PENDING)));
|
||||
oneOf(db).endTransaction(txn2);
|
||||
// Check whether message 2 is ready to be delivered
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn3));
|
||||
oneOf(db).getMessageState(txn3, messageId2);
|
||||
will(returnValue(PENDING));
|
||||
oneOf(db).getMessageDependencies(txn3, messageId2);
|
||||
will(returnValue(Collections.singletonMap(messageId, DELIVERED)));
|
||||
// Get message 2 and its metadata
|
||||
oneOf(db).getRawMessage(txn3, messageId2);
|
||||
will(returnValue(raw));
|
||||
oneOf(db).getGroup(txn3, groupId);
|
||||
will(returnValue(group));
|
||||
oneOf(db).getMessageMetadataForValidator(txn3, messageId2);
|
||||
will(returnValue(metadata));
|
||||
// Deliver message 2
|
||||
oneOf(hook).incomingMessage(txn3, message2, metadata);
|
||||
oneOf(db).getRawMessage(txn3, messageId2);
|
||||
will(returnValue(raw));
|
||||
oneOf(db).setMessageState(txn3, messageId2, DELIVERED);
|
||||
// Message 2 has one pending dependent: 3 (same dependent as 1)
|
||||
oneOf(db).getMessageDependents(txn3, messageId2);
|
||||
will(returnValue(Collections.singletonMap(messageId3, PENDING)));
|
||||
oneOf(db).endTransaction(txn3);
|
||||
// Deliver the pending message
|
||||
// Check whether message 3 is ready to be delivered (via 1)
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn4));
|
||||
oneOf(hook).incomingMessage(txn4, message1, metadata);
|
||||
oneOf(db).getRawMessage(txn4, messageId1);
|
||||
oneOf(db).getMessageState(txn4, messageId3);
|
||||
will(returnValue(PENDING));
|
||||
oneOf(db).getMessageDependencies(txn4, messageId3);
|
||||
will(returnValue(twoDependencies));
|
||||
// Get message 3 and its metadata
|
||||
oneOf(db).getRawMessage(txn4, messageId3);
|
||||
will(returnValue(raw));
|
||||
oneOf(db).setMessageState(txn4, message1, clientId, DELIVERED);
|
||||
oneOf(db).getMessageDependents(txn4, messageId1);
|
||||
will(returnValue(Collections.emptyMap()));
|
||||
oneOf(db).getGroup(txn4, groupId);
|
||||
will(returnValue(group));
|
||||
oneOf(db).getMessageMetadataForValidator(txn4, messageId3);
|
||||
will(returnValue(metadata));
|
||||
// Deliver message 3
|
||||
oneOf(hook).incomingMessage(txn4, message3, metadata);
|
||||
oneOf(db).getRawMessage(txn4, messageId3);
|
||||
will(returnValue(raw));
|
||||
oneOf(db).setMessageState(txn4, messageId3, DELIVERED);
|
||||
// Message 3 has one pending dependent: 4
|
||||
oneOf(db).getMessageDependents(txn4, messageId3);
|
||||
will(returnValue(Collections.singletonMap(messageId4, PENDING)));
|
||||
oneOf(db).endTransaction(txn4);
|
||||
// Check whether message 3 is ready to be delivered (again, via 2)
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn5));
|
||||
oneOf(db).getMessageState(txn5, messageId3);
|
||||
will(returnValue(DELIVERED)); // Already delivered
|
||||
oneOf(db).endTransaction(txn5);
|
||||
// Check whether message 4 is ready to be delivered (via 1 and 3)
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn6));
|
||||
oneOf(db).getMessageState(txn6, messageId4);
|
||||
will(returnValue(PENDING));
|
||||
oneOf(db).getMessageDependencies(txn6, messageId4);
|
||||
will(returnValue(Collections.singletonMap(messageId3, DELIVERED)));
|
||||
// Get message 4 and its metadata
|
||||
oneOf(db).getRawMessage(txn6, messageId4);
|
||||
will(returnValue(raw));
|
||||
oneOf(db).getGroup(txn6, groupId);
|
||||
will(returnValue(group));
|
||||
oneOf(db).getMessageMetadataForValidator(txn6, messageId4);
|
||||
will(returnValue(metadata));
|
||||
// Deliver message 4
|
||||
oneOf(hook).incomingMessage(txn6, message4, metadata);
|
||||
oneOf(db).getRawMessage(txn6, messageId4);
|
||||
will(returnValue(raw));
|
||||
oneOf(db).setMessageState(txn6, messageId4, DELIVERED);
|
||||
// Message 4 has no pending dependents
|
||||
oneOf(db).getMessageDependents(txn6, messageId4);
|
||||
will(returnValue(Collections.emptyMap()));
|
||||
oneOf(db).endTransaction(txn6);
|
||||
}});
|
||||
|
||||
ValidationManagerImpl vm = new ValidationManagerImpl(db, dbExecutor,
|
||||
@@ -799,6 +912,8 @@ public class ValidationManagerImplTest extends BriarTestCase {
|
||||
assertTrue(txn2.isComplete());
|
||||
assertTrue(txn3.isComplete());
|
||||
assertTrue(txn4.isComplete());
|
||||
assertTrue(txn5.isComplete());
|
||||
assertTrue(txn6.isComplete());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -810,6 +925,9 @@ public class ValidationManagerImplTest extends BriarTestCase {
|
||||
final MessageValidator validator = context.mock(MessageValidator.class);
|
||||
final IncomingMessageHook hook =
|
||||
context.mock(IncomingMessageHook.class);
|
||||
final Map<MessageId, State> twoDependencies = new LinkedHashMap<>();
|
||||
twoDependencies.put(messageId, DELIVERED);
|
||||
twoDependencies.put(messageId2, UNKNOWN);
|
||||
final Transaction txn = new Transaction(null, true);
|
||||
final Transaction txn1 = new Transaction(null, false);
|
||||
final Transaction txn2 = new Transaction(null, false);
|
||||
@@ -826,22 +944,23 @@ public class ValidationManagerImplTest extends BriarTestCase {
|
||||
// Store the validation result
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn1));
|
||||
oneOf(db).getMessageDependencies(txn1, messageId);
|
||||
will(returnValue(Collections.emptyMap()));
|
||||
oneOf(db).mergeMessageMetadata(txn1, messageId, metadata);
|
||||
oneOf(db).setMessageState(txn1, message, clientId, VALID);
|
||||
// Deliver the message
|
||||
oneOf(hook).incomingMessage(txn1, message, metadata);
|
||||
oneOf(db).getRawMessage(txn1, messageId);
|
||||
will(returnValue(raw));
|
||||
oneOf(db).setMessageState(txn1, messageId, DELIVERED);
|
||||
// Get any pending dependents
|
||||
oneOf(db).getMessageDependents(txn1, messageId);
|
||||
will(returnValue(Collections.singletonMap(messageId1, PENDING)));
|
||||
oneOf(db).endTransaction(txn1);
|
||||
// Deliver first message
|
||||
// Check whether the pending dependent is ready to be delivered
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn2));
|
||||
oneOf(hook).incomingMessage(txn2, message, metadata);
|
||||
oneOf(db).getRawMessage(txn2, messageId);
|
||||
will(returnValue(raw));
|
||||
oneOf(db).setMessageState(txn2, message, clientId, DELIVERED);
|
||||
oneOf(db).getMessageDependents(txn2, messageId);
|
||||
will(returnValue(Collections.singletonMap(messageId1, PENDING)));
|
||||
oneOf(db).getMessageState(txn2, messageId1);
|
||||
will(returnValue(PENDING));
|
||||
oneOf(db).getMessageDependencies(txn2, messageId1);
|
||||
will(returnValue(Collections.singletonMap(messageId2, VALID)));
|
||||
will(returnValue(twoDependencies));
|
||||
oneOf(db).endTransaction(txn2);
|
||||
}});
|
||||
|
||||
@@ -860,7 +979,6 @@ public class ValidationManagerImplTest extends BriarTestCase {
|
||||
|
||||
@Test
|
||||
public void testMessageDependencyCycle() throws Exception {
|
||||
states.put(messageId1, UNKNOWN);
|
||||
final MessageContext cycleContext = new MessageContext(metadata,
|
||||
Collections.singletonList(messageId));
|
||||
|
||||
@@ -891,9 +1009,9 @@ public class ValidationManagerImplTest extends BriarTestCase {
|
||||
oneOf(db).addMessageDependencies(txn1, message,
|
||||
validResultWithDependencies.getDependencies());
|
||||
oneOf(db).getMessageDependencies(txn1, messageId);
|
||||
will(returnValue(states));
|
||||
will(returnValue(Collections.singletonMap(messageId1, UNKNOWN)));
|
||||
oneOf(db).mergeMessageMetadata(txn1, messageId, metadata);
|
||||
oneOf(db).setMessageState(txn1, message, clientId, PENDING);
|
||||
oneOf(db).setMessageState(txn1, messageId, PENDING);
|
||||
oneOf(db).endTransaction(txn1);
|
||||
// Second message is coming in
|
||||
oneOf(db).startTransaction(true);
|
||||
@@ -912,7 +1030,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
|
||||
oneOf(db).getMessageDependencies(txn3, messageId1);
|
||||
will(returnValue(Collections.singletonMap(messageId, PENDING)));
|
||||
oneOf(db).mergeMessageMetadata(txn3, messageId1, metadata);
|
||||
oneOf(db).setMessageState(txn3, message1, clientId, PENDING);
|
||||
oneOf(db).setMessageState(txn3, messageId1, PENDING);
|
||||
oneOf(db).endTransaction(txn3);
|
||||
}});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user