1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.scxml;
18  
19  import java.net.URL;
20  import java.util.Iterator;
21  import java.util.Set;
22  
23  import junit.framework.Test;
24  import junit.framework.TestCase;
25  import junit.framework.TestSuite;
26  import junit.textui.TestRunner;
27  
28  import org.apache.commons.scxml.model.State;
29  /***
30   * Unit tests for testing conflict resolution amongst multiple transitions
31   * within the {@link org.apache.commons.scxml.SCXMLExecutor}'s default
32   * semantics.
33   *
34   * Upto v0.6, non-deterministic behavior leads to an error condition. Based
35   * on the February 2007 WD, such non-determinism should now be resolved
36   * based on document order and heirarchy of states within the state machine.
37   * This class tests various such cases where more than one candidate
38   * transition exists at a particular point, and tie-breaking rules are used
39   * to make progress, rather than resulting in error conditions.
40   */
41  public class TieBreakerTest extends TestCase {
42      /***
43       * Construct a new instance of SCXMLExecutorTest with
44       * the specified name
45       */
46      public TieBreakerTest(String name) {
47          super(name);
48      }
49  
50      public static Test suite() {
51          TestSuite suite = new TestSuite(TieBreakerTest.class);
52          suite.setName("SCXML Executor Tie-Breaker Tests");
53          return suite;
54      }
55  
56      // Test data
57      private URL tiebreaker01, tiebreaker02, tiebreaker03, tiebreaker04,
58          tiebreaker05, tiebreaker06;
59      private SCXMLExecutor exec;
60  
61      /***
62       * Set up instance variables required by this test case.
63       */
64      public void setUp() {
65          tiebreaker01 = this.getClass().getClassLoader().
66              getResource("org/apache/commons/scxml/tie-breaker-01.xml");
67          tiebreaker02 = this.getClass().getClassLoader().
68              getResource("org/apache/commons/scxml/tie-breaker-02.xml");
69          tiebreaker03 = this.getClass().getClassLoader().
70              getResource("org/apache/commons/scxml/tie-breaker-03.xml");
71          tiebreaker04 = this.getClass().getClassLoader().
72              getResource("org/apache/commons/scxml/tie-breaker-04.xml");
73          tiebreaker05 = this.getClass().getClassLoader().
74              getResource("org/apache/commons/scxml/tie-breaker-05.xml");
75          tiebreaker06 = this.getClass().getClassLoader().
76              getResource("org/apache/commons/scxml/tie-breaker-06.xml");
77      }
78  
79      /***
80       * Tear down instance variables required by this test case.
81       */
82      public void tearDown() {
83          tiebreaker01 = tiebreaker02 = tiebreaker03 = tiebreaker04 =
84              tiebreaker05 = tiebreaker06 = null;
85      }
86  
87      /***
88       * Test the implementation
89       */
90      public void testTieBreaker01() {
91          exec = SCXMLTestHelper.getExecutor(tiebreaker01);
92          assertNotNull(exec);
93          Set currentStates = exec.getCurrentStatus().getStates();
94          assertEquals(1, currentStates.size());
95          assertEquals("ten", ((State)currentStates.iterator().
96              next()).getId());
97          currentStates = SCXMLTestHelper.fireEvent(exec, "ten.done");
98          assertEquals(1, currentStates.size());
99          assertEquals("twenty", ((State)currentStates.iterator().
100             next()).getId());
101     }
102 
103     public void testTieBreaker02() {
104         exec = SCXMLTestHelper.getExecutor(tiebreaker02);
105         assertNotNull(exec);
106         Set currentStates = exec.getCurrentStatus().getStates();
107         assertEquals(1, currentStates.size());
108         assertEquals("eleven", ((State)currentStates.iterator().
109             next()).getId());
110         currentStates = SCXMLTestHelper.fireEvent(exec, "ten.done");
111         assertEquals(1, currentStates.size());
112         assertEquals("thirty", ((State)currentStates.iterator().
113             next()).getId());
114     }
115 
116     public void testTieBreaker03() {
117         exec = SCXMLTestHelper.getExecutor(tiebreaker03);
118         assertNotNull(exec);
119         Set currentStates = exec.getCurrentStatus().getStates();
120         assertEquals(1, currentStates.size());
121         assertEquals("eleven", ((State)currentStates.iterator().
122             next()).getId());
123         currentStates = SCXMLTestHelper.fireEvent(exec, "ten.done");
124         assertEquals(1, currentStates.size());
125         assertEquals("forty", ((State)currentStates.iterator().
126             next()).getId());
127     }
128 
129     public void testTieBreaker04() {
130         exec = SCXMLTestHelper.getExecutor(tiebreaker04);
131         assertNotNull(exec);
132         Set currentStates = SCXMLTestHelper.fireEvent(exec, "event_2");
133         assertEquals(1, currentStates.size());
134         currentStates = SCXMLTestHelper.fireEvent(exec, "event_1");
135         assertEquals(1, currentStates.size());
136     }
137 
138     public void testTieBreaker05() {
139         exec = SCXMLTestHelper.getExecutor(tiebreaker05);
140         assertNotNull(exec);
141         Set currentStates = exec.getCurrentStatus().getStates();
142         assertEquals(3, currentStates.size());
143         String id = ((State) currentStates.iterator().next()).getId();
144         Iterator iter = currentStates.iterator();
145         while (iter.hasNext()) {
146             id = ((State) iter.next()).getId();
147             assertTrue(id.equals("s11") || id.equals("s212")
148                 || id.equals("s2111"));
149         }
150         currentStates = SCXMLTestHelper.fireEvent(exec, "event1");
151         assertEquals(3, currentStates.size());
152         id = ((State) currentStates.iterator().next()).getId();
153         iter = currentStates.iterator();
154         while (iter.hasNext()) {
155             id = ((State) iter.next()).getId();
156             assertTrue(id.equals("s12") || id.equals("s212")
157                 || id.equals("s2112"));
158         }
159     }
160 
161     public void testTieBreaker06() {
162         exec = SCXMLTestHelper.getExecutor(SCXMLTestHelper.parse(tiebreaker06));
163         assertNotNull(exec);
164         Set currentStates = exec.getCurrentStatus().getStates();
165         assertEquals(1, currentStates.size());
166     }
167 
168     public static void main(String args[]) {
169         TestRunner.run(suite());
170     }
171 }
172