/** * The contents of this file are subject to the OpenMRS Public License * Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://license.openmrs.org * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the * License for the specific language governing rights and limitations * under the License. * * Copyright (C) OpenMRS, LLC. All Rights Reserved. */ package org.openmrs.test; import java.util.Properties; import org.apache.commons.lang.StringUtils; import org.junit.Assert; import org.openmrs.api.context.Context; import org.openmrs.api.db.SerializedObjectDAOTest; import org.openmrs.module.Module; import org.openmrs.module.ModuleClassLoader; import org.openmrs.module.ModuleConstants; import org.openmrs.module.ModuleFactory; import org.openmrs.module.ModuleInteroperabilityTest; import org.openmrs.module.ModuleUtil; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.test.context.TestContext; import org.springframework.test.context.support.AbstractTestExecutionListener; /** * To use this annotation: * <ol> * <li>Add the @StartModule( { "/path/to/your/module.omod" } ) annotation to the test class * <li>Add the @DirtiesContext method to the last test method in the class * </ol> * * @see SerializedObjectDAOTest * @see ModuleInteroperabilityTest * @see BaseContextSensitiveTest */ public class StartModuleExecutionListener extends AbstractTestExecutionListener { // stores the last class that restarted the module system because we only // want it restarted once per class, not once per method private static String lastClassRun = ""; /** * called before @BeforeTransaction methods * * @see org.springframework.test.context.support.AbstractTestExecutionListener#prepareTestInstance(org.springframework.test.context.TestContext) */ @Override public void prepareTestInstance(TestContext testContext) throws Exception { StartModule startModuleAnnotation = testContext.getTestClass().getAnnotation(StartModule.class); // if the developer listed some modules with the @StartModule annotation on the class if (startModuleAnnotation != null) { if (!lastClassRun.equals(testContext.getTestClass().getSimpleName())) { // mark this with our class so that the services are only restarted once lastClassRun = testContext.getTestClass().getSimpleName(); if (!Context.isSessionOpen()) Context.openSession(); // load the omods that the dev defined for this class String modulesToLoad = StringUtils.join(startModuleAnnotation.value(), " "); Properties props = BaseContextSensitiveTest.runtimeProperties; props.setProperty(ModuleConstants.RUNTIMEPROPERTY_MODULE_LIST_TO_LOAD, modulesToLoad); try { ModuleUtil.startup(props); } catch (Exception e) { System.out.println("Error while starting modules: "); e.printStackTrace(System.out); throw e; } Assert.assertTrue("Some of the modules did not start successfully for " + testContext.getTestClass().getSimpleName() + ". Only " + ModuleFactory.getStartedModules().size() + " modules started instead of " + startModuleAnnotation.value().length, startModuleAnnotation.value().length <= ModuleFactory.getStartedModules().size()); // refresh spring so the Services are recreated (aka serializer gets put into the SerializationService) new ClassPathXmlApplicationContext(new String[] { "applicationContext-service.xml", "classpath*:moduleApplicationContext.xml" }); // session is closed by the test framework //Context.closeSession(); } } } }