Component state - Tests for the "driver" code

This commit is contained in:
Emmanuel BENOîT 2015-09-17 23:41:21 +02:00
parent 97eb6477d7
commit c62d3800e6
3 changed files with 272 additions and 12 deletions

1
TODO
View file

@ -1,5 +1,4 @@
To Do: To Do:
* Tests for driver-related stuff in ComponentState
* Registry tests * Registry tests
* Registry doc * Registry doc
* General usage documentation * General usage documentation

View file

@ -352,6 +352,10 @@ public final class ComponentState
* This method attempts to initialise a component. It makes sure that all of the component's dependencies have been * This method attempts to initialise a component. It makes sure that all of the component's dependencies have been
* initialised, then executes the lifecycle action for the {@link LifecycleStage#INITIALISE INITIALISE} stage. Then, * initialised, then executes the lifecycle action for the {@link LifecycleStage#INITIALISE INITIALISE} stage. Then,
* if the component has drivers, it initialises them. * if the component has drivers, it initialises them.
* <p>
* Note: unlike the {@link #start()} method, which can be called from anywhere, this method is always called in
* "the right order" by the registry. Because of that, no attempts at protecting from a second execution of the
* initialisation action are made.
* *
* @throws ComponentInitialisationException * @throws ComponentInitialisationException
* if an error occurs while executing an initialisation action * if an error occurs while executing an initialisation action

View file

@ -73,7 +73,7 @@ public class TestComponentState
@Override @Override
public void setComponentRegistry( ComponentRegistry registry ) public void setComponentRegistry( final ComponentRegistry registry )
{ {
this.registry = registry; this.registry = registry;
} }
@ -118,12 +118,12 @@ public class TestComponentState
final ComponentState cs = new ComponentState( reg , ci ); final ComponentState cs = new ComponentState( reg , ci );
try { try {
if ( initialised ) { if ( initialised ) {
Field f = ComponentState.class.getDeclaredField( "initialised" ); final Field f = ComponentState.class.getDeclaredField( "initialised" );
f.setAccessible( true ); f.setAccessible( true );
f.setBoolean( cs , true ); f.setBoolean( cs , true );
} }
if ( active ) { if ( active ) {
Field f = ComponentState.class.getDeclaredField( "active" ); final Field f = ComponentState.class.getDeclaredField( "active" );
f.setAccessible( true ); f.setAccessible( true );
f.setBoolean( cs , true ); f.setBoolean( cs , true );
} }
@ -310,7 +310,7 @@ public class TestComponentState
public void testInitNoAction( ) public void testInitNoAction( )
{ {
final NewComponentInfo< Object > ci = new NewComponentInfo< Object >( new Object( ) ); final NewComponentInfo< Object > ci = new NewComponentInfo< Object >( new Object( ) );
final ComponentState cs = makeState( ci , reg , false , false ); final ComponentState cs = TestComponentState.makeState( ci , this.reg , false , false );
cs.init( ); cs.init( );
Assert.assertTrue( cs.isInitialised( ) ); Assert.assertTrue( cs.isInitialised( ) );
} }
@ -325,7 +325,7 @@ public class TestComponentState
.setLifecycleAction( LifecycleStage.INITIALISE , ( o ) -> { .setLifecycleAction( LifecycleStage.INITIALISE , ( o ) -> {
o.stage = LifecycleStage.INITIALISE; o.stage = LifecycleStage.INITIALISE;
} ); } );
final ComponentState cs = makeState( ci , reg , false , false ); final ComponentState cs = TestComponentState.makeState( ci , this.reg , false , false );
cs.init( ); cs.init( );
Assert.assertSame( LifecycleStage.INITIALISE , lcaTest.stage ); Assert.assertSame( LifecycleStage.INITIALISE , lcaTest.stage );
Assert.assertTrue( cs.isInitialised( ) ); Assert.assertTrue( cs.isInitialised( ) );
@ -341,7 +341,7 @@ public class TestComponentState
.setLifecycleAction( LifecycleStage.INITIALISE , ( o ) -> { .setLifecycleAction( LifecycleStage.INITIALISE , ( o ) -> {
o.stage = LifecycleStage.INITIALISE; o.stage = LifecycleStage.INITIALISE;
} ); } );
final ComponentState cs = makeState( ci , reg , true , false ); final ComponentState cs = TestComponentState.makeState( ci , this.reg , true , false );
cs.init( ); cs.init( );
Assert.assertNull( lcaTest.stage ); Assert.assertNull( lcaTest.stage );
} }
@ -411,6 +411,72 @@ public class TestComponentState
} }
/** Test: {@link ComponentState#init()} initialises the component's drivers */
@Test
public void testInitDrivers( )
{
final NewComponentInfo< Object > ci1 = new NewComponentInfo< Object >( new Object( ) );
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.setDriverFor( cs1 );
cs1.init( );
Assert.assertTrue( cs2.isInitialised( ) );
}
/**
* Test: {@link ComponentState#init()} initialises the component's drivers after the component
*/
@Test
public void testInitDriversOrder( )
{
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( ) ) //
.setLifecycleAction( LifecycleStage.INITIALISE , ( o ) -> {
Assert.assertSame( LifecycleStage.INITIALISE , lcaTest.stage );
} );
final ComponentState cs2 = TestComponentState.makeState( ci2 , this.reg , false , false );
cs2.setDriverFor( cs1 );
cs1.init( );
}
/**
* Test: {@link ComponentState#init()} initialises the component even if the drivers fail to initialise
*/
@Test
public void testInitDriverFailure( )
{
final NewComponentInfo< Object > ci1 = new NewComponentInfo< Object >( new Object( ) );
final ComponentState cs1 = TestComponentState.makeState( ci1 , this.reg , false , false );
final NewComponentInfo< Object > ci2 = new NewComponentInfo< Object >( new Object( ) ) //
.setLifecycleAction( LifecycleStage.INITIALISE , ( o ) -> {
throw new ComponentInitialisationException( );
} );
final ComponentState cs2 = TestComponentState.makeState( ci2 , this.reg , false , false );
cs2.setDriverFor( cs1 );
try {
cs1.init( );
} catch ( final ComponentInitialisationException e ) {
Assert.assertTrue( cs1.isInitialised( ) );
return;
}
Assert.fail( "no ComponentInitialisationException" );
}
/** Test: {@link ComponentState#destroy()} throws {@link IllegalStateException} if the component is active */ /** Test: {@link ComponentState#destroy()} throws {@link IllegalStateException} if the component is active */
@Test( expected = IllegalStateException.class ) @Test( expected = IllegalStateException.class )
public void testDestroyActive( ) public void testDestroyActive( )
@ -509,6 +575,52 @@ public class TestComponentState
} }
/** Test: {@link ComponentState#destroy()} destroys the component's drivers */
@Test
public void testDestroyDrivers( )
{
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.setDriverFor( cs1 );
cs1.destroy( );
Assert.assertFalse( cs2.isInitialised( ) );
}
/**
* Test: {@link ComponentState#destroy()} destroys the component's drivers after the component's other reverse
* dependencies
*/
@Test
public void testDestroyDriversOrder( )
{
final LCATest lcaTest = new LCATest( );
final NewComponentInfo< Object > ci1 = new NewComponentInfo< Object >( new Object( ) );
final ComponentState cs1 = TestComponentState.makeState( ci1 , this.reg , true , false );
final NewComponentInfo< Object > ci3 = new NewComponentInfo< Object >( new Object( ) ) //
.setLifecycleAction( LifecycleStage.DESTROY , ( o ) -> {
Assert.assertNull( lcaTest.stage );
} );
final ComponentState cs3 = TestComponentState.makeState( ci3 , this.reg , true , false );
cs3.addDependency( cs1 );
final NewComponentInfo< LCATest > ci2 = new NewComponentInfo< LCATest >( lcaTest ) //
.setLifecycleAction( LifecycleStage.DESTROY , ( o ) -> {
o.stage = LifecycleStage.DESTROY;
} );
final ComponentState cs2 = TestComponentState.makeState( ci2 , this.reg , true , false );
cs2.setDriverFor( cs1 );
cs2.addDependency( cs1 );
cs1.destroy( );
}
/** Test: {@link ComponentState#start()} on uninitialised components throws {@link IllegalStateException} */ /** Test: {@link ComponentState#start()} on uninitialised components throws {@link IllegalStateException} */
@Test( expected = IllegalStateException.class ) @Test( expected = IllegalStateException.class )
public void testStartUninitialised( ) public void testStartUninitialised( )
@ -525,7 +637,7 @@ public class TestComponentState
public void testStartFailedRegistry( ) public void testStartFailedRegistry( )
{ {
final NewComponentInfo< Object > ci = new NewComponentInfo< Object >( new Object( ) ); final NewComponentInfo< Object > ci = new NewComponentInfo< Object >( new Object( ) );
final ComponentState cs = makeState( ci , reg , true , false ); final ComponentState cs = TestComponentState.makeState( ci , this.reg , true , false );
this.reg.failed = true; this.reg.failed = true;
cs.start( ); cs.start( );
} }
@ -536,7 +648,7 @@ public class TestComponentState
public void testStartInactiveRegistry( ) public void testStartInactiveRegistry( )
{ {
final NewComponentInfo< Object > ci = new NewComponentInfo< Object >( new Object( ) ); final NewComponentInfo< Object > ci = new NewComponentInfo< Object >( new Object( ) );
final ComponentState cs = makeState( ci , reg , true , false ); final ComponentState cs = TestComponentState.makeState( ci , this.reg , true , false );
cs.start( ); cs.start( );
} }
@ -546,7 +658,7 @@ public class TestComponentState
public void testStartNoAction( ) public void testStartNoAction( )
{ {
final NewComponentInfo< Object > ci = new NewComponentInfo< Object >( new Object( ) ); final NewComponentInfo< Object > ci = new NewComponentInfo< Object >( new Object( ) );
final ComponentState cs = makeState( ci , reg , true , false ); final ComponentState cs = TestComponentState.makeState( ci , this.reg , true , false );
this.reg.active = true; this.reg.active = true;
cs.start( ); cs.start( );
Assert.assertTrue( cs.isActive( ) ); Assert.assertTrue( cs.isActive( ) );
@ -562,7 +674,7 @@ public class TestComponentState
.setLifecycleAction( LifecycleStage.START , ( o ) -> { .setLifecycleAction( LifecycleStage.START , ( o ) -> {
o.stage = LifecycleStage.START; o.stage = LifecycleStage.START;
} ); } );
final ComponentState cs = makeState( ci , reg , true , false ); final ComponentState cs = TestComponentState.makeState( ci , this.reg , true , false );
this.reg.active = true; this.reg.active = true;
cs.start( ); cs.start( );
Assert.assertSame( LifecycleStage.START , lcaTest.stage ); Assert.assertSame( LifecycleStage.START , lcaTest.stage );
@ -651,6 +763,103 @@ public class TestComponentState
} }
/** Test: {@link ComponentState#start()} starts the component's drivers */
@Test
public void testStartDrivers( )
{
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.setDriverFor( cs1 );
cs2.addDependency( cs1 );
this.reg.active = true;
cs1.start( );
Assert.assertTrue( cs2.isActive( ) );
}
/**
* Test: {@link ComponentState#start()} starts the component's drivers after the component
*/
@Test
public void testStartDriversOrder( )
{
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( ) ) //
.setLifecycleAction( LifecycleStage.START , ( o ) -> {
Assert.assertSame( LifecycleStage.START , lcaTest.stage );
} );
final ComponentState cs2 = TestComponentState.makeState( ci2 , this.reg , true , false );
cs2.setDriverFor( cs1 );
cs2.addDependency( cs1 );
this.reg.active = true;
cs1.start( );
}
/**
* Test: {@link ComponentState#start()} starts the component even if the drivers fail to start
*/
@Test
public void testStartDriverFailure( )
{
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( ) ) //
.setLifecycleAction( LifecycleStage.START , ( o ) -> {
throw new ComponentStartupException( );
} );
final ComponentState cs2 = TestComponentState.makeState( ci2 , this.reg , true , false );
cs2.setDriverFor( cs1 );
cs2.addDependency( cs1 );
this.reg.active = true;
try {
cs1.start( );
} catch ( final ComponentStartupException e ) {
Assert.assertTrue( cs1.isActive( ) );
return;
}
Assert.fail( "no ComponentStartupException" );
}
/** Test: {@link ComponentState#start()} on a driver starts the component and the drivers */
@Test
public void testStartDriverDirectly( )
{
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.setDriverFor( cs1 );
cs2.addDependency( cs1 );
final NewComponentInfo< Object > ci3 = new NewComponentInfo< Object >( new Object( ) );
final ComponentState cs3 = TestComponentState.makeState( ci3 , this.reg , true , false );
cs3.setDriverFor( cs1 );
cs3.addDependency( cs1 );
this.reg.active = true;
cs2.start( );
Assert.assertTrue( cs1.isActive( ) );
Assert.assertTrue( cs2.isActive( ) );
Assert.assertTrue( cs3.isActive( ) );
}
/** Test: {@link ComponentState#stop()} with a failed registry throws {@link IllegalStateException} */ /** Test: {@link ComponentState#stop()} with a failed registry throws {@link IllegalStateException} */
@Test( expected = IllegalStateException.class ) @Test( expected = IllegalStateException.class )
public void testStopFailedRegistry( ) public void testStopFailedRegistry( )
@ -704,7 +913,7 @@ public class TestComponentState
this.reg.active = true; this.reg.active = true;
try { try {
cs.stop( ); cs.stop( );
} catch ( ComponentShutdownException e ) { } catch ( final ComponentShutdownException e ) {
Assert.assertSame( failure , e ); Assert.assertSame( failure , e );
Assert.assertTrue( cs.isActive( ) ); Assert.assertTrue( cs.isActive( ) );
return; return;
@ -730,6 +939,54 @@ public class TestComponentState
} }
/** Test: {@link ComponentState#stop()} stops the component's drivers */
@Test
public void testStopDrivers( )
{
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.setDriverFor( cs1 );
this.reg.active = true;
cs1.stop( );
Assert.assertFalse( cs2.isActive( ) );
}
/**
* Test: {@link ComponentState#stop()} stops the component's drivers after the component's other reverse
* dependencies
*/
@Test
public void testStopDriversOrder( )
{
final LCATest lcaTest = new LCATest( );
final NewComponentInfo< Object > ci1 = new NewComponentInfo< Object >( new Object( ) );
final ComponentState cs1 = TestComponentState.makeState( ci1 , this.reg , true , true );
final NewComponentInfo< Object > ci3 = new NewComponentInfo< Object >( new Object( ) ) //
.setLifecycleAction( LifecycleStage.STOP , ( o ) -> {
Assert.assertNull( lcaTest.stage );
} );
final ComponentState cs3 = TestComponentState.makeState( ci3 , this.reg , true , true );
cs3.addDependency( cs1 );
final NewComponentInfo< LCATest > ci2 = new NewComponentInfo< LCATest >( lcaTest ) //
.setLifecycleAction( LifecycleStage.STOP , ( o ) -> {
o.stage = LifecycleStage.STOP;
} );
final ComponentState cs2 = TestComponentState.makeState( ci2 , this.reg , true , true );
cs2.setDriverFor( cs1 );
cs2.addDependency( cs1 );
this.reg.active = true;
cs1.stop( );
}
/** Test: {@link ComponentState#restart()} with a failed registry throws {@link IllegalStateException} */ /** Test: {@link ComponentState#restart()} with a failed registry throws {@link IllegalStateException} */
@Test( expected = IllegalStateException.class ) @Test( expected = IllegalStateException.class )
public void testRestartFailedRegistry( ) public void testRestartFailedRegistry( )