1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.statemachine;
19
20 import org.apache.statemachine.StateMachine.Fsm;
21 import org.apache.statemachine.StateMachine.FsmImpl;
22 import org.apache.statemachine.StateMachine.State;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
25 import org.testng.Assert;
26 import org.testng.annotations.Test;
27
28 import java.util.concurrent.CountDownLatch;
29 import java.util.concurrent.Executors;
30
31 public class TestStateMachine {
32 private final static Logger LOG = LoggerFactory.getLogger(TestStateMachine.class);
33
34 static class TestEvent implements StateMachine.DeferrableEvent {
35 CountDownLatch latch = new CountDownLatch(1);
36 Throwable t = null;
37 int i = 0;
38
39 public void error(Throwable t) {
40 this.t = t;
41 latch.countDown();
42 }
43
44 public void success(int i) {
45 this.i = i;
46 latch.countDown();
47 }
48
49 public int get() throws Throwable {
50 latch.await();
51 if (t != null) {
52 throw t;
53 }
54 return i;
55 }
56 }
57
58 static class CompletingState extends State {
59 int completed = 0;
60
61 CompletingState(Fsm fsm) {
62 super(fsm);
63 }
64
65 public State handleEvent(TestEvent e) {
66 e.success(completed++);
67 return this;
68 }
69 }
70
71 static class DeferringState extends State {
72 int count = 0;
73
74 DeferringState(Fsm fsm) {
75 super(fsm);
76 }
77
78 public State handleEvent(TestEvent e) {
79 if (count++ < 5) {
80 fsm.deferEvent(e);
81 return this;
82 } else {
83 fsm.deferEvent(e);
84 return new CompletingState(fsm);
85 }
86 }
87 }
88
89 @Test(timeOut = 60_000)
90 public void testOrdering() throws Throwable {
91 Fsm fsm = new FsmImpl(Executors.newSingleThreadScheduledExecutor());
92 fsm.setInitState(new DeferringState(fsm));
93 for (int i = 0; i < 10; i++) {
94 fsm.sendEvent(new TestEvent());
95 }
96 TestEvent te = new TestEvent();
97 fsm.sendEvent(te);
98 Assert.assertEquals(10, te.get());
99 }
100 }