Add support for completion transitions

- Currently into as internal new feature, add state
  completed concecept and use it in various places.
- Main focus for this commit is to add support using
  anonymous transitions with state do actions which
  requires proper completion schematics.
- Internal functionality here will probably expose to
  user level in future releases using various other
  concepts.
- Backport #466
- Relates #504
This commit is contained in:
jvalkeal
2018-02-12 13:30:37 +02:00
parent 6743d42792
commit a4d43131ea
23 changed files with 962 additions and 67 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,6 +25,8 @@ import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -38,6 +40,7 @@ import org.springframework.statemachine.listener.StateMachineListener;
import org.springframework.statemachine.listener.StateMachineListenerAdapter;
import org.springframework.statemachine.state.State;
import org.springframework.statemachine.transition.Transition;
import org.springframework.util.StringUtils;
import demo.CommonConfiguration;
import demo.tasks.Application.Events;
@@ -45,6 +48,8 @@ import demo.tasks.Application.States;
public class TasksTests {
private final static Log log = LogFactory.getLog(TasksTests.class);
private AnnotationConfigApplicationContext context;
private StateMachine<States,Events> machine;
@@ -61,9 +66,9 @@ public class TasksTests {
@Test
public void testRunOnce() throws InterruptedException {
listener.reset(8, 0, 0);
listener.reset(8, 8, 0);
tasks.run();
assertThat(listener.stateChangedLatch.await(8, TimeUnit.SECONDS), is(true));
assertThat(listener.stateEnteredLatch.await(8, TimeUnit.SECONDS), is(true));
assertThat(machine.getState().getIds(), contains(States.READY));
Map<Object, Object> variables = machine.getExtendedState().getVariables();
assertThat(variables.size(), is(3));
@@ -71,23 +76,38 @@ public class TasksTests {
@Test
public void testRunTwice() throws InterruptedException {
listener.reset(8, 0, 0);
listener.reset(8, 8, 0);
tasks.run();
assertThat(listener.stateChangedLatch.await(8, TimeUnit.SECONDS), is(true));
assertThat(listener.stateEnteredLatch.await(8, TimeUnit.SECONDS), is(true));
assertThat(machine.getState().getIds(), contains(States.READY));
Map<Object, Object> variables = machine.getExtendedState().getVariables();
assertThat(variables.size(), is(3));
listener.reset(8, 0, 0);
listener.reset(8, 8, 0);
tasks.run();
assertThat(listener.stateChangedLatch.await(8, TimeUnit.SECONDS), is(true));
assertThat(listener.stateEnteredLatch.await(8, TimeUnit.SECONDS), is(true));
assertThat(machine.getState().getIds(), contains(States.READY));
variables = machine.getExtendedState().getVariables();
assertThat(variables.size(), is(3));
}
@Test
public void testRunSmoke() throws InterruptedException {
for (int i = 0; i < 20; i++) {
log.info("testRunSmoke SMOKE START " + i);
listener.reset(8, 8, 0);
tasks.run();
boolean await = listener.stateEnteredLatch.await(8, TimeUnit.SECONDS);
String reason = "Machine was " + machine + " " + StringUtils.collectionToCommaDelimitedString(listener.statesEntered);
assertThat(reason , await, is(true));
assertThat(machine.getState().getIds(), contains(States.READY));
log.info("testRunSmoke SMOKE STOP " + i);
}
}
@Test
public void testFailAutomaticFix() throws InterruptedException {
listener.reset(10, 0, 0);

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %t %m%n</pattern>
<charset>utf8</charset>
</encoder>
</appender>
<root level="WARN">
<appender-ref ref="CONSOLE" />
</root>
<logger name="org.springframework.statemachine" level="DEBUG"/>
</configuration>