/* * Copyright 2014 Groupon, Inc * * Groupon 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.killbill.automaton; import org.killbill.xmlloader.XMLLoader; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.testng.Assert; import org.testng.annotations.Test; import com.google.common.io.Resources; public class TestStateMachine { private final Logger logger = LoggerFactory.getLogger(TestStateMachine.class); @Test(groups = "fast") public void testStateMachine() throws Exception { final DefaultStateMachineConfig sms = XMLLoader.getObjectFromString(Resources.getResource("PaymentStates.xml").toExternalForm(), DefaultStateMachineConfig.class); Assert.assertEquals(sms.getStateMachines().length, 2); final DefaultStateMachine sm1 = sms.getStateMachines()[0]; Assert.assertEquals(sm1.getStates().length, 3); Assert.assertEquals(sm1.getStates()[0].getName(), "AUTH_INIT"); Assert.assertEquals(sm1.getStates()[1].getName(), "AUTH_SUCCESS"); Assert.assertEquals(sm1.getStates()[2].getName(), "AUTH_FAILED"); Assert.assertEquals(sm1.getOperations().length, 1); Assert.assertEquals(sm1.getOperations()[0].getName(), "OP_AUTHORIZE"); Assert.assertEquals(sm1.getTransitions().length, 2); Assert.assertEquals(sm1.getTransitions()[0].getInitialState().getName(), "AUTH_INIT"); Assert.assertEquals(sm1.getTransitions()[0].getOperation().getName(), "OP_AUTHORIZE"); Assert.assertEquals(sm1.getTransitions()[0].getOperationResult(), OperationResult.SUCCESS); Assert.assertEquals(sm1.getTransitions()[0].getFinalState().getName(), "AUTH_SUCCESS"); Assert.assertEquals(sm1.getTransitions()[1].getInitialState().getName(), "AUTH_INIT"); Assert.assertEquals(sm1.getTransitions()[1].getOperation().getName(), "OP_AUTHORIZE"); Assert.assertEquals(sm1.getTransitions()[1].getOperationResult(), OperationResult.FAILURE); Assert.assertEquals(sm1.getTransitions()[1].getFinalState().getName(), "AUTH_FAILED"); final DefaultStateMachine sm2 = sms.getStateMachines()[1]; Assert.assertEquals(sm2.getStates().length, 4); Assert.assertEquals(sm2.getStates()[0].getName(), "CAPTURE_INIT"); Assert.assertEquals(sm2.getStates()[1].getName(), "CAPTURE_SUCCESS"); Assert.assertEquals(sm2.getStates()[2].getName(), "CAPTURE_FAILED"); Assert.assertEquals(sm2.getStates()[3].getName(), "CAPTURE_ERRORED"); Assert.assertEquals(sm2.getOperations().length, 1); Assert.assertEquals(sm2.getOperations()[0].getName(), "OP_CAPTURE"); Assert.assertEquals(sm2.getTransitions().length, 3); Assert.assertEquals(sm2.getTransitions()[0].getInitialState().getName(), "CAPTURE_INIT"); Assert.assertEquals(sm2.getTransitions()[0].getOperation().getName(), "OP_CAPTURE"); Assert.assertEquals(sm2.getTransitions()[0].getOperationResult(), OperationResult.SUCCESS); Assert.assertEquals(sm2.getTransitions()[0].getFinalState().getName(), "CAPTURE_SUCCESS"); Assert.assertEquals(sm2.getTransitions()[1].getInitialState().getName(), "CAPTURE_INIT"); Assert.assertEquals(sm2.getTransitions()[1].getOperation().getName(), "OP_CAPTURE"); Assert.assertEquals(sm2.getTransitions()[1].getOperationResult(), OperationResult.FAILURE); Assert.assertEquals(sm2.getTransitions()[1].getFinalState().getName(), "CAPTURE_FAILED"); Assert.assertEquals(sm2.getTransitions()[2].getInitialState().getName(), "CAPTURE_INIT"); Assert.assertEquals(sm2.getTransitions()[2].getOperation().getName(), "OP_CAPTURE"); Assert.assertEquals(sm2.getTransitions()[2].getOperationResult(), OperationResult.EXCEPTION); Assert.assertEquals(sm2.getTransitions()[2].getFinalState().getName(), "CAPTURE_ERRORED"); Assert.assertEquals(sms.getLinkStateMachines().length, 1); Assert.assertEquals(sms.getLinkStateMachines()[0].getInitialState().getName(), "AUTH_SUCCESS"); Assert.assertEquals(sms.getLinkStateMachines()[0].getInitialStateMachine().getName(), "AUTHORIZE"); Assert.assertEquals(sms.getLinkStateMachines()[0].getFinalState().getName(), "CAPTURE_INIT"); Assert.assertEquals(sms.getLinkStateMachines()[0].getFinalStateMachine().getName(), "CAPTURE"); } @Test(groups = "fast") public void testStateTransition() throws Exception { final DefaultStateMachineConfig sms = XMLLoader.getObjectFromString(Resources.getResource("PaymentStates.xml").toExternalForm(), DefaultStateMachineConfig.class); final DefaultStateMachine sm1 = sms.getStateMachines()[1]; final State state = sm1.getState("CAPTURE_INIT"); final Operation operation = sm1.getOperation("OP_CAPTURE"); state.runOperation(operation, new Operation.OperationCallback() { @Override public OperationResult doOperationCallback() throws OperationException { return OperationResult.SUCCESS; } }, new State.EnteringStateCallback() { @Override public void enteringState(final State newState, final Operation.OperationCallback operationCallback, final OperationResult operationResult, final State.LeavingStateCallback leavingStateCallback) { logger.info("Entering state " + newState.getName()); Assert.assertEquals(newState.getName(), "CAPTURE_SUCCESS"); } }, new State.LeavingStateCallback() { @Override public void leavingState(final State oldState) { logger.info("Leaving state " + oldState.getName()); Assert.assertEquals(oldState.getName(), "CAPTURE_INIT"); } } ); state.runOperation(operation, new Operation.OperationCallback() { @Override public OperationResult doOperationCallback() throws OperationException { return OperationResult.FAILURE; } }, new State.EnteringStateCallback() { @Override public void enteringState(final State newState, final Operation.OperationCallback operationCallback, final OperationResult operationResult, final State.LeavingStateCallback leavingStateCallback) { logger.info("Entering state " + newState.getName()); Assert.assertEquals(newState.getName(), "CAPTURE_FAILED"); } }, new State.LeavingStateCallback() { @Override public void leavingState(final State oldState) { logger.info("Leaving state " + oldState.getName()); Assert.assertEquals(oldState.getName(), "CAPTURE_INIT"); } } ); try { state.runOperation(operation, new Operation.OperationCallback() { @Override public OperationResult doOperationCallback() throws OperationException { throw new OperationException(); } }, new State.EnteringStateCallback() { @Override public void enteringState(final State newState, final Operation.OperationCallback operationCallback, final OperationResult operationResult, final State.LeavingStateCallback leavingStateCallback) { logger.info("Entering state " + newState.getName()); Assert.assertEquals(newState.getName(), "CAPTURE_ERRORED"); } }, new State.LeavingStateCallback() { @Override public void leavingState(final State oldState) { logger.info("Leaving state " + oldState.getName()); Assert.assertEquals(oldState.getName(), "CAPTURE_INIT"); } } ); Assert.fail("Should throw an exception"); } catch (final OperationException e) { Assert.assertTrue(true); } } @Test(groups = "fast") public void testLinkedStateMachines() throws Exception { final DefaultStateMachineConfig sms = XMLLoader.getObjectFromString(Resources.getResource("PaymentStates.xml").toExternalForm(), DefaultStateMachineConfig.class); final DefaultStateMachine sm1 = sms.getStateMachines()[0]; final State state = sm1.getState("AUTH_SUCCESS"); final DefaultStateMachine sm2 = sms.getStateMachines()[1]; final Operation operation = sm2.getOperation("OP_CAPTURE"); state.runOperation(operation, new Operation.OperationCallback() { @Override public OperationResult doOperationCallback() throws OperationException { return OperationResult.SUCCESS; } }, new State.EnteringStateCallback() { @Override public void enteringState(final State newState, final Operation.OperationCallback operationCallback, final OperationResult operationResult, final State.LeavingStateCallback leavingStateCallback) { logger.info("Entering state " + newState.getName()); Assert.assertEquals(newState.getName(), "CAPTURE_SUCCESS"); } }, new State.LeavingStateCallback() { @Override public void leavingState(final State oldState) { logger.info("Leaving state " + oldState.getName()); Assert.assertEquals(oldState.getName(), "CAPTURE_INIT"); } } ); } }