/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.river.container.hsm; import java.util.List; import java.lang.reflect.InvocationTargetException; import java.util.logging.Logger; import java.lang.reflect.Field; import java.util.logging.Level; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; /** * * @author trasukg */ public class PlainMachineExecutorTest { private static final Logger log = Logger.getLogger(PlainMachineExecutorTest.class.getName()); public PlainMachineExecutorTest() throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { } @BeforeClass public static void setUpClass() throws Exception { Logger.getLogger("org.apache.river.container.hsm").setLevel(Level.FINER); } @AfterClass public static void tearDownClass() throws Exception { } @Before public void setUp() { } @After public void tearDown() { } TestSMInterface UUT = (TestSMInterface) PlainStateMachineExecutor.createProxy(TestSM.class); @Test /** * Verify that the list of active states is correct at beginning. * */ public void testActiveStates() { assertEquals(3, UUT.getActiveStates().size()); assertTrue("activeStates should contain root state.", UUT.getActiveStates().contains(TestSM.class)); assertTrue("activeStates should contain A.", UUT.getActiveStates().contains(TestSM.A.class)); assertTrue("activeStates should contain A1.", UUT.getActiveStates().contains(TestSM.A.A1.class)); } @Test /** * Test that the top-level (state-invariant) sayHelloConstant() method * returns the correct value. Verifies that the top-level proxy is * functioning correctly. */ public void testStateMachine() throws InstantiationException, IllegalAccessException { assertEquals("Hello", UUT.sayConstantHello()); } @Test /** * Test that the top-level (state-invariant) sayHelloConstant() method * returns the correct value. Verifies that the top-level proxy is * functioning correctly. */ public void testNullReturn() throws InstantiationException, IllegalAccessException { assertEquals(null, UUT.returnNull()); } @Test /** * <p> Verify that transitions from state A to B work, and that the * behaviour varies with state. </p> * * <p> First call to sayHello() should return "Hello", second call should * return "There". </p> * */ public void testSimpleTransition() throws InstantiationException, IllegalAccessException { assertTrue("activeStates should contain A.", UUT.getActiveStates().contains(TestSM.A.class)); log.info("\n\nCalling hello()\n\n"); assertEquals("Hello", UUT.sayHello()); log.info("\n\n...done\n\n"); List<Class> activeStates = UUT.getActiveStates(); assertTrue("activeStates should contain B after transition.", activeStates.contains(TestSM.B.class)); log.info("TestSM.B appears to have been active."); assertFalse("activeStates should not contain A after transition.", activeStates.contains(TestSM.A.class)); assertEquals("There", UUT.sayHello()); } @Test /** * When we enter a state, the entry method should be called. */ public void testEntryMethodExecution() { assertEquals(1, UUT.getAEntryCount()); UUT.sayHello(); assertEquals(1, UUT.getAExitCount()); } @Test /** * When we transition to a state but we are already in that state, the * onEntry method should not be run. */ public void testNullTransition() { UUT.nullTransition(); UUT.nullTransition(); UUT.nullTransition(); assertEquals(1, UUT.getNullTransitionEntryCount()); } @Test /** * Make sure that the gotoA() and gotoB() methods cause the appropriate * transitions. */ public void testABTransitions() { UUT.gotoA(); assertTrue("activeStates should contain A.", UUT.getActiveStates().contains(TestSM.A.class)); assertFalse("activeStates should not contain B.", UUT.getActiveStates().contains(TestSM.B.class)); UUT.gotoB(); assertFalse("activeStates should not contain A.", UUT.getActiveStates().contains(TestSM.A.class)); assertTrue("activeStates should contain B.", UUT.getActiveStates().contains(TestSM.B.class)); UUT.gotoA(); assertTrue("activeStates should contain A.", UUT.getActiveStates().contains(TestSM.A.class)); assertFalse("activeStates should not contain B.", UUT.getActiveStates().contains(TestSM.B.class)); } @Test /** * @Retained annotations should be respected, and states should be * initialized on entry if the * @Retained is not there. */ public void testStateInitialization() { UUT.gotoA(); assertTrue("activeStates should contain A.", UUT.getActiveStates().contains(TestSM.A.class)); assertFalse("activeStates should not contain B.", UUT.getActiveStates().contains(TestSM.B.class)); UUT.gotoB(); assertFalse("activeStates should not contain A.", UUT.getActiveStates().contains(TestSM.A.class)); assertTrue("activeStates should contain B.", UUT.getActiveStates().contains(TestSM.B.class)); assertTrue("activeStates should contain B1.", UUT.getActiveStates().contains(TestSM.B1.class)); UUT.moveSubstateOfB(); assertTrue("activeStates should contain B2.", UUT.getActiveStates().contains(TestSM.B2.class)); UUT.gotoA(); /* the substate isn't marked @Retained, so should reset to initial on gotoB(). */ UUT.gotoB(); assertTrue("activeStates should contain B1.", UUT.getActiveStates().contains(TestSM.B1.class)); } @Test /** * <p> Verify that the second interface is on the proxy and effective. </p> * * <p> After call to doSecondInterfaceAction(), call to sayHello() should * return "HelloFromC". </p> * */ public void testSecondInterface() throws InstantiationException, IllegalAccessException { log.info("\n\nCalling doSecondInterfaceAction()\n\n"); TestSMSecondInterface UUT2=(TestSMSecondInterface) UUT; UUT2.doSecondInterfaceAction(); log.info("\n\n...done\n\n"); List<Class> activeStates = UUT.getActiveStates(); assertTrue("activeStates should contain C after transition.", activeStates.contains(TestSM.C.class)); log.info("TestSM.C appears to have been active."); assertFalse("activeStates should not contain A after transition.", activeStates.contains(TestSM.A.class)); assertEquals("HelloFromC", UUT.sayHello()); } /** * Calling an event method that isn't implemented in the current state * should throw an IllegalStateException. */ @Test(expected = IllegalStateException.class) public void testUnimplementedMethod() { UUT.unimplementedMethod(); } }