Sismic: An open source Python API for statechart execution, validation and testing

Statecharts, originally invented by David Harel, are a well-known visual modeling language for representing the executable behavior of complex reactive event-based systems. While several commercial tools exist for simulating statecharts and generating executable source code, these tools tend to be mostly commercial, or require the use of an integrated visual environment for using them.

As part of a research project conducted at the University of Mons, we have come up with a much more lightweight approach for defining, validating and executing statecharts, by proposing an open source API implemented in Python 3. This API, developed by Alexandre Decan, has been baptised Sismic, a recursive acronym for Sismic Interactive Statechart Model Interpreter and Checker.

The Sismic API is available through the Python package manager PyPI and can be easily installed using the pip installer. There is also an extensive online user manual. The source code is released under the GNU Lesser General Public Licence version 3.0 (LGPLv3), and is available through GitHub.

Looking for a lightweight approach for defining, validating and executing statecharts? Use our open source API implemented in Python 3 Click To Tweet

Our 2018 research article A method for testing and validating executable statechart models published in the Software and Systems Modeling journal explains how to use Sismic for defining, validating and testing executable statecharts. It also includes the results of a controlled user study to evaluate the feasibility, usefulness and adequacy of the proposed techniques.

We have used Sismic in the classroom for teaching executable behavioural modeling to bachelor students. The tool is also being used successfully by several companies. Based on their feedback, we continue to improve Sismic with new features.

Core Sismic features

Some of the most prominent features of Sismic are the following:

  • An easy textual way to define statecharts with the human-friendly YAML markup language
  • Support for statechart visualization using PlantUML
  • A statechart interpreter with a fully observable and controllable simulation engine
  • The ability to easily integrate (and interact with) regular Python code
  • Support for design by contract for statecharts, by expressing invariants, pre- and postconditions on states and transitions
  • Support for expressing runtime behavioral properties over statecharts
  • Support for behavior-driven development (BDD) using the Gherkin language

Sismic in action

To illustrate how to use Sismic, consider the following example of a microwave controller, whose visual rendering with PlantUML is shown below:

microwave state machine drawn with PlantUML

Here is a code fragment of the YAML description of this statechart:

name: door opened
on entry: send('lamp_on')
on exit: send('lamp_off')
initial: opened without item
states:
 - name: opened without item
   transitions:
     - event: door_closed
       target: closed without item
     - event: item_placed
       target: opened with item
 - name: opened with item
   transitions:
     - event: item_removed
       target: opened without item
     - event: door_closed
       target: closed with item

To execute this statechart directly from with a Python program, it suffices to use the proper API calls to the Sismic interpreter. Here is some example code:

from sismic.io import import_from_yaml
from sismic.interpreter import Interpreter

statechart = import_from_yaml(filepath='microwave.yaml')
interpreter = Interpreter(statechart)

interpreter.queue('door_opened')
interpreter.execute()
interpreter.queue('item_placed', 'door_closed')
assert 'closed with item' in interpreter.configuration

Bertrand Meyer introduced the principles of Design by Contract (DbC) and popularised them through his Eiffel programming language. While DbC has gained some amount of acceptance at the programming level, there is hardly any support for it at the modeling level.

In Sismic, it is possible to define contracts as part of a statechart, expressed in terms of preconditions, postconditions and invariants over states and transitions. At runtime, the statechart interpreter will verify the conditions specified by the contracts. Here’s an example for the microwave statechart, showing how the contract of state “controller” is defined:

contract:
 - always: not sent('heating_on') or active('cooking mode')
 - always: timer >= 0
 - always: 0 <= power <= MAXPOWER

Another key feature of Sismic is its support for monitoring properties at runtime. These properties are expressed as statecharts themselves. Such property statecharts can be used to express functional properties of the intended behaviour in terms of the events that are consumed or sent, or in terms of the states that are entered or exited by a statechart.

When a statechart is executed by Sismic, specific meta-events are created based on the events that are sent or consumed, the states that are entered of exited, etc. When the statechart being monitored is executed, the meta-events are propagated to all associated property statecharts. The property statecharts will look for property violations based on those meta-events, following a fail fast approach: they will report a failure as soon as the monitored behavior leads to a final state of the property statechart.

Here’s an example of a property statechart checking that microwaves are not emitted when the door is open:

Microwave statechart

Finally, Sismic provides support for Behavior-Driven Development (BDD). This agile development technique allows to express scenarios or test cases by domain experts in natural language. This allows designers to focus on the purpose of the model rather than the technical details. Here’s an example of a scenario describing that a microwave lamp must be on while cooking:

Scenario: Lamp is on while cooking
 Given I open the door
 And I place an item in the oven
 And I close the door
 And I press increase timer button 5 times
 When I press start button
 Then lamp turns on

This scenario can be automatically executed and checked by Sismic using the command-line utility sismic-bdd:

sismic-bdd microwave.yaml --features lighting.feature --steps steps.py

Of course, there is no magic involved. The mapping file (steps.py) need to be provided by the developer, but often this mapping is very straightforward.

To appreciate how Sismic works in practice, and to explore more of its internal workings, we invite you to install and play around with it, consult its online documentation, or even read its source code… We hope that this tool can be of use to you, and welcome any feedback!

Comments
  1. Fermigier
  2. Tom Mens

Reply

Your email address will not be published. Required fields are marked *

Pin It on Pinterest

Share This