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

Results, reports and replay

A run writes a directory. Its heart is result.json: everything the run measured, with the provenance that lets a reader judge it.

What is in a result

PartWhat it tells
provenanceThe version of netscenario, the time, the backend and the tc it used, the kernel, the processor, and the precision of the timers of the machine when the run began.
seedThe seed, whether the run drew it, and whether the same seed gives the same lost packets. If not, it says why.
workloadsFor each stream: the counts, the delay percentiles, the jitter, the loss runs, the reordering, the throughput and the series over time.
eventsEach step of the timeline as it was done: when it was due, when it was done, and for a step at a packet, which packet.
expectThe verdict of the checks of the file.

The numbers are in SI units in the Python layer (seconds, bits per second, ratios from 0 to 1). In result.json times are nanoseconds. Results reference defines every field.

In Python

The scenario of the first run:

# The smallest scenario: two nodes, one link without any impairment, one stream.
version: 0
name: minimal
duration: 5s
topology:
  nodes: [client, server]
  links:
    - id: access
      between: [client, server]
workloads:
  - id: media
    kind: udp-cbr
    from: client
    to: server
    rate: 1mbit
    packet-size: 1200b

Then:

import netscenario as ns

result = ns.run(ns.Scenario.load("minimal.yaml"), packets=True)
media = result["media"]

print(f"lost {media.lost} of {media.sent}")
print(f"p99 delay {media.delay.p99 * 1000:.2f} ms")
print("timers:", result.provenance.timers.sleeps[0].p99)

# One row for each packet, as a table that becomes a pandas or polars frame
packets = media.packets_table()
print(len(packets), packets.names)

The per-packet records, the series over time and the steps of the timeline are tables of plain Python values. to_pandas() and to_polars() turn them into frames; install netscenario[pandas] or netscenario[polars] for that. Nothing is imported unless you call it.

Reports

netscenario report <dir> turns a result directory into a report. It reads the files of the directory and nothing else, so a report can be made on another machine, later.

netscenario report out --format md       # Markdown, for the summary of a CI job
netscenario report out --format junit    # JUnit XML, for the test report of a CI
netscenario report out --format html     # one HTML file with the plots

The Markdown report of a run begins with where and with what it was made, then the checks of the file, then a table of the workloads. The HTML is one file, readable offline.

Replay

scenario.json in the directory is the scenario as it ran, with the files it read and the changes made from code. replay runs a recorded run again and compares the lost packets:

netscenario replay out

If the loss repeats from the seed, a replay loses exactly the same packets and the exit code is 0; if the packets differ, the exit code is 1 and the comparison says which. A run whose loss was not promised to repeat (a machine whose tc cannot apply a seed, an outage, a change made by a test) says so in seed.not_reproducible_because, and the replay compares what it can.

Sets of runs

--repetitions n runs a scenario n times with derived seeds and writes runset.json with an interval for each metric. A claim about a set (expect with repetitions) is judged on that interval: Statistics and checks.