refactor: update build documentation and switch comparison script to CSV

Update README with comprehensive build/verification instructions and modify the client comparison script to consume CSV output instead of the legacy machine format.
This commit is contained in:
Nils Andreas Svee committed 2026-06-22 16:01:25 +07:00
1 parent 5b40593fda
commit 170f229e7b
2 files changed
+37 -23

No files matched your search

+25 -5
View File
@@ -44,7 +44,7 @@ cargo install --path crates/irtt-cli --features tui
Or run it directly without installing: Or run it directly without installing:
```sh ```sh
cargo run -p irtt-cli -- <server> cargo run -p irtt-cli --bin irtt-cli -- <server>
``` ```
For space-sensitive packaging, such as OpenWrt packages, distributors can ship For space-sensitive packaging, such as OpenWrt packages, distributors can ship
@@ -52,9 +52,29 @@ only `irtt-rs` and symlink or hardlink applet names such as `irtt-cli`,
`irtt-tui`, and future server applet names to it. Applet dispatch is based on `irtt-tui`, and future server applet names to it. Applet dispatch is based on
the invoked binary name. the invoked binary name.
cargo-dist release archives currently bundle all enabled applets for a target. cargo-dist release archives are currently configured with the `full` feature
That is separate from space-sensitive package layouts, which may still ship one set, so target archives bundle the enabled applet binaries: `irtt-rs`,
binary plus applet-name symlinks or hardlinks. `irtt-cli`, and `irtt-tui`. That is separate from space-sensitive package
layouts, which may still ship one dispatcher binary plus applet-name symlinks
or hardlinks. cargo-dist is not currently configured to create those links.
## Build verification
Useful local release/package sanity checks:
```sh
cargo fmt --check
cargo test -p irtt-cli
cargo clippy --workspace --all-targets -- -D warnings
cargo build -p irtt-cli --release
cargo build -p irtt-cli --no-default-features --release
cargo build -p irtt-cli --features tui --release
cargo build -p irtt-cli --all-features --release
```
The no-default-features build only provides the `irtt-rs` dispatcher binary;
the default build provides `irtt-rs` and `irtt-cli`; `tui`, `full`, and
all-features builds also provide `irtt-tui`.
## CLI usage ## CLI usage
@@ -101,7 +121,7 @@ For available options:
```sh ```sh
irtt-cli --help irtt-cli --help
irtt-tui --help irtt-tui --help # when built or installed with the tui feature
``` ```
## Event row output ## Event row output
+12 -18
View File
@@ -9,6 +9,7 @@ the local Rust client output.
from __future__ import annotations from __future__ import annotations
import argparse import argparse
import csv
import datetime as dt import datetime as dt
import json import json
import math import math
@@ -147,7 +148,7 @@ def parse_args() -> argparse.Namespace:
default=DEFAULT_IRTT_RS_COMMAND, default=DEFAULT_IRTT_RS_COMMAND,
help=( help=(
"Command prefix or direct path for the Rust client. Arguments for " "Command prefix or direct path for the Rust client. Arguments for "
"target, duration, interval, and machine output are appended. " "target, duration, interval, and CSV event output are appended. "
f"Default: {DEFAULT_IRTT_RS_COMMAND!r}" f"Default: {DEFAULT_IRTT_RS_COMMAND!r}"
), ),
) )
@@ -386,8 +387,10 @@ def run_case(
case.duration, case.duration,
"--interval", "--interval",
case.interval, case.interval,
"--output", "--format",
"machine", "csv",
"--columns",
"event,seq,effective_rtt_us,raw_rtt_us,adjusted_rtt_us,server_processing_us,client_send_wall_ns",
*args.rust_extra_arg, *args.rust_extra_arg,
] ]
@@ -402,7 +405,7 @@ def run_case(
rust_samples = case_dir / "irtt-rs-rtt-samples.csv" rust_samples = case_dir / "irtt-rs-rtt-samples.csv"
upstream_samples = case_dir / "upstream-rtt-samples.csv" upstream_samples = case_dir / "upstream-rtt-samples.csv"
rust_metrics = parse_rust_machine(case_dir / "irtt-rs.stdout", rust_samples) rust_metrics = parse_rust_csv(case_dir / "irtt-rs.stdout", rust_samples)
upstream_metrics = parse_upstream(case_dir / "upstream.stdout", upstream_json, upstream_samples) upstream_metrics = parse_upstream(case_dir / "upstream.stdout", upstream_json, upstream_samples)
comparison = classify_difference(upstream_metrics, rust_metrics) comparison = classify_difference(upstream_metrics, rust_metrics)
@@ -529,16 +532,7 @@ def wait_process(proc: subprocess.Popen[bytes] | None) -> int:
return proc.wait() return proc.wait()
def parse_kv_line(line: str) -> dict[str, str]: def parse_rust_csv(path: Path, samples_path: Path) -> Metrics:
fields: dict[str, str] = {}
for token in shlex.split(line):
if "=" in token:
key, value = token.split("=", 1)
fields[key] = value
return fields
def parse_rust_machine(path: Path, samples_path: Path) -> Metrics:
metrics = Metrics(source="irtt-rs", samples_path=str(samples_path)) metrics = Metrics(source="irtt-rs", samples_path=str(samples_path))
effective: list[float] = [] effective: list[float] = []
raw: list[float] = [] raw: list[float] = []
@@ -552,11 +546,11 @@ def parse_rust_machine(path: Path, samples_path: Path) -> Metrics:
metrics.parse_notes.append(f"missing {path}") metrics.parse_notes.append(f"missing {path}")
return metrics return metrics
for line in path.read_text(encoding="utf-8", errors="replace").splitlines(): text = path.read_text(encoding="utf-8", errors="replace")
if not line.strip(): for fields in csv.DictReader(line for line in text.splitlines() if line.strip()):
continue
fields = parse_kv_line(line)
event = fields.get("event") event = fields.get("event")
if event is None:
continue
seq = parse_int(fields.get("seq")) seq = parse_int(fields.get("seq"))
if event == "echo_reply": if event == "echo_reply":
if seq is not None: if seq is not None: