View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
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 }