Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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:

FieldMeaningUnit
agent.quality.mosEstimated Mean Opinion Score1.0 (bad) – 4.5 (excellent)
agent.quality.rttRound-trip timemilliseconds
agent.quality.jitterReceive-side inter-arrival jittermilliseconds
agent.quality.packet_lossReceive-side packet losspercent

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.