/** * Copyright (c) 2009 - 2012 Red Hat, Inc. * * This software is licensed to you under the GNU General Public License, * version 2 (GPLv2). There is NO WARRANTY for this software, express or * implied, including the implied warranties of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 * along with this software; if not, see * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. * * Red Hat trademarks are not licensed under GPLv2. No permission is * granted to use or replicate Red Hat trademarks that are incorporated * in this software or its documentation. */ package org.candlepin.guice; import static org.junit.Assert.*; import static org.mockito.Matchers.*; import static org.mockito.Mockito.*; import org.candlepin.TestingModules; import org.candlepin.audit.AMQPBusPublisher; import org.candlepin.audit.HornetqContextListener; import org.candlepin.common.config.Configuration; import org.candlepin.common.config.ConfigurationException; import org.candlepin.common.config.ConfigurationPrefixes; import org.candlepin.common.config.MapConfiguration; import org.candlepin.config.ConfigProperties; import org.candlepin.junit.CandlepinLiquibaseResource; import org.candlepin.pinsetter.core.PinsetterContextListener; import com.google.inject.AbstractModule; import com.google.inject.Injector; import com.google.inject.Module; import com.google.inject.Stage; import org.jboss.resteasy.spi.Registry; import org.jboss.resteasy.spi.ResteasyProviderFactory; import org.junit.Before; import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; import java.util.LinkedList; import java.util.List; import java.util.concurrent.ScheduledExecutorService; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; /** * CandlepinContextListenerTest */ public class CandlepinContextListenerTest { private Configuration config; private CandlepinContextListener listener; private HornetqContextListener hqlistener; private PinsetterContextListener pinlistener; private AMQPBusPublisher buspublisher; private ScheduledExecutorService executorService; private ServletContextEvent evt; private ServletContext ctx; private VerifyConfigRead configRead; @SuppressWarnings("checkstyle:visibilitymodifier") @ClassRule @Rule public static CandlepinLiquibaseResource liquibase = new CandlepinLiquibaseResource(); @Before public void init() { config = mock(Configuration.class); when(config.subset(eq("org.quartz"))).thenReturn( new MapConfiguration(ConfigProperties.DEFAULT_PROPERTIES)); when(config.strippedSubset(eq(ConfigurationPrefixes.LOGGING_CONFIG_PREFIX))) .thenReturn(new MapConfiguration()); hqlistener = mock(HornetqContextListener.class); pinlistener = mock(PinsetterContextListener.class); buspublisher = mock(AMQPBusPublisher.class); executorService = mock(ScheduledExecutorService.class); configRead = mock(VerifyConfigRead.class); // for testing we override the getModules and readConfiguration methods // so we can insert our mock versions of listeners to verify // they are getting invoked properly. listener = new CandlepinContextListener() { @Override protected List<Module> getModules(ServletContext context) { List<Module> modules = new LinkedList<Module>(); // tried simply overriding CandlepinModule // but that caused it to read the local config // which means the test becomes non-deterministic. // so just load the items we need to verify the // functionality. modules.add(new TestingModules.JpaModule()); modules.add(new TestingModules.StandardTest(config)); modules.add(new ContextListenerTestModule()); return modules; } @Override protected Configuration readConfiguration(ServletContext context) throws ConfigurationException { configRead.verify(context); return config; } }; } @Test public void contextInitialized() { when(config.getBoolean(eq(ConfigProperties.HORNETQ_ENABLED))).thenReturn(true); prepareForInitialization(); listener.contextInitialized(evt); verify(hqlistener).contextInitialized(any(Injector.class)); verify(pinlistener).contextInitialized(); verify(ctx).setAttribute( eq(CandlepinContextListener.CONFIGURATION_NAME), eq(config)); verify(configRead).verify(eq(ctx)); } @Test public void hornetQDisabled() { when(config.getBoolean(eq(ConfigProperties.HORNETQ_ENABLED))).thenReturn(false); prepareForInitialization(); listener.contextInitialized(evt); verifyNoMoreInteractions(hqlistener); } @Test public void contextDestroyed() { when(config.getBoolean(eq(ConfigProperties.HORNETQ_ENABLED))).thenReturn(true); prepareForInitialization(); // we actually have to call contextInitialized before we // can call contextDestroyed, otherwise the listener's // member variables will be null. listener.contextInitialized(evt); // what we really want to test. listener.contextDestroyed(evt); // make sure we only call it 5 times all from init code verify(evt, atMost(5)).getServletContext(); verifyNoMoreInteractions(evt); // destroy shouldn't use it verify(hqlistener).contextDestroyed(); verify(pinlistener).contextDestroyed(); verifyZeroInteractions(buspublisher); } @Test public void ensureAMQPClosedProperly() { when(config.getBoolean( eq(ConfigProperties.AMQP_INTEGRATION_ENABLED))).thenReturn(true); when(config.getBoolean(eq(ConfigProperties.SUSPEND_MODE_ENABLED))).thenReturn(true); when(config.getLong(ConfigProperties.QPID_MODE_TANSITIONER_DELAY_GROWTH)).thenReturn(100L); when(config.getLong(ConfigProperties.QPID_MODE_TRANSITIONER_INITIAL_DELAY)).thenReturn(100L); prepareForInitialization(); // we actually have to call contextInitialized before we // can call contextDestroyed, otherwise the listener's // member variables will be null. listener.contextInitialized(evt); // test & verify listener.contextDestroyed(evt); verify(buspublisher).close(); } @Test(expected = RuntimeException.class) public void tharSheBlows() { listener = new CandlepinContextListener() { protected List<Module> getModules(ServletContext context) { return new LinkedList<Module>(); } protected Configuration readConfiguration(ServletContext context) throws ConfigurationException { throw new ConfigurationException("the ship is sinking"); } }; prepareForInitialization(); listener.contextInitialized(evt); } @Test public void exitStageLeft() { assertEquals(Stage.PRODUCTION, listener.getStage(ctx)); } private void prepareForInitialization() { evt = mock(ServletContextEvent.class); ctx = mock(ServletContext.class); Registry registry = mock(Registry.class); ResteasyProviderFactory rpfactory = mock(ResteasyProviderFactory.class); when(evt.getServletContext()).thenReturn(ctx); when(ctx.getAttribute(eq(Registry.class.getName()))).thenReturn(registry); when(ctx.getAttribute(eq(ResteasyProviderFactory.class.getName()))).thenReturn(rpfactory); when(ctx.getAttribute(eq(CandlepinContextListener.CONFIGURATION_NAME))).thenReturn(config); } public class ContextListenerTestModule extends AbstractModule { @SuppressWarnings("synthetic-access") @Override protected void configure() { bind(PinsetterContextListener.class).toInstance(pinlistener); bind(HornetqContextListener.class).toInstance(hqlistener); bind(AMQPBusPublisher.class).toInstance(buspublisher); bind(ScheduledExecutorService.class).toInstance(executorService); } } /** * VerifyConfigRead fake interface to use with mockito's mock and verify * methods to make sure the correct var was passed in and we called a * method we expected. */ interface VerifyConfigRead { void verify(ServletContext ctx); } }