Skip to content

Writing Scenarios

vladyslav-kinzerskiy edited this page Jun 15, 2026 · 2 revisions

Writing Scenarios

A scenario is a standard .robot file that imports the one rf-theia library and calls its keywords. Scenarios live in the consuming repo (e.g. perotheia/theia at testing/scenarios/), never inside rf-theia itself.

The one import

*** Settings ***
Library    rf_theia.TheiaTestLibrary

TheiaTestLibrary is the single entry point — a SUITE-scoped library. It is routing only: each keyword forwards to the runtime (rf_theia.runtime), so the keyword surface reads as a stable catalogue while the semantics evolve underneath.

Worked example: state machine reaches RUNNING

*** Settings ***
Library           rf_theia.TheiaTestLibrary

*** Test Cases ***
State machine reaches RUNNING
    Load Rig              central
    Start State Machine   sm
    Emit Event            sm    Ready
    Wait For State        sm    RUNNING    within=5s
    Assert Healthy        sm    within=10s
    Verdict               PASS
    [Teardown]            Tear Down Rig

Real example: supervisor restart cascade (from testing/scenarios/)

This is a live scenario from the consuming repo — it crashes a child under a rest_for_one supervisor and asserts the cascade matches the deployed executor.yaml:

*** Settings ***
Library          rf_theia.TheiaTestLibrary

Suite Setup       Run Keywords
...                   Load Rig             %{RIG_JSON=${CURDIR}/../../fixtures/demo_rig.json}
...                   AND   Load Supervision    %{EXECUTOR_YAML=${CURDIR}/../../fixtures/central_host_executor.yaml}
Suite Teardown    Tear Down Rig

*** Test Cases ***
Rest For One Cascade On Core Sup
    [Tags]    platform-executor    supervision    live    rest-for-one

    Crash Child    crypto

    Assert Restart Order    within=15s
    Assert Healthy          crypto         within=10s
    Assert Healthy          sm             within=15s
    Assert Healthy          network_sup    within=15s

    Assert Restart Within Limit    crypto
    Verdict    pass

With no explicit sequence, Assert Restart Order derives the expected order from the loaded supervision tree and the last Crash Child target. The match is a prefix check — trailing unrelated children are allowed.

Keyword families

The library groups keywords by capability "pair". Use Load Rig / Tear Down Rig once per suite; the rest operate against that suite-scoped runtime.

  • LifecycleLoad Rig, Tear Down Rig
  • Hybrid automata (flows) — drive registry flows on the live supervisor: Start State Machine, Stop State Machine, Emit Event, Wait For State, Verdict
  • Hybrid automata (gen_statem) — drive + observe one statem FC standalone: Start Statem Stack, Stop Statem Stack, Emit Statem Event, Wait For Statem State, Assert Statem Data. Full mechanism: Probe and Isolation Testing.
  • Temporal logic + traceOpen Trace, Close Trace, Assert Eventually, Assert Always, Assert Never
  • Supervision graphLoad Supervision, Get Supervisor Tree, Crash Child, Assert Restart Order, Assert Healthy, Assert Restart Within Limit
  • Distributed componentsRun Component, Stop Component, Component Call, Component Expect
  • Topology / netgraphLoad Topology, Assert Routes To, Assert Reachable, Assert Not Reachable, Assert Netgraph Matches Rig, Get Topology Issues
  • TPT idioms (vendored engine)Create Partition, Add Transition, Set Signal, Apply Ramp, Run Time Engine
  • UtilityT Wait

The legacy T Sup * / T Sig * Phase-1 keywords remain importable as plain methods for backward compatibility, but the role-named keywords above are the supported surface and the ones auto-exposed to Robot.

Keyword reference

Verified against rf_theia/TheiaTestLibrary.py. Time args (within, during) accept s/ms suffixes (e.g. 5s, 250ms) or a bare number (seconds).

Keyword Arguments What it does
Load Rig path, supervisor=localhost:5051 Bind a typed rig context from rig-deps JSON; lazily connect the supervisor gRPC channel.
Tear Down Rig Stop flows/components, close adapters, drop the runtime.
Start State Machine flow_name, **params Instantiate + run a flow from FLOW_REGISTRY (e.g. RestartChild target=sm) on a background thread.
Stop State Machine flow_name Stop a running flow explicitly.
Emit Event event_name, **payload Publish an event onto the runtime bus; flows react via keyed transitions.
Wait For State state_name, within=5s, flow="" Block until a flow enters state_name (reactive, no polling).
Verdict outcome Record a TTCN-3 verdict (error>fail>inconclusive>pass>none); worst wins across the suite.
Start Statem Stack node, gate, tester, art, ready="", within=12s Stage + run the central supervisor (THEIA_TRACE=1), enable STATEM trace on node, attach the event-injecting probe + trace observer.
Stop Statem Stack Tear down the statem probe + observer.
Emit Statem Event event, **fields Cast a gate-interface event (e.g. StartupComplete) at the FC's gate, in order, over the probe's connection.
Wait For Statem State state, within=2s Block until the FSM enters state (via the STATEM trace); returns the decoded transition payload (incl. data).
Assert Statem Data **expected Assert fields of the last observed transition's FSM data (OTP Data term).
Open Trace source Tail a trace feed (file path / file://) and republish each TRC v1 record as a trace_record event.
Close Trace Stop the trace watcher + close the feed.
Assert Eventually expr, within=5s Block until expr is True at least once (sees trace.event(...), service.state(...), flow(...) bindings).
Assert Always expr, during=1s Pass if expr stays True through the window; fail on first False.
Assert Never expr, during=1s Pass if expr stays False through the window; fail on first True.
Load Supervision path Load artheia's emitted executor.yaml; strategy + child order become queryable.
Get Supervisor Tree Return the supervisor's current tree as a name-keyed dict (parent, state, restart_count, uptime_ms, strategy).
Crash Child name Ask the supervisor to terminate name, anchoring the restart-observation window.
Assert Restart Order *expected, crashed="", within=10s Assert children restarted in order; explicit sequence or derived from the tree + last Crash Child. Prefix match.
Assert Healthy name, within=5s Pass if name reaches RUNNING within the window.
Assert Restart Within Limit name Assert name's restart count <= its owning supervisor's max_restarts.
Run Component component_name, on="", as_="" Instantiate a registry component (e.g. SmProber) on a target machine (local or SSH).
Stop Component instance Stop a running component instance.
Component Call instance, method, **kwargs Invoke a method on a running component.
Component Expect instance, method, **kwargs Same as Component Call; reads as an assertion.
Load Topology path Load artheia's emitted netgraph.json; enables static graph queries.
Assert Routes To source, msg, *expected Assert source emits msg to exactly the given destinations (order-insensitive).
Assert Reachable source, target Assert target is in source's transitive outbound closure.
Assert Not Reachable source, target Assert target is NOT reachable from source (isolation invariant).
Assert Netgraph Matches Rig severity=error Cross-check the loaded topology against the loaded rig; fail on errors (or warnings if severity=warning).
Get Topology Issues Return the last cross-check's issue list as strings.
Create Partition name TPT engine: add a partition.
Add Transition source, target, condition TPT engine: add a guarded transition (after 5s, event:X, or a signal comparison).
Set Signal name, value TPT engine: set a signal value.
Apply Ramp signal_name, start, end, duration TPT engine: ramp a signal over a duration.
Run Time Engine initial="", timeout=60s TPT engine: run the partition state machine.
T Wait duration Sleep for the given duration.

Registries

Two registries make new test fixtures one-liners, no keyword wiring:

  • FLOW_REGISTRY — flows callable via Start State Machine <Name>. Ships RestartChild.
  • COMPONENT_REGISTRY — components callable via Run Component <Name>. Ships Echo, Sink, SmProber, SmStub.

Tips

  • Use Suite Setup / Suite Teardown for Load Rig + Tear Down Rig so the supervisor channel and observers live for the whole suite.
  • Tag scenarios needing a live stack with live; run hermetic-only hosts with --exclude live.
  • Pass fixture paths via env with Robot's %{VAR=default} syntax (e.g. %{RIG_JSON=${CURDIR}/../../fixtures/demo_rig.json}).

rf-theia wiki


Install

pip install rf-theia
pip install 'rf-theia[mcp]'

Related wikis

Clone this wiki locally