mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-18 05:39:53 +01:00
Merge branch 'validation-manager-tests' into 'master'
Unit tests for ValidationManagerImpl Unit test for the validation manager. I also changed the way the validation manager loads unvalidated messages - instead of using a single DB task to load all unvalidated messages, it loads a list of message IDs and then loads each message in a separate task. This prevents the DatabaseExecutor from being blocked by a long-running task if there are lots of messages to validate. See merge request !113
This commit is contained in:
@@ -9,6 +9,7 @@ import org.briarproject.api.db.DatabaseExecutor;
|
|||||||
import org.briarproject.api.db.DbException;
|
import org.briarproject.api.db.DbException;
|
||||||
import org.briarproject.api.db.Metadata;
|
import org.briarproject.api.db.Metadata;
|
||||||
import org.briarproject.api.db.NoSuchGroupException;
|
import org.briarproject.api.db.NoSuchGroupException;
|
||||||
|
import org.briarproject.api.db.NoSuchMessageException;
|
||||||
import org.briarproject.api.db.Transaction;
|
import org.briarproject.api.db.Transaction;
|
||||||
import org.briarproject.api.event.Event;
|
import org.briarproject.api.event.Event;
|
||||||
import org.briarproject.api.event.EventListener;
|
import org.briarproject.api.event.EventListener;
|
||||||
@@ -23,8 +24,10 @@ import org.briarproject.api.sync.MessageValidator;
|
|||||||
import org.briarproject.api.sync.ValidationManager;
|
import org.briarproject.api.sync.ValidationManager;
|
||||||
import org.briarproject.util.ByteUtils;
|
import org.briarproject.util.ByteUtils;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Queue;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
@@ -81,19 +84,48 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
|||||||
dbExecutor.execute(new Runnable() {
|
dbExecutor.execute(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
// TODO: Don't do all of this in a single DB task
|
Queue<MessageId> unvalidated = new LinkedList<MessageId>();
|
||||||
Transaction txn = db.startTransaction();
|
Transaction txn = db.startTransaction();
|
||||||
try {
|
try {
|
||||||
for (MessageId id : db.getMessagesToValidate(txn, c)) {
|
unvalidated.addAll(db.getMessagesToValidate(txn, c));
|
||||||
byte[] raw = db.getRawMessage(txn, id);
|
|
||||||
Message m = parseMessage(id, raw);
|
|
||||||
Group g = db.getGroup(txn, m.getGroupId());
|
|
||||||
validateMessage(m, g);
|
|
||||||
}
|
|
||||||
txn.setComplete();
|
txn.setComplete();
|
||||||
} finally {
|
} finally {
|
||||||
db.endTransaction(txn);
|
db.endTransaction(txn);
|
||||||
}
|
}
|
||||||
|
validateNextMessage(unvalidated);
|
||||||
|
} catch (DbException e) {
|
||||||
|
if (LOG.isLoggable(WARNING))
|
||||||
|
LOG.log(WARNING, e.toString(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateNextMessage(final Queue<MessageId> unvalidated) {
|
||||||
|
if (unvalidated.isEmpty()) return;
|
||||||
|
dbExecutor.execute(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
Message m = null;
|
||||||
|
Group g = null;
|
||||||
|
Transaction txn = db.startTransaction();
|
||||||
|
try {
|
||||||
|
MessageId id = unvalidated.poll();
|
||||||
|
byte[] raw = db.getRawMessage(txn, id);
|
||||||
|
m = parseMessage(id, raw);
|
||||||
|
g = db.getGroup(txn, m.getGroupId());
|
||||||
|
txn.setComplete();
|
||||||
|
} catch (NoSuchMessageException e) {
|
||||||
|
LOG.info("Message removed before validation");
|
||||||
|
// Continue to next message
|
||||||
|
} catch (NoSuchGroupException e) {
|
||||||
|
LOG.info("Group removed before validation");
|
||||||
|
// Continue to next message
|
||||||
|
} finally {
|
||||||
|
db.endTransaction(txn);
|
||||||
|
}
|
||||||
|
if (m != null && g != null) validateMessage(m, g);
|
||||||
|
validateNextMessage(unvalidated);
|
||||||
} catch (DbException e) {
|
} catch (DbException e) {
|
||||||
if (LOG.isLoggable(WARNING))
|
if (LOG.isLoggable(WARNING))
|
||||||
LOG.log(WARNING, e.toString(), e);
|
LOG.log(WARNING, e.toString(), e);
|
||||||
@@ -158,21 +190,23 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
|||||||
if (e instanceof MessageAddedEvent) {
|
if (e instanceof MessageAddedEvent) {
|
||||||
// Validate the message if it wasn't created locally
|
// Validate the message if it wasn't created locally
|
||||||
MessageAddedEvent m = (MessageAddedEvent) e;
|
MessageAddedEvent m = (MessageAddedEvent) e;
|
||||||
if (m.getContactId() != null) loadGroup(m.getMessage());
|
if (m.getContactId() != null) loadGroupAndValidate(m.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadGroup(final Message m) {
|
private void loadGroupAndValidate(final Message m) {
|
||||||
dbExecutor.execute(new Runnable() {
|
dbExecutor.execute(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
|
Group g;
|
||||||
Transaction txn = db.startTransaction();
|
Transaction txn = db.startTransaction();
|
||||||
try {
|
try {
|
||||||
validateMessage(m, db.getGroup(txn, m.getGroupId()));
|
g = db.getGroup(txn, m.getGroupId());
|
||||||
txn.setComplete();
|
txn.setComplete();
|
||||||
} finally {
|
} finally {
|
||||||
db.endTransaction(txn);
|
db.endTransaction(txn);
|
||||||
}
|
}
|
||||||
|
validateMessage(m, g);
|
||||||
} catch (NoSuchGroupException e) {
|
} catch (NoSuchGroupException e) {
|
||||||
LOG.info("Group removed before validation");
|
LOG.info("Group removed before validation");
|
||||||
} catch (DbException e) {
|
} catch (DbException e) {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.briarproject.plugins;
|
package org.briarproject;
|
||||||
|
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
package org.briarproject.plugins.file;
|
package org.briarproject.plugins.file;
|
||||||
|
|
||||||
import org.briarproject.BriarTestCase;
|
import org.briarproject.BriarTestCase;
|
||||||
|
import org.briarproject.ImmediateExecutor;
|
||||||
import org.briarproject.TestUtils;
|
import org.briarproject.TestUtils;
|
||||||
import org.briarproject.api.contact.ContactId;
|
import org.briarproject.api.contact.ContactId;
|
||||||
import org.briarproject.api.plugins.TransportConnectionWriter;
|
import org.briarproject.api.plugins.TransportConnectionWriter;
|
||||||
import org.briarproject.api.plugins.simplex.SimplexPluginCallback;
|
import org.briarproject.api.plugins.simplex.SimplexPluginCallback;
|
||||||
import org.briarproject.plugins.ImmediateExecutor;
|
|
||||||
import org.briarproject.plugins.file.RemovableDriveMonitor.Callback;
|
import org.briarproject.plugins.file.RemovableDriveMonitor.Callback;
|
||||||
import org.jmock.Expectations;
|
import org.jmock.Expectations;
|
||||||
import org.jmock.Mockery;
|
import org.jmock.Mockery;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.google.inject.Guice;
|
|||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
|
|
||||||
import org.briarproject.BriarTestCase;
|
import org.briarproject.BriarTestCase;
|
||||||
|
import org.briarproject.ImmediateExecutor;
|
||||||
import org.briarproject.TestDatabaseModule;
|
import org.briarproject.TestDatabaseModule;
|
||||||
import org.briarproject.TestSystemModule;
|
import org.briarproject.TestSystemModule;
|
||||||
import org.briarproject.TestUtils;
|
import org.briarproject.TestUtils;
|
||||||
@@ -43,7 +44,6 @@ import org.briarproject.event.EventModule;
|
|||||||
import org.briarproject.identity.IdentityModule;
|
import org.briarproject.identity.IdentityModule;
|
||||||
import org.briarproject.lifecycle.LifecycleModule;
|
import org.briarproject.lifecycle.LifecycleModule;
|
||||||
import org.briarproject.messaging.MessagingModule;
|
import org.briarproject.messaging.MessagingModule;
|
||||||
import org.briarproject.plugins.ImmediateExecutor;
|
|
||||||
import org.briarproject.transport.TransportModule;
|
import org.briarproject.transport.TransportModule;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.briarproject.sync;
|
package org.briarproject.sync;
|
||||||
|
|
||||||
import org.briarproject.BriarTestCase;
|
import org.briarproject.BriarTestCase;
|
||||||
|
import org.briarproject.ImmediateExecutor;
|
||||||
import org.briarproject.TestUtils;
|
import org.briarproject.TestUtils;
|
||||||
import org.briarproject.api.TransportId;
|
import org.briarproject.api.TransportId;
|
||||||
import org.briarproject.api.contact.ContactId;
|
import org.briarproject.api.contact.ContactId;
|
||||||
@@ -10,7 +11,6 @@ import org.briarproject.api.event.EventBus;
|
|||||||
import org.briarproject.api.sync.Ack;
|
import org.briarproject.api.sync.Ack;
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
import org.briarproject.api.sync.PacketWriter;
|
import org.briarproject.api.sync.PacketWriter;
|
||||||
import org.briarproject.plugins.ImmediateExecutor;
|
|
||||||
import org.jmock.Expectations;
|
import org.jmock.Expectations;
|
||||||
import org.jmock.Mockery;
|
import org.jmock.Mockery;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|||||||
@@ -1,14 +1,285 @@
|
|||||||
package org.briarproject.sync;
|
package org.briarproject.sync;
|
||||||
|
|
||||||
import org.briarproject.BriarTestCase;
|
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 org.junit.Test;
|
||||||
|
|
||||||
import static org.junit.Assert.fail;
|
import java.util.Arrays;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
public class ValidationManagerImplTest extends BriarTestCase {
|
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
|
@Test
|
||||||
public void testUnitTestsExist() {
|
public void testMessagesAreValidatedAtStartup() throws Exception {
|
||||||
fail(); // FIXME: Write tests
|
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 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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user