847 lines
26 KiB
Java
847 lines
26 KiB
Java
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 );
|
|
}
|
|
|
|
}
|