package com.twitter.common.application.modules;
import java.lang.Thread.UncaughtExceptionHandler;
import java.net.InetSocketAddress;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableMap;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Module;
import org.junit.Test;
import com.twitter.common.application.ShutdownRegistry.ShutdownRegistryImpl;
import com.twitter.common.application.modules.LifecycleModule.LaunchException;
import com.twitter.common.application.modules.LifecycleModule.ServiceRunner;
import com.twitter.common.application.modules.LocalServiceRegistry.LocalService;
import com.twitter.common.base.Command;
import com.twitter.common.testing.EasyMockTest;
import static org.easymock.EasyMock.expect;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static com.twitter.common.application.modules.LifecycleModule.bindLocalService;
import static com.twitter.common.net.InetSocketAddressHelper.getLocalAddress;
/**
* @author William Farner
*/
public class LifecycleModuleTest extends EasyMockTest {
private static class SystemModule extends AbstractModule {
@Override protected void configure() {
install(new LifecycleModule());
bind(UncaughtExceptionHandler.class).toInstance(new UncaughtExceptionHandler() {
@Override public void uncaughtException(Thread thread, Throwable throwable) {
fail("Uncaught exception.");
}
});
}
}
@Test
public void testNoServices() {
control.replay();
Injector injector = Guice.createInjector(new SystemModule());
LocalServiceRegistry registry = injector.getInstance(LocalServiceRegistry.class);
assertEquals(Optional.<InetSocketAddress>absent(), registry.getPrimarySocket());
assertEquals(ImmutableMap.<String, InetSocketAddress>of(), registry.getAuxiliarySockets());
}
@Test
public void testNoRunner() throws Exception {
final Command primaryShutdown = createMock(Command.class);
final Command auxShutdown = createMock(Command.class);
primaryShutdown.execute();
auxShutdown.execute();
Module testModule = new AbstractModule() {
@Override protected void configure() {
bindLocalService(binder(), LocalService.primaryService(99, primaryShutdown));
bindLocalService(binder(), LocalService.auxiliaryService("foo", 100, auxShutdown));
}
};
Injector injector = Guice.createInjector(new SystemModule(), testModule);
LocalServiceRegistry registry = injector.getInstance(LocalServiceRegistry.class);
control.replay();
assertEquals(Optional.of(getLocalAddress(99)), registry.getPrimarySocket());
assertEquals(ImmutableMap.of("foo", getLocalAddress(100)), registry.getAuxiliarySockets());
injector.getInstance(ShutdownRegistryImpl.class).execute();
}
@Test
public void testOrdering() throws Exception {
final ServiceRunner runner = createMock(ServiceRunner.class);
Command shutdown = createMock(Command.class);
expect(runner.launch()).andReturn(LocalService.primaryService(100, shutdown));
shutdown.execute();
Module testModule = new AbstractModule() {
@Override protected void configure() {
LifecycleModule.runnerBinder(binder()).addBinding().toInstance(runner);
}
};
Injector injector = Guice.createInjector(new SystemModule(), testModule);
LocalServiceRegistry registry = injector.getInstance(LocalServiceRegistry.class);
control.replay();
assertEquals(Optional.of(getLocalAddress(100)), registry.getPrimarySocket());
injector.getInstance(ShutdownRegistryImpl.class).execute();
}
@Test(expected = IllegalStateException.class)
public void testFailedLauncher() throws Exception {
final ServiceRunner runner = createMock(ServiceRunner.class);
expect(runner.launch()).andThrow(new LaunchException("Injected failure."));
Module testModule = new AbstractModule() {
@Override protected void configure() {
LifecycleModule.runnerBinder(binder()).addBinding().toInstance(runner);
}
};
Injector injector = Guice.createInjector(new SystemModule(), testModule);
LocalServiceRegistry registry = injector.getInstance(LocalServiceRegistry.class);
control.replay();
assertEquals(Optional.of(getLocalAddress(100)), registry.getPrimarySocket());
}
}