mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-16 20:59:54 +01:00
More unit tests for DatabaseComponent.
This commit is contained in:
@@ -236,10 +236,11 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
|
|||||||
Batch batch = fillBatch(c, capacity);
|
Batch batch = fillBatch(c, capacity);
|
||||||
if(batch == null) break; // No more messages to send
|
if(batch == null) break; // No more messages to send
|
||||||
b.addBatch(batch);
|
b.addBatch(batch);
|
||||||
capacity -= batch.getSize();
|
long size = batch.getSize();
|
||||||
|
capacity -= size;
|
||||||
// If the batch is less than half full, stop trying - there may be
|
// If the batch is less than half full, stop trying - there may be
|
||||||
// more messages trickling in but we can't wait forever
|
// more messages trickling in but we can't wait forever
|
||||||
if(batch.getSize() * 2 < Batch.CAPACITY) break;
|
if(size * 2 < Batch.CAPACITY) break;
|
||||||
}
|
}
|
||||||
b.seal();
|
b.seal();
|
||||||
if(LOG.isLoggable(Level.FINE))
|
if(LOG.isLoggable(Level.FINE))
|
||||||
|
|||||||
@@ -176,10 +176,11 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
|
|||||||
Batch batch = fillBatch(c, capacity);
|
Batch batch = fillBatch(c, capacity);
|
||||||
if(batch == null) break; // No more messages to send
|
if(batch == null) break; // No more messages to send
|
||||||
b.addBatch(batch);
|
b.addBatch(batch);
|
||||||
capacity -= batch.getSize();
|
long size = batch.getSize();
|
||||||
|
capacity -= size;
|
||||||
// If the batch is less than half full, stop trying - there may be
|
// If the batch is less than half full, stop trying - there may be
|
||||||
// more messages trickling in but we can't wait forever
|
// more messages trickling in but we can't wait forever
|
||||||
if(batch.getSize() * 2 < Batch.CAPACITY) break;
|
if(size * 2 < Batch.CAPACITY) break;
|
||||||
}
|
}
|
||||||
b.seal();
|
b.seal();
|
||||||
if(LOG.isLoggable(Level.FINE))
|
if(LOG.isLoggable(Level.FINE))
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ import net.sf.briar.api.db.Rating;
|
|||||||
import net.sf.briar.api.db.Status;
|
import net.sf.briar.api.db.Status;
|
||||||
import net.sf.briar.api.protocol.AuthorId;
|
import net.sf.briar.api.protocol.AuthorId;
|
||||||
import net.sf.briar.api.protocol.Batch;
|
import net.sf.briar.api.protocol.Batch;
|
||||||
|
import net.sf.briar.api.protocol.BatchId;
|
||||||
import net.sf.briar.api.protocol.Bundle;
|
import net.sf.briar.api.protocol.Bundle;
|
||||||
|
import net.sf.briar.api.protocol.BundleId;
|
||||||
import net.sf.briar.api.protocol.GroupId;
|
import net.sf.briar.api.protocol.GroupId;
|
||||||
import net.sf.briar.api.protocol.Message;
|
import net.sf.briar.api.protocol.Message;
|
||||||
import net.sf.briar.api.protocol.MessageId;
|
import net.sf.briar.api.protocol.MessageId;
|
||||||
@@ -27,8 +29,12 @@ import com.google.inject.Provider;
|
|||||||
|
|
||||||
public abstract class DatabaseComponentTest extends TestCase {
|
public abstract class DatabaseComponentTest extends TestCase {
|
||||||
|
|
||||||
|
private static final int ONE_MEGABYTE = 1024 * 1024;
|
||||||
|
|
||||||
protected final Object txn = new Object();
|
protected final Object txn = new Object();
|
||||||
protected final AuthorId authorId;
|
protected final AuthorId authorId;
|
||||||
|
protected final BatchId batchId;
|
||||||
|
protected final BundleId bundleId;
|
||||||
protected final ContactId contactId;
|
protected final ContactId contactId;
|
||||||
protected final GroupId groupId;
|
protected final GroupId groupId;
|
||||||
protected final MessageId messageId, parentId;
|
protected final MessageId messageId, parentId;
|
||||||
@@ -40,6 +46,8 @@ public abstract class DatabaseComponentTest extends TestCase {
|
|||||||
public DatabaseComponentTest() {
|
public DatabaseComponentTest() {
|
||||||
super();
|
super();
|
||||||
authorId = new AuthorId(TestUtils.getRandomId());
|
authorId = new AuthorId(TestUtils.getRandomId());
|
||||||
|
batchId = new BatchId(TestUtils.getRandomId());
|
||||||
|
bundleId = new BundleId(TestUtils.getRandomId());
|
||||||
contactId = new ContactId(123);
|
contactId = new ContactId(123);
|
||||||
groupId = new GroupId(TestUtils.getRandomId());
|
groupId = new GroupId(TestUtils.getRandomId());
|
||||||
messageId = new MessageId(TestUtils.getRandomId());
|
messageId = new MessageId(TestUtils.getRandomId());
|
||||||
@@ -65,40 +73,27 @@ public abstract class DatabaseComponentTest extends TestCase {
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
final Provider<Batch> batchProvider = context.mock(Provider.class);
|
final Provider<Batch> batchProvider = context.mock(Provider.class);
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
|
allowing(database).startTransaction();
|
||||||
|
will(returnValue(txn));
|
||||||
|
allowing(database).commitTransaction(txn);
|
||||||
|
// open(false)
|
||||||
oneOf(database).open(false);
|
oneOf(database).open(false);
|
||||||
oneOf(cleaner).startCleaning();
|
oneOf(cleaner).startCleaning();
|
||||||
// getRating(authorId)
|
// getRating(authorId)
|
||||||
oneOf(database).startTransaction();
|
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(database).getRating(txn, authorId);
|
oneOf(database).getRating(txn, authorId);
|
||||||
will(returnValue(Rating.UNRATED));
|
will(returnValue(Rating.UNRATED));
|
||||||
oneOf(database).commitTransaction(txn);
|
|
||||||
// addContact(contactId)
|
// addContact(contactId)
|
||||||
oneOf(database).startTransaction();
|
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(database).addContact(txn, contactId);
|
oneOf(database).addContact(txn, contactId);
|
||||||
oneOf(database).commitTransaction(txn);
|
|
||||||
// subscribe(groupId)
|
// subscribe(groupId)
|
||||||
oneOf(database).startTransaction();
|
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(database).addSubscription(txn, groupId);
|
oneOf(database).addSubscription(txn, groupId);
|
||||||
oneOf(database).commitTransaction(txn);
|
|
||||||
// getSubscriptions()
|
// getSubscriptions()
|
||||||
oneOf(database).startTransaction();
|
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(database).getSubscriptions(txn);
|
oneOf(database).getSubscriptions(txn);
|
||||||
will(returnValue(subs));
|
will(returnValue(subs));
|
||||||
oneOf(database).commitTransaction(txn);
|
|
||||||
// unsubscribe(groupId)
|
// unsubscribe(groupId)
|
||||||
oneOf(database).startTransaction();
|
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(database).removeSubscription(txn, groupId);
|
oneOf(database).removeSubscription(txn, groupId);
|
||||||
oneOf(database).commitTransaction(txn);
|
|
||||||
// removeContact(contactId)
|
// removeContact(contactId)
|
||||||
oneOf(database).startTransaction();
|
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(database).removeContact(txn, contactId);
|
oneOf(database).removeContact(txn, contactId);
|
||||||
oneOf(database).commitTransaction(txn);
|
// close()
|
||||||
oneOf(cleaner).stopCleaning();
|
oneOf(cleaner).stopCleaning();
|
||||||
oneOf(database).close();
|
oneOf(database).close();
|
||||||
}});
|
}});
|
||||||
@@ -128,7 +123,7 @@ public abstract class DatabaseComponentTest extends TestCase {
|
|||||||
final Provider<Batch> batchProvider = context.mock(Provider.class);
|
final Provider<Batch> batchProvider = context.mock(Provider.class);
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
// setRating(Rating.GOOD)
|
// setRating(Rating.GOOD)
|
||||||
oneOf(database).startTransaction();
|
allowing(database).startTransaction();
|
||||||
will(returnValue(txn));
|
will(returnValue(txn));
|
||||||
oneOf(database).setRating(txn, authorId, Rating.GOOD);
|
oneOf(database).setRating(txn, authorId, Rating.GOOD);
|
||||||
// The sendability of the author's messages should be incremented
|
// The sendability of the author's messages should be incremented
|
||||||
@@ -453,6 +448,7 @@ public abstract class DatabaseComponentTest extends TestCase {
|
|||||||
final Provider<Batch> batchProvider = context.mock(Provider.class);
|
final Provider<Batch> batchProvider = context.mock(Provider.class);
|
||||||
final Bundle bundle = context.mock(Bundle.class);
|
final Bundle bundle = context.mock(Bundle.class);
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
|
// Check that the contact is still in the DB
|
||||||
oneOf(database).startTransaction();
|
oneOf(database).startTransaction();
|
||||||
will(returnValue(txn));
|
will(returnValue(txn));
|
||||||
oneOf(database).containsContact(txn, contactId);
|
oneOf(database).containsContact(txn, contactId);
|
||||||
@@ -469,4 +465,144 @@ public abstract class DatabaseComponentTest extends TestCase {
|
|||||||
|
|
||||||
context.assertIsSatisfied();
|
context.assertIsSatisfied();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGenerateBundle() throws DbException {
|
||||||
|
Mockery context = new Mockery();
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
final Database<Object> database = context.mock(Database.class);
|
||||||
|
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
final Provider<Batch> batchProvider = context.mock(Provider.class);
|
||||||
|
final Bundle bundle = context.mock(Bundle.class);
|
||||||
|
final Batch batch = context.mock(Batch.class);
|
||||||
|
context.checking(new Expectations() {{
|
||||||
|
allowing(database).startTransaction();
|
||||||
|
will(returnValue(txn));
|
||||||
|
allowing(database).commitTransaction(txn);
|
||||||
|
allowing(database).containsContact(txn, contactId);
|
||||||
|
will(returnValue(true));
|
||||||
|
// Add acks to the bundle
|
||||||
|
oneOf(database).removeBatchesToAck(txn, contactId);
|
||||||
|
will(returnValue(Collections.singleton(batchId)));
|
||||||
|
oneOf(bundle).addAck(batchId);
|
||||||
|
// Add subscriptions to the bundle
|
||||||
|
oneOf(database).getSubscriptions(txn);
|
||||||
|
will(returnValue(Collections.singleton(groupId)));
|
||||||
|
oneOf(bundle).addSubscription(groupId);
|
||||||
|
// Prepare to add batches to the bundle
|
||||||
|
oneOf(bundle).getCapacity();
|
||||||
|
will(returnValue((long) ONE_MEGABYTE));
|
||||||
|
// Add messages to the batch
|
||||||
|
oneOf(database).getSendableMessages(txn, contactId, ONE_MEGABYTE);
|
||||||
|
will(returnValue(Collections.singleton(messageId)));
|
||||||
|
oneOf(batchProvider).get();
|
||||||
|
will(returnValue(batch));
|
||||||
|
oneOf(database).getMessage(txn, messageId);
|
||||||
|
will(returnValue(message));
|
||||||
|
oneOf(batch).addMessage(message);
|
||||||
|
oneOf(batch).seal();
|
||||||
|
// Record the batch as outstanding
|
||||||
|
oneOf(batch).getId();
|
||||||
|
will(returnValue(batchId));
|
||||||
|
oneOf(database).addOutstandingBatch(txn, contactId, batchId,
|
||||||
|
Collections.singleton(messageId));
|
||||||
|
// Add the batch to the bundle
|
||||||
|
oneOf(bundle).addBatch(batch);
|
||||||
|
// Check whether to add another batch
|
||||||
|
oneOf(batch).getSize();
|
||||||
|
will(returnValue((long) message.getSize()));
|
||||||
|
// Nope
|
||||||
|
oneOf(bundle).seal();
|
||||||
|
}});
|
||||||
|
DatabaseComponent db = createDatabaseComponent(database, cleaner,
|
||||||
|
batchProvider);
|
||||||
|
|
||||||
|
db.generateBundle(contactId, bundle);
|
||||||
|
|
||||||
|
context.assertIsSatisfied();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReceiveBundleThrowsExceptionIfContactIsMissing()
|
||||||
|
throws DbException {
|
||||||
|
Mockery context = new Mockery();
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
final Database<Object> database = context.mock(Database.class);
|
||||||
|
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
final Provider<Batch> batchProvider = context.mock(Provider.class);
|
||||||
|
final Bundle bundle = context.mock(Bundle.class);
|
||||||
|
context.checking(new Expectations() {{
|
||||||
|
// Check that the contact is still in the DB
|
||||||
|
oneOf(database).startTransaction();
|
||||||
|
will(returnValue(txn));
|
||||||
|
oneOf(database).containsContact(txn, contactId);
|
||||||
|
will(returnValue(false));
|
||||||
|
oneOf(database).commitTransaction(txn);
|
||||||
|
}});
|
||||||
|
DatabaseComponent db = createDatabaseComponent(database, cleaner,
|
||||||
|
batchProvider);
|
||||||
|
|
||||||
|
try {
|
||||||
|
db.receiveBundle(contactId, bundle);
|
||||||
|
assertTrue(false);
|
||||||
|
} catch(NoSuchContactException expected) {}
|
||||||
|
|
||||||
|
context.assertIsSatisfied();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReceivedBundle() throws DbException {
|
||||||
|
Mockery context = new Mockery();
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
final Database<Object> database = context.mock(Database.class);
|
||||||
|
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
final Provider<Batch> batchProvider = context.mock(Provider.class);
|
||||||
|
final Bundle bundle = context.mock(Bundle.class);
|
||||||
|
final Batch batch = context.mock(Batch.class);
|
||||||
|
context.checking(new Expectations() {{
|
||||||
|
allowing(database).startTransaction();
|
||||||
|
will(returnValue(txn));
|
||||||
|
allowing(database).commitTransaction(txn);
|
||||||
|
allowing(database).containsContact(txn, contactId);
|
||||||
|
will(returnValue(true));
|
||||||
|
// Acks
|
||||||
|
oneOf(bundle).getAcks();
|
||||||
|
will(returnValue(Collections.singleton(batchId)));
|
||||||
|
oneOf(database).removeAckedBatch(txn, contactId, batchId);
|
||||||
|
// Subscriptions
|
||||||
|
oneOf(database).clearSubscriptions(txn, contactId);
|
||||||
|
oneOf(bundle).getSubscriptions();
|
||||||
|
will(returnValue(Collections.singleton(groupId)));
|
||||||
|
oneOf(database).addSubscription(txn, contactId, groupId);
|
||||||
|
// Batches
|
||||||
|
oneOf(bundle).getBatches();
|
||||||
|
will(returnValue(Collections.singleton(batch)));
|
||||||
|
oneOf(batch).getMessages();
|
||||||
|
will(returnValue(Collections.singleton(message)));
|
||||||
|
oneOf(database).containsSubscription(txn, groupId);
|
||||||
|
will(returnValue(true));
|
||||||
|
oneOf(database).addMessage(txn, message);
|
||||||
|
will(returnValue(false)); // Duplicate message
|
||||||
|
oneOf(database).setStatus(txn, contactId, messageId, Status.SEEN);
|
||||||
|
// Batch to ack
|
||||||
|
oneOf(batch).getId();
|
||||||
|
will(returnValue(batchId));
|
||||||
|
oneOf(database).addBatchToAck(txn, contactId, batchId);
|
||||||
|
// Lost batches
|
||||||
|
oneOf(bundle).getId();
|
||||||
|
will(returnValue(bundleId));
|
||||||
|
oneOf(database).addReceivedBundle(txn, contactId, bundleId);
|
||||||
|
will(returnValue(Collections.singleton(batchId)));
|
||||||
|
oneOf(database).removeLostBatch(txn, contactId, batchId);
|
||||||
|
}});
|
||||||
|
DatabaseComponent db = createDatabaseComponent(database, cleaner,
|
||||||
|
batchProvider);
|
||||||
|
|
||||||
|
db.receiveBundle(contactId, bundle);
|
||||||
|
|
||||||
|
context.assertIsSatisfied();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user