Call quality
Beyond was there audio (Audio testing), ringo-flow can assert on
how good the audio was — the RTP media metrics each agent reports for its call,
grouped under agent.quality:
| Field | Meaning | Unit |
|---|---|---|
agent.quality.mos | Estimated Mean Opinion Score | 1.0 (bad) – 4.5 (excellent) |
agent.quality.rtt | Round-trip time | milliseconds |
agent.quality.jitter | Receive-side inter-arrival jitter | milliseconds |
agent.quality.packet_loss | Receive-side packet loss | percent |
The MOS is an estimate from the simplified ITU-T G.107 E-model, derived from latency, jitter and loss — a single number to gate call quality on.
When the values are available
The metrics come from RTCP reports, which the peers exchange only about
every ~5 seconds. So right after the call is established each field is ()
(not present) — let the call run a few seconds first:
await_until(|| assert(caller.quality.mos).is_present(), "10s");
The values are snapshotted when the call closes, so they survive the hangup — you can read or assert on them after the call, not just during it.
Example
scenario("call quality", |ctx| {
ctx.caller.dial(ctx.callee);
await_until(|| assert(ctx.callee.state).equals(State::Ringing));
ctx.callee.accept();
await_until(|| assert(ctx.caller.state).equals(State::Established));
// Let RTCP accumulate, then wait for the first report:
await_until(|| assert(ctx.caller.quality.mos).is_present(), "10s");
let q = ctx.caller.quality;
log(`caller → MOS ${q.mos} · RTT ${q.rtt}ms · jitter ${q.jitter}ms · loss ${q.packet_loss}%`);
ctx.caller.hangup();
await_until(|| assert(ctx.caller.state).equals(State::Idle));
// The snapshot survives the hangup — assert on the final values:
assert(ctx.caller.quality.mos).at_least(4.0);
assert(ctx.caller.quality.packet_loss).at_most(1.0);
assert(ctx.caller.quality.rtt).at_most(150);
});
The values are raw floats (e.g.
MOS 4.236…). To shorten a log line, round in Rhai:let mos = (caller.quality.mos * 100.0).round() / 100.0;.
Exporting metrics
To record these values without writing assertions — e.g. for trend monitoring —
run with --metrics. ringo-flow then emits a per-agent
metric event (MOS, jitter, loss, RTT + registered) at each scenario’s end,
which a machine consumer can scrape from the --json stream.