package info.ebenoit.ebul.cmp; import java.lang.reflect.Field; import org.junit.Assert; import org.junit.Before; import org.junit.Test; /** Tests for {@link ComponentState} */ public class TestComponentState { /** * A "fake" {@link ComponentRegistry} whose initialisation, activation and failure state can be modified manually */ private static class FakeRegistry extends ComponentRegistry { private boolean initialised; private boolean active; private boolean failed; @Override public boolean isInitialised( ) { return this.initialised; } @Override public boolean isActive( ) { return this.active; } @Override public boolean hasFailed( ) { return this.failed; } } /** Class used to test name provider handling */ private static class PCmpTest { private final String componentName; public PCmpTest( final String componentName ) { super( ); this.componentName = componentName; } public String getComponentName( ) { return this.componentName; } } /** Class used to test registry-aware components */ private static class RACmpTest implements RegistryAware { private ComponentRegistry registry; @Override public void setComponentRegistry( ComponentRegistry registry ) { this.registry = registry; } } /** Class used to test methods that affect the component's lifecycle */ private static class LCATest { private LifecycleStage stage; } /** Class used to test {@link ComponentState#restart()} */ private static class RestartTest { private boolean stopped; private boolean started; private static ComponentState get( final ComponentRegistry reg , final boolean active ) { return TestComponentState.makeState( RestartTest.getDef( ) , reg , true , active ); } private static NewComponentInfo< RestartTest > getDef( ) { return new NewComponentInfo< >( new RestartTest( ) ) // .setLifecycleAction( LifecycleStage.START , o -> { o.started = true; } ) // .setLifecycleAction( LifecycleStage.STOP , o -> { o.stopped = true; } ); } } private static ComponentState makeState( final NewComponentInfo< ? > ci , final ComponentRegistry reg , final boolean initialised , final boolean active ) { final ComponentState cs = new ComponentState( reg , ci ); try { if ( initialised ) { Field f = ComponentState.class.getDeclaredField( "initialised" ); f.setAccessible( true ); f.setBoolean( cs , true ); } if ( active ) { Field f = ComponentState.class.getDeclaredField( "active" ); f.setAccessible( true ); f.setBoolean( cs , true ); } } catch ( NoSuchFieldException | IllegalAccessException e ) { throw new RuntimeException( e ); } return cs; } private FakeRegistry reg; @Before public void setup( ) { this.reg = new FakeRegistry( ); } /** Test: initialising a {@link ComponentState} using an existing object */ @Test public void testInitialiseWithObject( ) { final Object object = new Object( ); final NewComponentInfo< Object > ci = new NewComponentInfo< Object >( object ); final ComponentState cs = new ComponentState( this.reg , ci ); Assert.assertSame( object , cs.getComponent( ) ); } /** Test: initialising a {@link ComponentState} using a component supplier */ @Test public void testInitialiseWithSupplier( ) { final Object object = new Object( ); final NewComponentInfo< Object > ci = new NewComponentInfo< Object >( ( ) -> object ); final ComponentState cs = new ComponentState( this.reg , ci ); Assert.assertSame( object , cs.getComponent( ) ); } /** * Test: initialising a {@link ComponentState} using a component supplier that throws an exception throws a * {@link ComponentCreationException} */ @Test( expected = ComponentCreationException.class ) public void testInitialiseWithFailingSupplier( ) { final NewComponentInfo< Object > ci = new NewComponentInfo< Object >( ( ) -> { throw new Exception( "failing" ); } ); new ComponentState( this.reg , ci ); } /** Test: initialising a {@link ComponentState} with a <code>null</code> name */ @Test public void testInitialiseNullName( ) { final Object object = new Object( ); final NewComponentInfo< Object > ci = new NewComponentInfo< Object >( object ); final ComponentState cs = new ComponentState( this.reg , ci ); Assert.assertNull( cs.getName( ) ); } /** Test: initialising a {@link ComponentState} with an automatic name */ @Test public void testInitialiseAutoName( ) { final Object object = new Object( ); final NewComponentInfo< Object > ci = new NewComponentInfo< Object >( object ) // .setName( "" ); final ComponentState cs = new ComponentState( this.reg , ci ); Assert.assertEquals( "Object" , cs.getName( ) ); } /** Test: initialising a {@link ComponentState} with a supplied name */ @Test public void testInitialiseWithName( ) { final Object object = new Object( ); final NewComponentInfo< Object > ci = new NewComponentInfo< Object >( object ).setName( "Test" ); final ComponentState cs = new ComponentState( this.reg , ci ); Assert.assertEquals( "Test" , cs.getName( ) ); } /** Test: initialising a {@link ComponentState} with a name provider */ @Test public void testInitialiseWithParametricComponent( ) { final PCmpTest object = new PCmpTest( "ParametricName" ); final NewComponentInfo< PCmpTest > ci = new NewComponentInfo< PCmpTest >( object ) // .setNameProvider( o -> o.getComponentName( ) ); final ComponentState cs = new ComponentState( this.reg , ci ); Assert.assertEquals( "ParametricName" , cs.getName( ) ); } /** Test: initialising a {@link ComponentState} with a name provider overrides any configured name */ @Test public void testInitialiseWithParametricComponentAndName( ) { final PCmpTest object = new PCmpTest( "ParametricName" ); final NewComponentInfo< PCmpTest > ci = new NewComponentInfo< PCmpTest >( object ) // .setNameProvider( o -> o.getComponentName( ) ) // .setName( "Test" ); final ComponentState cs = new ComponentState( this.reg , ci ); Assert.assertEquals( "ParametricName" , cs.getName( ) ); } /** Test: initialising a {@link ComponentState} that implements {@link RegistryAware} */ @Test public void testInitialiseRegistryAware( ) { final RACmpTest object = new RACmpTest( ); final NewComponentInfo< Object > ci = new NewComponentInfo< Object >( object ); new ComponentState( this.reg , ci ); Assert.assertSame( this.reg , object.registry ); } /** Test: {@link ComponentState} copies autostart flag */ @Test public void testInitialiseAutostart( ) { final Object object = new Object( ); NewComponentInfo< Object > ci = new NewComponentInfo< Object >( object ); ComponentState cs = new ComponentState( this.reg , ci ); Assert.assertFalse( cs.hasAutostart( ) ); ci = new NewComponentInfo< Object >( object ).setAutostart( true ); cs = new ComponentState( this.reg , ci ); Assert.assertTrue( cs.hasAutostart( ) ); } /** Test: {@link ComponentState#toString()} on anonymous components */ @Test public void testToStringAnon( ) { final Object object = new Object( ); final NewComponentInfo< Object > ci = new NewComponentInfo< Object >( object ); final ComponentState cs = new ComponentState( this.reg , ci ); Assert.assertEquals( "anonymous component of type " + Object.class.getCanonicalName( ) , cs.toString( ) ); } /** Test: {@link ComponentState#toString()} on named components */ @Test public void testToStringNamed( ) { final Object object = new Object( ); final NewComponentInfo< Object > ci = new NewComponentInfo< Object >( object ).setName( "Test" ); final ComponentState cs = new ComponentState( this.reg , ci ); Assert.assertEquals( "component 'Test' of type " + Object.class.getCanonicalName( ) , cs.toString( ) ); } /** Test: {@link ComponentState#addDependency(ComponentState)} adds the specified dependency */ @Test public void testAddDependency( ) { final Object object = new Object( ); final NewComponentInfo< Object > ci = new NewComponentInfo< Object >( object ); final ComponentState cs1 = new ComponentState( this.reg , ci ); final ComponentState cs2 = new ComponentState( this.reg , ci ); cs1.addDependency( cs2 ); Assert.assertEquals( 1 , cs1.getDependencies( ).size( ) ); Assert.assertTrue( cs1.getDependencies( ).contains( cs2 ) ); Assert.assertEquals( 1 , cs2.getReverseDependencies( ).size( ) ); Assert.assertTrue( cs2.getReverseDependencies( ).contains( cs1 ) ); } /** Test: {@link ComponentState#init()} with no lifecycle action runs without a hitch */ @Test public void testInitNoAction( ) { final NewComponentInfo< Object > ci = new NewComponentInfo< Object >( new Object( ) ); final ComponentState cs = makeState( ci , reg , false , false ); cs.init( ); Assert.assertTrue( cs.isInitialised( ) ); } /** Test: {@link ComponentState#init()} runs the initialisation action */ @Test public void testInitAction( ) { final LCATest lcaTest = new LCATest( ); final NewComponentInfo< LCATest > ci = new NewComponentInfo< LCATest >( lcaTest ) // .setLifecycleAction( LifecycleStage.INITIALISE , ( o ) -> { o.stage = LifecycleStage.INITIALISE; } ); final ComponentState cs = makeState( ci , reg , false , false ); cs.init( ); Assert.assertSame( LifecycleStage.INITIALISE , lcaTest.stage ); Assert.assertTrue( cs.isInitialised( ) ); } /** Test: {@link ComponentState#init()} on an initialised component does nothing */ @Test public void testInitAlreadyInitialised( ) { final LCATest lcaTest = new LCATest( ); final NewComponentInfo< LCATest > ci = new NewComponentInfo< LCATest >( lcaTest ) // .setLifecycleAction( LifecycleStage.INITIALISE , ( o ) -> { o.stage = LifecycleStage.INITIALISE; } ); final ComponentState cs = makeState( ci , reg , true , false ); cs.init( ); Assert.assertNull( lcaTest.stage ); } /** Test: {@link ComponentState#init()} re-throws {@link ComponentInitialisationException} */ @Test public void testInitActionExceptionPassthrough( ) { final ComponentInitialisationException failure = new ComponentInitialisationException( ); final NewComponentInfo< Object > ci = new NewComponentInfo< Object >( new Object( ) ) // .setLifecycleAction( LifecycleStage.INITIALISE , ( o ) -> { throw failure; } ); final ComponentState cs = TestComponentState.makeState( ci , this.reg , false , false ); try { cs.init( ); } catch ( final ComponentInitialisationException e ) { Assert.assertFalse( cs.isInitialised( ) ); Assert.assertSame( failure , e ); return; } Assert.fail( "no ComponentInitialisationException" ); } /** * Test: {@link ComponentState#init()} transmits other exceptions using a {@link ComponentInitialisationException} */ @Test public void testInitActionExceptionTransmit( ) { final Exception failure = new Exception( ); final NewComponentInfo< Object > ci = new NewComponentInfo< Object >( new Object( ) ) // .setLifecycleAction( LifecycleStage.INITIALISE , ( o ) -> { throw failure; } ); final ComponentState cs = TestComponentState.makeState( ci , this.reg , false , false ); try { cs.init( ); } catch ( final ComponentInitialisationException e ) { Assert.assertFalse( cs.isInitialised( ) ); Assert.assertSame( failure , e.getCause( ) ); return; } Assert.fail( "no ComponentInitialisationException" ); } /** Test: {@link ComponentState#init()} attempts to initialise a component's dependencies */ @Test public void testInitDependencies( ) { final LCATest lcaTest = new LCATest( ); final NewComponentInfo< LCATest > ci1 = new NewComponentInfo< LCATest >( lcaTest ) // .setLifecycleAction( LifecycleStage.INITIALISE , ( o ) -> { o.stage = LifecycleStage.INITIALISE; } ); final ComponentState cs1 = TestComponentState.makeState( ci1 , this.reg , false , false ); final NewComponentInfo< Object > ci2 = new NewComponentInfo< Object >( new Object( ) ); final ComponentState cs2 = TestComponentState.makeState( ci2 , this.reg , false , false ); cs2.addDependency( cs1 ); cs2.init( ); Assert.assertSame( LifecycleStage.INITIALISE , lcaTest.stage ); } /** Test: {@link ComponentState#destroy()} throws {@link IllegalStateException} if the component is active */ @Test( expected = IllegalStateException.class ) public void testDestroyActive( ) { final NewComponentInfo< Object > ci = new NewComponentInfo< Object >( new Object( ) ); final ComponentState cs = TestComponentState.makeState( ci , this.reg , true , true ); cs.destroy( ); } /** Test: {@link ComponentState#destroy()} with no configured action works */ @Test public void testDestroyNoAction( ) { final NewComponentInfo< Object > ci = new NewComponentInfo< Object >( new Object( ) ); final ComponentState cs = TestComponentState.makeState( ci , this.reg , true , false ); cs.destroy( ); Assert.assertFalse( cs.isInitialised( ) ); } /** Test: {@link ComponentState#destroy()} executes the configured destruction action */ @Test public void testDestroyAction( ) { final LCATest lcaTest = new LCATest( ); final NewComponentInfo< LCATest > ci = new NewComponentInfo< LCATest >( lcaTest ) // .setLifecycleAction( LifecycleStage.DESTROY , ( o ) -> { o.stage = LifecycleStage.DESTROY; } ); final ComponentState cs = TestComponentState.makeState( ci , this.reg , true , false ); cs.destroy( ); Assert.assertFalse( cs.isInitialised( ) ); Assert.assertSame( LifecycleStage.DESTROY , lcaTest.stage ); } /** Test: {@link ComponentState#destroy()} re-throws {@link ComponentDestructionException} */ @Test public void testDestroyActionExceptionPassthrough( ) { final ComponentDestructionException failure = new ComponentDestructionException( ); final NewComponentInfo< Object > ci = new NewComponentInfo< Object >( new Object( ) ) // .setLifecycleAction( LifecycleStage.DESTROY , ( o ) -> { throw failure; } ); final ComponentState cs = TestComponentState.makeState( ci , this.reg , true , false ); try { cs.destroy( ); } catch ( final ComponentDestructionException e ) { Assert.assertTrue( cs.isInitialised( ) ); Assert.assertSame( failure , e ); return; } Assert.fail( "no ComponentDestructionException" ); } /** * Test: {@link ComponentState#destroy()} transmits other exceptions using a {@link ComponentDestructionException} */ @Test public void testDestroyActionExceptionTransmit( ) { final Exception failure = new Exception( ); final NewComponentInfo< Object > ci = new NewComponentInfo< Object >( new Object( ) ) // .setLifecycleAction( LifecycleStage.DESTROY , ( o ) -> { throw failure; } ); final ComponentState cs = TestComponentState.makeState( ci , this.reg , true , false ); try { cs.destroy( ); } catch ( final ComponentDestructionException e ) { Assert.assertTrue( cs.isInitialised( ) ); Assert.assertSame( failure , e.getCause( ) ); return; } Assert.fail( "no ComponentDestructionException" ); } /** Test: {@link ComponentState#destroy()} destroys reverse dependencies */ @Test public void testDestroyReverseDeps( ) { final NewComponentInfo< Object > ci1 = new NewComponentInfo< Object >( new Object( ) ); final ComponentState cs1 = TestComponentState.makeState( ci1 , this.reg , true , false ); final NewComponentInfo< Object > ci2 = new NewComponentInfo< Object >( new Object( ) ); final ComponentState cs2 = TestComponentState.makeState( ci2 , this.reg , true , false ); cs2.addDependency( cs1 ); cs1.destroy( ); Assert.assertFalse( cs2.isInitialised( ) ); } /** Test: {@link ComponentState#start()} on uninitialised components throws {@link IllegalStateException} */ @Test( expected = IllegalStateException.class ) public void testStartUninitialised( ) { final NewComponentInfo< Object > ci = new NewComponentInfo< Object >( new Object( ) ); final ComponentState cs = new ComponentState( this.reg , ci ); this.reg.active = true; cs.start( ); } /** Test: {@link ComponentState#start()} with a failed registry throws {@link IllegalStateException} */ @Test( expected = IllegalStateException.class ) public void testStartFailedRegistry( ) { final NewComponentInfo< Object > ci = new NewComponentInfo< Object >( new Object( ) ); final ComponentState cs = makeState( ci , reg , true , false ); this.reg.failed = true; cs.start( ); } /** Test: {@link ComponentState#start()} with an inactive registry throws {@link IllegalStateException} */ @Test( expected = IllegalStateException.class ) public void testStartInactiveRegistry( ) { final NewComponentInfo< Object > ci = new NewComponentInfo< Object >( new Object( ) ); final ComponentState cs = makeState( ci , reg , true , false ); cs.start( ); } /** Test: {@link ComponentState#start()} with no lifecycle action runs without a hitch */ @Test public void testStartNoAction( ) { final NewComponentInfo< Object > ci = new NewComponentInfo< Object >( new Object( ) ); final ComponentState cs = makeState( ci , reg , true , false ); this.reg.active = true; cs.start( ); Assert.assertTrue( cs.isActive( ) ); } /** Test: {@link ComponentState#start()} runs the startup action */ @Test public void testStartStartupAction( ) { final LCATest lcaTest = new LCATest( ); final NewComponentInfo< LCATest > ci = new NewComponentInfo< LCATest >( lcaTest ) // .setLifecycleAction( LifecycleStage.START , ( o ) -> { o.stage = LifecycleStage.START; } ); final ComponentState cs = makeState( ci , reg , true , false ); this.reg.active = true; cs.start( ); Assert.assertSame( LifecycleStage.START , lcaTest.stage ); Assert.assertTrue( cs.isActive( ) ); } /** Test: {@link ComponentState#start()} on an active component does nothing */ @Test public void testStartStartupAlreadyActive( ) { final LCATest lcaTest = new LCATest( ); final NewComponentInfo< LCATest > ci = new NewComponentInfo< LCATest >( lcaTest ) // .setLifecycleAction( LifecycleStage.START , ( o ) -> { o.stage = LifecycleStage.START; } ); final ComponentState cs = TestComponentState.makeState( ci , this.reg , true , true ); this.reg.active = true; cs.start( ); Assert.assertNull( lcaTest.stage ); } /** Test: {@link ComponentState#start()} re-throws {@link ComponentStartupException} */ @Test public void testStartStartupActionExceptionPassthrough( ) { final ComponentStartupException failure = new ComponentStartupException( ); final NewComponentInfo< Object > ci = new NewComponentInfo< Object >( new Object( ) ) // .setLifecycleAction( LifecycleStage.START , ( o ) -> { throw failure; } ); final ComponentState cs = TestComponentState.makeState( ci , this.reg , true , false ); this.reg.active = true; try { cs.start( ); } catch ( final ComponentStartupException e ) { Assert.assertFalse( cs.isActive( ) ); Assert.assertSame( failure , e ); return; } Assert.fail( "no ComponentStartupException" ); } /** Test: {@link ComponentState#start()} transmits other exceptions using a {@link ComponentStartupException} */ @Test public void testStartStartupActionExceptionTransmit( ) { final Exception failure = new Exception( ); final NewComponentInfo< Object > ci = new NewComponentInfo< Object >( new Object( ) ) // .setLifecycleAction( LifecycleStage.START , ( o ) -> { throw failure; } ); final ComponentState cs = TestComponentState.makeState( ci , this.reg , true , false ); this.reg.active = true; try { cs.start( ); } catch ( final ComponentStartupException e ) { Assert.assertFalse( cs.isActive( ) ); Assert.assertSame( failure , e.getCause( ) ); return; } Assert.fail( "no ComponentStartupException" ); } /** Test: {@link ComponentState#start()} attempts to start a component's dependencies */ @Test public void testStartDependencies( ) { final LCATest lcaTest = new LCATest( ); final NewComponentInfo< LCATest > ci1 = new NewComponentInfo< LCATest >( lcaTest ) // .setLifecycleAction( LifecycleStage.START , ( o ) -> { o.stage = LifecycleStage.START; } ); final ComponentState cs1 = TestComponentState.makeState( ci1 , this.reg , true , false ); final NewComponentInfo< Object > ci2 = new NewComponentInfo< Object >( new Object( ) ); final ComponentState cs2 = TestComponentState.makeState( ci2 , this.reg , true , false ); cs2.addDependency( cs1 ); this.reg.active = true; cs2.start( ); Assert.assertSame( LifecycleStage.START , lcaTest.stage ); } /** Test: {@link ComponentState#stop()} with a failed registry throws {@link IllegalStateException} */ @Test( expected = IllegalStateException.class ) public void testStopFailedRegistry( ) { final NewComponentInfo< Object > ci = new NewComponentInfo< Object >( new Object( ) ); final ComponentState cs = TestComponentState.makeState( ci , this.reg , true , true ); this.reg.failed = true; cs.stop( ); } /** Test: {@link ComponentState#stop()} with no configured action works */ @Test public void testStopNoAction( ) { final NewComponentInfo< Object > ci = new NewComponentInfo< Object >( new Object( ) ); final ComponentState cs = TestComponentState.makeState( ci , this.reg , true , true ); this.reg.active = true; cs.stop( ); Assert.assertFalse( cs.isActive( ) ); } /** Test: {@link ComponentState#stop()} executes the configured stop action */ @Test public void testStopAction( ) { final LCATest lcaTest = new LCATest( ); final NewComponentInfo< LCATest > ci = new NewComponentInfo< LCATest >( lcaTest ) // .setLifecycleAction( LifecycleStage.STOP , ( o ) -> { o.stage = LifecycleStage.STOP; } ); final ComponentState cs = TestComponentState.makeState( ci , this.reg , true , true ); this.reg.active = true; cs.stop( ); Assert.assertFalse( cs.isActive( ) ); Assert.assertSame( LifecycleStage.STOP , lcaTest.stage ); } /** Test: {@link ComponentState#stop()} transmits an exception thrown by the configured stop action */ @Test public void testStopActionFailure( ) { final ComponentShutdownException failure = new ComponentShutdownException( ); final NewComponentInfo< Object > ci = new NewComponentInfo< Object >( new Object( ) ) // .setLifecycleAction( LifecycleStage.STOP , ( o ) -> { throw failure; } ); final ComponentState cs = TestComponentState.makeState( ci , this.reg , true , true ); this.reg.active = true; try { cs.stop( ); } catch ( ComponentShutdownException e ) { Assert.assertSame( failure , e ); Assert.assertTrue( cs.isActive( ) ); return; } Assert.fail( "expected ComponentShutdownException" ); } /** Test: {@link ComponentState#stop()} stops reverse dependencies */ @Test public void testStopReverseDeps( ) { final NewComponentInfo< Object > ci1 = new NewComponentInfo< Object >( new Object( ) ); final ComponentState cs1 = TestComponentState.makeState( ci1 , this.reg , true , true ); final NewComponentInfo< Object > ci2 = new NewComponentInfo< Object >( new Object( ) ); final ComponentState cs2 = TestComponentState.makeState( ci2 , this.reg , true , true ); cs2.addDependency( cs1 ); this.reg.active = true; cs1.stop( ); Assert.assertFalse( cs2.isActive( ) ); } /** Test: {@link ComponentState#restart()} with a failed registry throws {@link IllegalStateException} */ @Test( expected = IllegalStateException.class ) public void testRestartFailedRegistry( ) { final NewComponentInfo< RestartTest > ci = new NewComponentInfo< >( new RestartTest( ) ); final ComponentState cs = TestComponentState.makeState( ci , this.reg , true , true ); this.reg.failed = true; cs.restart( ); } /** Test: {@link ComponentState#restart()} on a stopped component does nothing */ @Test public void testRestartInactive( ) { final ComponentState cs = RestartTest.get( this.reg , false ); final RestartTest rt = (RestartTest) cs.getComponent( ); this.reg.active = true; cs.restart( ); Assert.assertFalse( rt.stopped ); Assert.assertFalse( rt.started ); } /** Test: {@link ComponentState#restart()} on an active component restarts it */ @Test public void testRestartActive( ) { final ComponentState cs = RestartTest.get( this.reg , true ); final RestartTest rt = (RestartTest) cs.getComponent( ); this.reg.active = true; cs.restart( ); Assert.assertTrue( rt.stopped ); Assert.assertTrue( rt.started ); } /** Test: {@link ComponentState#restart()} throws a {@link ComponentShutdownException} when stop fails */ @Test public void testRestartWhenStopFails( ) { final Exception failure = new Exception( ); final NewComponentInfo< RestartTest > ci = RestartTest.getDef( ); ci.setLifecycleAction( LifecycleStage.STOP , ( o ) -> { throw failure; } ); final ComponentState cs = TestComponentState.makeState( ci , this.reg , true , true ); this.reg.active = true; try { cs.restart( ); } catch ( final ComponentShutdownException e ) { Assert.assertSame( failure , e.getCause( ) ); Assert.assertTrue( cs.isActive( ) ); return; } Assert.fail( "no ComponentShutdownException" ); } /** Test: {@link ComponentState#restart()} throws a {@link ComponentStartupException} when start fails */ @Test public void testRestartWhenStartFails( ) { final Exception failure = new Exception( ); final NewComponentInfo< RestartTest > ci = RestartTest.getDef( ); ci.setLifecycleAction( LifecycleStage.START , ( o ) -> { throw failure; } ); final ComponentState cs = TestComponentState.makeState( ci , this.reg , true , true ); this.reg.active = true; try { cs.restart( ); } catch ( final ComponentStartupException e ) { Assert.assertSame( failure , e.getCause( ) ); Assert.assertFalse( cs.isActive( ) ); return; } Assert.fail( "no ComponentStartupException" ); } /** Test: {@link ComponentState#restart()} restarts active reverse dependencies */ @Test public void testRestartActiveReverseDeps( ) { final ComponentState cs1 = TestComponentState.makeState( RestartTest.getDef( ) , this.reg , true , true ); final ComponentState cs2 = TestComponentState.makeState( RestartTest.getDef( ) , this.reg , true , true ); cs2.addDependency( cs1 ); this.reg.active = true; cs1.restart( ); final RestartTest rt = (RestartTest) cs2.getComponent( ); Assert.assertTrue( rt.stopped ); Assert.assertTrue( rt.started ); } /** Test: {@link ComponentState#restart()} does not start inactive reverse dependencies */ @Test public void testRestartInactiveReverseDeps( ) { final ComponentState cs1 = TestComponentState.makeState( RestartTest.getDef( ) , this.reg , true , true ); final ComponentState cs2 = TestComponentState.makeState( RestartTest.getDef( ) , this.reg , true , false ); cs2.addDependency( cs1 ); this.reg.active = true; cs1.restart( ); final RestartTest rt = (RestartTest) cs2.getComponent( ); Assert.assertFalse( rt.stopped ); Assert.assertFalse( rt.started ); } }