Skip to content

Add a scenario ​

A scenario is one JSON file. You write the conversation once, capture the C server's answers, commit the normalised trace, and from then on CI checks the Rust server gives the same answers.

1. Write the file ​

parity/scenarios/my-videoroom.json:

json
{
  "scenario": "my-videoroom",
  "description": "VideoRoom exists and list on the demo room, and the error for a room that is not there",
  "steps": [
    {"step": "create", "request": {"janus": "create", "transaction": "x"},
     "expect": "success", "save": {"session": "data.id"}},
    {"step": "attach", "path": "/janus/{session}",
     "request": {"janus": "attach", "plugin": "janus.plugin.videoroom", "transaction": "y"},
     "expect": "success", "save": {"handle": "data.id"}},
    {"step": "exists", "path": "/janus/{session}/{handle}",
     "request": {"janus": "message", "transaction": "z", "body": {"request": "exists", "room": 1234}},
     "expect": "success"},
    {"step": "missing", "path": "/janus/{session}/{handle}",
     "request": {"janus": "message", "transaction": "w", "body": {"request": "exists", "room": 9999}},
     "expect": "success"}
  ]
}
  • scenario equals the file name without .json.
  • A step is a request (path defaults to /janus; api can be admin or ws) or poll: N, which collects N events with long polls and records them as <step>-1 to <step>-N.
  • expect is the janus value of the reply (or a list). Plugin errors come back as success, so the proof of those is in the trace, not in expect.
  • save keeps a value from a reply ({"var": "dotted.path"}), and {var} in a later path or in a string that is exactly {var} is replaced by it.
  • setup edits a sample config before the server starts: {"file": "janus.jcfg", "find": "#broadcast = true", "replace": "broadcast = true"}. The text must be in the file, or the run stops with a message.
  • @file:sdp/offer-audio-video.sdp in a request string is replaced with that SDP file, with CRLF line ends. Reuse the Chrome, Firefox and Safari offers in parity/scenarios/sdp/.
  • Also available: wait_ms, background and await for overlapping requests, raw_body, headers, record_headers, any_path, allow_drop for HTTP edge cases. The full format is in parity/scenarios/README.md.

Use ids you choose ("id" of a publisher, a fixed room) instead of letting the server draw them, so that normalisation does not have to guess.

2. Capture the C answers ​

Needs Docker and the janus-c:bc0de3b3 image (build it):

sh
cargo run -p xtask -- capture --scenario my-videoroom

It starts a container janus-cap-my-videoroom, runs the steps, and writes parity/traces/my-videoroom/raw.json (every exchange as it came, git-ignored) and normalised.json (committed). Capture the same scenario twice: the two normalised.json files must be byte-identical. If they are not, something the normaliser does not know changes between runs. Fix the scenario to avoid it, or teach xtask/src/capture/normalise.rs and its copy parity/src/numbered.rs about it.

3. Replay on the Rust server ​

sh
cargo run -p xtask -- parity-run --scenario my-videoroom

A pass prints PASS my-videoroom (N exchanges). A failure prints the first differing exchange as a diff: that diff is your to-do list.

4. Record that it is verified ​

Add the scenario to the harness.planned list of parity/status.json with "state": "verified" once it passes, update the notes of the component it covers, then run:

sh
cargo run -p xtask -- progress
cargo run -p xtask -- progress --check

The README bar for parity verified counts those entries.

Before you capture

Run the scenario's requests by hand against the C container first (docker run --rm -p 8088:8088 janus-c:bc0de3b3), so you know the replies you are about to pin make sense.

GPL-3.0-or-later, like the Janus gateway it ports.