Return early when starting/stopping if not in expected state.

This commit is contained in:
akwizgran
2022-06-09 18:01:32 +01:00
parent 85d1addd04
commit de3a87fff5
3 changed files with 115 additions and 63 deletions

View File

@@ -5,6 +5,7 @@ import org.briarproject.bramble.api.db.DatabaseComponent;
import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.event.EventBus;
import org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook;
import org.briarproject.bramble.api.lifecycle.Service;
import org.briarproject.bramble.api.lifecycle.event.LifecycleEvent;
import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.test.BrambleMockTestCase;
@@ -13,12 +14,10 @@ import org.jmock.Expectations;
import org.junit.Before;
import org.junit.Test;
import java.util.concurrent.atomic.AtomicBoolean;
import static junit.framework.TestCase.assertTrue;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.RUNNING;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.STARTING;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.STOPPING;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.STOPPED;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.ALREADY_RUNNING;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.CLOCK_ERROR;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.SUCCESS;
import static org.briarproject.bramble.api.system.Clock.MAX_REASONABLE_TIME_MS;
@@ -31,6 +30,8 @@ public class LifecycleManagerImplTest extends BrambleMockTestCase {
private final DatabaseComponent db = context.mock(DatabaseComponent.class);
private final EventBus eventBus = context.mock(EventBus.class);
private final Clock clock = context.mock(Clock.class);
private final OpenDatabaseHook hook = context.mock(OpenDatabaseHook.class);
private final Service service = context.mock(Service.class);
private final SecretKey dbKey = getSecretKey();
@@ -45,8 +46,6 @@ public class LifecycleManagerImplTest extends BrambleMockTestCase {
public void testOpenDatabaseHooksAreCalledAtStartup() throws Exception {
long now = System.currentTimeMillis();
Transaction txn = new Transaction(null, false);
AtomicBoolean called = new AtomicBoolean(false);
OpenDatabaseHook hook = transaction -> called.set(true);
context.checking(new DbExpectations() {{
oneOf(clock).currentTimeMillis();
@@ -55,6 +54,7 @@ public class LifecycleManagerImplTest extends BrambleMockTestCase {
will(returnValue(false));
oneOf(db).transaction(with(false), withDbRunnable(txn));
oneOf(db).removeTemporaryMessages(txn);
oneOf(hook).onDatabaseOpened(txn);
allowing(eventBus).broadcast(with(any(LifecycleEvent.class)));
}});
@@ -62,7 +62,38 @@ public class LifecycleManagerImplTest extends BrambleMockTestCase {
assertEquals(SUCCESS, lifecycleManager.startServices(dbKey));
assertEquals(RUNNING, lifecycleManager.getLifecycleState());
assertTrue(called.get());
}
@Test
public void testServicesAreStartedAndStopped() throws Exception {
long now = System.currentTimeMillis();
Transaction txn = new Transaction(null, false);
context.checking(new DbExpectations() {{
oneOf(clock).currentTimeMillis();
will(returnValue(now));
oneOf(db).open(dbKey, lifecycleManager);
will(returnValue(false));
oneOf(db).transaction(with(false), withDbRunnable(txn));
oneOf(db).removeTemporaryMessages(txn);
oneOf(service).startService();
allowing(eventBus).broadcast(with(any(LifecycleEvent.class)));
}});
lifecycleManager.registerService(service);
assertEquals(SUCCESS, lifecycleManager.startServices(dbKey));
assertEquals(RUNNING, lifecycleManager.getLifecycleState());
context.assertIsSatisfied();
context.checking(new Expectations() {{
oneOf(db).close();
oneOf(service).stopService();
allowing(eventBus).broadcast(with(any(LifecycleEvent.class)));
}});
lifecycleManager.stopServices();
assertEquals(STOPPED, lifecycleManager.getLifecycleState());
}
@Test
@@ -89,6 +120,31 @@ public class LifecycleManagerImplTest extends BrambleMockTestCase {
assertEquals(STARTING, lifecycleManager.getLifecycleState());
}
@Test
public void testSecondCallToStartServicesReturnsEarly() throws Exception {
long now = System.currentTimeMillis();
Transaction txn = new Transaction(null, false);
context.checking(new DbExpectations() {{
oneOf(clock).currentTimeMillis();
will(returnValue(now));
oneOf(db).open(dbKey, lifecycleManager);
will(returnValue(false));
oneOf(db).transaction(with(false), withDbRunnable(txn));
oneOf(db).removeTemporaryMessages(txn);
allowing(eventBus).broadcast(with(any(LifecycleEvent.class)));
}});
assertEquals(SUCCESS, lifecycleManager.startServices(dbKey));
assertEquals(RUNNING, lifecycleManager.getLifecycleState());
context.assertIsSatisfied();
// Calling startServices() again should not try to open the DB or
// start the services again
assertEquals(ALREADY_RUNNING, lifecycleManager.startServices(dbKey));
assertEquals(RUNNING, lifecycleManager.getLifecycleState());
}
@Test
public void testSecondCallToStopServicesReturnsEarly() throws Exception {
long now = System.currentTimeMillis();
@@ -101,7 +157,7 @@ public class LifecycleManagerImplTest extends BrambleMockTestCase {
will(returnValue(false));
oneOf(db).transaction(with(false), withDbRunnable(txn));
oneOf(db).removeTemporaryMessages(txn);
exactly(2).of(eventBus).broadcast(with(any(LifecycleEvent.class)));
allowing(eventBus).broadcast(with(any(LifecycleEvent.class)));
}});
assertEquals(SUCCESS, lifecycleManager.startServices(dbKey));
@@ -109,17 +165,17 @@ public class LifecycleManagerImplTest extends BrambleMockTestCase {
context.assertIsSatisfied();
context.checking(new Expectations() {{
oneOf(eventBus).broadcast(with(any(LifecycleEvent.class)));
oneOf(db).close();
allowing(eventBus).broadcast(with(any(LifecycleEvent.class)));
}});
lifecycleManager.stopServices();
assertEquals(STOPPING, lifecycleManager.getLifecycleState());
assertEquals(STOPPED, lifecycleManager.getLifecycleState());
context.assertIsSatisfied();
// Calling stopServices() again should not broadcast another event or
// try to close the DB again
lifecycleManager.stopServices();
assertEquals(STOPPING, lifecycleManager.getLifecycleState());
assertEquals(STOPPED, lifecycleManager.getLifecycleState());
}
}