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:
1 parent
5b40593fda
commit
170f229e7b
2 files changed
+37
-23
No files matched your search
@@ -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
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
Reference in new issue
Block a user