From f18c86b0d3f129a5689b71acb067d121ea5a7e5f Mon Sep 17 00:00:00 2001 From: akwizgran <akwizgran@users.sourceforge.net> Date: Fri, 16 Sep 2011 13:06:04 +0100 Subject: [PATCH] Unit tests for private messages. --- test/net/sf/briar/db/H2DatabaseTest.java | 171 ++++++++++++++++++++--- 1 file changed, 148 insertions(+), 23 deletions(-) diff --git a/test/net/sf/briar/db/H2DatabaseTest.java b/test/net/sf/briar/db/H2DatabaseTest.java index ad49d1b497..bef871e2d3 100644 --- a/test/net/sf/briar/db/H2DatabaseTest.java +++ b/test/net/sf/briar/db/H2DatabaseTest.java @@ -58,11 +58,11 @@ public class H2DatabaseTest extends TestCase { private final BatchId batchId; private final ContactId contactId; private final GroupId groupId; - private final MessageId messageId; + private final MessageId messageId, privateMessageId; private final long timestamp; private final int size; private final byte[] raw; - private final Message message; + private final Message message, privateMessage; private final Group group; private final Map<String, Map<String, String>> transports; private final Map<Group, Long> subscriptions; @@ -80,12 +80,15 @@ public class H2DatabaseTest extends TestCase { contactId = new ContactId(1); groupId = new GroupId(TestUtils.getRandomId()); messageId = new MessageId(TestUtils.getRandomId()); + privateMessageId = new MessageId(TestUtils.getRandomId()); timestamp = System.currentTimeMillis(); size = 1234; raw = new byte[size]; random.nextBytes(raw); message = new TestMessage(messageId, null, groupId, authorId, timestamp, raw); + privateMessage = + new TestMessage(privateMessageId, null, null, null, timestamp, raw); group = groupFactory.createGroup(groupId, "Group name", null); transports = Collections.singletonMap("foo", Collections.singletonMap("bar", "baz")); @@ -112,6 +115,9 @@ public class H2DatabaseTest extends TestCase { assertFalse(db.containsMessage(txn, messageId)); db.addGroupMessage(txn, message); assertTrue(db.containsMessage(txn, messageId)); + assertFalse(db.containsMessage(txn, privateMessageId)); + db.addPrivateMessage(txn, privateMessage, contactId); + assertTrue(db.containsMessage(txn, privateMessageId)); db.commitTransaction(txn); db.close(); @@ -124,9 +130,13 @@ public class H2DatabaseTest extends TestCase { assertTrue(db.containsMessage(txn, messageId)); byte[] raw1 = db.getMessage(txn, messageId); assertTrue(Arrays.equals(raw, raw1)); + assertTrue(db.containsMessage(txn, privateMessageId)); + raw1 = db.getMessage(txn, privateMessageId); + assertTrue(Arrays.equals(raw, raw1)); // Delete the records - db.removeContact(txn, contactId); db.removeMessage(txn, messageId); + db.removeMessage(txn, privateMessageId); + db.removeContact(txn, contactId); db.removeSubscription(txn, groupId); db.commitTransaction(txn); db.close(); @@ -138,6 +148,7 @@ public class H2DatabaseTest extends TestCase { assertEquals(Collections.emptyMap(), db.getTransports(txn, contactId)); assertFalse(db.containsSubscription(txn, groupId)); assertFalse(db.containsMessage(txn, messageId)); + assertFalse(db.containsMessage(txn, privateMessageId)); db.commitTransaction(txn); db.close(); } @@ -189,7 +200,7 @@ public class H2DatabaseTest extends TestCase { } @Test - public void testUnsubscribingRemovesMessage() throws DbException { + public void testUnsubscribingRemovesGroupMessage() throws DbException { Database<Connection> db = open(false); Connection txn = db.startTransaction(); @@ -197,7 +208,7 @@ public class H2DatabaseTest extends TestCase { db.addSubscription(txn, group); db.addGroupMessage(txn, message); - // Unsubscribing from the group should delete the message + // Unsubscribing from the group should remove the message assertTrue(db.containsMessage(txn, messageId)); db.removeSubscription(txn, groupId); assertFalse(db.containsMessage(txn, messageId)); @@ -207,7 +218,93 @@ public class H2DatabaseTest extends TestCase { } @Test - public void testSendableMessagesMustBeSendable() throws DbException { + public void testRemovingContactRemovesPrivateMessage() throws DbException { + Database<Connection> db = open(false); + Connection txn = db.startTransaction(); + + // Add a contact and store a private message + assertEquals(contactId, db.addContact(txn, transports, secret)); + db.addPrivateMessage(txn, privateMessage, contactId); + + // Removing the contact should remove the message + assertTrue(db.containsMessage(txn, privateMessageId)); + db.removeContact(txn, contactId); + assertFalse(db.containsMessage(txn, privateMessageId)); + + db.commitTransaction(txn); + db.close(); + } + + @Test + public void testSendablePrivateMessagesMustHaveStatusNew() + throws DbException { + Database<Connection> db = open(false); + Connection txn = db.startTransaction(); + + // Add a contact and store a private message + assertEquals(contactId, db.addContact(txn, transports, secret)); + db.addPrivateMessage(txn, privateMessage, contactId); + + // The message has no status yet, so it should not be sendable + assertFalse(db.hasSendableMessages(txn, contactId)); + Iterator<MessageId> it = + db.getSendableMessages(txn, contactId, ONE_MEGABYTE).iterator(); + assertFalse(it.hasNext()); + + // Changing the status to NEW should make the message sendable + db.setStatus(txn, contactId, privateMessageId, Status.NEW); + assertTrue(db.hasSendableMessages(txn, contactId)); + it = db.getSendableMessages(txn, contactId, ONE_MEGABYTE).iterator(); + assertTrue(it.hasNext()); + assertEquals(privateMessageId, it.next()); + assertFalse(it.hasNext()); + + // Changing the status to SENT should make the message unsendable + db.setStatus(txn, contactId, privateMessageId, Status.SENT); + assertFalse(db.hasSendableMessages(txn, contactId)); + it = db.getSendableMessages(txn, contactId, ONE_MEGABYTE).iterator(); + assertFalse(it.hasNext()); + + // Changing the status to SEEN should also make the message unsendable + db.setStatus(txn, contactId, privateMessageId, Status.SEEN); + it = db.getSendableMessages(txn, contactId, ONE_MEGABYTE).iterator(); + assertFalse(it.hasNext()); + + db.commitTransaction(txn); + db.close(); + } + + @Test + public void testSendablePrivateMessagesMustFitCapacity() + throws DbException { + Database<Connection> db = open(false); + Connection txn = db.startTransaction(); + + // Add a contact and store a private message + assertEquals(contactId, db.addContact(txn, transports, secret)); + db.addPrivateMessage(txn, privateMessage, contactId); + db.setStatus(txn, contactId, privateMessageId, Status.NEW); + + // The message is sendable, but too large to send + assertTrue(db.hasSendableMessages(txn, contactId)); + Iterator<MessageId> it = + db.getSendableMessages(txn, contactId, size - 1).iterator(); + assertFalse(it.hasNext()); + + // The message is just the right size to send + assertTrue(db.hasSendableMessages(txn, contactId)); + it = db.getSendableMessages(txn, contactId, size).iterator(); + assertTrue(it.hasNext()); + assertEquals(privateMessageId, it.next()); + assertFalse(it.hasNext()); + + db.commitTransaction(txn); + db.close(); + } + + @Test + public void testSendableGroupMessagesMustHavePositiveSendability() + throws DbException { Database<Connection> db = open(false); Connection txn = db.startTransaction(); @@ -244,7 +341,8 @@ public class H2DatabaseTest extends TestCase { } @Test - public void testSendableMessagesMustHaveStatusNew() throws DbException { + public void testSendableGroupMessagesMustHaveStatusNew() + throws DbException { Database<Connection> db = open(false); Connection txn = db.startTransaction(); @@ -286,7 +384,7 @@ public class H2DatabaseTest extends TestCase { } @Test - public void testSendableMessagesMustBeSubscribed() throws DbException { + public void testSendableGroupMessagesMustBeSubscribed() throws DbException { Database<Connection> db = open(false); Connection txn = db.startTransaction(); @@ -324,7 +422,7 @@ public class H2DatabaseTest extends TestCase { } @Test - public void testSendableMessagesMustBeNewerThanSubscriptions() + public void testSendableGroupMessagesMustBeNewerThanSubscriptions() throws DbException { Database<Connection> db = open(false); Connection txn = db.startTransaction(); @@ -360,7 +458,7 @@ public class H2DatabaseTest extends TestCase { } @Test - public void testSendableMessagesMustFitCapacity() throws DbException { + public void testSendableGroupMessagesMustFitCapacity() throws DbException { Database<Connection> db = open(false); Connection txn = db.startTransaction(); @@ -391,7 +489,7 @@ public class H2DatabaseTest extends TestCase { } @Test - public void testSendableMessagesMustBeVisible() throws DbException { + public void testSendableGroupMessagesMustBeVisible() throws DbException { Database<Connection> db = open(false); Connection txn = db.startTransaction(); @@ -538,7 +636,7 @@ public class H2DatabaseTest extends TestCase { db.setSendability(txn, messageId, 1); db.setStatus(txn, contactId, messageId, Status.NEW); - // Get the message and mark it as sent + // Retrieve the message from the database and mark it as sent Iterator<MessageId> it = db.getSendableMessages(txn, contactId, ONE_MEGABYTE).iterator(); assertTrue(it.hasNext()); @@ -551,8 +649,10 @@ public class H2DatabaseTest extends TestCase { // The message should no longer be sendable it = db.getSendableMessages(txn, contactId, ONE_MEGABYTE).iterator(); assertFalse(it.hasNext()); + // Pretend that the batch was acked db.removeAckedBatch(txn, contactId, batchId); + // The message still should not be sendable it = db.getSendableMessages(txn, contactId, ONE_MEGABYTE).iterator(); assertFalse(it.hasNext()); @@ -588,8 +688,10 @@ public class H2DatabaseTest extends TestCase { // The message should no longer be sendable it = db.getSendableMessages(txn, contactId, ONE_MEGABYTE).iterator(); assertFalse(it.hasNext()); + // Pretend that the batch was lost db.removeLostBatch(txn, contactId, batchId); + // The message should be sendable again it = db.getSendableMessages(txn, contactId, ONE_MEGABYTE).iterator(); assertTrue(it.hasNext()); @@ -611,6 +713,7 @@ public class H2DatabaseTest extends TestCase { // Add a contact assertEquals(contactId, db.addContact(txn, transports, secret)); + // Add some outstanding batches, a few ms apart for(int i = 0; i < ids.length; i++) { db.addOutstandingBatch(txn, contactId, ids[i], @@ -619,6 +722,7 @@ public class H2DatabaseTest extends TestCase { Thread.sleep(5); } catch(InterruptedException ignored) {} } + // The contact acks the batches in reverse order. The first // RETRANSMIT_THRESHOLD - 1 acks should not trigger any retransmissions for(int i = 0; i < Database.RETRANSMIT_THRESHOLD - 1; i++) { @@ -626,6 +730,7 @@ public class H2DatabaseTest extends TestCase { Collection<BatchId> lost = db.getLostBatches(txn, contactId); assertEquals(Collections.emptyList(), lost); } + // The next ack should trigger the retransmission of the remaining // five outstanding batches int index = ids.length - Database.RETRANSMIT_THRESHOLD; @@ -650,6 +755,7 @@ public class H2DatabaseTest extends TestCase { // Add a contact assertEquals(contactId, db.addContact(txn, transports, secret)); + // Add some outstanding batches, a few ms apart for(int i = 0; i < ids.length; i++) { db.addOutstandingBatch(txn, contactId, ids[i], @@ -658,6 +764,7 @@ public class H2DatabaseTest extends TestCase { Thread.sleep(5); } catch(InterruptedException ignored) {} } + // The contact acks the batches in the order they were sent - nothing // should be retransmitted for(int i = 0; i < ids.length; i++) { @@ -781,10 +888,12 @@ public class H2DatabaseTest extends TestCase { // Sanity check: there should be enough space on disk for this test String path = testDir.getAbsolutePath(); assertTrue(FileSystemUtils.freeSpaceKb(path) * 1024L > MAX_SIZE); + // The free space should not be more than the allowed maximum size long free = db.getFreeSpace(); assertTrue(free <= MAX_SIZE); assertTrue(free > 0); + // Storing a message should reduce the free space Connection txn = db.startTransaction(); db.addSubscription(txn, group); @@ -872,13 +981,14 @@ public class H2DatabaseTest extends TestCase { } @Test - public void testUpdateTransportPropertiess() throws DbException { + public void testUpdateTransportProperties() throws DbException { Database<Connection> db = open(false); Connection txn = db.startTransaction(); // Add a contact with some transport properties assertEquals(contactId, db.addContact(txn, transports, secret)); assertEquals(transports, db.getTransports(txn, contactId)); + // Replace the transport properties Map<String, Map<String, String>> transports1 = new TreeMap<String, Map<String, String>>(); @@ -886,15 +996,18 @@ public class H2DatabaseTest extends TestCase { transports1.put("bar", Collections.singletonMap("baz", "quux")); db.setTransports(txn, contactId, transports1, 1); assertEquals(transports1, db.getTransports(txn, contactId)); + // Remove the transport properties db.setTransports(txn, contactId, Collections.<String, Map<String, String>>emptyMap(), 2); assertEquals(Collections.emptyMap(), db.getTransports(txn, contactId)); + // Set the local transport properties for(String name : transports.keySet()) { db.setTransportProperties(txn, name, transports.get(name)); } assertEquals(transports, db.getTransports(txn)); + // Remove the local transport properties for(String name : transports.keySet()) { db.setTransportProperties(txn, name, @@ -917,9 +1030,11 @@ public class H2DatabaseTest extends TestCase { // Set the transport config db.setTransportConfig(txn, "foo", config); assertEquals(config, db.getTransportConfig(txn, "foo")); + // Update the transport config db.setTransportConfig(txn, "foo", config1); assertEquals(config1, db.getTransportConfig(txn, "foo")); + // Remove the transport config db.setTransportConfig(txn, "foo", Collections.<String, String>emptyMap()); @@ -937,6 +1052,7 @@ public class H2DatabaseTest extends TestCase { // Add a contact with some transport properties assertEquals(contactId, db.addContact(txn, transports, secret)); assertEquals(transports, db.getTransports(txn, contactId)); + // Replace the transport properties using a timestamp of 2 Map<String, Map<String, String>> transports1 = new TreeMap<String, Map<String, String>>(); @@ -944,12 +1060,14 @@ public class H2DatabaseTest extends TestCase { transports1.put("bar", Collections.singletonMap("baz", "quux")); db.setTransports(txn, contactId, transports1, 2); assertEquals(transports1, db.getTransports(txn, contactId)); + // Try to replace the transport properties using a timestamp of 1 Map<String, Map<String, String>> transports2 = new TreeMap<String, Map<String, String>>(); transports2.put("bar", Collections.singletonMap("baz", "quux")); transports2.put("baz", Collections.singletonMap("quux", "fnord")); db.setTransports(txn, contactId, transports2, 1); + // The old properties should still be there assertEquals(transports1, db.getTransports(txn, contactId)); @@ -967,10 +1085,12 @@ public class H2DatabaseTest extends TestCase { // Add a contact assertEquals(contactId, db.addContact(txn, transports, secret)); + // Add some subscriptions db.setSubscriptions(txn, contactId, subscriptions, 1); assertEquals(Collections.singletonList(group), db.getSubscriptions(txn, contactId)); + // Update the subscriptions Map<Group, Long> subscriptions1 = Collections.singletonMap(group1, 0L); db.setSubscriptions(txn, contactId, subscriptions1, 2); @@ -992,13 +1112,16 @@ public class H2DatabaseTest extends TestCase { // Add a contact assertEquals(contactId, db.addContact(txn, transports, secret)); + // Add some subscriptions db.setSubscriptions(txn, contactId, subscriptions, 2); assertEquals(Collections.singletonList(group), db.getSubscriptions(txn, contactId)); + // Try to update the subscriptions using a timestamp of 1 Map<Group, Long> subscriptions1 = Collections.singletonMap(group1, 0L); db.setSubscriptions(txn, contactId, subscriptions1, 1); + // The old subscriptions should still be there assertEquals(Collections.singletonList(group), db.getSubscriptions(txn, contactId)); @@ -1036,9 +1159,9 @@ public class H2DatabaseTest extends TestCase { db.addSubscription(txn, group); db.setSubscriptions(txn, contactId, subscriptions, 1); db.addGroupMessage(txn, message); - // Set the sendability to > 0 + + // Set the sendability to > 0 and the status to SEEN db.setSendability(txn, messageId, 1); - // Set the status to SEEN db.setStatus(txn, contactId, messageId, Status.SEEN); // The message is not sendable because its status is SEEN @@ -1059,9 +1182,9 @@ public class H2DatabaseTest extends TestCase { db.addSubscription(txn, group); db.setSubscriptions(txn, contactId, subscriptions, 1); db.addGroupMessage(txn, message); - // Set the sendability to 0 + + // Set the sendability to 0 and the status to NEW db.setSendability(txn, messageId, 0); - // Set the status to NEW db.setStatus(txn, contactId, messageId, Status.NEW); // The message is not sendable because its sendability is 0 @@ -1076,17 +1199,17 @@ public class H2DatabaseTest extends TestCase { Database<Connection> db = open(false); Connection txn = db.startTransaction(); - // Add a contact, subscribe to a group and store a message + // Add a contact, subscribe to a group and store a message - + // the message is older than the contact's subscription assertEquals(contactId, db.addContact(txn, transports, secret)); db.addSubscription(txn, group); db.setVisibility(txn, groupId, Collections.singleton(contactId)); - // The message is older than the contact's subscription Map<Group, Long> subs = Collections.singletonMap(group, timestamp + 1); db.setSubscriptions(txn, contactId, subs, 1); db.addGroupMessage(txn, message); - // Set the sendability to > 0 + + // Set the sendability to > 0 and the status to NEW db.setSendability(txn, messageId, 1); - // Set the status to NEW db.setStatus(txn, contactId, messageId, Status.NEW); // The message is not sendable because it's too old @@ -1107,9 +1230,9 @@ public class H2DatabaseTest extends TestCase { db.setVisibility(txn, groupId, Collections.singleton(contactId)); db.setSubscriptions(txn, contactId, subscriptions, 1); db.addGroupMessage(txn, message); - // Set the sendability to > 0 + + // Set the sendability to > 0 and the status to NEW db.setSendability(txn, messageId, 1); - // Set the status to NEW db.setStatus(txn, contactId, messageId, Status.NEW); // The message is sendable so it should be returned @@ -1207,6 +1330,7 @@ public class H2DatabaseTest extends TestCase { db.setVisibility(txn, groupId, Collections.singleton(contactId)); db.setSubscriptions(txn, contactId, subscriptions, 1); db.addGroupMessage(txn, message); + // The message has already been seen by the contact db.setStatus(txn, contactId, messageId, Status.SEEN); @@ -1228,6 +1352,7 @@ public class H2DatabaseTest extends TestCase { db.setVisibility(txn, groupId, Collections.singleton(contactId)); db.setSubscriptions(txn, contactId, subscriptions, 1); db.addGroupMessage(txn, message); + // The message has not been seen by the contact db.setStatus(txn, contactId, messageId, Status.NEW); -- GitLab