Shutdown manager (untested on Windows).

This commit is contained in:
akwizgran
2011-11-18 17:13:55 +00:00
parent 859ece6328
commit 046becd388
22 changed files with 467 additions and 96 deletions

View File

@@ -26,6 +26,7 @@
<test name='net.sf.briar.i18n.FontManagerTest'/>
<test name='net.sf.briar.i18n.I18nTest'/>
<test name='net.sf.briar.invitation.InvitationWorkerTest'/>
<test name='net.sf.briar.lifecycle.ShutdownManagerImplTest'/>
<test name='net.sf.briar.plugins.PluginManagerImplTest'/>
<test name='net.sf.briar.plugins.file.LinuxRemovableDriveFinderTest'/>
<test name='net.sf.briar.plugins.file.MacRemovableDriveFinderTest'/>

View File

@@ -54,6 +54,7 @@ import net.sf.briar.api.transport.ConnectionWriter;
import net.sf.briar.api.transport.ConnectionWriterFactory;
import net.sf.briar.crypto.CryptoModule;
import net.sf.briar.db.DatabaseModule;
import net.sf.briar.lifecycle.LifecycleModule;
import net.sf.briar.protocol.ProtocolModule;
import net.sf.briar.protocol.writers.ProtocolWritersModule;
import net.sf.briar.serial.SerialModule;
@@ -102,10 +103,11 @@ public class ProtocolIntegrationTest extends TestCase {
}
};
Injector i = Guice.createInjector(testModule, new CryptoModule(),
new DatabaseModule(), new ProtocolModule(),
new ProtocolWritersModule(), new SerialModule(),
new TestDatabaseModule(), new TransportBatchModule(),
new TransportModule(), new TransportStreamModule());
new DatabaseModule(), new LifecycleModule(),
new ProtocolModule(), new ProtocolWritersModule(),
new SerialModule(), new TestDatabaseModule(),
new TransportBatchModule(), new TransportModule(),
new TransportStreamModule());
connectionContextFactory =
i.getInstance(ConnectionContextFactory.class);
connectionReaderFactory = i.getInstance(ConnectionReaderFactory.class);

View File

@@ -7,6 +7,7 @@ import java.util.Collections;
import net.sf.briar.api.db.DatabaseComponent;
import net.sf.briar.api.db.DbException;
import net.sf.briar.api.lifecycle.ShutdownManager;
import net.sf.briar.db.DatabaseCleaner.Callback;
import org.jmock.Expectations;
@@ -25,11 +26,12 @@ public class DatabaseComponentImplTest extends DatabaseComponentTest {
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
context.checking(new Expectations() {{
oneOf(database).getFreeSpace();
will(returnValue(MIN_FREE_SPACE));
}});
Callback db = createDatabaseComponentImpl(database, cleaner);
Callback db = createDatabaseComponentImpl(database, cleaner, shutdown);
db.checkFreeSpaceAndClean();
@@ -42,6 +44,7 @@ public class DatabaseComponentImplTest extends DatabaseComponentTest {
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
context.checking(new Expectations() {{
oneOf(database).getFreeSpace();
will(returnValue(MIN_FREE_SPACE - 1));
@@ -54,7 +57,7 @@ public class DatabaseComponentImplTest extends DatabaseComponentTest {
oneOf(database).getFreeSpace();
will(returnValue(MIN_FREE_SPACE));
}});
Callback db = createDatabaseComponentImpl(database, cleaner);
Callback db = createDatabaseComponentImpl(database, cleaner, shutdown);
db.checkFreeSpaceAndClean();
@@ -68,6 +71,7 @@ public class DatabaseComponentImplTest extends DatabaseComponentTest {
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
context.checking(new Expectations() {{
oneOf(database).getFreeSpace();
will(returnValue(MIN_FREE_SPACE - 1));
@@ -82,7 +86,7 @@ public class DatabaseComponentImplTest extends DatabaseComponentTest {
oneOf(database).getFreeSpace();
will(returnValue(MIN_FREE_SPACE));
}});
Callback db = createDatabaseComponentImpl(database, cleaner);
Callback db = createDatabaseComponentImpl(database, cleaner, shutdown);
db.checkFreeSpaceAndClean();
@@ -96,6 +100,7 @@ public class DatabaseComponentImplTest extends DatabaseComponentTest {
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
context.checking(new Expectations() {{
oneOf(database).getFreeSpace();
will(returnValue(MIN_FREE_SPACE - 1));
@@ -112,7 +117,7 @@ public class DatabaseComponentImplTest extends DatabaseComponentTest {
oneOf(database).getFreeSpace();
will(returnValue(MIN_FREE_SPACE));
}});
Callback db = createDatabaseComponentImpl(database, cleaner);
Callback db = createDatabaseComponentImpl(database, cleaner, shutdown);
db.checkFreeSpaceAndClean();
@@ -121,12 +126,14 @@ public class DatabaseComponentImplTest extends DatabaseComponentTest {
@Override
protected <T> DatabaseComponent createDatabaseComponent(
Database<T> database, DatabaseCleaner cleaner) {
return createDatabaseComponentImpl(database, cleaner);
Database<T> database, DatabaseCleaner cleaner,
ShutdownManager shutdown) {
return createDatabaseComponentImpl(database, cleaner, shutdown);
}
private <T> DatabaseComponentImpl<T> createDatabaseComponentImpl(
Database<T> database, DatabaseCleaner cleaner) {
return new DatabaseComponentImpl<T>(database, cleaner);
Database<T> database, DatabaseCleaner cleaner,
ShutdownManager shutdown) {
return new DatabaseComponentImpl<T>(database, cleaner, shutdown);
}
}

View File

@@ -22,6 +22,7 @@ import net.sf.briar.api.db.event.DatabaseListener;
import net.sf.briar.api.db.event.MessagesAddedEvent;
import net.sf.briar.api.db.event.RatingChangedEvent;
import net.sf.briar.api.db.event.TransportAddedEvent;
import net.sf.briar.api.lifecycle.ShutdownManager;
import net.sf.briar.api.protocol.Ack;
import net.sf.briar.api.protocol.AuthorId;
import net.sf.briar.api.protocol.Batch;
@@ -103,14 +104,17 @@ public abstract class DatabaseComponentTest extends TestCase {
}
protected abstract <T> DatabaseComponent createDatabaseComponent(
Database<T> database, DatabaseCleaner cleaner);
Database<T> database, DatabaseCleaner cleaner,
ShutdownManager shutdown);
@Test
@SuppressWarnings("unchecked")
public void testSimpleCalls() throws Exception {
final int shutdownHandle = 12345;
Mockery context = new Mockery();
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
final ConnectionWindow connectionWindow =
context.mock(ConnectionWindow.class);
final Group group = context.mock(Group.class);
@@ -124,6 +128,8 @@ public abstract class DatabaseComponentTest extends TestCase {
oneOf(cleaner).startCleaning(
with(any(DatabaseCleaner.Callback.class)),
with(any(long.class)));
oneOf(shutdown).addShutdownHook(with(any(Runnable.class)));
will(returnValue(shutdownHandle));
// getRating(authorId)
oneOf(database).getRating(txn, authorId);
will(returnValue(Rating.UNRATED));
@@ -189,10 +195,12 @@ public abstract class DatabaseComponentTest extends TestCase {
oneOf(database).removeContact(txn, contactId);
oneOf(listener).eventOccurred(with(any(ContactRemovedEvent.class)));
// close()
oneOf(shutdown).removeShutdownHook(shutdownHandle);
oneOf(cleaner).stopCleaning();
oneOf(database).close();
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner);
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.open(false);
db.addListener(listener);
@@ -224,6 +232,7 @@ public abstract class DatabaseComponentTest extends TestCase {
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
context.checking(new Expectations() {{
// setRating(authorId, Rating.GOOD)
allowing(database).startTransaction();
@@ -241,7 +250,8 @@ public abstract class DatabaseComponentTest extends TestCase {
will(returnValue(null));
oneOf(database).commitTransaction(txn);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner);
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.setRating(authorId, Rating.GOOD);
@@ -254,6 +264,7 @@ public abstract class DatabaseComponentTest extends TestCase {
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
context.checking(new Expectations() {{
// setRating(authorId, Rating.GOOD)
oneOf(database).startTransaction();
@@ -275,7 +286,8 @@ public abstract class DatabaseComponentTest extends TestCase {
oneOf(database).setSendability(txn, parentId, 2);
oneOf(database).commitTransaction(txn);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner);
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.setRating(authorId, Rating.GOOD);
@@ -289,6 +301,7 @@ public abstract class DatabaseComponentTest extends TestCase {
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
context.checking(new Expectations() {{
// setRating(authorId, Rating.GOOD)
oneOf(database).startTransaction();
@@ -313,7 +326,8 @@ public abstract class DatabaseComponentTest extends TestCase {
will(returnValue(null));
oneOf(database).commitTransaction(txn);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner);
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.setRating(authorId, Rating.GOOD);
@@ -327,6 +341,7 @@ public abstract class DatabaseComponentTest extends TestCase {
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
context.checking(new Expectations() {{
// addLocalGroupMessage(message)
oneOf(database).startTransaction();
@@ -335,7 +350,8 @@ public abstract class DatabaseComponentTest extends TestCase {
will(returnValue(false));
oneOf(database).commitTransaction(txn);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner);
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.addLocalGroupMessage(message);
@@ -348,6 +364,7 @@ public abstract class DatabaseComponentTest extends TestCase {
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
context.checking(new Expectations() {{
// addLocalGroupMessage(message)
oneOf(database).startTransaction();
@@ -358,7 +375,8 @@ public abstract class DatabaseComponentTest extends TestCase {
will(returnValue(false));
oneOf(database).commitTransaction(txn);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner);
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.addLocalGroupMessage(message);
@@ -371,6 +389,7 @@ public abstract class DatabaseComponentTest extends TestCase {
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
context.checking(new Expectations() {{
// addLocalGroupMessage(message)
oneOf(database).startTransaction();
@@ -390,7 +409,8 @@ public abstract class DatabaseComponentTest extends TestCase {
oneOf(database).setSendability(txn, messageId, 0);
oneOf(database).commitTransaction(txn);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner);
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.addLocalGroupMessage(message);
@@ -404,6 +424,7 @@ public abstract class DatabaseComponentTest extends TestCase {
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
context.checking(new Expectations() {{
// addLocalGroupMessage(message)
oneOf(database).startTransaction();
@@ -426,7 +447,8 @@ public abstract class DatabaseComponentTest extends TestCase {
will(returnValue(null));
oneOf(database).commitTransaction(txn);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner);
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.addLocalGroupMessage(message);
@@ -439,6 +461,7 @@ public abstract class DatabaseComponentTest extends TestCase {
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
context.checking(new Expectations() {{
allowing(database).startTransaction();
will(returnValue(txn));
@@ -449,7 +472,8 @@ public abstract class DatabaseComponentTest extends TestCase {
oneOf(database).addPrivateMessage(txn, privateMessage, contactId);
will(returnValue(false));
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner);
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.addLocalPrivateMessage(privateMessage, contactId);
@@ -462,6 +486,7 @@ public abstract class DatabaseComponentTest extends TestCase {
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
context.checking(new Expectations() {{
allowing(database).startTransaction();
will(returnValue(txn));
@@ -473,7 +498,8 @@ public abstract class DatabaseComponentTest extends TestCase {
will(returnValue(true));
oneOf(database).setStatus(txn, contactId, messageId, Status.NEW);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner);
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.addLocalPrivateMessage(privateMessage, contactId);
@@ -487,6 +513,7 @@ public abstract class DatabaseComponentTest extends TestCase {
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
final AckWriter ackWriter = context.mock(AckWriter.class);
final BatchWriter batchWriter = context.mock(BatchWriter.class);
final OfferWriter offerWriter = context.mock(OfferWriter.class);
@@ -510,7 +537,8 @@ public abstract class DatabaseComponentTest extends TestCase {
will(returnValue(false));
exactly(19).of(database).commitTransaction(txn);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner);
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
try {
db.addLocalPrivateMessage(privateMessage, contactId);
@@ -621,6 +649,7 @@ public abstract class DatabaseComponentTest extends TestCase {
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
final AckWriter ackWriter = context.mock(AckWriter.class);
context.checking(new Expectations() {{
allowing(database).startTransaction();
@@ -641,7 +670,8 @@ public abstract class DatabaseComponentTest extends TestCase {
oneOf(database).removeBatchesToAck(txn, contactId,
Collections.singletonList(batchId));
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner);
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.generateAck(contactId, ackWriter);
@@ -659,6 +689,7 @@ public abstract class DatabaseComponentTest extends TestCase {
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
final BatchWriter batchWriter = context.mock(BatchWriter.class);
context.checking(new Expectations() {{
allowing(database).startTransaction();
@@ -688,7 +719,8 @@ public abstract class DatabaseComponentTest extends TestCase {
oneOf(database).addOutstandingBatch(txn, contactId, batchId,
sendable);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner);
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.generateBatch(contactId, batchWriter);
@@ -708,6 +740,7 @@ public abstract class DatabaseComponentTest extends TestCase {
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
final BatchWriter batchWriter = context.mock(BatchWriter.class);
context.checking(new Expectations() {{
allowing(database).startTransaction();
@@ -734,7 +767,8 @@ public abstract class DatabaseComponentTest extends TestCase {
oneOf(database).addOutstandingBatch(txn, contactId, batchId,
Collections.singletonList(messageId1));
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner);
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.generateBatch(contactId, batchWriter, requested);
@@ -751,6 +785,7 @@ public abstract class DatabaseComponentTest extends TestCase {
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
final OfferWriter offerWriter = context.mock(OfferWriter.class);
context.checking(new Expectations() {{
allowing(database).startTransaction();
@@ -768,7 +803,8 @@ public abstract class DatabaseComponentTest extends TestCase {
will(returnValue(false));
oneOf(offerWriter).finish();
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner);
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
assertEquals(Collections.singletonList(messageId),
db.generateOffer(contactId, offerWriter));
@@ -783,6 +819,7 @@ public abstract class DatabaseComponentTest extends TestCase {
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
final SubscriptionUpdateWriter subscriptionUpdateWriter =
context.mock(SubscriptionUpdateWriter.class);
context.checking(new Expectations() {{
@@ -797,7 +834,8 @@ public abstract class DatabaseComponentTest extends TestCase {
oneOf(database).getSubscriptionsSent(txn, contactId);
will(returnValue(now));
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner);
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.generateSubscriptionUpdate(contactId, subscriptionUpdateWriter);
@@ -814,6 +852,7 @@ public abstract class DatabaseComponentTest extends TestCase {
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
final SubscriptionUpdateWriter subscriptionUpdateWriter =
context.mock(SubscriptionUpdateWriter.class);
context.checking(new Expectations() {{
@@ -837,7 +876,8 @@ public abstract class DatabaseComponentTest extends TestCase {
with(Collections.singletonMap(group, 0L)),
with(any(long.class)));
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner);
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.generateSubscriptionUpdate(contactId, subscriptionUpdateWriter);
@@ -851,6 +891,7 @@ public abstract class DatabaseComponentTest extends TestCase {
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
final TransportUpdateWriter transportUpdateWriter =
context.mock(TransportUpdateWriter.class);
context.checking(new Expectations() {{
@@ -865,7 +906,8 @@ public abstract class DatabaseComponentTest extends TestCase {
oneOf(database).getTransportsSent(txn, contactId);
will(returnValue(now));
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner);
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.generateTransportUpdate(contactId, transportUpdateWriter);
@@ -882,6 +924,7 @@ public abstract class DatabaseComponentTest extends TestCase {
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
final TransportUpdateWriter transportUpdateWriter =
context.mock(TransportUpdateWriter.class);
context.checking(new Expectations() {{
@@ -904,7 +947,8 @@ public abstract class DatabaseComponentTest extends TestCase {
oneOf(transportUpdateWriter).writeTransports(with(transports),
with(any(long.class)));
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner);
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.generateTransportUpdate(contactId, transportUpdateWriter);
@@ -918,6 +962,7 @@ public abstract class DatabaseComponentTest extends TestCase {
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
final Ack ack = context.mock(Ack.class);
context.checking(new Expectations() {{
allowing(database).startTransaction();
@@ -934,7 +979,8 @@ public abstract class DatabaseComponentTest extends TestCase {
will(returnValue(Collections.singletonList(batchId1)));
oneOf(database).removeLostBatch(txn, contactId, batchId1);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner);
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.receiveAck(contactId, ack);
@@ -947,6 +993,7 @@ public abstract class DatabaseComponentTest extends TestCase {
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
final Batch batch = context.mock(Batch.class);
context.checking(new Expectations() {{
allowing(database).startTransaction();
@@ -965,7 +1012,8 @@ public abstract class DatabaseComponentTest extends TestCase {
will(returnValue(batchId));
oneOf(database).addBatchToAck(txn, contactId, batchId);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner);
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.receiveBatch(contactId, batch);
@@ -978,6 +1026,7 @@ public abstract class DatabaseComponentTest extends TestCase {
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
final Batch batch = context.mock(Batch.class);
context.checking(new Expectations() {{
allowing(database).startTransaction();
@@ -995,7 +1044,8 @@ public abstract class DatabaseComponentTest extends TestCase {
will(returnValue(batchId));
oneOf(database).addBatchToAck(txn, contactId, batchId);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner);
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.receiveBatch(contactId, batch);
@@ -1009,6 +1059,7 @@ public abstract class DatabaseComponentTest extends TestCase {
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
final Batch batch = context.mock(Batch.class);
context.checking(new Expectations() {{
allowing(database).startTransaction();
@@ -1027,7 +1078,8 @@ public abstract class DatabaseComponentTest extends TestCase {
will(returnValue(batchId));
oneOf(database).addBatchToAck(txn, contactId, batchId);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner);
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.receiveBatch(contactId, batch);
@@ -1041,6 +1093,7 @@ public abstract class DatabaseComponentTest extends TestCase {
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
final Batch batch = context.mock(Batch.class);
context.checking(new Expectations() {{
allowing(database).startTransaction();
@@ -1063,7 +1116,8 @@ public abstract class DatabaseComponentTest extends TestCase {
will(returnValue(batchId));
oneOf(database).addBatchToAck(txn, contactId, batchId);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner);
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.receiveBatch(contactId, batch);
@@ -1076,6 +1130,7 @@ public abstract class DatabaseComponentTest extends TestCase {
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
final Batch batch = context.mock(Batch.class);
context.checking(new Expectations() {{
allowing(database).startTransaction();
@@ -1107,7 +1162,8 @@ public abstract class DatabaseComponentTest extends TestCase {
will(returnValue(batchId));
oneOf(database).addBatchToAck(txn, contactId, batchId);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner);
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.receiveBatch(contactId, batch);
@@ -1120,6 +1176,7 @@ public abstract class DatabaseComponentTest extends TestCase {
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
final Batch batch = context.mock(Batch.class);
context.checking(new Expectations() {{
allowing(database).startTransaction();
@@ -1153,7 +1210,8 @@ public abstract class DatabaseComponentTest extends TestCase {
will(returnValue(batchId));
oneOf(database).addBatchToAck(txn, contactId, batchId);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner);
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.receiveBatch(contactId, batch);
@@ -1175,6 +1233,7 @@ public abstract class DatabaseComponentTest extends TestCase {
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
final Offer offer = context.mock(Offer.class);
final RequestWriter requestWriter = context.mock(RequestWriter.class);
context.checking(new Expectations() {{
@@ -1194,7 +1253,8 @@ public abstract class DatabaseComponentTest extends TestCase {
will(returnValue(false)); // Not visible - request message # 2
oneOf(requestWriter).writeRequest(expectedRequest, 3);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner);
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.receiveOffer(contactId, offer, requestWriter);
@@ -1208,6 +1268,7 @@ public abstract class DatabaseComponentTest extends TestCase {
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
final SubscriptionUpdate subscriptionUpdate =
context.mock(SubscriptionUpdate.class);
context.checking(new Expectations() {{
@@ -1224,7 +1285,8 @@ public abstract class DatabaseComponentTest extends TestCase {
oneOf(database).setSubscriptions(txn, contactId,
Collections.singletonMap(group, 0L), timestamp);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner);
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.receiveSubscriptionUpdate(contactId, subscriptionUpdate);
@@ -1238,6 +1300,7 @@ public abstract class DatabaseComponentTest extends TestCase {
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
final TransportUpdate transportUpdate =
context.mock(TransportUpdate.class);
context.checking(new Expectations() {{
@@ -1254,7 +1317,8 @@ public abstract class DatabaseComponentTest extends TestCase {
oneOf(database).setTransports(txn, contactId, transports,
timestamp);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner);
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.receiveTransportUpdate(contactId, transportUpdate);
@@ -1267,6 +1331,7 @@ public abstract class DatabaseComponentTest extends TestCase {
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
final DatabaseListener listener = context.mock(DatabaseListener.class);
context.checking(new Expectations() {{
// addLocalGroupMessage(message)
@@ -1288,7 +1353,8 @@ public abstract class DatabaseComponentTest extends TestCase {
// The message was added, so the listener should be called
oneOf(listener).eventOccurred(with(any(MessagesAddedEvent.class)));
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner);
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.addListener(listener);
db.addLocalGroupMessage(message);
@@ -1302,6 +1368,7 @@ public abstract class DatabaseComponentTest extends TestCase {
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
final DatabaseListener listener = context.mock(DatabaseListener.class);
context.checking(new Expectations() {{
allowing(database).startTransaction();
@@ -1316,7 +1383,8 @@ public abstract class DatabaseComponentTest extends TestCase {
// The message was added, so the listener should be called
oneOf(listener).eventOccurred(with(any(MessagesAddedEvent.class)));
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner);
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.addListener(listener);
db.addLocalPrivateMessage(privateMessage, contactId);
@@ -1331,6 +1399,7 @@ public abstract class DatabaseComponentTest extends TestCase {
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
final DatabaseListener listener = context.mock(DatabaseListener.class);
context.checking(new Expectations() {{
// addLocalGroupMessage(message)
@@ -1343,7 +1412,8 @@ public abstract class DatabaseComponentTest extends TestCase {
oneOf(database).commitTransaction(txn);
// The message was not added, so the listener should not be called
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner);
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.addListener(listener);
db.addLocalGroupMessage(message);
@@ -1358,6 +1428,7 @@ public abstract class DatabaseComponentTest extends TestCase {
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
final DatabaseListener listener = context.mock(DatabaseListener.class);
context.checking(new Expectations() {{
allowing(database).startTransaction();
@@ -1370,7 +1441,8 @@ public abstract class DatabaseComponentTest extends TestCase {
will(returnValue(false));
// The message was not added, so the listener should not be called
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner);
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.addListener(listener);
db.addLocalPrivateMessage(privateMessage, contactId);
@@ -1387,6 +1459,7 @@ public abstract class DatabaseComponentTest extends TestCase {
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
final DatabaseListener listener = context.mock(DatabaseListener.class);
context.checking(new Expectations() {{
oneOf(database).startTransaction();
@@ -1400,7 +1473,8 @@ public abstract class DatabaseComponentTest extends TestCase {
oneOf(listener).eventOccurred(with(any(
TransportAddedEvent.class)));
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner);
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.addListener(listener);
db.setLocalProperties(transportId, properties);
@@ -1417,6 +1491,7 @@ public abstract class DatabaseComponentTest extends TestCase {
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
final DatabaseListener listener = context.mock(DatabaseListener.class);
context.checking(new Expectations() {{
oneOf(database).startTransaction();
@@ -1425,7 +1500,8 @@ public abstract class DatabaseComponentTest extends TestCase {
will(returnValue(properties));
oneOf(database).commitTransaction(txn);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner);
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.addListener(listener);
db.setLocalProperties(transportId, properties);
@@ -1439,6 +1515,7 @@ public abstract class DatabaseComponentTest extends TestCase {
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
context.checking(new Expectations() {{
allowing(database).startTransaction();
will(returnValue(txn));
@@ -1448,7 +1525,8 @@ public abstract class DatabaseComponentTest extends TestCase {
// setSeen(contactId, Collections.singletonList(messageId))
oneOf(database).setStatusSeenIfVisible(txn, contactId, messageId);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner);
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.setSeen(contactId, Collections.singletonList(messageId));

View File

@@ -44,6 +44,7 @@ import net.sf.briar.api.transport.ConnectionContextFactory;
import net.sf.briar.api.transport.ConnectionWindow;
import net.sf.briar.api.transport.ConnectionWindowFactory;
import net.sf.briar.crypto.CryptoModule;
import net.sf.briar.lifecycle.LifecycleModule;
import net.sf.briar.protocol.ProtocolModule;
import net.sf.briar.protocol.writers.ProtocolWritersModule;
import net.sf.briar.serial.SerialModule;
@@ -105,10 +106,11 @@ public class H2DatabaseTest extends TestCase {
}
};
Injector i = Guice.createInjector(testModule, new CryptoModule(),
new DatabaseModule(), new ProtocolModule(),
new ProtocolWritersModule(), new SerialModule(),
new TransportBatchModule(), new TransportModule(),
new TransportStreamModule(), new TestDatabaseModule(testDir));
new DatabaseModule(), new LifecycleModule(),
new ProtocolModule(), new ProtocolWritersModule(),
new SerialModule(), new TransportBatchModule(),
new TransportModule(), new TransportStreamModule(),
new TestDatabaseModule(testDir));
connectionContextFactory =
i.getInstance(ConnectionContextFactory.class);
connectionWindowFactory = i.getInstance(ConnectionWindowFactory.class);

View File

@@ -0,0 +1,29 @@
package net.sf.briar.lifecycle;
import java.util.HashSet;
import java.util.Set;
import junit.framework.TestCase;
import net.sf.briar.api.lifecycle.ShutdownManager;
import org.junit.Test;
public class ShutdownManagerImplTest extends TestCase {
@Test
public void testAddAndRemove() {
ShutdownManager s = new ShutdownManagerImpl();
Set<Integer> handles = new HashSet<Integer>();
for(int i = 0; i < 100; i++) {
int handle = s.addShutdownHook(new Runnable() {
public void run() {}
});
// The handles should all be distinct
assertTrue(handles.add(handle));
}
// The hooks should be removable
for(int handle : handles) assertTrue(s.removeShutdownHook(handle));
// The hooks should no longer be removable
for(int handle : handles) assertFalse(s.removeShutdownHook(handle));
}
}

View File

@@ -17,6 +17,7 @@ import net.sf.briar.api.crypto.CryptoComponent;
import net.sf.briar.api.crypto.ErasableKey;
import net.sf.briar.api.db.DatabaseComponent;
import net.sf.briar.api.db.DbException;
import net.sf.briar.api.lifecycle.ShutdownManager;
import net.sf.briar.api.protocol.Transport;
import net.sf.briar.api.protocol.TransportId;
import net.sf.briar.api.protocol.TransportIndex;
@@ -65,9 +66,11 @@ public class ConnectionRecogniserImplTest extends TestCase {
public void testUnexpectedIv() throws Exception {
Mockery context = new Mockery();
final DatabaseComponent db = context.mock(DatabaseComponent.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
context.checking(new Expectations() {{
oneOf(db).addListener(with(any(ConnectionRecogniserImpl.class)));
// Initialise
oneOf(shutdown).addShutdownHook(with(any(Runnable.class)));
oneOf(db).getLocalTransports();
will(returnValue(transports));
oneOf(db).getContacts();
@@ -77,8 +80,9 @@ public class ConnectionRecogniserImplTest extends TestCase {
oneOf(db).getConnectionWindow(contactId, remoteIndex);
will(returnValue(connectionWindow));
}});
Executor e = new ImmediateExecutor();
ConnectionRecogniser c = new ConnectionRecogniserImpl(crypto, db, e);
Executor executor = new ImmediateExecutor();
ConnectionRecogniser c = new ConnectionRecogniserImpl(crypto, db,
executor, shutdown);
c.acceptConnection(transportId, new byte[IV_LENGTH], new Callback() {
public void connectionAccepted(ConnectionContext ctx) {
@@ -112,9 +116,11 @@ public class ConnectionRecogniserImplTest extends TestCase {
Mockery context = new Mockery();
final DatabaseComponent db = context.mock(DatabaseComponent.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
context.checking(new Expectations() {{
oneOf(db).addListener(with(any(ConnectionRecogniserImpl.class)));
// Initialise
oneOf(shutdown).addShutdownHook(with(any(Runnable.class)));
oneOf(db).getLocalTransports();
will(returnValue(transports));
oneOf(db).getContacts();
@@ -127,8 +133,9 @@ public class ConnectionRecogniserImplTest extends TestCase {
oneOf(db).setConnectionWindow(contactId, remoteIndex,
connectionWindow);
}});
Executor e = new ImmediateExecutor();
ConnectionRecogniser c = new ConnectionRecogniserImpl(crypto, db, e);
Executor executor = new ImmediateExecutor();
ConnectionRecogniser c = new ConnectionRecogniserImpl(crypto, db,
executor, shutdown);
// The IV should not be expected by the wrong transport
TransportId wrong = new TransportId(TestUtils.getRandomId());
c.acceptConnection(wrong, encryptedIv, new Callback() {

View File

@@ -18,6 +18,7 @@ import net.sf.briar.api.transport.ConnectionWriter;
import net.sf.briar.api.transport.ConnectionWriterFactory;
import net.sf.briar.crypto.CryptoModule;
import net.sf.briar.db.DatabaseModule;
import net.sf.briar.lifecycle.LifecycleModule;
import net.sf.briar.protocol.ProtocolModule;
import net.sf.briar.protocol.writers.ProtocolWritersModule;
import net.sf.briar.serial.SerialModule;
@@ -50,10 +51,11 @@ public class ConnectionWriterTest extends TestCase {
}
};
Injector i = Guice.createInjector(testModule, new CryptoModule(),
new DatabaseModule(), new ProtocolModule(),
new ProtocolWritersModule(), new SerialModule(),
new TestDatabaseModule(), new TransportBatchModule(),
new TransportModule(), new TransportStreamModule());
new DatabaseModule(), new LifecycleModule(),
new ProtocolModule(), new ProtocolWritersModule(),
new SerialModule(), new TestDatabaseModule(),
new TransportBatchModule(), new TransportModule(),
new TransportStreamModule());
connectionContextFactory =
i.getInstance(ConnectionContextFactory.class);
connectionWriterFactory = i.getInstance(ConnectionWriterFactory.class);

View File

@@ -40,6 +40,7 @@ import net.sf.briar.api.transport.ConnectionRecogniser.Callback;
import net.sf.briar.api.transport.ConnectionWriterFactory;
import net.sf.briar.crypto.CryptoModule;
import net.sf.briar.db.DatabaseModule;
import net.sf.briar.lifecycle.LifecycleModule;
import net.sf.briar.protocol.ProtocolModule;
import net.sf.briar.protocol.writers.ProtocolWritersModule;
import net.sf.briar.serial.SerialModule;
@@ -81,32 +82,24 @@ public class BatchConnectionReadWriteTest extends TestCase {
@Before
public void setUp() {
testDir.mkdirs();
// Create Alice's injector
Module aliceTestModule = new AbstractModule() {
alice = createInjector(aliceDir);
bob = createInjector(bobDir);
}
private Injector createInjector(File dir) {
Module testModule = new AbstractModule() {
@Override
public void configure() {
bind(Executor.class).toInstance(
new ScheduledThreadPoolExecutor(5));
}
};
alice = Guice.createInjector(aliceTestModule, new CryptoModule(),
new DatabaseModule(), new ProtocolModule(),
new ProtocolWritersModule(), new SerialModule(),
new TestDatabaseModule(aliceDir), new TransportBatchModule(),
new TransportModule(), new TransportStreamModule());
// Create Bob's injector
Module bobTestModule = new AbstractModule() {
@Override
public void configure() {
bind(Executor.class).toInstance(
new ScheduledThreadPoolExecutor(5));
}
};
bob = Guice.createInjector(bobTestModule, new CryptoModule(),
new DatabaseModule(), new ProtocolModule(),
new ProtocolWritersModule(), new SerialModule(),
new TestDatabaseModule(bobDir), new TransportBatchModule(),
new TransportModule(), new TransportStreamModule());
return Guice.createInjector(testModule, new CryptoModule(),
new DatabaseModule(), new LifecycleModule(),
new ProtocolModule(), new ProtocolWritersModule(),
new SerialModule(), new TestDatabaseModule(dir),
new TransportBatchModule(), new TransportModule(),
new TransportStreamModule());
}
@Test