TestHFSM Package

TestHFSM Package

This files are part of the ‘symplehfsm’ package.

symplehfsm_demo Module

This is a full blown example. It uses all features of the symplehfsm framework (entry-, exit- and transition-actions, guards). There are also tests for each transition. This example shows the usage of different actions implementations applied to the same state machine (one for testing, one for the interactive demo).

It’s all about:

making a statemachine testable based on: http://accu.org/index.php/journals/1548


------------------------------------------------------------------------------

Statechart used to test the SympleHFSM
based on 
[Samek] Miro Samek, Practical Statecharts in C/C++, CMP Books 2002. 
There's a companion website with additional information: http://www.quantum-leaps.com
taken from: http://accu.org/index.php/journals/252

see also: http://en.wikipedia.org/wiki/UML_state_machine#Local_versus_external_transitions
making a statemachine testable based on: http://accu.org/index.php/journals/1548

          +-------------------------------------------------------------------------------------+
*--init-->|                                         s0                                          |
          +-------------------------------------------------------------------------------------+
          | entry/                                                                              |
          | exit/                                                                               |
          |       +-------------------------+    +------------------------------------------+   |
          |   *-->|        s1               |    |               s2                         |   |
          |       +-------------------------+    +------------------------------------------+   |
          |       | entry/                  |-c->| entry/              +-----------------+  |   |
          |<--d---| exit/                   |    | exit/               | h[!foo]/ foo=1; |  |   |
          |       |     +---------------+   |<-c-|      +----------------------------+   |  |   |
          |       | *-->|      s11      |   |    |  *-->|             s21            |<--+  |   |
          |       |     +---------------+   |    |      +----------------------------+      |   |
          |    +--|     | entry/        |   |    |      | entry/                     |      |   |
          |   a|  |     | exit/         |<---f---|      | exit/                      |      |   |
          |    +->|     | h[foo]/ foo=0;|   |    |      |       +--------------+     |      |   |
          |       |     |               |   |    |      |   *-->|     s211     |     |      |   |
          |       |--b->|               |   |    |      |       +--------------+     |      |   |
          |       |     |               |   |--------f--------->| entry/       |     |      |   |
          |       |     |               |   |    |      |       | exit/        |--------g------>|
          |       |     |               |----------g----------->|              |     |      |   |
          |       |     |               |   |    |      |--b--->|              |<-------e-------|
          |       |     |               |   |    |      |<---d--|              |     |      |   |
          |       |     |               |   |    |      |       +--------------+     |      |   |
          |       |     +---------------+   |    |      +----------------------------+      |   |--exit-->O
          |       |                         |    |                                          |   |
          |       +-------------------------+    +------------------------------------------+   |
          |                                                                                     |
          +-------------------------------------------------------------------------------------+


  As far as I understand it, current_state always points to either s11 or s211 (one of the leaf states).
  Also for the transitions triggered by an event I assume it works as follows:

  event| from -> to | transition actions
   init:  s0 ->  s11:   s0.entry, s1.entry, s11.entry
   exit:s211 ->   s0: s211.exit, s21.exit, s2.exit, s0.exit
         s11 ->   s0:  s11.exit, s1.exit, s0.exit
      a:  s1 ->   s1:  s11.exit,  s1.exit,  s1.entry, s11.entry
      b:  s1 ->  s11:  s11.exit, s11.entry
         s21 -> s211: s211.exit, s211.entry
      c:  s1 ->   s2:  s11.exit,  s1.exit,  s2.entry, s21.entry, s211.entry
          s2 ->   s1: s211.exit, s21.exit,  s2.exit, s1.entry, s11.entry
      d:  s1 ->   s0:  s11.exit,  s1.exit,  s1.entry, s11.entry
        s211 ->  s21: s211.exit, s211.entry
      e:  s0 -> s211:  s11.exit,  s1.exit, s2.entry, s21.entry, s211.entry
                      s211.exit, s21.exit,  s2.exit, s2.entry, s21.entry, s211.entry
      f:  s2 ->  s11: s211.exit, s21.exit,  s2.exit, s1.entry, s11.entry
          s1 -> s211:  s11.exit,  s1.exit,  s2.entry, s21.entry, s211.entry
      g: s11 -> s211:  s11.exit,  s1.exit,  s2.entry, s21.entry, s211.entry
        s211 ->   s0: s211.exit, s21.exit,  s2.exit,  s1.entry, s11.entry
      h: s11 foo==True: actions.unset_foo
         s11 foo==False: do nothing
         s21 foo==False: s211.exit, s21.exit, actions.set_foo, s21.entry, s211.entry
         s21 foo==True: do nothing
      
  Actions:
      set_foo() => foo = 1
      unset_foo() => foo = 0

The action specifications shown are:

   *

     The transition from s21 to itself (a self-transition). This is an example of a transition 
     that has a guard (in brackets []) and an associated action (after the slash /). The guard 
     is a condition that must evaluate to true to enable the transition. If it evaluates to false, 
     the transition is not taken and none of the actions are executed. A self-transition exits and 
     reenters the state, hence the associated exit and entry actions are executed.
   *

     The internal transition inside s11 is not drawn with an arrow. It merely specifies an action 
     that is to be taken when a certain event occurs, but no transition to another state occurs, 
     and no exit or entry actions are performed. In our case the internal transition has a guard, 
     so the associated action (foo = 0) is only executed when the h key is pressed while foo 
     evaluates to true.

..todo: loop action back to event -> queue?

class examples.TestHFSM.symplehfsm_demo.Actions[source]

Bases: object

The Actions the statemachine can execute.

check_foo()[source]
check_foo_inverted()[source]
enter_s0()[source]
enter_s1()[source]
enter_s11()[source]
enter_s2()[source]
enter_s21()[source]
enter_s211()[source]
exit_s0()[source]
exit_s1()[source]
exit_s11()[source]
exit_s2()[source]
exit_s21()[source]
exit_s211()[source]
set_foo()[source]
trans_s0_to_s211_e()[source]
trans_s11_to_s11_h()[source]
trans_s11_to_s211_g()[source]
trans_s1_to_s0_d()[source]
trans_s1_to_s11_b()[source]
trans_s1_to_s1_a()[source]
trans_s1_to_s211_f()[source]
trans_s1_to_s2_c()[source]
trans_s211_to_s0_g()[source]
trans_s211_to_s21_d()[source]
trans_s21_to_s211_b()[source]
trans_s21_to_s21_h()[source]
trans_s2_to_s11_f()[source]
trans_s2_to_s1_c()[source]
unset_foo()[source]
class examples.TestHFSM.symplehfsm_demo.EventEnum[source]

Bases: object

Event identifiers of the statemachine (the events it can handle).

a = 0
b = 1
c = 2
d = 3
e = 4
f = 5
g = 6
h = 7
class examples.TestHFSM.symplehfsm_demo.MyStateMachine(actions)[source]

Bases: object

a()[source]
b()[source]
c()[source]
current_state
d()[source]
e()[source]
exit()[source]
f()[source]
g()[source]
h()[source]
init()[source]
set_state(new_state)[source]
sm_structure = <symplehfsm.Structure object at 0x0364A150>
class examples.TestHFSM.symplehfsm_demo.SympleHFSMTests(methodName='runTest')[source]

Bases: symplehfsm.BaseHFSMTests

Testcases for MyStateMachine using the BaseHFSMTests as base.

class TActions[source]

Bases: examples.TestHFSM.symplehfsm_demo.Actions

Test Actions for testing, captures all actions for comparison

class AEnum[source]

Bases: object

Define an ‘enum’ to have comparable values for each action

CHECKFOO = 'CHECKFOO'
ENTERS0 = 'ENTERS0'
ENTERS1 = 'ENTERS1'
ENTERS11 = 'ENTERS11'
ENTERS2 = 'ENTERS2'
ENTERS21 = 'ENTERS21'
ENTERS211 = 'ENTERS211'
EXITS0 = 'EXITS0'
EXITS1 = 'EXITS1'
EXITS11 = 'EXITS11'
EXITS2 = 'EXITS2'
EXITS21 = 'EXITS21'
EXITS211 = 'EXITS211'
SETFOO = 'SETFOO'
TRANS_S0_TO_S211_E = 'TRANS_S0_TO_S211_E'
TRANS_S11_TO_S11_H = 'TRANS_S11_TO_S11_H'
TRANS_S11_TO_S211_G = 'TRANS_S11_TO_S211_G'
TRANS_S1_TO_S0_D = 'TRANS_S1_TO_S0_D'
TRANS_S1_TO_S11_B = 'TRANS_S1_TO_S11_B'
TRANS_S1_TO_S1_A = 'TRANS_S1_TO_S1_A'
TRANS_S1_TO_S211_F = 'TRANS_S1_TO_S211_F'
TRANS_S1_TO_S2_C = 'TRANS_S1_TO_S2_C'
TRANS_S211_TO_S0_G = 'TRANS_S211_TO_S0_G'
TRANS_S211_TO_S21_D = 'TRANS_S211_TO_S21_D'
TRANS_S21_TO_S211_B = 'TRANS_S21_TO_S211_B'
TRANS_S21_TO_S21_H = 'TRANS_S21_TO_S21_H'
TRANS_S2_TO_S11_F = 'TRANS_S2_TO_S11_F'
TRANS_S2_TO_S1_C = 'TRANS_S2_TO_S1_C'
UNSETFOO = 'UNSETFOO'
SympleHFSMTests.TActions.check_foo()[source]
SympleHFSMTests.TActions.check_foo_inverted()[source]
SympleHFSMTests.TActions.enter_s0()[source]
SympleHFSMTests.TActions.enter_s1()[source]
SympleHFSMTests.TActions.enter_s11()[source]
SympleHFSMTests.TActions.enter_s2()[source]
SympleHFSMTests.TActions.enter_s21()[source]
SympleHFSMTests.TActions.enter_s211()[source]
SympleHFSMTests.TActions.exit_s0()[source]
SympleHFSMTests.TActions.exit_s1()[source]
SympleHFSMTests.TActions.exit_s11()[source]
SympleHFSMTests.TActions.exit_s2()[source]
SympleHFSMTests.TActions.exit_s21()[source]
SympleHFSMTests.TActions.exit_s211()[source]
SympleHFSMTests.TActions.separator()[source]
SympleHFSMTests.TActions.set_foo()[source]
SympleHFSMTests.TActions.trans_s0_to_s211_e()[source]
SympleHFSMTests.TActions.trans_s11_to_s11_h()[source]
SympleHFSMTests.TActions.trans_s11_to_s211_g()[source]
SympleHFSMTests.TActions.trans_s1_to_s0_d()[source]
SympleHFSMTests.TActions.trans_s1_to_s11_b()[source]
SympleHFSMTests.TActions.trans_s1_to_s1_a()[source]
SympleHFSMTests.TActions.trans_s1_to_s211_f()[source]
SympleHFSMTests.TActions.trans_s1_to_s2_c()[source]
SympleHFSMTests.TActions.trans_s211_to_s0_g()[source]
SympleHFSMTests.TActions.trans_s211_to_s21_d()[source]
SympleHFSMTests.TActions.trans_s21_to_s211_b()[source]
SympleHFSMTests.TActions.trans_s21_to_s21_h()[source]
SympleHFSMTests.TActions.trans_s2_to_s11_f()[source]
SympleHFSMTests.TActions.trans_s2_to_s1_c()[source]
SympleHFSMTests.TActions.unset_foo()[source]
SympleHFSMTests.setUp()[source]
SympleHFSMTests.tearDown()[source]
SympleHFSMTests.test_exit_transition_from_s11()[source]
SympleHFSMTests.test_exit_transition_from_s211()[source]
SympleHFSMTests.test_initial_transition_state()[source]
SympleHFSMTests.test_s0_t0_s211_event_e_case_s211()[source]
SympleHFSMTests.test_s0_to_s211_event_e_case_s11()[source]
SympleHFSMTests.test_s11_to_s11_event_h_guard_false()[source]
SympleHFSMTests.test_s11_to_s11_event_h_guard_true()[source]
SympleHFSMTests.test_s11_to_s211_event_g()[source]
SympleHFSMTests.test_s1_to_s0_event_d()[source]
SympleHFSMTests.test_s1_to_s11_event_b()[source]
SympleHFSMTests.test_s1_to_s1_event_a()[source]
SympleHFSMTests.test_s1_to_s211_event_f()[source]
SympleHFSMTests.test_s1_to_s2_event_c()[source]
SympleHFSMTests.test_s211_to_s0_event_g()[source]
SympleHFSMTests.test_s211_to_s211_event_a_no_guard()[source]
SympleHFSMTests.test_s211_to_s211_event_h_guard_false()[source]
SympleHFSMTests.test_s211_to_s211_event_h_guard_true()[source]
SympleHFSMTests.test_s211_to_s21_event_d()[source]
SympleHFSMTests.test_s21_to_s211_event_b()[source]
SympleHFSMTests.test_s2_to_s11_event_f()[source]
SympleHFSMTests.test_s2_to_s1_event_c()[source]
class examples.TestHFSM.symplehfsm_demo.SympleHFSMTestsOptimized(methodName='runTest')[source]

Bases: examples.TestHFSM.symplehfsm_demo.SympleHFSMTests

setUp()[source]
examples.TestHFSM.symplehfsm_demo.demo()[source]

The demo. This is the main method that runs the interactive demo.

examples.TestHFSM.symplehfsm_demo.print_chart()[source]

Table Of Contents

Previous topic

examples Package

Next topic

mousefollower Package

This Page