The examples in the tutorial show how to build up a suite definition using the python api.
However the suite definition describes the static structure, it not until it is loaded in the server, that we see its dynamic behaviour.
The python api allows the simulation of the dynamic behaviour of the suite, (in the same manner as the server).
Simulation has the following benefits:
- Exercise the suite definition. There is no need for '.ecf' files
- Allows for very easy experimentation.
- Can be done on the client side, no need for server
- Can help in detecting deadlock's
- Will simulate with both 'real' and 'hybrid' clocks
- A year's simulation can be done in a few seconds
The simulation relies on you adding simple verification attributes. (This is similar to c/c++/python asserts)
There are however restrictions. If the definition has large loops due to Repeat date attributes, which run indefinitely, then in this case the simulation will never complete, and will timeout after a years worth of run time.
This can be compensated for by adding start and end clock. Here is an example of a text based suite definition that use a verify attribute, for which we want check our assumption about the dynamic behaviour.
suite year # use real clock otherwise the date wont change clock real 1.1.2017 # define a start date for deterministic simulation endclock 1.1.2018 # When to finish. A endclock is *ONLY* for use with the simulator. family cronFamily task t cron -d 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 -m 1,2,3,4,5,6,7,8,9,10,11,12 10:00 # run every day for a year verify complete:365 # verify that this task completes 365 times endfamily endsuite suite leap_year # use real clock otherwise the date wont change clock real 1.1.2016 # define a start date for deterministic simulation endclock 1.1.2017 # When to finish. A endclock is *ONLY* for use with the simulator. family cronFamily task t cron -d 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 -m 1,2,3,4,5,6,7,8,9,10,11,12 10:00 # run every day for a year verify complete:366 # verify that this task completes 366 times in a leap year endfamily endsuite
This python segment show how to load a text based suite definition(cron.def) and simulate it in python.
import ecflow defs = Defs("cron.def") result = defs.simulate() assert len(result) == 0, "Expected simulation to return without any errors, but found:\n" + result
If the simulation does not complete it will produce two files, which will help in the analysis:
- defs.depth: This file shows a depth first view, of why simulation did not complete.
- defs.flat: This shows a simple flat view, of why simulation did not complete
Both files will show which nodes are holding, and include the state of the holding trigger expressions.
def simulate_deadlock():
This simulation is expected to fail, since we have a deadlock/ race condition
suite dead_lock family family task t1 trigger t2 == complete task t2 trigger t1 == complete endfamily endsuite | siumuate a deadlock. Create definition in python import ecflow defs = ecflow.Defs().add( Suite("dead_lock").add( Family("family").add( Task("t1").add( Trigger(t2 == complete)), Task("t2").add( Trigger(t1 == complete))))) theResult = defs.simulate(); # simulate the definition assert len(theResult) != 0, "Expected simulation to return errors" print theResult |