package org.marketcetera.module; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.io.File; import java.math.BigDecimal; import java.math.BigInteger; import java.net.URI; import java.net.URL; import java.util.Date; import java.util.Properties; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; /* $License$ */ /** * Tests Module provider and module lifecycle & information reporting. * * @author anshul@marketcetera.com */ public class LifecycleTest extends ModuleTestBase { @BeforeClass public static void setup() throws Exception { SingletonModule.clearInstances(); sManager = new ModuleManager(); sManager.init(); } @AfterClass public static void cleanup() throws Exception { sManager.stop(); } @Before public void clear() throws Exception { MultipleModule.clearInstances(); } /** * Tests get providers API. * * @throws Exception if there are unexpected errors. */ @Test public void getProviders() throws Exception { //Should see the following providers checkAllProviders(sManager.getProviders()); } /** * Tests the get provider info API. * * @throws Exception if there are unexpected errors. */ @Test public void getProviderInfo() throws Exception { //Now verify the Provider Info for each of the providers assertProviderInfo(SinkModuleFactory.PROVIDER_URN, new String[0], new Class[0], Messages.SINK_MODULE_FACTORY_DESC.getText(), false,false); assertProviderInfo(SingleModuleFactory.PROVIDER_URN, new String[0], new Class[0], TestMessages.SINGLE_1_PROVIDER.getText(), false, false); assertProviderInfo(MultipleModuleFactory.PROVIDER_URN, new String[]{ModuleURN.class.getName()}, new Class[]{ModuleURN.class}, TestMessages.MULTIPLE_1_PROVIDER.getText(), true, true); assertProviderInfo(ComplexModuleFactory.PROVIDER_URN, new String[]{String.class.getName(), File.class.getName(), URL.class.getName(), Date.class.getName()}, new Class[]{String.class, File.class, URL.class, Date.class}, TestMessages.MULTIPLE_2_PROVIDER.getText(), false, true); assertProviderInfo(JMXTestModuleFactory.PROVIDER_URN, new String[]{ModuleURN.class.getName(), Boolean.class.getName(), Boolean.TYPE.getName(), Byte.class.getName(), Byte.TYPE.getName(), Character.class.getName(), Character.TYPE.getName(), Short.class.getName(), Short.TYPE.getName(), Integer.class.getName(), Integer.TYPE.getName(), Float.class.getName(), Float.TYPE.getName(), Long.class.getName(), Long.TYPE.getName(), Double.class.getName(), Double.TYPE.getName(), String.class.getName(), BigDecimal.class.getName(), BigInteger.class.getName(), File.class.getName(), URL.class.getName(), Properties.class.getName()}, new Class[]{ModuleURN.class, Boolean.class, Boolean.TYPE, Byte.class, Byte.TYPE, Character.class, Character.TYPE, Short.class, Short.TYPE, Integer.class, Integer.TYPE, Float.class, Float.TYPE, Long.class, Long.TYPE, Double.class, Double.TYPE, String.class, BigDecimal.class, BigInteger.class, File.class, URL.class, Properties.class}, TestMessages.MULTIPLE_3_PROVIDER.getText(), false, true); final ModuleURN unknownProvider = new ModuleURN("metc:test:unknown"); new ExpectedFailure<ProviderNotFoundException>( Messages.PROVIDER_NOT_FOUND, unknownProvider.toString()){ protected void run() throws Exception { sManager.getProviderInfo(unknownProvider); } }; } /** * Tests get module instances API. * * @throws Exception if there are unexpected errors. */ @Test public void getModuleInstances() throws Exception { assertContains(sManager.getModuleInstances(null), new ModuleURN[]{ SinkModuleFactory.INSTANCE_URN, SingleModuleFactory.INSTANCE_URN}); assertTrue(sManager.getModuleInstances( new ModuleURN("metc:not:exists")).isEmpty()); } /** * Tests get module info API. * * @throws Exception if there are unexpected errors. */ @Test public void getModuleInfo() throws Exception { assertModuleInfo(SinkModuleFactory.INSTANCE_URN, ModuleState.STARTED, null, null,false,true, true, false, false); assertModuleInfo(SingleModuleFactory.INSTANCE_URN, ModuleState.CREATED, null, null,false,false, false, false, false); //Verify the singleton module instance. assertEquals(1,SingletonModule.getInstances()); assertFalse(SingletonModule.getInstance().isStartInvoked()); assertFalse(SingletonModule.getInstance().isStopInvoked()); } /** * Tests that attempt to create another instance of singleton module fails. * * @throws Exception if there are unexpected errors. */ @Test public void createSingletonModuleFail() throws Exception { new ExpectedFailure<ModuleCreationException>( Messages.CANNOT_CREATE_SINGLETON, SingleModuleFactory.PROVIDER_URN.toString(), SingleModuleFactory.INSTANCE_URN.toString()){ protected void run() throws Exception { sManager.createModule(SingleModuleFactory.PROVIDER_URN, "Whatever"); } }; } /** * Tests creation of a singleton module that can not be auto-created * as its creation requires parameters be supplied to it. * * @throws Exception if there were unexpected errors. */ @Test public void createSingletonModule() throws Exception { //verify that the singleton module whose creation requires //parameters, doesn't exist. new ExpectedFailure<ModuleNotFoundException>( Messages.MODULE_NOT_FOUND, SingleParmModuleFactory.INSTANCE_URN.toString()){ protected void run() throws Exception { sManager.getModuleInfo(SingleParmModuleFactory.INSTANCE_URN); } }; //now create the module ModuleURN urn = sManager.createModule( SingleParmModuleFactory.PROVIDER_URN, new URI("http://blah")); assertEquals(SingleParmModuleFactory.INSTANCE_URN, urn); //try creating another instance and verify that it fails new ExpectedFailure<ModuleCreationException>( Messages.CANNOT_CREATE_SINGLETON, SingleParmModuleFactory.PROVIDER_URN.toString(), SingleParmModuleFactory.INSTANCE_URN.toString()){ protected void run() throws Exception { sManager.createModule(SingleParmModuleFactory.PROVIDER_URN, "http://whatever"); } }; } /** * Tests create module API. * * @throws Exception if there are unexpected errors. */ @Test public void createModule() throws Exception { new ExpectedFailure<ModuleCreationException>( Messages.CANNOT_CREATE_MODULE_WRONG_PARAM_NUM, MultipleModuleFactory.PROVIDER_URN.toString(), 1, 0) { protected void run() throws Exception { sManager.createModule(MultipleModuleFactory.PROVIDER_URN); } }; new ExpectedFailure<ModuleCreationException>( Messages.CANNOT_CREATE_MODULE_WRONG_PARAM_TYPE, MultipleModuleFactory.PROVIDER_URN.toString(), 0,ModuleURN.class.getName(), String.class.getName()) { protected void run() throws Exception { sManager.createModule(MultipleModuleFactory.PROVIDER_URN, "metc:string:type:not:work"); } }; //verify that URN validation is happening. final ModuleURN urn1 = new ModuleURN("invalidURN"); new ExpectedFailure<InvalidURNException>( Messages.INVALID_URN_SCHEME, urn1.scheme(), urn1.toString(), ModuleURN.SCHEME) { protected void run() throws Exception { sManager.createModule(MultipleModuleFactory.PROVIDER_URN, urn1); } }; //verify the details on the module instance that got created assertEquals(1, MultipleModule.getNumInstances()); assertModuleBase(urn1, false, false, true, false); //verify that we URN is validated to belong to the provider final ModuleURN urn2 = new ModuleURN("metc:test:wrong:myinstance"); new ExpectedFailure<InvalidURNException>( Messages.INSTANCE_PROVIDER_URN_MISMATCH, urn2.toString(), MultipleModuleFactory.PROVIDER_URN.toString()) { protected void run() throws Exception { sManager.createModule(MultipleModuleFactory.PROVIDER_URN, urn2); } }; //verify the details on the module instance that got created assertEquals(2, MultipleModule.getNumInstances()); assertModuleBase(urn2, false, false, true, false); ModuleURN moduleURN = new ModuleURN(MultipleModuleFactory.PROVIDER_URN,"myinstance"); final ModuleURN urn3 = sManager.createModule(MultipleModuleFactory.PROVIDER_URN, moduleURN); assertEquals(moduleURN, urn3); assertContains(sManager.getModuleInstances(null), new ModuleURN[]{ SinkModuleFactory.INSTANCE_URN, SingleModuleFactory.INSTANCE_URN, urn3}); assertModuleInfo(urn3, ModuleState.STARTED, null, null, false, true, false, false, false); assertEquals(3, MultipleModule.getNumInstances()); assertModuleBase(urn3, true, false, true, false); //Try creating a duplicate module and verify that fails new ExpectedFailure<ModuleCreationException>( Messages.DUPLICATE_MODULE_URN,urn3.toString()) { protected void run() throws Exception { sManager.createModule(MultipleModuleFactory.PROVIDER_URN, urn3); } }; } /** * Tests a more complex invocation of createModule API. * * @throws Exception if there are unexpected errors. */ @Test public void createModuleComplex() throws Exception { //verify that various errors from the within the module //creation are caught. final String instanceName = "complicated"; //test incorrect file path error from the module new ExpectedFailure<ModuleCreationException>( TestMessages.INCORRECT_FILE_PATH) { protected void run() throws Exception { sManager.createModule(ComplexModuleFactory.PROVIDER_URN, instanceName, new File("yellow"), new URL("http://what?"), new Date()); } }; //test incorrect url error new ExpectedFailure<ModuleCreationException>( TestMessages.INCORRECT_URL) { protected void run() throws Exception { sManager.createModule(ComplexModuleFactory.PROVIDER_URN, instanceName, File.listRoots()[0], new URL("ftp://what?"), new Date()); } }; //test date not supplied error. new ExpectedFailure<ModuleCreationException>( TestMessages.DATE_NOT_SUPPLIED) { protected void run() throws Exception { sManager.createModule(ComplexModuleFactory.PROVIDER_URN, instanceName, File.listRoots()[0], new URL("http://what?"), null); } }; ModuleURN urn = sManager.createModule(ComplexModuleFactory.PROVIDER_URN, instanceName, File.listRoots()[0], new URL("http://what?"), new Date()); assertEquals(instanceName, urn.instanceName()); assertContains(sManager.getModuleInstances( ComplexModuleFactory.PROVIDER_URN),new ModuleURN[]{urn}); assertModuleInfo(urn, ModuleState.CREATED, null, null, false, false, false, false, false); assertEquals(1, MultipleModule.getNumInstances()); assertModuleBase(urn, false, false, false, false); } /** * Tests delete module API. * * @throws Exception if there are unexpected errors. */ @Test public void deleteModule() throws Exception { //verify URN validation new ExpectedFailure<InvalidURNException>(Messages.EMPTY_URN, "") { protected void run() throws Exception { sManager.deleteModule(null); } }; final ModuleURN invalidURN = new ModuleURN("invalidURN"); new ExpectedFailure<InvalidURNException>(Messages.INVALID_URN_SCHEME, invalidURN.scheme(), invalidURN.toString(), ModuleURN.SCHEME){ protected void run() throws Exception { sManager.deleteModule(invalidURN); } }; //verify non-existing module final ModuleURN notExist = new ModuleURN("metc:test:notexist:no"); new ExpectedFailure<ModuleNotFoundException>(Messages.MODULE_NOT_FOUND, notExist.toString()){ protected void run() throws Exception { sManager.deleteModule(notExist); } }; //verify that singleton modules cannot be deleted new ExpectedFailure<ModuleException>(Messages.CANNOT_DELETE_SINGLETON, SingleModuleFactory.INSTANCE_URN.toString()){ protected void run() throws Exception { sManager.deleteModule(SingleModuleFactory.INSTANCE_URN); } }; //create a new module and delete it final ModuleURN moduleURN = new ModuleURN( MultipleModuleFactory.PROVIDER_URN,"deleted"); sManager.createModule(MultipleModuleFactory.PROVIDER_URN, moduleURN); assertModuleInfo(moduleURN, ModuleState.STARTED, null, null, false, true, false, false, false); //stop the module and delete it sManager.stop(moduleURN); assertModuleInfo(moduleURN, ModuleState.STOPPED, null, null, false, true, false, false, false); sManager.deleteModule(moduleURN); //verify that its deleted for(ModuleURN urn: sManager.getModuleInstances(moduleURN.parent())) { assertFalse(urn.equals(moduleURN)); } new ExpectedFailure<ModuleNotFoundException>(Messages.MODULE_NOT_FOUND, moduleURN.toString()){ protected void run() throws Exception { sManager.getModuleInfo(moduleURN); } }; //create the module again and delete it while its started. sManager.createModule(MultipleModuleFactory.PROVIDER_URN, moduleURN); assertModuleInfo(moduleURN, ModuleState.STARTED, null, null, false, true, false, false, false); //verify that delete fails if the module was started new ExpectedFailure<ModuleStateException>( Messages.DELETE_FAILED_MODULE_STATE_INCORRECT, moduleURN.toString(), ModuleState.STARTED, ModuleState.DELETABLE_STATES.toString()){ protected void run() throws Exception { sManager.deleteModule(moduleURN); } }; //Stop the module and verify that it can be deleted sManager.stop(moduleURN); //verify stop invocation. assertModuleBase(moduleURN,true, true, true, false); sManager.deleteModule(moduleURN); //verify that the module is deleted for(ModuleURN urn: sManager.getModuleInstances(moduleURN.parent())) { assertFalse(urn.equals(moduleURN)); } new ExpectedFailure<ModuleNotFoundException>(Messages.MODULE_NOT_FOUND, moduleURN.toString()){ protected void run() throws Exception { sManager.getModuleInfo(moduleURN); } }; } /** * Tests start module API. * * @throws Exception if there are unexpected errors. */ @Test public void startModule() throws Exception { //Verify that URL validation is happening. new ExpectedFailure<InvalidURNException>( Messages.EMPTY_URN, ""){ protected void run() throws Exception { sManager.start(null); } }; final ModuleURN urn1 = new ModuleURN("invalidURN"); new ExpectedFailure<InvalidURNException>( Messages.INVALID_URN_SCHEME, urn1.scheme(), urn1.toString(), ModuleURN.SCHEME){ protected void run() throws Exception { sManager.start(urn1); } }; //attempt starting a module instance that doesn't exist final ModuleURN urn2 = new ModuleURN("metc:does:not:exist"); new ExpectedFailure<ModuleNotFoundException>( Messages.MODULE_NOT_FOUND,urn2.toString()){ protected void run() throws Exception { sManager.start(urn2); } }; //attempt starting an autocreate module instance that doesn't exist final ModuleURN urn3 = new ModuleURN(ComplexModuleFactory.PROVIDER_URN,"startTesting"); new ExpectedFailure<ModuleNotFoundException>( Messages.MODULE_NOT_FOUND,urn3.toString()){ protected void run() throws Exception { sManager.start(urn3); } }; //create that module and then attempt starting it sManager.createModule(ComplexModuleFactory.PROVIDER_URN, urn3.instanceName(), File.listRoots()[0], new URL("http://what?"), new Date()); assertModuleInfo(urn3, ModuleState.CREATED, null, null, false, false, false, false, false); assertModuleBase(urn3, false, false, false, false); sManager.start(urn3); assertModuleInfo(urn3, ModuleState.STARTED, null, null, false, false, false, false, false); assertModuleBase(urn3, true, false, false, false); //attempt starting a module that is already started new ExpectedFailure<ModuleStateException>( Messages.MODULE_NOT_STARTED_STATE_INCORRECT, urn3.toString(), ModuleState.STARTED, ModuleState.STARTABLE_STATES.toString()){ protected void run() throws Exception { sManager.start(urn3); } }; } /** * Tests failures when invoking the start module API. * * @throws Exception if there are unexpected errors. */ @Test public void startFailure() throws Exception { //create a module final ModuleURN urn = new ModuleURN(ComplexModuleFactory.PROVIDER_URN, "startFail"); sManager.createModule(ComplexModuleFactory.PROVIDER_URN, urn.instanceName(), File.listRoots()[0], new URL("http://what?"), new Date()); ModuleInfo info = assertModuleInfo(urn, ModuleState.CREATED, null, null, false, false, false, false, false); //verify that there's no start failure message assertNull(info.getLastStartFailure()); MultipleModule m = (MultipleModule) assertModuleBase( urn, false, false, false, false); m.setFailStart(true); new ExpectedFailure<ModuleException>( TestMessages.TEST_START_STOP_FAILURE){ protected void run() throws Exception { sManager.start(urn); } }; info = assertModuleInfo(urn, ModuleState.START_FAILED, null, null, false, false, false, false, false); assertModuleBase(urn, true, false, false, false); //verify the start failure message assertEquals(TestMessages.TEST_START_STOP_FAILURE.getText(), info.getLastStartFailure()); m.setFailStart(false); sManager.start(urn); info = assertModuleInfo(urn, ModuleState.STARTED, null, null, false, false, false, false, false); assertModuleBase(urn, true, false, false, false); //verify that the start failure message is cleared assertNull(info.getLastStartFailure()); } /** * Tests the stop module API. * * @throws Exception if there are unexpected errors. */ @Test public void stopModule() throws Exception { //Verify that URN validation is happening new ExpectedFailure<InvalidURNException>( Messages.EMPTY_URN, ""){ protected void run() throws Exception { sManager.stop(null); } }; final ModuleURN urn1 = new ModuleURN("invalidURN"); //try stopping a module with an invalid URN new ExpectedFailure<InvalidURNException>( Messages.INVALID_URN_SCHEME, urn1.scheme(), urn1.toString(), ModuleURN.SCHEME){ protected void run() throws Exception { sManager.stop(urn1); } }; //attempt stopping a module that doesn't exist final ModuleURN urn2 = new ModuleURN("metc:does:not:exist"); new ExpectedFailure<ModuleNotFoundException>( Messages.MODULE_NOT_FOUND,urn2.toString()){ protected void run() throws Exception { sManager.stop(urn2); } }; //Create a module for testing final ModuleURN urn3 = new ModuleURN( ComplexModuleFactory.PROVIDER_URN,"stopTesting"); sManager.createModule(ComplexModuleFactory.PROVIDER_URN, urn3.instanceName(), File.listRoots()[0], new URL("http://what?"), new Date()); assertModuleInfo(urn3, ModuleState.CREATED, null, null, false, false, false, false, false); assertModuleBase(urn3, false, false, false, false); //try stopping a module that is not started new ExpectedFailure<ModuleStateException>( Messages.MODULE_NOT_STOPPED_STATE_INCORRECT, urn3.toString(), ModuleState.CREATED, ModuleState.STOPPABLE_STATES.toString()){ protected void run() throws Exception { sManager.stop(urn3); } }; //start the module and then try stopping it sManager.start(urn3); assertModuleInfo(urn3, ModuleState.STARTED, null, null, false, false, false, false, false); assertModuleBase(urn3, true, false, false, false); //try stopping the module sManager.stop(urn3); assertModuleInfo(urn3, ModuleState.STOPPED, null, null, false, false, false, false, false); assertModuleBase(urn3, true, true, false, false); //try stopping this module again and observe the failure new ExpectedFailure<ModuleStateException>( Messages.MODULE_NOT_STOPPED_STATE_INCORRECT, urn3.toString(), ModuleState.STOPPED, ModuleState.STOPPABLE_STATES.toString()){ protected void run() throws Exception { sManager.stop(urn3); } }; } /** * Tests for failures when invoking the stop module API. * * @throws Exception if there are unexpected errors. */ @Test public void stopFailure() throws Exception { //create a module final ModuleURN urn = new ModuleURN(ComplexModuleFactory.PROVIDER_URN,"stopFail"); sManager.createModule(ComplexModuleFactory.PROVIDER_URN, urn.instanceName(), File.listRoots()[0], new URL("http://what?"), new Date()); ModuleInfo info = assertModuleInfo(urn, ModuleState.CREATED, null, null, false, false, false, false, false); //verify that there's no stop failure message assertNull(info.getLastStopFailure()); assertModuleBase(urn, false, false, false, false); //now start the module. sManager.start(urn); info = assertModuleInfo(urn, ModuleState.STARTED, null, null, false, false, false, false, false); assertNull(info.getLastStopFailure()); MultipleModule m = (MultipleModule) assertModuleBase( urn, true, false, false, false); //setup stop to fail m.setFailStop(true); new ExpectedFailure<ModuleException>( TestMessages.TEST_START_STOP_FAILURE){ protected void run() throws Exception { sManager.stop(urn); } }; info = assertModuleInfo(urn, ModuleState.STOP_FAILED, null, null, false, false, false, false, false); assertModuleBase(urn, true, true, false, false); //verify the start failure message assertEquals(TestMessages.TEST_START_STOP_FAILURE.getText(), info.getLastStopFailure()); m.setFailStop(false); sManager.stop(urn); info = assertModuleInfo(urn, ModuleState.STOPPED, null, null, false, false, false, false, false); assertModuleBase(urn, true, true, false, false); //verify that the start failure message is cleared assertNull(info.getLastStopFailure()); } /** * Verifies that the sink module cannot be stopped. * * @throws Exception if there are unexpected errors. */ @Test public void sinkStopFailure() throws Exception { //verify module's start. ModuleInfo info = assertModuleInfo(SinkModuleFactory.INSTANCE_URN, ModuleState.STARTED, null, null, false, true, true, false, false); assertNull(info.getLastStartFailure()); assertNull(info.getLastStopFailure()); //attempt stopping it new ExpectedFailure<ModuleException>( Messages.CANNOT_STOP_SINK_MODULE){ protected void run() throws Exception { sManager.stop(SinkModuleFactory.INSTANCE_URN); } }; //verify the state again. info = assertModuleInfo(SinkModuleFactory.INSTANCE_URN, ModuleState.STARTED, null, null, false, true, true, false, false); assertNull(info.getLastStartFailure()); assertNull(info.getLastStopFailure()); } private void assertProviderInfo( ModuleURN inURN, String[] parameterTypeNames, Class<?>[] parameterTypes, String description, boolean autoInstantiate, boolean multipleInstances) throws Exception { assertProviderInfo(sManager, inURN, parameterTypeNames, parameterTypes, description, autoInstantiate, multipleInstances); } private ModuleInfo assertModuleInfo(ModuleURN inURN, ModuleState inState, DataFlowID[] inInitDataFlows, DataFlowID[] inParticipateDataFlows, boolean inAutocreated, boolean inAutostart, boolean inReceiver, boolean inEmitter, boolean inFlowRequester) throws Exception { return assertModuleInfo(sManager, inURN, inState, inInitDataFlows, inParticipateDataFlows, inAutocreated, inAutostart, inReceiver, inEmitter, inFlowRequester); } private static ModuleManager sManager = null; }