From 476b1edbadf5bba6c4c1a67c709af066b1d54f40 Mon Sep 17 00:00:00 2001 From: akwizgran <akwizgran@users.sourceforge.net> Date: Fri, 26 Feb 2016 14:16:25 +0000 Subject: [PATCH] Unit tests for ValidationManagerImpl. --- .../sync/ValidationManagerImplTest.java | 277 +++++++++++++++++- 1 file changed, 274 insertions(+), 3 deletions(-) diff --git a/briar-tests/src/org/briarproject/sync/ValidationManagerImplTest.java b/briar-tests/src/org/briarproject/sync/ValidationManagerImplTest.java index 4863c85c9a..b55bacd906 100644 --- a/briar-tests/src/org/briarproject/sync/ValidationManagerImplTest.java +++ b/briar-tests/src/org/briarproject/sync/ValidationManagerImplTest.java @@ -1,14 +1,285 @@ package org.briarproject.sync; import org.briarproject.BriarTestCase; +import org.briarproject.ImmediateExecutor; +import org.briarproject.TestUtils; +import org.briarproject.api.UniqueId; +import org.briarproject.api.contact.ContactId; +import org.briarproject.api.db.DatabaseComponent; +import org.briarproject.api.db.Metadata; +import org.briarproject.api.db.NoSuchGroupException; +import org.briarproject.api.db.NoSuchMessageException; +import org.briarproject.api.db.Transaction; +import org.briarproject.api.event.MessageAddedEvent; +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.MessageId; +import org.briarproject.api.sync.MessageValidator; +import org.briarproject.api.sync.ValidationManager.ValidationHook; +import org.briarproject.util.ByteUtils; +import org.jmock.Expectations; +import org.jmock.Mockery; import org.junit.Test; -import static org.junit.Assert.fail; +import java.util.Arrays; +import java.util.concurrent.Executor; public class ValidationManagerImplTest extends BriarTestCase { + private final ClientId clientId = new ClientId(TestUtils.getRandomId()); + private final MessageId messageId = new MessageId(TestUtils.getRandomId()); + private final MessageId messageId1 = new MessageId(TestUtils.getRandomId()); + private final GroupId groupId = new GroupId(TestUtils.getRandomId()); + private final byte[] descriptor = new byte[32]; + private final Group group = new Group(groupId, clientId, descriptor); + private final long timestamp = System.currentTimeMillis(); + private final byte[] raw = new byte[123]; + private final Message message = new Message(messageId, groupId, timestamp, + raw); + private final Message message1 = new Message(messageId1, groupId, timestamp, + raw); + private final Metadata metadata = new Metadata(); + private final ContactId contactId = new ContactId(234); + + public ValidationManagerImplTest() { + // Encode the messages + System.arraycopy(groupId.getBytes(), 0, raw, 0, UniqueId.LENGTH); + ByteUtils.writeUint64(timestamp, raw, UniqueId.LENGTH); + } + + @Test + public void testMessagesAreValidatedAtStartup() 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 ValidationHook hook = context.mock(ValidationHook.class); + final Transaction txn = new Transaction(null); + final Transaction txn1 = new Transaction(null); + final Transaction txn2 = new Transaction(null); + final Transaction txn3 = new Transaction(null); + final Transaction txn4 = new Transaction(null); + context.checking(new Expectations() {{ + // Get messages to validate + oneOf(db).startTransaction(); + will(returnValue(txn)); + oneOf(db).getMessagesToValidate(txn, clientId); + will(returnValue(Arrays.asList(messageId, messageId1))); + oneOf(db).endTransaction(txn); + // Load the first raw message and group + oneOf(db).startTransaction(); + will(returnValue(txn1)); + oneOf(db).getRawMessage(txn1, messageId); + will(returnValue(raw)); + oneOf(db).getGroup(txn1, groupId); + will(returnValue(group)); + oneOf(db).endTransaction(txn1); + // Validate the first message: valid + oneOf(validator).validateMessage(message, group); + will(returnValue(metadata)); + // Store the validation result for the first message + oneOf(db).startTransaction(); + will(returnValue(txn2)); + oneOf(db).mergeMessageMetadata(txn2, messageId, metadata); + oneOf(db).setMessageValid(txn2, message, clientId, true); + oneOf(db).setMessageShared(txn2, message, true); + // Call the hook for the first message + oneOf(hook).validatingMessage(txn2, message, clientId, metadata); + oneOf(db).endTransaction(txn2); + // Load the second raw message and group + oneOf(db).startTransaction(); + will(returnValue(txn3)); + oneOf(db).getRawMessage(txn3, messageId1); + will(returnValue(raw)); + oneOf(db).getGroup(txn3, groupId); + will(returnValue(group)); + oneOf(db).endTransaction(txn3); + // Validate the second message: invalid + oneOf(validator).validateMessage(message1, group); + will(returnValue(null)); + // Store the validation result for the second message + oneOf(db).startTransaction(); + will(returnValue(txn4)); + oneOf(db).setMessageValid(txn4, message1, clientId, false); + oneOf(db).endTransaction(txn4); + }}); + + ValidationManagerImpl vm = new ValidationManagerImpl(db, dbExecutor, + cryptoExecutor); + vm.registerMessageValidator(clientId, validator); + vm.registerValidationHook(hook); + vm.start(); + + context.assertIsSatisfied(); + } + + @Test + public void testValidationContinuesAfterNoSuchMessageException() + 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 ValidationHook hook = context.mock(ValidationHook.class); + final Transaction txn = new Transaction(null); + final Transaction txn1 = new Transaction(null); + final Transaction txn2 = new Transaction(null); + final Transaction txn3 = new Transaction(null); + context.checking(new Expectations() {{ + // Get messages to validate + oneOf(db).startTransaction(); + will(returnValue(txn)); + oneOf(db).getMessagesToValidate(txn, clientId); + will(returnValue(Arrays.asList(messageId, messageId1))); + oneOf(db).endTransaction(txn); + // Load the first raw message - *gasp* it's gone! + oneOf(db).startTransaction(); + will(returnValue(txn1)); + oneOf(db).getRawMessage(txn1, messageId); + will(throwException(new NoSuchMessageException())); + oneOf(db).endTransaction(txn1); + // Load the second raw message and group + oneOf(db).startTransaction(); + will(returnValue(txn2)); + oneOf(db).getRawMessage(txn2, messageId1); + will(returnValue(raw)); + oneOf(db).getGroup(txn2, groupId); + will(returnValue(group)); + oneOf(db).endTransaction(txn2); + // Validate the second message: invalid + oneOf(validator).validateMessage(message1, group); + will(returnValue(null)); + // Store the validation result for the second message + oneOf(db).startTransaction(); + will(returnValue(txn3)); + oneOf(db).setMessageValid(txn3, message1, clientId, false); + oneOf(db).endTransaction(txn3); + }}); + + ValidationManagerImpl vm = new ValidationManagerImpl(db, dbExecutor, + cryptoExecutor); + vm.registerMessageValidator(clientId, validator); + vm.registerValidationHook(hook); + vm.start(); + + context.assertIsSatisfied(); + } + @Test - public void testUnitTestsExist() { - fail(); // FIXME: Write tests + public void testValidationContinuesAfterNoSuchGroupException() + 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 ValidationHook hook = context.mock(ValidationHook.class); + final Transaction txn = new Transaction(null); + final Transaction txn1 = new Transaction(null); + final Transaction txn2 = new Transaction(null); + final Transaction txn3 = new Transaction(null); + context.checking(new Expectations() {{ + // Get messages to validate + oneOf(db).startTransaction(); + will(returnValue(txn)); + oneOf(db).getMessagesToValidate(txn, clientId); + will(returnValue(Arrays.asList(messageId, messageId1))); + oneOf(db).endTransaction(txn); + // Load the first raw message + oneOf(db).startTransaction(); + will(returnValue(txn1)); + oneOf(db).getRawMessage(txn1, messageId); + will(returnValue(raw)); + // Load the group - *gasp* it's gone! + oneOf(db).getGroup(txn1, groupId); + will(throwException(new NoSuchGroupException())); + oneOf(db).endTransaction(txn1); + // Load the second raw message and group + oneOf(db).startTransaction(); + will(returnValue(txn2)); + oneOf(db).getRawMessage(txn2, messageId1); + will(returnValue(raw)); + oneOf(db).getGroup(txn2, groupId); + will(returnValue(group)); + oneOf(db).endTransaction(txn2); + // Validate the second message: invalid + oneOf(validator).validateMessage(message1, group); + will(returnValue(null)); + // Store the validation result for the second message + oneOf(db).startTransaction(); + will(returnValue(txn3)); + oneOf(db).setMessageValid(txn3, message1, clientId, false); + oneOf(db).endTransaction(txn3); + }}); + + ValidationManagerImpl vm = new ValidationManagerImpl(db, dbExecutor, + cryptoExecutor); + vm.registerMessageValidator(clientId, validator); + vm.registerValidationHook(hook); + vm.start(); + + context.assertIsSatisfied(); + } + + @Test + public void testNonLocalMessagesAreValidatedWhenAdded() 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 ValidationHook hook = context.mock(ValidationHook.class); + final Transaction txn = new Transaction(null); + final Transaction txn1 = new Transaction(null); + context.checking(new Expectations() {{ + // Load the group + oneOf(db).startTransaction(); + will(returnValue(txn)); + oneOf(db).getGroup(txn, groupId); + will(returnValue(group)); + oneOf(db).endTransaction(txn); + // Validate the message: valid + oneOf(validator).validateMessage(message, group); + will(returnValue(metadata)); + // Store the validation result + oneOf(db).startTransaction(); + will(returnValue(txn1)); + oneOf(db).mergeMessageMetadata(txn1, messageId, metadata); + oneOf(db).setMessageValid(txn1, message, clientId, true); + oneOf(db).setMessageShared(txn1, message, true); + // Call the hook + oneOf(hook).validatingMessage(txn1, message, clientId, metadata); + oneOf(db).endTransaction(txn1); + }}); + + ValidationManagerImpl vm = new ValidationManagerImpl(db, dbExecutor, + cryptoExecutor); + vm.registerMessageValidator(clientId, validator); + vm.registerValidationHook(hook); + vm.eventOccurred(new MessageAddedEvent(message, contactId)); + + context.assertIsSatisfied(); + } + + @Test + public void testLocalMessagesAreNotValidatedWhenAdded() 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 ValidationHook hook = context.mock(ValidationHook.class); + + ValidationManagerImpl vm = new ValidationManagerImpl(db, dbExecutor, + cryptoExecutor); + vm.registerMessageValidator(clientId, validator); + vm.registerValidationHook(hook); + vm.eventOccurred(new MessageAddedEvent(message, null)); + + context.assertIsSatisfied(); } } -- GitLab