Separate the sync layer from its clients. #112

This commit is contained in:
akwizgran
2015-12-21 14:36:24 +00:00
parent f5f572139a
commit 5355951466
117 changed files with 3160 additions and 3465 deletions

View File

@@ -6,18 +6,14 @@ import com.google.inject.Injector;
import org.briarproject.api.TransportId;
import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.crypto.KeyPair;
import org.briarproject.api.crypto.SecretKey;
import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.AuthorFactory;
import org.briarproject.api.sync.Ack;
import org.briarproject.api.sync.ClientId;
import org.briarproject.api.sync.Group;
import org.briarproject.api.sync.GroupFactory;
import org.briarproject.api.sync.Message;
import org.briarproject.api.sync.MessageFactory;
import org.briarproject.api.sync.MessageId;
import org.briarproject.api.sync.MessageVerifier;
import org.briarproject.api.sync.Offer;
import org.briarproject.api.sync.PacketReader;
import org.briarproject.api.sync.PacketReaderFactory;
@@ -26,7 +22,6 @@ import org.briarproject.api.sync.PacketWriterFactory;
import org.briarproject.api.sync.Request;
import org.briarproject.api.sync.SubscriptionUpdate;
import org.briarproject.api.sync.TransportUpdate;
import org.briarproject.api.sync.UnverifiedMessage;
import org.briarproject.api.transport.StreamContext;
import org.briarproject.api.transport.StreamReaderFactory;
import org.briarproject.api.transport.StreamWriterFactory;
@@ -46,6 +41,7 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import static org.briarproject.api.sync.SyncConstants.MAX_GROUP_DESCRIPTOR_LENGTH;
import static org.briarproject.api.transport.TransportConstants.TAG_LENGTH;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
@@ -58,7 +54,6 @@ public class ProtocolIntegrationTest extends BriarTestCase {
private final StreamWriterFactory streamWriterFactory;
private final PacketReaderFactory packetReaderFactory;
private final PacketWriterFactory packetWriterFactory;
private final MessageVerifier messageVerifier;
private final ContactId contactId;
private final SecretKey tagKey, headerKey;
@@ -78,29 +73,22 @@ public class ProtocolIntegrationTest extends BriarTestCase {
streamWriterFactory = i.getInstance(StreamWriterFactory.class);
packetReaderFactory = i.getInstance(PacketReaderFactory.class);
packetWriterFactory = i.getInstance(PacketWriterFactory.class);
messageVerifier = i.getInstance(MessageVerifier.class);
contactId = new ContactId(234);
// Create the transport keys
tagKey = TestUtils.createSecretKey();
headerKey = TestUtils.createSecretKey();
// Create a group
GroupFactory groupFactory = i.getInstance(GroupFactory.class);
group = groupFactory.createGroup("Group");
// Create an author
AuthorFactory authorFactory = i.getInstance(AuthorFactory.class);
CryptoComponent crypto = i.getInstance(CryptoComponent.class);
KeyPair authorKeyPair = crypto.generateSignatureKeyPair();
Author author = authorFactory.createAuthor("Alice",
authorKeyPair.getPublic().getEncoded());
// Create two messages to the group: one anonymous, one pseudonymous
ClientId clientId = new ClientId(TestUtils.getRandomId());
byte[] descriptor = new byte[MAX_GROUP_DESCRIPTOR_LENGTH];
group = groupFactory.createGroup(clientId, descriptor);
// Add two messages to the group
MessageFactory messageFactory = i.getInstance(MessageFactory.class);
String contentType = "text/plain";
long timestamp = System.currentTimeMillis();
String messageBody = "Hello world";
message = messageFactory.createAnonymousMessage(null, group,
"text/plain", timestamp, messageBody.getBytes("UTF-8"));
message1 = messageFactory.createPseudonymousMessage(null, group,
author, authorKeyPair.getPrivate(), contentType, timestamp,
message = messageFactory.createMessage(group.getId(), timestamp,
messageBody.getBytes("UTF-8"));
message1 = messageFactory.createMessage(group.getId(), timestamp,
messageBody.getBytes("UTF-8"));
messageIds = Arrays.asList(message.getId(), message1.getId());
// Create some transport properties
@@ -125,8 +113,8 @@ public class ProtocolIntegrationTest extends BriarTestCase {
packetWriter.writeAck(new Ack(messageIds));
packetWriter.writeMessage(message.getSerialised());
packetWriter.writeMessage(message1.getSerialised());
packetWriter.writeMessage(message.getRaw());
packetWriter.writeMessage(message1.getRaw());
packetWriter.writeOffer(new Offer(messageIds));
@@ -163,11 +151,11 @@ public class ProtocolIntegrationTest extends BriarTestCase {
// Read and verify the messages
assertTrue(packetReader.hasMessage());
UnverifiedMessage m = packetReader.readMessage();
checkMessageEquality(message, messageVerifier.verifyMessage(m));
Message m = packetReader.readMessage();
checkMessageEquality(message, m);
assertTrue(packetReader.hasMessage());
m = packetReader.readMessage();
checkMessageEquality(message1, messageVerifier.verifyMessage(m));
checkMessageEquality(message1, m);
assertFalse(packetReader.hasMessage());
// Read the offer
@@ -198,10 +186,7 @@ public class ProtocolIntegrationTest extends BriarTestCase {
private void checkMessageEquality(Message m1, Message m2) {
assertEquals(m1.getId(), m2.getId());
assertEquals(m1.getParent(), m2.getParent());
assertEquals(m1.getGroup(), m2.getGroup());
assertEquals(m1.getAuthor(), m2.getAuthor());
assertEquals(m1.getTimestamp(), m2.getTimestamp());
assertArrayEquals(m1.getSerialised(), m2.getSerialised());
assertArrayEquals(m1.getRaw(), m2.getRaw());
}
}

View File

@@ -1,83 +0,0 @@
package org.briarproject;
import org.briarproject.api.identity.Author;
import org.briarproject.api.sync.Group;
import org.briarproject.api.sync.Message;
import org.briarproject.api.sync.MessageId;
public class TestMessage implements Message {
private final MessageId id, parent;
private final Group group;
private final Author author;
private final String contentType;
private final long timestamp;
private final byte[] raw;
private final int bodyStart, bodyLength;
public TestMessage(MessageId id, MessageId parent, Group group,
Author author, String contentType, long timestamp, byte[] raw) {
this(id, parent, group, author, contentType, timestamp, raw, 0,
raw.length);
}
public TestMessage(MessageId id, MessageId parent, Group group,
Author author, String contentType, long timestamp, byte[] raw,
int bodyStart, int bodyLength) {
this.id = id;
this.parent = parent;
this.group = group;
this.author = author;
this.contentType = contentType;
this.timestamp = timestamp;
this.raw = raw;
this.bodyStart = bodyStart;
this.bodyLength = bodyLength;
}
public MessageId getId() {
return id;
}
public MessageId getParent() {
return parent;
}
public Group getGroup() {
return group;
}
public Author getAuthor() {
return author;
}
public String getContentType() {
return contentType;
}
public long getTimestamp() {
return timestamp;
}
public byte[] getSerialised() {
return raw;
}
public int getBodyStart() {
return bodyStart;
}
public int getBodyLength() {
return bodyLength;
}
@Override
public int hashCode() {
return id.hashCode();
}
@Override
public boolean equals(Object o) {
return o instanceof Message && id.equals(((Message)o).getId());
}
}

View File

@@ -1,7 +1,6 @@
package org.briarproject.db;
import org.briarproject.BriarTestCase;
import org.briarproject.TestMessage;
import org.briarproject.TestUtils;
import org.briarproject.api.Settings;
import org.briarproject.api.TransportId;
@@ -10,8 +9,10 @@ import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.crypto.SecretKey;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.Metadata;
import org.briarproject.api.db.NoSuchContactException;
import org.briarproject.api.db.NoSuchLocalAuthorException;
import org.briarproject.api.db.NoSuchMessageException;
import org.briarproject.api.db.NoSuchSubscriptionException;
import org.briarproject.api.db.NoSuchTransportException;
import org.briarproject.api.event.ContactAddedEvent;
@@ -25,6 +26,7 @@ import org.briarproject.api.event.MessageAddedEvent;
import org.briarproject.api.event.MessageRequestedEvent;
import org.briarproject.api.event.MessageToAckEvent;
import org.briarproject.api.event.MessageToRequestEvent;
import org.briarproject.api.event.MessageValidatedEvent;
import org.briarproject.api.event.MessagesAckedEvent;
import org.briarproject.api.event.MessagesSentEvent;
import org.briarproject.api.event.SubscriptionAddedEvent;
@@ -34,6 +36,7 @@ import org.briarproject.api.identity.AuthorId;
import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.lifecycle.ShutdownManager;
import org.briarproject.api.sync.Ack;
import org.briarproject.api.sync.ClientId;
import org.briarproject.api.sync.Group;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.Message;
@@ -56,7 +59,7 @@ import java.util.Collection;
import java.util.Collections;
import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.api.sync.MessagingConstants.GROUP_SALT_LENGTH;
import static org.briarproject.api.sync.SyncConstants.MAX_GROUP_DESCRIPTOR_LENGTH;
import static org.briarproject.db.DatabaseConstants.MAX_OFFERED_MESSAGES;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -66,28 +69,31 @@ import static org.junit.Assert.fail;
public class DatabaseComponentImplTest extends BriarTestCase {
protected final Object txn = new Object();
protected final GroupId groupId;
protected final Group group;
protected final AuthorId authorId;
protected final Author author;
protected final AuthorId localAuthorId;
protected final LocalAuthor localAuthor;
protected final MessageId messageId, messageId1;
protected final String contentType;
protected final long timestamp;
protected final int size;
protected final byte[] raw;
protected final Message message, message1;
protected final TransportId transportId;
protected final TransportProperties transportProperties;
protected final int maxLatency;
protected final ContactId contactId;
protected final Contact contact;
private final Object txn = new Object();
private final ClientId clientId;
private final GroupId groupId;
private final Group group;
private final AuthorId authorId;
private final Author author;
private final AuthorId localAuthorId;
private final LocalAuthor localAuthor;
private final MessageId messageId, messageId1;
private final int size;
private final byte[] raw;
private final Message message;
private final Metadata metadata;
private final TransportId transportId;
private final TransportProperties transportProperties;
private final int maxLatency;
private final ContactId contactId;
private final Contact contact;
public DatabaseComponentImplTest() {
clientId = new ClientId(TestUtils.getRandomId());
groupId = new GroupId(TestUtils.getRandomId());
group = new Group(groupId, "Group", new byte[GROUP_SALT_LENGTH]);
ClientId clientId = new ClientId(TestUtils.getRandomId());
byte[] descriptor = new byte[MAX_GROUP_DESCRIPTOR_LENGTH];
group = new Group(groupId, clientId, descriptor);
authorId = new AuthorId(TestUtils.getRandomId());
author = new Author(authorId, "Alice", new byte[MAX_PUBLIC_KEY_LENGTH]);
localAuthorId = new AuthorId(TestUtils.getRandomId());
@@ -95,14 +101,12 @@ public class DatabaseComponentImplTest extends BriarTestCase {
new byte[MAX_PUBLIC_KEY_LENGTH], new byte[100], 1234);
messageId = new MessageId(TestUtils.getRandomId());
messageId1 = new MessageId(TestUtils.getRandomId());
contentType = "text/plain";
timestamp = System.currentTimeMillis();
long timestamp = System.currentTimeMillis();
size = 1234;
raw = new byte[size];
message = new TestMessage(messageId, null, group, author, contentType,
timestamp, raw);
message1 = new TestMessage(messageId1, messageId, group, null,
contentType, timestamp, raw);
message = new Message(messageId, groupId, timestamp, raw);
metadata = new Metadata();
metadata.put("foo", new byte[] {'b', 'a', 'r'});
transportId = new TransportId("id");
transportProperties = new TransportProperties(Collections.singletonMap(
"bar", "baz"));
@@ -125,9 +129,9 @@ public class DatabaseComponentImplTest extends BriarTestCase {
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
final EventBus eventBus = context.mock(EventBus.class);
context.checking(new Expectations() {{
exactly(11).of(database).startTransaction();
exactly(10).of(database).startTransaction();
will(returnValue(txn));
exactly(11).of(database).commitTransaction(txn);
exactly(10).of(database).commitTransaction(txn);
// open()
oneOf(database).open();
will(returnValue(false));
@@ -161,11 +165,6 @@ public class DatabaseComponentImplTest extends BriarTestCase {
// addGroup() again
oneOf(database).containsGroup(txn, groupId);
will(returnValue(true));
// getMessageHeaders()
oneOf(database).containsGroup(txn, groupId);
will(returnValue(true));
oneOf(database).getMessageHeaders(txn, groupId);
will(returnValue(Collections.emptyList()));
// getGroups()
oneOf(database).getGroups(txn);
will(returnValue(Collections.singletonList(group)));
@@ -182,8 +181,6 @@ public class DatabaseComponentImplTest extends BriarTestCase {
// removeContact()
oneOf(database).containsContact(txn, contactId);
will(returnValue(true));
oneOf(database).getInboxGroupId(txn, contactId);
will(returnValue(null));
oneOf(database).removeContact(txn, contactId);
oneOf(eventBus).broadcast(with(any(ContactRemovedEvent.class)));
// removeLocalAuthor()
@@ -208,7 +205,6 @@ public class DatabaseComponentImplTest extends BriarTestCase {
db.getRemoteProperties(transportId));
db.addGroup(group); // First time - listeners called
db.addGroup(group); // Second time - not called
assertEquals(Collections.emptyList(), db.getMessageHeaders(groupId));
assertEquals(Collections.singletonList(group), db.getGroups());
db.removeGroup(group);
db.removeContact(contactId);
@@ -237,7 +233,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
DatabaseComponent db = createDatabaseComponent(database, eventBus,
shutdown);
db.addLocalMessage(message);
db.addLocalMessage(message, clientId, metadata);
context.assertIsSatisfied();
}
@@ -262,7 +258,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
DatabaseComponent db = createDatabaseComponent(database, eventBus,
shutdown);
db.addLocalMessage(message);
db.addLocalMessage(message, clientId, metadata);
context.assertIsSatisfied();
}
@@ -282,7 +278,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
oneOf(database).containsGroup(txn, groupId);
will(returnValue(true));
oneOf(database).addMessage(txn, message, true);
oneOf(database).setReadFlag(txn, messageId, true);
oneOf(database).mergeMessageMetadata(txn, messageId, metadata);
oneOf(database).getVisibility(txn, groupId);
will(returnValue(Collections.singletonList(contactId)));
oneOf(database).getContactIds(txn);
@@ -291,13 +287,14 @@ public class DatabaseComponentImplTest extends BriarTestCase {
will(returnValue(false));
oneOf(database).addStatus(txn, contactId, messageId, false, false);
oneOf(database).commitTransaction(txn);
// The message was added, so the listener should be called
// The message was added, so the listeners should be called
oneOf(eventBus).broadcast(with(any(MessageAddedEvent.class)));
oneOf(eventBus).broadcast(with(any(MessageValidatedEvent.class)));
}});
DatabaseComponent db = createDatabaseComponent(database, eventBus,
shutdown);
db.addLocalMessage(message);
db.addLocalMessage(message, clientId, metadata);
context.assertIsSatisfied();
}
@@ -385,7 +382,14 @@ public class DatabaseComponentImplTest extends BriarTestCase {
}
try {
db.getInboxGroupId(contactId);
db.getMessageStatus(contactId, groupId);
fail();
} catch (NoSuchContactException expected) {
// Expected
}
try {
db.getMessageStatus(contactId, messageId);
fail();
} catch (NoSuchContactException expected) {
// Expected
@@ -469,13 +473,6 @@ public class DatabaseComponentImplTest extends BriarTestCase {
// Expected
}
try {
db.setInboxGroup(contactId, group);
fail();
} catch (NoSuchContactException expected) {
// Expected
}
context.assertIsSatisfied();
}
@@ -540,6 +537,9 @@ public class DatabaseComponentImplTest extends BriarTestCase {
exactly(5).of(database).containsGroup(txn, groupId);
will(returnValue(false));
exactly(5).of(database).abortTransaction(txn);
// This is needed for getMessageStatus() to proceed
exactly(1).of(database).containsContact(txn, contactId);
will(returnValue(true));
}});
DatabaseComponent db = createDatabaseComponent(database, eventBus,
shutdown);
@@ -552,7 +552,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
}
try {
db.getMessageHeaders(groupId);
db.getMessageStatus(contactId, groupId);
fail();
} catch (NoSuchSubscriptionException expected) {
// Expected
@@ -582,6 +582,59 @@ public class DatabaseComponentImplTest extends BriarTestCase {
context.assertIsSatisfied();
}
@Test
public void testVariousMethodsThrowExceptionIfMessageIsMissing()
throws Exception {
Mockery context = new Mockery();
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
final EventBus eventBus = context.mock(EventBus.class);
context.checking(new Expectations() {{
// Check whether the message is in the DB (which it's not)
exactly(4).of(database).startTransaction();
will(returnValue(txn));
exactly(4).of(database).containsMessage(txn, messageId);
will(returnValue(false));
exactly(4).of(database).abortTransaction(txn);
// This is needed for getMessageStatus() to proceed
exactly(1).of(database).containsContact(txn, contactId);
will(returnValue(true));
}});
DatabaseComponent db = createDatabaseComponent(database, eventBus,
shutdown);
try {
db.getRawMessage(messageId);
fail();
} catch (NoSuchMessageException expected) {
// Expected
}
try {
db.getMessageMetadata(messageId);
fail();
} catch (NoSuchMessageException expected) {
// Expected
}
try {
db.getMessageStatus(contactId, messageId);
fail();
} catch (NoSuchMessageException expected) {
// Expected
}
try {
db.mergeMessageMetadata(messageId, metadata);
fail();
} catch (NoSuchMessageException expected) {
// Expected
}
context.assertIsSatisfied();
}
@Test
public void testVariousMethodsThrowExceptionIfTransportIsMissing()
throws Exception {

View File

@@ -2,21 +2,22 @@ package org.briarproject.db;
import org.briarproject.BriarTestCase;
import org.briarproject.TestDatabaseConfig;
import org.briarproject.TestMessage;
import org.briarproject.TestUtils;
import org.briarproject.api.TransportId;
import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.crypto.SecretKey;
import org.briarproject.api.db.DbException;
import org.briarproject.api.db.Metadata;
import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.AuthorId;
import org.briarproject.api.identity.LocalAuthor;
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.MessageHeader;
import org.briarproject.api.sync.MessageId;
import org.briarproject.api.sync.MessageStatus;
import org.briarproject.api.transport.IncomingKeys;
import org.briarproject.api.transport.OutgoingKeys;
import org.briarproject.api.transport.TransportKeys;
@@ -42,13 +43,11 @@ import java.util.concurrent.atomic.AtomicBoolean;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.api.sync.MessageHeader.State.STORED;
import static org.briarproject.api.sync.MessagingConstants.GROUP_SALT_LENGTH;
import static org.briarproject.api.sync.SyncConstants.MAX_GROUP_DESCRIPTOR_LENGTH;
import static org.briarproject.api.sync.SyncConstants.MAX_MESSAGE_LENGTH;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -65,7 +64,6 @@ public class H2DatabaseTest extends BriarTestCase {
private final AuthorId localAuthorId;
private final LocalAuthor localAuthor;
private final MessageId messageId;
private final String contentType;
private final long timestamp;
private final int size;
private final byte[] raw;
@@ -75,20 +73,20 @@ public class H2DatabaseTest extends BriarTestCase {
public H2DatabaseTest() throws Exception {
groupId = new GroupId(TestUtils.getRandomId());
group = new Group(groupId, "Group", new byte[GROUP_SALT_LENGTH]);
ClientId clientId = new ClientId(TestUtils.getRandomId());
byte[] descriptor = new byte[MAX_GROUP_DESCRIPTOR_LENGTH];
group = new Group(groupId, clientId, descriptor);
AuthorId authorId = new AuthorId(TestUtils.getRandomId());
author = new Author(authorId, "Alice", new byte[MAX_PUBLIC_KEY_LENGTH]);
localAuthorId = new AuthorId(TestUtils.getRandomId());
localAuthor = new LocalAuthor(localAuthorId, "Bob",
new byte[MAX_PUBLIC_KEY_LENGTH], new byte[100], 1234);
messageId = new MessageId(TestUtils.getRandomId());
contentType = "text/plain";
timestamp = System.currentTimeMillis();
size = 1234;
raw = new byte[size];
random.nextBytes(raw);
message = new TestMessage(messageId, null, group, author, contentType,
timestamp, raw);
message = new Message(messageId, groupId, timestamp, raw);
transportId = new TransportId("id");
contactId = new ContactId(1);
}
@@ -309,8 +307,7 @@ public class H2DatabaseTest extends BriarTestCase {
// Add some messages to ack
MessageId messageId1 = new MessageId(TestUtils.getRandomId());
Message message1 = new TestMessage(messageId1, null, group, author,
contentType, timestamp, raw);
Message message1 = new Message(messageId1, groupId, timestamp, raw);
db.addMessage(txn, message, true);
db.addStatus(txn, contactId, messageId, false, true);
db.raiseAckFlag(txn, contactId, messageId);
@@ -404,10 +401,9 @@ public class H2DatabaseTest extends BriarTestCase {
@Test
public void testGetFreeSpace() throws Exception {
byte[] largeBody = new byte[ONE_MEGABYTE];
byte[] largeBody = new byte[MAX_MESSAGE_LENGTH];
for (int i = 0; i < largeBody.length; i++) largeBody[i] = (byte) i;
Message message = new TestMessage(messageId, null, group, author,
contentType, timestamp, largeBody);
Message message = new Message(messageId, groupId, timestamp, largeBody);
Database<Connection> db = open(false);
// Sanity check: there should be enough space on disk for this test
@@ -718,343 +714,15 @@ public class H2DatabaseTest extends BriarTestCase {
db.close();
}
@Test
public void testGetParentWithNoParent() throws Exception {
Database<Connection> db = open(false);
Connection txn = db.startTransaction();
// Subscribe to a group
db.addGroup(txn, group);
// A message with no parent should return null
MessageId childId = new MessageId(TestUtils.getRandomId());
Message child = new TestMessage(childId, null, group, null, contentType,
timestamp, raw);
db.addMessage(txn, child, true);
assertTrue(db.containsMessage(txn, childId));
assertNull(db.getParent(txn, childId));
db.commitTransaction(txn);
db.close();
}
@Test
public void testGetParentWithAbsentParent() throws Exception {
Database<Connection> db = open(false);
Connection txn = db.startTransaction();
// Subscribe to a group
db.addGroup(txn, group);
// A message with an absent parent should return null
MessageId childId = new MessageId(TestUtils.getRandomId());
MessageId parentId = new MessageId(TestUtils.getRandomId());
Message child = new TestMessage(childId, parentId, group, null,
contentType, timestamp, raw);
db.addMessage(txn, child, true);
assertTrue(db.containsMessage(txn, childId));
assertFalse(db.containsMessage(txn, parentId));
assertNull(db.getParent(txn, childId));
db.commitTransaction(txn);
db.close();
}
@Test
public void testGetParentWithParentInAnotherGroup() throws Exception {
GroupId groupId1 = new GroupId(TestUtils.getRandomId());
Group group1 = new Group(groupId1, "Another group",
new byte[GROUP_SALT_LENGTH]);
Database<Connection> db = open(false);
Connection txn = db.startTransaction();
// Subscribe to two groups
db.addGroup(txn, group);
db.addGroup(txn, group1);
// A message with a parent in another group should return null
MessageId childId = new MessageId(TestUtils.getRandomId());
MessageId parentId = new MessageId(TestUtils.getRandomId());
Message child = new TestMessage(childId, parentId, group, null,
contentType, timestamp, raw);
Message parent = new TestMessage(parentId, null, group1, null,
contentType, timestamp, raw);
db.addMessage(txn, child, true);
db.addMessage(txn, parent, true);
assertTrue(db.containsMessage(txn, childId));
assertTrue(db.containsMessage(txn, parentId));
assertNull(db.getParent(txn, childId));
db.commitTransaction(txn);
db.close();
}
@Test
public void testGetParentWithParentInSameGroup() throws Exception {
Database<Connection> db = open(false);
Connection txn = db.startTransaction();
// Subscribe to a group
db.addGroup(txn, group);
// A message with a parent in the same group should return the parent
MessageId childId = new MessageId(TestUtils.getRandomId());
MessageId parentId = new MessageId(TestUtils.getRandomId());
Message child = new TestMessage(childId, parentId, group, null,
contentType, timestamp, raw);
Message parent = new TestMessage(parentId, null, group, null,
contentType, timestamp, raw);
db.addMessage(txn, child, true);
db.addMessage(txn, parent, true);
assertTrue(db.containsMessage(txn, childId));
assertTrue(db.containsMessage(txn, parentId));
assertEquals(parentId, db.getParent(txn, childId));
db.commitTransaction(txn);
db.close();
}
@Test
public void testGetMessageBody() throws Exception {
Database<Connection> db = open(false);
Connection txn = db.startTransaction();
// Add a contact and subscribe to a group
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
db.addGroup(txn, group);
// Store a couple of messages
int bodyLength = raw.length - 20;
Message message = new TestMessage(messageId, null, group, null,
contentType, timestamp, raw, 5, bodyLength);
MessageId messageId1 = new MessageId(TestUtils.getRandomId());
Message message1 = new TestMessage(messageId1, null, group, null,
contentType, timestamp, raw, 10, bodyLength);
db.addMessage(txn, message, true);
db.addMessage(txn, message1, true);
// Calculate the expected message bodies
byte[] expectedBody = new byte[bodyLength];
System.arraycopy(raw, 5, expectedBody, 0, bodyLength);
assertFalse(Arrays.equals(expectedBody, new byte[bodyLength]));
byte[] expectedBody1 = new byte[bodyLength];
System.arraycopy(raw, 10, expectedBody1, 0, bodyLength);
System.arraycopy(raw, 10, expectedBody1, 0, bodyLength);
// Retrieve the raw messages
assertArrayEquals(raw, db.getRawMessage(txn, messageId));
assertArrayEquals(raw, db.getRawMessage(txn, messageId1));
// Retrieve the message bodies
byte[] body = db.getMessageBody(txn, messageId);
assertArrayEquals(expectedBody, body);
byte[] body1 = db.getMessageBody(txn, messageId1);
assertArrayEquals(expectedBody1, body1);
db.commitTransaction(txn);
db.close();
}
@Test
public void testGetMessageHeaders() throws Exception {
Database<Connection> db = open(false);
Connection txn = db.startTransaction();
// Subscribe to a group
db.addGroup(txn, group);
// Store a couple of messages
db.addMessage(txn, message, true);
MessageId messageId1 = new MessageId(TestUtils.getRandomId());
MessageId parentId = new MessageId(TestUtils.getRandomId());
long timestamp1 = System.currentTimeMillis();
Message message1 = new TestMessage(messageId1, parentId, group, author,
contentType, timestamp1, raw);
db.addMessage(txn, message1, true);
// Mark one of the messages read
db.setReadFlag(txn, messageId, true);
// Retrieve the message headers (order is undefined)
Collection<MessageHeader> headers = db.getMessageHeaders(txn, groupId);
assertEquals(2, headers.size());
boolean firstFound = false, secondFound = false;
for (MessageHeader header : headers) {
if (messageId.equals(header.getId())) {
assertHeadersMatch(message, header);
assertTrue(header.isRead());
firstFound = true;
} else if (messageId1.equals(header.getId())) {
assertHeadersMatch(message1, header);
assertFalse(header.isRead());
secondFound = true;
} else {
fail();
}
}
// Both the headers should have been retrieved
assertTrue(firstFound);
assertTrue(secondFound);
db.commitTransaction(txn);
db.close();
}
private void assertHeadersMatch(Message m, MessageHeader h) {
assertEquals(m.getId(), h.getId());
if (m.getParent() == null) assertNull(h.getParent());
else assertEquals(m.getParent(), h.getParent());
assertEquals(m.getGroup().getId(), h.getGroupId());
if (m.getAuthor() == null) assertNull(h.getAuthor());
else assertEquals(m.getAuthor(), h.getAuthor());
assertEquals(m.getContentType(), h.getContentType());
assertEquals(m.getTimestamp(), h.getTimestamp());
}
@Test
public void testAuthorStatus() throws Exception {
Database<Connection> db = open(false);
Connection txn = db.startTransaction();
// Add a contact and subscribe to a group
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
db.addGroup(txn, group);
// Store a message from the contact - status VERIFIED
db.addMessage(txn, message, true);
AuthorId authorId1 = new AuthorId(TestUtils.getRandomId());
// Store a message from an unknown author - status UNKNOWN
Author author1 = new Author(authorId1, "Bob",
new byte[MAX_PUBLIC_KEY_LENGTH]);
MessageId messageId1 = new MessageId(TestUtils.getRandomId());
Message message1 = new TestMessage(messageId1, null, group, author1,
contentType, timestamp, raw);
db.addMessage(txn, message1, true);
// Store an anonymous message - status ANONYMOUS
MessageId messageId2 = new MessageId(TestUtils.getRandomId());
Message message2 = new TestMessage(messageId2, null, group, null,
contentType, timestamp, raw);
db.addMessage(txn, message2, true);
// Retrieve the message headers (order is undefined)
Collection<MessageHeader> headers = db.getMessageHeaders(txn, groupId);
assertEquals(3, headers.size());
boolean firstFound = false, secondFound = false, thirdFound = false;
for (MessageHeader header : headers) {
if (messageId.equals(header.getId())) {
assertHeadersMatch(message, header);
assertEquals(Author.Status.VERIFIED, header.getAuthorStatus());
firstFound = true;
} else if (messageId1.equals(header.getId())) {
assertHeadersMatch(message1, header);
assertEquals(Author.Status.UNKNOWN, header.getAuthorStatus());
secondFound = true;
} else if (messageId2.equals(header.getId())) {
assertHeadersMatch(message2, header);
assertEquals(Author.Status.ANONYMOUS, header.getAuthorStatus());
thirdFound = true;
} else {
fail();
}
}
// All of the headers should have been retrieved
assertTrue(firstFound);
assertTrue(secondFound);
assertTrue(thirdFound);
db.commitTransaction(txn);
db.close();
}
@Test
public void testReadFlag() throws Exception {
Database<Connection> db = open(false);
Connection txn = db.startTransaction();
// Subscribe to a group and store a message
db.addGroup(txn, group);
db.addMessage(txn, message, true);
// The message should be unread by default
assertFalse(db.getReadFlag(txn, messageId));
// Mark the message read
db.setReadFlag(txn, messageId, true);
// The message should be read
assertTrue(db.getReadFlag(txn, messageId));
// Mark the message unread
db.setReadFlag(txn, messageId, false);
// The message should be unread
assertFalse(db.getReadFlag(txn, messageId));
db.commitTransaction(txn);
db.close();
}
@Test
public void testGetUnreadMessageCounts() throws Exception {
Database<Connection> db = open(false);
Connection txn = db.startTransaction();
// Subscribe to a couple of groups
db.addGroup(txn, group);
GroupId groupId1 = new GroupId(TestUtils.getRandomId());
Group group1 = new Group(groupId1, "Another group",
new byte[GROUP_SALT_LENGTH]);
db.addGroup(txn, group1);
// Store two messages in the first group
db.addMessage(txn, message, true);
MessageId messageId1 = new MessageId(TestUtils.getRandomId());
Message message1 = new TestMessage(messageId1, null, group, author,
contentType, timestamp, raw);
db.addMessage(txn, message1, true);
// Store one message in the second group
MessageId messageId2 = new MessageId(TestUtils.getRandomId());
Message message2 = new TestMessage(messageId2, null, group1, author,
contentType, timestamp, raw);
db.addMessage(txn, message2, true);
// Mark one of the messages in the first group read
db.setReadFlag(txn, messageId, true);
// There should be one unread message in each group
Map<GroupId, Integer> counts = db.getUnreadMessageCounts(txn);
assertEquals(2, counts.size());
Integer count = counts.get(groupId);
assertNotNull(count);
assertEquals(1, count.intValue());
count = counts.get(groupId1);
assertNotNull(count);
assertEquals(1, count.intValue());
// Mark the read message unread
db.setReadFlag(txn, messageId, false);
// Mark the message in the second group read
db.setReadFlag(txn, messageId2, true);
// There should be two unread messages in the first group, none in
// the second group
counts = db.getUnreadMessageCounts(txn);
assertEquals(1, counts.size());
count = counts.get(groupId);
assertNotNull(count);
assertEquals(2, count.intValue());
db.commitTransaction(txn);
db.close();
}
@Test
public void testMultipleSubscriptionsAndUnsubscriptions() throws Exception {
// Create some groups
List<Group> groups = new ArrayList<Group>();
for (int i = 0; i < 100; i++) {
GroupId id = new GroupId(TestUtils.getRandomId());
String name = "Group " + i;
groups.add(new Group(id, name, new byte[GROUP_SALT_LENGTH]));
ClientId clientId = new ClientId(TestUtils.getRandomId());
byte[] descriptor = new byte[MAX_GROUP_DESCRIPTOR_LENGTH];
groups.add(new Group(id, clientId, descriptor));
}
Database<Connection> db = open(false);
@@ -1288,41 +956,6 @@ public class H2DatabaseTest extends BriarTestCase {
db.close();
}
@Test
public void testGetInboxMessageHeaders() throws Exception {
Database<Connection> db = open(false);
Connection txn = db.startTransaction();
// Add a contact and an inbox group - no headers should be returned
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
db.addGroup(txn, group);
db.setInboxGroup(txn, contactId, group);
assertEquals(Collections.emptyList(),
db.getInboxMessageHeaders(txn, contactId));
// Add a message to the inbox group - the header should be returned
db.addMessage(txn, message, true);
db.addStatus(txn, contactId, messageId, false, false);
Collection<MessageHeader> headers =
db.getInboxMessageHeaders(txn, contactId);
assertEquals(1, headers.size());
MessageHeader header = headers.iterator().next();
assertEquals(messageId, header.getId());
assertNull(header.getParent());
assertEquals(groupId, header.getGroupId());
assertEquals(localAuthor, header.getAuthor());
assertEquals(contentType, header.getContentType());
assertEquals(timestamp, header.getTimestamp());
assertEquals(true, header.isLocal());
assertEquals(false, header.isRead());
assertEquals(STORED, header.getStatus());
assertFalse(header.isRead());
db.commitTransaction(txn);
db.close();
}
@Test
public void testOfferedMessages() throws Exception {
Database<Connection> db = open(false);
@@ -1392,6 +1025,116 @@ public class H2DatabaseTest extends BriarTestCase {
db.close();
}
@Test
public void testMessageMetadata() 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, true);
// Attach some metadata to the message
Metadata metadata = new Metadata();
metadata.put("foo", new byte[]{'b', 'a', 'r'});
db.mergeMessageMetadata(txn, messageId, metadata);
// Retrieve the metadata for the message
Metadata retrieved = db.getMessageMetadata(txn, messageId);
assertEquals(1, retrieved.size());
assertTrue(retrieved.containsKey("foo"));
assertArrayEquals(metadata.get("foo"), retrieved.get("foo"));
// Retrieve the metadata for the group
Map<MessageId, Metadata> all = db.getMessageMetadata(txn, groupId);
assertEquals(1, all.size());
assertTrue(all.containsKey(messageId));
retrieved = all.get(messageId);
assertEquals(1, retrieved.size());
assertTrue(retrieved.containsKey("foo"));
assertArrayEquals(metadata.get("foo"), retrieved.get("foo"));
db.commitTransaction(txn);
db.close();
}
@Test
public void testGetMessageStatus() throws Exception {
Database<Connection> db = open(false);
Connection txn = db.startTransaction();
// Add a contact who subscribes to a group
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
db.setGroups(txn, contactId, Collections.singletonList(group), 1);
// Subscribe to the group and make it visible to the contact
db.addGroup(txn, group);
db.addVisibility(txn, contactId, groupId);
// Add a message to the group
db.addMessage(txn, message, true);
db.addStatus(txn, contactId, messageId, false, false);
// The message should not be sent or seen
MessageStatus status = db.getMessageStatus(txn, contactId, messageId);
assertEquals(messageId, status.getMessageId());
assertEquals(contactId, status.getContactId());
assertFalse(status.isSent());
assertFalse(status.isSeen());
// The same status should be returned when querying by group
Collection<MessageStatus> statuses = db.getMessageStatus(txn,
contactId, groupId);
assertEquals(1, statuses.size());
status = statuses.iterator().next();
assertEquals(messageId, status.getMessageId());
assertEquals(contactId, status.getContactId());
assertFalse(status.isSent());
assertFalse(status.isSeen());
// Pretend the message was sent to the contact
db.updateExpiryTime(txn, contactId, messageId, Integer.MAX_VALUE);
// The message should be sent but not seen
status = db.getMessageStatus(txn, contactId, messageId);
assertEquals(messageId, status.getMessageId());
assertEquals(contactId, status.getContactId());
assertTrue(status.isSent());
assertFalse(status.isSeen());
// The same status should be returned when querying by group
statuses = db.getMessageStatus(txn, contactId, groupId);
assertEquals(1, statuses.size());
status = statuses.iterator().next();
assertEquals(messageId, status.getMessageId());
assertEquals(contactId, status.getContactId());
assertTrue(status.isSent());
assertFalse(status.isSeen());
// Pretend the message was acked by the contact
db.raiseSeenFlag(txn, contactId, messageId);
// The message should be sent and seen
status = db.getMessageStatus(txn, contactId, messageId);
assertEquals(messageId, status.getMessageId());
assertEquals(contactId, status.getContactId());
assertTrue(status.isSent());
assertTrue(status.isSeen());
// The same status should be returned when querying by group
statuses = db.getMessageStatus(txn, contactId, groupId);
assertEquals(1, statuses.size());
status = statuses.iterator().next();
assertEquals(messageId, status.getMessageId());
assertEquals(contactId, status.getContactId());
assertTrue(status.isSent());
assertTrue(status.isSeen());
db.commitTransaction(txn);
db.close();
}
@Test
public void testExceptionHandling() throws Exception {
Database<Connection> db = open(false);

View File

@@ -15,13 +15,19 @@ import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.crypto.KeyPair;
import org.briarproject.api.crypto.PrivateKey;
import org.briarproject.api.crypto.Signature;
import org.briarproject.api.forum.ForumConstants;
import org.briarproject.api.forum.ForumPost;
import org.briarproject.api.forum.ForumPostFactory;
import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.AuthorFactory;
import org.briarproject.api.messaging.MessagingConstants;
import org.briarproject.api.messaging.PrivateMessage;
import org.briarproject.api.messaging.PrivateMessageFactory;
import org.briarproject.api.sync.Ack;
import org.briarproject.api.sync.ClientId;
import org.briarproject.api.sync.Group;
import org.briarproject.api.sync.GroupFactory;
import org.briarproject.api.sync.Message;
import org.briarproject.api.sync.MessageFactory;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.MessageId;
import org.briarproject.api.sync.Offer;
import org.briarproject.api.sync.PacketWriter;
@@ -33,6 +39,8 @@ import org.briarproject.crypto.CryptoModule;
import org.briarproject.data.DataModule;
import org.briarproject.db.DatabaseModule;
import org.briarproject.event.EventModule;
import org.briarproject.forum.ForumModule;
import org.briarproject.messaging.MessagingModule;
import org.junit.Test;
import java.io.ByteArrayOutputStream;
@@ -43,14 +51,14 @@ import java.util.Random;
import static org.briarproject.api.TransportPropertyConstants.MAX_PROPERTIES_PER_TRANSPORT;
import static org.briarproject.api.TransportPropertyConstants.MAX_PROPERTY_LENGTH;
import static org.briarproject.api.TransportPropertyConstants.MAX_TRANSPORT_ID_LENGTH;
import static org.briarproject.api.forum.ForumConstants.MAX_FORUM_POST_BODY_LENGTH;
import static org.briarproject.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
import static org.briarproject.api.sync.MessagingConstants.MAX_BODY_LENGTH;
import static org.briarproject.api.sync.MessagingConstants.MAX_CONTENT_TYPE_LENGTH;
import static org.briarproject.api.sync.MessagingConstants.MAX_GROUP_NAME_LENGTH;
import static org.briarproject.api.sync.MessagingConstants.MAX_PAYLOAD_LENGTH;
import static org.briarproject.api.sync.MessagingConstants.MAX_SUBSCRIPTIONS;
import static org.briarproject.api.messaging.MessagingConstants.MAX_PRIVATE_MESSAGE_BODY_LENGTH;
import static org.briarproject.api.sync.SyncConstants.MAX_GROUP_DESCRIPTOR_LENGTH;
import static org.briarproject.api.sync.SyncConstants.MAX_PACKET_PAYLOAD_LENGTH;
import static org.briarproject.api.sync.SyncConstants.MAX_SUBSCRIPTIONS;
import static org.junit.Assert.assertTrue;
public class ConstantsTest extends BriarTestCase {
@@ -58,18 +66,21 @@ public class ConstantsTest extends BriarTestCase {
private final CryptoComponent crypto;
private final GroupFactory groupFactory;
private final AuthorFactory authorFactory;
private final MessageFactory messageFactory;
private final PrivateMessageFactory privateMessageFactory;
private final ForumPostFactory forumPostFactory;
private final PacketWriterFactory packetWriterFactory;
public ConstantsTest() throws Exception {
Injector i = Guice.createInjector(new TestDatabaseModule(),
new TestLifecycleModule(), new TestSystemModule(),
new CryptoModule(), new DatabaseModule(), new EventModule(),
new SyncModule(), new DataModule());
new CryptoModule(), new DatabaseModule(), new DataModule(),
new EventModule(), new ForumModule(), new MessagingModule(),
new SyncModule());
crypto = i.getInstance(CryptoComponent.class);
groupFactory = i.getInstance(GroupFactory.class);
authorFactory = i.getInstance(AuthorFactory.class);
messageFactory = i.getInstance(MessageFactory.class);
privateMessageFactory = i.getInstance(PrivateMessageFactory.class);
forumPostFactory = i.getInstance(ForumPostFactory.class);
packetWriterFactory = i.getInstance(PacketWriterFactory.class);
}
@@ -100,14 +111,13 @@ public class ConstantsTest extends BriarTestCase {
sig.initSign(keyPair.getPrivate());
sig.update(toBeSigned);
byte[] signature = sig.sign();
assertTrue("Length " + signature.length,
signature.length <= MAX_SIGNATURE_LENGTH);
assertTrue(signature.length <= MAX_SIGNATURE_LENGTH);
}
}
@Test
public void testMessageIdsFitIntoLargeAck() throws Exception {
testMessageIdsFitIntoAck(MAX_PAYLOAD_LENGTH);
testMessageIdsFitIntoAck(MAX_PACKET_PAYLOAD_LENGTH);
}
@Test
@@ -116,36 +126,53 @@ public class ConstantsTest extends BriarTestCase {
}
@Test
public void testMessageFitsIntoPacket() throws Exception {
public void testPrivateMessageFitsIntoPacket() throws Exception {
// Create a maximum-length private message
GroupId groupId = new GroupId(TestUtils.getRandomId());
long timestamp = Long.MAX_VALUE;
MessageId parent = new MessageId(TestUtils.getRandomId());
// Create a maximum-length group
String groupName = TestUtils.createRandomString(MAX_GROUP_NAME_LENGTH);
Group group = groupFactory.createGroup(groupName);
String contentType = TestUtils.createRandomString(
MessagingConstants.MAX_CONTENT_TYPE_LENGTH);
byte[] body = new byte[MAX_PRIVATE_MESSAGE_BODY_LENGTH];
PrivateMessage message = privateMessageFactory.createPrivateMessage(
groupId, timestamp, parent, contentType, body);
// Check the size of the serialised message
int length = message.getMessage().getRaw().length;
assertTrue(length > UniqueId.LENGTH + 8 + UniqueId.LENGTH
+ MessagingConstants.MAX_CONTENT_TYPE_LENGTH
+ MAX_PRIVATE_MESSAGE_BODY_LENGTH);
assertTrue(length <= MAX_PACKET_PAYLOAD_LENGTH);
}
@Test
public void testForumPostFitsIntoPacket() throws Exception {
// Create a maximum-length author
String authorName =
TestUtils.createRandomString(MAX_AUTHOR_NAME_LENGTH);
String authorName = TestUtils.createRandomString(
MAX_AUTHOR_NAME_LENGTH);
byte[] authorPublic = new byte[MAX_PUBLIC_KEY_LENGTH];
Author author = authorFactory.createAuthor(authorName, authorPublic);
// Create a maximum-length message
PrivateKey privateKey = crypto.generateSignatureKeyPair().getPrivate();
String contentType =
TestUtils.createRandomString(MAX_CONTENT_TYPE_LENGTH);
// Create a maximum-length forum post
GroupId groupId = new GroupId(TestUtils.getRandomId());
long timestamp = Long.MAX_VALUE;
byte[] body = new byte[MAX_BODY_LENGTH];
Message message = messageFactory.createPseudonymousMessage(parent,
group, author, privateKey, contentType, timestamp, body);
MessageId parent = new MessageId(TestUtils.getRandomId());
String contentType = TestUtils.createRandomString(
ForumConstants.MAX_CONTENT_TYPE_LENGTH);
byte[] body = new byte[MAX_FORUM_POST_BODY_LENGTH];
PrivateKey privateKey = crypto.generateSignatureKeyPair().getPrivate();
ForumPost post = forumPostFactory.createPseudonymousPost(groupId,
timestamp, parent, author, contentType, body, privateKey);
// Check the size of the serialised message
int length = message.getSerialised().length;
assertTrue(length > UniqueId.LENGTH + MAX_GROUP_NAME_LENGTH
+ MAX_PUBLIC_KEY_LENGTH + MAX_AUTHOR_NAME_LENGTH
+ MAX_PUBLIC_KEY_LENGTH + MAX_CONTENT_TYPE_LENGTH
+ MAX_BODY_LENGTH);
assertTrue(length <= MAX_PAYLOAD_LENGTH);
int length = post.getMessage().getRaw().length;
assertTrue(length > UniqueId.LENGTH + 8 + UniqueId.LENGTH
+ MAX_AUTHOR_NAME_LENGTH + MAX_PUBLIC_KEY_LENGTH
+ ForumConstants.MAX_CONTENT_TYPE_LENGTH
+ MAX_FORUM_POST_BODY_LENGTH);
assertTrue(length <= MAX_PACKET_PAYLOAD_LENGTH);
}
@Test
public void testMessageIdsFitIntoLargeOffer() throws Exception {
testMessageIdsFitIntoOffer(MAX_PAYLOAD_LENGTH);
testMessageIdsFitIntoOffer(MAX_PACKET_PAYLOAD_LENGTH);
}
@Test
@@ -155,7 +182,7 @@ public class ConstantsTest extends BriarTestCase {
@Test
public void testMessageIdsFitIntoLargeRequest() throws Exception {
testMessageIdsFitIntoRequest(MAX_PAYLOAD_LENGTH);
testMessageIdsFitIntoRequest(MAX_PACKET_PAYLOAD_LENGTH);
}
@Test
@@ -181,16 +208,19 @@ public class ConstantsTest extends BriarTestCase {
PacketWriter writer = packetWriterFactory.createPacketWriter(out);
writer.writeTransportUpdate(u);
// Check the size of the serialised transport update
assertTrue(out.size() <= MAX_PAYLOAD_LENGTH);
assertTrue(out.size() <= MAX_PACKET_PAYLOAD_LENGTH);
}
@Test
public void testGroupsFitIntoSubscriptionUpdate() throws Exception {
// Create the maximum number of maximum-length groups
Random random = new Random();
ClientId clientId = new ClientId(TestUtils.getRandomId());
Collection<Group> groups = new ArrayList<Group>();
for (int i = 0; i < MAX_SUBSCRIPTIONS; i++) {
String name = TestUtils.createRandomString(MAX_GROUP_NAME_LENGTH);
groups.add(groupFactory.createGroup(name));
byte[] descriptor = new byte[MAX_GROUP_DESCRIPTOR_LENGTH];
random.nextBytes(descriptor);
groups.add(groupFactory.createGroup(clientId, descriptor));
}
// Create a maximum-length subscription update
SubscriptionUpdate u = new SubscriptionUpdate(groups, Long.MAX_VALUE);
@@ -199,7 +229,7 @@ public class ConstantsTest extends BriarTestCase {
PacketWriter writer = packetWriterFactory.createPacketWriter(out);
writer.writeSubscriptionUpdate(u);
// Check the size of the serialised subscription update
assertTrue(out.size() <= MAX_PAYLOAD_LENGTH);
assertTrue(out.size() <= MAX_PACKET_PAYLOAD_LENGTH);
}
private void testMessageIdsFitIntoAck(int length) throws Exception {

View File

@@ -1,100 +0,0 @@
package org.briarproject.sync;
import org.briarproject.BriarTestCase;
import org.briarproject.api.FormatException;
import org.briarproject.api.crypto.MessageDigest;
import org.junit.Test;
import java.security.GeneralSecurityException;
import java.util.Random;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
public class ConsumersTest extends BriarTestCase {
@Test
public void testDigestingConsumer() throws Exception {
byte[] data = new byte[1234];
// Generate some random data and digest it
new Random().nextBytes(data);
MessageDigest messageDigest = new TestMessageDigest();
messageDigest.update(data);
byte[] dig = messageDigest.digest();
// Check that feeding a DigestingConsumer generates the same digest
DigestingConsumer dc = new DigestingConsumer(messageDigest);
dc.write(data[0]);
dc.write(data, 1, data.length - 2);
dc.write(data[data.length - 1]);
byte[] dig1 = messageDigest.digest();
assertArrayEquals(dig, dig1);
}
@Test(expected = FormatException.class)
public void testCountingConsumer() throws Exception {
byte[] data = new byte[1234];
CountingConsumer cc = new CountingConsumer(data.length);
cc.write(data[0]);
cc.write(data, 1, data.length - 2);
cc.write(data[data.length - 1]);
assertEquals(data.length, cc.getCount());
cc.write((byte) 0);
}
@Test
public void testCopyingConsumer() throws Exception {
byte[] data = new byte[1234];
new Random().nextBytes(data);
// Check that a CopyingConsumer creates a faithful copy
CopyingConsumer cc = new CopyingConsumer();
cc.write(data[0]);
cc.write(data, 1, data.length - 2);
cc.write(data[data.length - 1]);
assertArrayEquals(data, cc.getCopy());
}
private static class TestMessageDigest implements MessageDigest {
private final java.security.MessageDigest delegate;
private TestMessageDigest() throws GeneralSecurityException {
delegate = java.security.MessageDigest.getInstance("SHA-256");
}
public byte[] digest() {
return delegate.digest();
}
public byte[] digest(byte[] input) {
return delegate.digest(input);
}
public int digest(byte[] buf, int offset, int len) {
byte[] digest = digest();
len = Math.min(len, digest.length);
System.arraycopy(digest, 0, buf, offset, len);
return len;
}
public int getDigestLength() {
return delegate.getDigestLength();
}
public void reset() {
delegate.reset();
}
public void update(byte input) {
delegate.update(input);
}
public void update(byte[] input) {
delegate.update(input);
}
public void update(byte[] input, int offset, int len) {
delegate.update(input, offset, len);
}
}
}

View File

@@ -1,50 +1,29 @@
package org.briarproject.sync;
import com.google.inject.Guice;
import com.google.inject.Injector;
import org.briarproject.BriarTestCase;
import org.briarproject.TestUtils;
import org.briarproject.api.FormatException;
import org.briarproject.api.data.BdfReaderFactory;
import org.briarproject.api.data.BdfWriter;
import org.briarproject.api.data.BdfWriterFactory;
import org.briarproject.data.DataModule;
import org.briarproject.api.UniqueId;
import org.briarproject.util.ByteUtils;
import org.junit.Test;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import static org.briarproject.api.data.DataConstants.LIST_END_LENGTH;
import static org.briarproject.api.data.DataConstants.UNIQUE_ID_LENGTH;
import static org.briarproject.api.sync.MessagingConstants.HEADER_LENGTH;
import static org.briarproject.api.sync.MessagingConstants.MAX_PAYLOAD_LENGTH;
import static org.briarproject.api.sync.PacketTypes.ACK;
import static org.briarproject.api.sync.PacketTypes.OFFER;
import static org.briarproject.api.sync.PacketTypes.REQUEST;
import static org.briarproject.api.sync.SyncConstants.MAX_PACKET_PAYLOAD_LENGTH;
import static org.briarproject.api.sync.SyncConstants.PACKET_HEADER_LENGTH;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
public class PacketReaderImplTest extends BriarTestCase {
// FIXME: This is an integration test, not a unit test
private final BdfReaderFactory bdfReaderFactory;
private final BdfWriterFactory bdfWriterFactory;
public PacketReaderImplTest() throws Exception {
Injector i = Guice.createInjector(new DataModule());
bdfReaderFactory = i.getInstance(BdfReaderFactory.class);
bdfWriterFactory = i.getInstance(BdfWriterFactory.class);
}
@Test(expected = FormatException.class)
public void testFormatExceptionIfAckIsTooLarge() throws Exception {
byte[] b = createAck(true);
ByteArrayInputStream in = new ByteArrayInputStream(b);
PacketReaderImpl reader = new PacketReaderImpl(bdfReaderFactory, null,
null, in);
PacketReaderImpl reader = new PacketReaderImpl(null, null, null, in);
reader.readAck();
}
@@ -52,8 +31,7 @@ public class PacketReaderImplTest extends BriarTestCase {
public void testNoFormatExceptionIfAckIsMaximumSize() throws Exception {
byte[] b = createAck(false);
ByteArrayInputStream in = new ByteArrayInputStream(b);
PacketReaderImpl reader = new PacketReaderImpl(bdfReaderFactory, null,
null, in);
PacketReaderImpl reader = new PacketReaderImpl(null, null, null, in);
reader.readAck();
}
@@ -61,8 +39,7 @@ public class PacketReaderImplTest extends BriarTestCase {
public void testEmptyAck() throws Exception {
byte[] b = createEmptyAck();
ByteArrayInputStream in = new ByteArrayInputStream(b);
PacketReaderImpl reader = new PacketReaderImpl(bdfReaderFactory, null,
null, in);
PacketReaderImpl reader = new PacketReaderImpl(null, null, null, in);
reader.readAck();
}
@@ -70,8 +47,7 @@ public class PacketReaderImplTest extends BriarTestCase {
public void testFormatExceptionIfOfferIsTooLarge() throws Exception {
byte[] b = createOffer(true);
ByteArrayInputStream in = new ByteArrayInputStream(b);
PacketReaderImpl reader = new PacketReaderImpl(bdfReaderFactory, null,
null, in);
PacketReaderImpl reader = new PacketReaderImpl(null, null, null, in);
reader.readOffer();
}
@@ -79,10 +55,7 @@ public class PacketReaderImplTest extends BriarTestCase {
public void testNoFormatExceptionIfOfferIsMaximumSize() throws Exception {
byte[] b = createOffer(false);
ByteArrayInputStream in = new ByteArrayInputStream(b);
PacketReaderImpl
reader = new PacketReaderImpl(
bdfReaderFactory, null,
null, in);
PacketReaderImpl reader = new PacketReaderImpl(null, null, null, in);
reader.readOffer();
}
@@ -90,8 +63,7 @@ public class PacketReaderImplTest extends BriarTestCase {
public void testEmptyOffer() throws Exception {
byte[] b = createEmptyOffer();
ByteArrayInputStream in = new ByteArrayInputStream(b);
PacketReaderImpl reader = new PacketReaderImpl(bdfReaderFactory, null,
null, in);
PacketReaderImpl reader = new PacketReaderImpl(null, null, null, in);
reader.readOffer();
}
@@ -99,8 +71,7 @@ public class PacketReaderImplTest extends BriarTestCase {
public void testFormatExceptionIfRequestIsTooLarge() throws Exception {
byte[] b = createRequest(true);
ByteArrayInputStream in = new ByteArrayInputStream(b);
PacketReaderImpl reader = new PacketReaderImpl(bdfReaderFactory, null,
null, in);
PacketReaderImpl reader = new PacketReaderImpl(null, null, null, in);
reader.readRequest();
}
@@ -108,8 +79,7 @@ public class PacketReaderImplTest extends BriarTestCase {
public void testNoFormatExceptionIfRequestIsMaximumSize() throws Exception {
byte[] b = createRequest(false);
ByteArrayInputStream in = new ByteArrayInputStream(b);
PacketReaderImpl reader = new PacketReaderImpl(bdfReaderFactory, null,
null, in);
PacketReaderImpl reader = new PacketReaderImpl(null, null, null, in);
reader.readRequest();
}
@@ -117,110 +87,76 @@ public class PacketReaderImplTest extends BriarTestCase {
public void testEmptyRequest() throws Exception {
byte[] b = createEmptyRequest();
ByteArrayInputStream in = new ByteArrayInputStream(b);
PacketReaderImpl reader = new PacketReaderImpl(bdfReaderFactory, null,
null, in);
PacketReaderImpl reader = new PacketReaderImpl(null, null, null, in);
reader.readRequest();
}
private byte[] createAck(boolean tooBig) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
out.write(new byte[HEADER_LENGTH]);
BdfWriter w = bdfWriterFactory.createWriter(out);
w.writeListStart();
w.writeListStart();
while (out.size() + UNIQUE_ID_LENGTH + LIST_END_LENGTH * 2
< HEADER_LENGTH + MAX_PAYLOAD_LENGTH) {
w.writeRaw(TestUtils.getRandomId());
out.write(new byte[PACKET_HEADER_LENGTH]);
while (out.size() + UniqueId.LENGTH <= PACKET_HEADER_LENGTH
+ MAX_PACKET_PAYLOAD_LENGTH) {
out.write(TestUtils.getRandomId());
}
if (tooBig) w.writeRaw(TestUtils.getRandomId());
w.writeListEnd();
w.writeListEnd();
assertEquals(tooBig, out.size() > HEADER_LENGTH + MAX_PAYLOAD_LENGTH);
if (tooBig) out.write(TestUtils.getRandomId());
assertEquals(tooBig, out.size() > PACKET_HEADER_LENGTH +
MAX_PACKET_PAYLOAD_LENGTH);
byte[] packet = out.toByteArray();
packet[1] = ACK;
ByteUtils.writeUint16(packet.length - HEADER_LENGTH, packet, 2);
ByteUtils.writeUint16(packet.length - PACKET_HEADER_LENGTH, packet, 2);
return packet;
}
private byte[] createEmptyAck() throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
out.write(new byte[HEADER_LENGTH]);
BdfWriter w = bdfWriterFactory.createWriter(out);
w.writeListStart();
w.writeListStart();
w.writeListEnd();
w.writeListEnd();
byte[] packet = out.toByteArray();
byte[] packet = new byte[PACKET_HEADER_LENGTH];
packet[1] = ACK;
ByteUtils.writeUint16(packet.length - HEADER_LENGTH, packet, 2);
ByteUtils.writeUint16(packet.length - PACKET_HEADER_LENGTH, packet, 2);
return packet;
}
private byte[] createOffer(boolean tooBig) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
out.write(new byte[HEADER_LENGTH]);
BdfWriter w = bdfWriterFactory.createWriter(out);
w.writeListStart();
w.writeListStart();
while (out.size() + UNIQUE_ID_LENGTH + LIST_END_LENGTH * 2
< HEADER_LENGTH + MAX_PAYLOAD_LENGTH) {
w.writeRaw(TestUtils.getRandomId());
out.write(new byte[PACKET_HEADER_LENGTH]);
while (out.size() + UniqueId.LENGTH <= PACKET_HEADER_LENGTH
+ MAX_PACKET_PAYLOAD_LENGTH) {
out.write(TestUtils.getRandomId());
}
if (tooBig) w.writeRaw(TestUtils.getRandomId());
w.writeListEnd();
w.writeListEnd();
assertEquals(tooBig, out.size() > HEADER_LENGTH + MAX_PAYLOAD_LENGTH);
if (tooBig) out.write(TestUtils.getRandomId());
assertEquals(tooBig, out.size() > PACKET_HEADER_LENGTH +
MAX_PACKET_PAYLOAD_LENGTH);
byte[] packet = out.toByteArray();
packet[1] = OFFER;
ByteUtils.writeUint16(packet.length - HEADER_LENGTH, packet, 2);
ByteUtils.writeUint16(packet.length - PACKET_HEADER_LENGTH, packet, 2);
return packet;
}
private byte[] createEmptyOffer() throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
out.write(new byte[HEADER_LENGTH]);
BdfWriter w = bdfWriterFactory.createWriter(out);
w.writeListStart();
w.writeListStart();
w.writeListEnd();
w.writeListEnd();
byte[] packet = out.toByteArray();
byte[] packet = new byte[PACKET_HEADER_LENGTH];
packet[1] = OFFER;
ByteUtils.writeUint16(packet.length - HEADER_LENGTH, packet, 2);
ByteUtils.writeUint16(packet.length - PACKET_HEADER_LENGTH, packet, 2);
return packet;
}
private byte[] createRequest(boolean tooBig) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
out.write(new byte[HEADER_LENGTH]);
BdfWriter w = bdfWriterFactory.createWriter(out);
w.writeListStart();
w.writeListStart();
while (out.size() + UNIQUE_ID_LENGTH + LIST_END_LENGTH * 2
< HEADER_LENGTH + MAX_PAYLOAD_LENGTH) {
w.writeRaw(TestUtils.getRandomId());
out.write(new byte[PACKET_HEADER_LENGTH]);
while (out.size() + UniqueId.LENGTH <= PACKET_HEADER_LENGTH
+ MAX_PACKET_PAYLOAD_LENGTH) {
out.write(TestUtils.getRandomId());
}
if (tooBig) w.writeRaw(TestUtils.getRandomId());
w.writeListEnd();
w.writeListEnd();
assertEquals(tooBig, out.size() > HEADER_LENGTH + MAX_PAYLOAD_LENGTH);
if (tooBig) out.write(TestUtils.getRandomId());
assertEquals(tooBig, out.size() > PACKET_HEADER_LENGTH +
MAX_PACKET_PAYLOAD_LENGTH);
byte[] packet = out.toByteArray();
packet[1] = REQUEST;
ByteUtils.writeUint16(packet.length - HEADER_LENGTH, packet, 2);
ByteUtils.writeUint16(packet.length - PACKET_HEADER_LENGTH, packet, 2);
return packet;
}
private byte[] createEmptyRequest() throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
out.write(new byte[HEADER_LENGTH]);
BdfWriter w = bdfWriterFactory.createWriter(out);
w.writeListStart();
w.writeListStart();
w.writeListEnd();
w.writeListEnd();
byte[] packet = out.toByteArray();
byte[] packet = new byte[PACKET_HEADER_LENGTH];
packet[1] = REQUEST;
ByteUtils.writeUint16(packet.length - HEADER_LENGTH, packet, 2);
ByteUtils.writeUint16(packet.length - PACKET_HEADER_LENGTH, packet, 2);
return packet;
}
}

View File

@@ -22,16 +22,14 @@ import org.briarproject.api.identity.AuthorId;
import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.messaging.MessagingManager;
import org.briarproject.api.messaging.PrivateConversation;
import org.briarproject.api.messaging.PrivateMessage;
import org.briarproject.api.messaging.PrivateMessageFactory;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.Message;
import org.briarproject.api.sync.MessageVerifier;
import org.briarproject.api.sync.MessagingSession;
import org.briarproject.api.sync.PacketReader;
import org.briarproject.api.sync.PacketReaderFactory;
import org.briarproject.api.sync.PacketWriter;
import org.briarproject.api.sync.PacketWriterFactory;
import org.briarproject.api.sync.SyncSession;
import org.briarproject.api.transport.KeyManager;
import org.briarproject.api.transport.StreamContext;
import org.briarproject.api.transport.StreamReaderFactory;
@@ -73,6 +71,8 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
private final TransportId transportId = new TransportId("id");
private final SecretKey master = TestUtils.createSecretKey();
private final long timestamp = System.currentTimeMillis();
private final AuthorId aliceId = new AuthorId(TestUtils.getRandomId());
private final AuthorId bobId = new AuthorId(TestUtils.getRandomId());
private Injector alice, bob;
@@ -106,14 +106,12 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
KeyManager keyManager = alice.getInstance(KeyManager.class);
keyManager.start();
// Add an identity for Alice
AuthorId aliceId = new AuthorId(TestUtils.getRandomId());
LocalAuthor aliceAuthor = new LocalAuthor(aliceId, "Alice",
new byte[MAX_PUBLIC_KEY_LENGTH], new byte[100], 1234);
new byte[MAX_PUBLIC_KEY_LENGTH], new byte[100], timestamp);
IdentityManager identityManager =
alice.getInstance(IdentityManager.class);
identityManager.addLocalAuthor(aliceAuthor);
// Add Bob as a contact
AuthorId bobId = new AuthorId(TestUtils.getRandomId());
Author bobAuthor = new Author(bobId, "Bob",
new byte[MAX_PUBLIC_KEY_LENGTH]);
ContactManager contactManager = alice.getInstance(ContactManager.class);
@@ -121,19 +119,17 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
// Create the private conversation
MessagingManager messagingManager =
alice.getInstance(MessagingManager.class);
messagingManager.addContact(contactId, master);
messagingManager.addContact(contactId);
// Derive and store the transport keys
keyManager.addContact(contactId, Collections.singletonList(transportId),
master, timestamp, true);
// Send Bob a message
byte[] body = "Hi Bob!".getBytes("UTF-8");
PrivateMessageFactory messageFactory =
PrivateMessageFactory privateMessageFactory =
alice.getInstance(PrivateMessageFactory.class);
GroupId groupId = messagingManager.getConversationId(contactId);
PrivateConversation conversation =
messagingManager.getConversation(groupId);
Message message = messageFactory.createPrivateMessage(null,
conversation, "text/plain", timestamp, body);
byte[] body = "Hi Bob!".getBytes("UTF-8");
PrivateMessage message = privateMessageFactory.createPrivateMessage(
groupId, timestamp, null, "text/plain", body);
messagingManager.addLocalMessage(message);
// Get a stream context
StreamContext ctx = keyManager.getStreamContext(contactId, transportId);
@@ -150,7 +146,7 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
alice.getInstance(PacketWriterFactory.class);
PacketWriter packetWriter = packetWriterFactory.createPacketWriter(
streamWriter);
MessagingSession session = new SimplexOutgoingSession(db,
SyncSession session = new SimplexOutgoingSession(db,
new ImmediateExecutor(), eventBus, contactId, transportId,
MAX_LATENCY, packetWriter);
// Write whatever needs to be written
@@ -173,14 +169,12 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
KeyManager keyManager = bob.getInstance(KeyManager.class);
keyManager.start();
// Add an identity for Bob
AuthorId bobId = new AuthorId(TestUtils.getRandomId());
LocalAuthor bobAuthor = new LocalAuthor(bobId, "Bob",
new byte[MAX_PUBLIC_KEY_LENGTH], new byte[100], 1234);
new byte[MAX_PUBLIC_KEY_LENGTH], new byte[100], timestamp);
IdentityManager identityManager =
bob.getInstance(IdentityManager.class);
identityManager.addLocalAuthor(bobAuthor);
// Add Alice as a contact
AuthorId aliceId = new AuthorId(TestUtils.getRandomId());
Author aliceAuthor = new Author(aliceId, "Alice",
new byte[MAX_PUBLIC_KEY_LENGTH]);
ContactManager contactManager = bob.getInstance(ContactManager.class);
@@ -188,7 +182,7 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
// Create the private conversation
MessagingManager messagingManager =
bob.getInstance(MessagingManager.class);
messagingManager.addContact(contactId, master);
messagingManager.addContact(contactId);
// Derive and store the transport keys
keyManager.addContact(contactId, Collections.singletonList(transportId),
master, timestamp, false);
@@ -209,15 +203,13 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
streamReaderFactory.createStreamReader(in, ctx);
// Create an incoming sync session
EventBus eventBus = bob.getInstance(EventBus.class);
MessageVerifier messageVerifier =
bob.getInstance(MessageVerifier.class);
PacketReaderFactory packetReaderFactory =
bob.getInstance(PacketReaderFactory.class);
PacketReader packetReader = packetReaderFactory.createPacketReader(
streamReader);
MessagingSession session = new IncomingSession(db,
new ImmediateExecutor(), new ImmediateExecutor(), eventBus,
messageVerifier, contactId, transportId, packetReader);
SyncSession session = new IncomingSession(db,
new ImmediateExecutor(), eventBus, contactId, transportId,
packetReader);
// No messages should have been added yet
assertFalse(listener.messageAdded);
// Read whatever needs to be read

View File

@@ -12,11 +12,13 @@ public class ByteUtilsTest extends BriarTestCase {
@Test
public void testReadUint16() {
byte[] b = StringUtils.fromHexString("000000");
byte[] b = StringUtils.fromHexString("00000000");
assertEquals(0, ByteUtils.readUint16(b, 1));
b = StringUtils.fromHexString("000001");
b = StringUtils.fromHexString("00000100");
assertEquals(1, ByteUtils.readUint16(b, 1));
b = StringUtils.fromHexString("00FFFF");
b = StringUtils.fromHexString("007FFF00");
assertEquals(Short.MAX_VALUE, ByteUtils.readUint16(b, 1));
b = StringUtils.fromHexString("00FFFF00");
assertEquals(65535, ByteUtils.readUint16(b, 1));
}
@@ -32,11 +34,13 @@ public class ByteUtilsTest extends BriarTestCase {
@Test
public void testReadUint32() {
byte[] b = StringUtils.fromHexString("0000000000");
byte[] b = StringUtils.fromHexString("000000000000");
assertEquals(0, ByteUtils.readUint32(b, 1));
b = StringUtils.fromHexString("0000000001");
b = StringUtils.fromHexString("000000000100");
assertEquals(1, ByteUtils.readUint32(b, 1));
b = StringUtils.fromHexString("00FFFFFFFF");
b = StringUtils.fromHexString("007FFFFFFF00");
assertEquals(Integer.MAX_VALUE, ByteUtils.readUint32(b, 1));
b = StringUtils.fromHexString("00FFFFFFFF00");
assertEquals(4294967295L, ByteUtils.readUint32(b, 1));
}
@@ -50,6 +54,30 @@ public class ByteUtilsTest extends BriarTestCase {
ByteUtils.readUint32(new byte[4], 1);
}
@Test
public void testReadUint64() {
byte[] b = StringUtils.fromHexString("00000000000000000000");
assertEquals(0L, ByteUtils.readUint64(b, 1));
b = StringUtils.fromHexString("00000000000000000100");
assertEquals(1L, ByteUtils.readUint64(b, 1));
b = StringUtils.fromHexString("007FFFFFFFFFFFFFFF00");
assertEquals(Long.MAX_VALUE, ByteUtils.readUint64(b, 1));
b = StringUtils.fromHexString("00800000000000000000");
assertEquals(Long.MIN_VALUE, ByteUtils.readUint64(b, 1));
b = StringUtils.fromHexString("00FFFFFFFFFFFFFFFF00");
assertEquals(-1L, ByteUtils.readUint64(b, 1));
}
@Test(expected = IllegalArgumentException.class)
public void testReadUint64ValidatesArguments1() {
ByteUtils.readUint64(new byte[7], 0);
}
@Test(expected = IllegalArgumentException.class)
public void testReadUint64ValidatesArguments2() {
ByteUtils.readUint64(new byte[8], 1);
}
@Test
public void testWriteUint16() {
byte[] b = new byte[4];