ipyrf 2.0.0__tar.gz → 2.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ipyrf-2.0.0/src/ipyrf.egg-info → ipyrf-2.1.0}/PKG-INFO +131 -21
- {ipyrf-2.0.0 → ipyrf-2.1.0}/README.rst +127 -20
- {ipyrf-2.0.0 → ipyrf-2.1.0}/pyproject.toml +6 -2
- {ipyrf-2.0.0 → ipyrf-2.1.0}/src/ipyrf/cli.py +169 -8
- ipyrf-2.1.0/src/ipyrf/clock_offset.py +317 -0
- {ipyrf-2.0.0 → ipyrf-2.1.0}/src/ipyrf/controllers.py +2 -10
- {ipyrf-2.0.0 → ipyrf-2.1.0}/src/ipyrf/interactive.py +2 -10
- {ipyrf-2.0.0 → ipyrf-2.1.0}/src/ipyrf/logger.py +3 -3
- {ipyrf-2.0.0 → ipyrf-2.1.0}/src/ipyrf/pacer.py +6 -3
- ipyrf-2.1.0/src/ipyrf/recorder.py +190 -0
- ipyrf-2.1.0/src/ipyrf/report/__init__.py +15 -0
- ipyrf-2.1.0/src/ipyrf/report/__main__.py +4 -0
- ipyrf-2.1.0/src/ipyrf/report/analysis.py +579 -0
- ipyrf-2.1.0/src/ipyrf/report/cli.py +143 -0
- ipyrf-2.1.0/src/ipyrf/report/data.py +209 -0
- ipyrf-2.1.0/src/ipyrf/report/export.py +41 -0
- ipyrf-2.1.0/src/ipyrf/report/html.py +777 -0
- ipyrf-2.1.0/src/ipyrf/report/loader.py +215 -0
- ipyrf-2.1.0/src/ipyrf/report/pipeline.py +47 -0
- ipyrf-2.1.0/src/ipyrf/report/plots.py +593 -0
- {ipyrf-2.0.0 → ipyrf-2.1.0}/src/ipyrf/tcp.py +104 -43
- {ipyrf-2.0.0 → ipyrf-2.1.0}/src/ipyrf/test.py +20 -4
- {ipyrf-2.0.0 → ipyrf-2.1.0}/src/ipyrf/udp.py +42 -11
- {ipyrf-2.0.0 → ipyrf-2.1.0}/src/ipyrf/utils.py +35 -11
- {ipyrf-2.0.0 → ipyrf-2.1.0/src/ipyrf.egg-info}/PKG-INFO +131 -21
- {ipyrf-2.0.0 → ipyrf-2.1.0}/src/ipyrf.egg-info/SOURCES.txt +17 -2
- {ipyrf-2.0.0 → ipyrf-2.1.0}/src/ipyrf.egg-info/entry_points.txt +1 -0
- ipyrf-2.1.0/src/ipyrf.egg-info/requires.txt +8 -0
- ipyrf-2.1.0/test/test_clock_offset.py +290 -0
- {ipyrf-2.0.0 → ipyrf-2.1.0}/test/test_ipyrf.py +45 -15
- ipyrf-2.1.0/test/test_pacer.py +22 -0
- ipyrf-2.1.0/test/test_recorder.py +338 -0
- ipyrf-2.1.0/test/test_report.py +414 -0
- ipyrf-2.1.0/test/test_utils.py +25 -0
- ipyrf-2.0.0/src/ipyrf/packet_recorder.py +0 -115
- ipyrf-2.0.0/src/ipyrf.egg-info/requires.txt +0 -4
- ipyrf-2.0.0/test/test_packet_recorder.py +0 -262
- {ipyrf-2.0.0 → ipyrf-2.1.0}/LICENSE +0 -0
- {ipyrf-2.0.0 → ipyrf-2.1.0}/setup.cfg +0 -0
- {ipyrf-2.0.0 → ipyrf-2.1.0}/src/ipyrf/__init__.py +0 -0
- {ipyrf-2.0.0 → ipyrf-2.1.0}/src/ipyrf/__main__.py +0 -0
- {ipyrf-2.0.0 → ipyrf-2.1.0}/src/ipyrf/handshake.py +0 -0
- {ipyrf-2.0.0 → ipyrf-2.1.0}/src/ipyrf/latency.py +0 -0
- {ipyrf-2.0.0 → ipyrf-2.1.0}/src/ipyrf/traffic_pattern.py +0 -0
- {ipyrf-2.0.0 → ipyrf-2.1.0}/src/ipyrf/video_trace.py +0 -0
- {ipyrf-2.0.0 → ipyrf-2.1.0}/src/ipyrf.egg-info/dependency_links.txt +0 -0
- {ipyrf-2.0.0 → ipyrf-2.1.0}/src/ipyrf.egg-info/top_level.txt +0 -0
- {ipyrf-2.0.0 → ipyrf-2.1.0}/test/test_bind_to_device.py +0 -0
- {ipyrf-2.0.0 → ipyrf-2.1.0}/test/test_controllers.py +0 -0
- {ipyrf-2.0.0 → ipyrf-2.1.0}/test/test_handshake.py +0 -0
- {ipyrf-2.0.0 → ipyrf-2.1.0}/test/test_tcp_framing.py +0 -0
- {ipyrf-2.0.0 → ipyrf-2.1.0}/test/test_traffic_pattern.py +0 -0
- {ipyrf-2.0.0 → ipyrf-2.1.0}/test/test_video_trace.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ipyrf
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.1.0
|
|
4
4
|
Summary: A tiny iperf3-like tool with JSON output (TCP/UDP)
|
|
5
5
|
Author: Steinwurf ApS
|
|
6
6
|
License: MIT License
|
|
@@ -40,9 +40,12 @@ Classifier: Topic :: System :: Benchmark
|
|
|
40
40
|
Requires-Python: >=3.8
|
|
41
41
|
Description-Content-Type: text/x-rst
|
|
42
42
|
License-File: LICENSE
|
|
43
|
+
Requires-Dist: plotly>=5.18
|
|
43
44
|
Provides-Extra: test
|
|
44
45
|
Requires-Dist: pytest>=7.0; extra == "test"
|
|
45
46
|
Requires-Dist: pytest-cov>=4.0; extra == "test"
|
|
47
|
+
Provides-Extra: report-export
|
|
48
|
+
Requires-Dist: kaleido>=0.2; extra == "report-export"
|
|
46
49
|
Dynamic: license-file
|
|
47
50
|
|
|
48
51
|
ipyrf
|
|
@@ -56,9 +59,11 @@ Features
|
|
|
56
59
|
- JSON or human-readable output
|
|
57
60
|
- Optional bandwidth capping (TCP/UDP)
|
|
58
61
|
- UDP packet loss estimation
|
|
59
|
-
- Optional
|
|
62
|
+
- Optional receive-side recording of UDP datagrams and TCP framed records
|
|
63
|
+
- Interactive HTML reports from ``--record`` CSVs (``ipyrf-report``)
|
|
60
64
|
- Linux TCP congestion control selection (if available)
|
|
61
65
|
- Client ``--bind-dev`` to transmit via a specific network interface (Linux)
|
|
66
|
+
- Clock-offset measurement to a remote host over SSH (``ipyrf offset``)
|
|
62
67
|
|
|
63
68
|
Installation
|
|
64
69
|
------------
|
|
@@ -125,7 +130,7 @@ The project includes a comprehensive test suite using pytest:
|
|
|
125
130
|
Usage
|
|
126
131
|
-----
|
|
127
132
|
|
|
128
|
-
The package installs
|
|
133
|
+
The package installs console scripts named ``ipyrf`` and ``ipyrf-report``.
|
|
129
134
|
|
|
130
135
|
Quick examples
|
|
131
136
|
~~~~~~~~~~~~~~
|
|
@@ -135,6 +140,7 @@ TCP server:
|
|
|
135
140
|
.. code-block:: bash
|
|
136
141
|
|
|
137
142
|
ipyrf tcp server 0.0.0.0 --port 12345
|
|
143
|
+
ipyrf tcp server 0.0.0.0 --port 12345 --record records.csv
|
|
138
144
|
ipyrf tcp server 0.0.0.0 --port 12345 --trace-dir /var/traces
|
|
139
145
|
|
|
140
146
|
TCP client:
|
|
@@ -154,7 +160,7 @@ UDP server:
|
|
|
154
160
|
.. code-block:: bash
|
|
155
161
|
|
|
156
162
|
ipyrf udp server 0.0.0.0 --port 12345
|
|
157
|
-
ipyrf udp server 0.0.0.0 --port 12345 --
|
|
163
|
+
ipyrf udp server 0.0.0.0 --port 12345 --record records.csv
|
|
158
164
|
ipyrf udp server 0.0.0.0 --port 12345 --trace-dir /var/traces
|
|
159
165
|
|
|
160
166
|
UDP client (with bandwidth cap and optional payload size):
|
|
@@ -169,6 +175,13 @@ UDP client (with bandwidth cap and optional payload size):
|
|
|
169
175
|
ipyrf udp client 127.0.0.1 --port 12345 --bandwidth 50M --time 5 --reverse
|
|
170
176
|
ipyrf udp client 127.0.0.1 --port 12345 --traffic-pattern trace.json --reverse
|
|
171
177
|
|
|
178
|
+
Clock offset (this host vs a remote SSH machine):
|
|
179
|
+
|
|
180
|
+
.. code-block:: bash
|
|
181
|
+
|
|
182
|
+
ipyrf offset user@rasp1
|
|
183
|
+
ipyrf offset user@rasp1 --json
|
|
184
|
+
|
|
172
185
|
Reverse mode
|
|
173
186
|
------------
|
|
174
187
|
|
|
@@ -320,12 +333,16 @@ Top-level structure:
|
|
|
320
333
|
|
|
321
334
|
ipyrf [tcp|udp] [server|client] [OPTIONS]
|
|
322
335
|
ipyrf generate video -o FILE [OPTIONS]
|
|
336
|
+
ipyrf offset HOST [OPTIONS]
|
|
337
|
+
ipyrf-report RECORD [OPTIONS]
|
|
323
338
|
|
|
324
339
|
Common options (both protocols, both roles):
|
|
325
340
|
|
|
326
341
|
- ``--port``: Port (default 5201)
|
|
327
342
|
- ``--logfile``: Redirect output to a file
|
|
328
343
|
- ``--json_log``: Emit logs in JSON (newline-delimited)
|
|
344
|
+
- ``--record PATH``: Write received records to a CSV file after the test
|
|
345
|
+
(UDP datagrams or TCP framed records). On a client, requires ``--reverse``
|
|
329
346
|
|
|
330
347
|
TCP-specific options:
|
|
331
348
|
|
|
@@ -361,7 +378,6 @@ UDP-specific options:
|
|
|
361
378
|
is sent; the server must have the same file
|
|
362
379
|
- ``--loops N``: Replay ``--traffic-pattern`` N times (default 1)
|
|
363
380
|
- ``-l/--length``: UDP payload length (default 1200)
|
|
364
|
-
- ``--packet-record PATH``: UDP server: write received packet traces to a CSV file after the test
|
|
365
381
|
- ``--inactivity-timeout SECONDS``: UDP server: exit after this many seconds
|
|
366
382
|
without receiving packets (default 2.0)
|
|
367
383
|
- ``--trace-dir DIR``: UDP server: directory of traffic-pattern files for
|
|
@@ -384,33 +400,127 @@ Generate options:
|
|
|
384
400
|
- ``--duration``: Synthetic length in seconds (default 10), or optional
|
|
385
401
|
truncate when importing from ffprobe
|
|
386
402
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
403
|
+
Offset options:
|
|
404
|
+
|
|
405
|
+
- ``offset HOST``: Measure clock offset to ``HOST`` over SSH
|
|
406
|
+
- ``--samples N``: Number of round-trip samples (default 30)
|
|
407
|
+
- ``--interval SECONDS``: Delay between samples (default 0.2)
|
|
408
|
+
- ``--json``: Write a JSON summary to stdout
|
|
409
|
+
- ``--python CMD``: Python interpreter on the remote host (default
|
|
410
|
+
``python3``)
|
|
411
|
+
- ``--ssh-arg ARG``: Extra argument forwarded to ``ssh`` (repeatable)
|
|
412
|
+
|
|
413
|
+
Report options (``ipyrf-report``):
|
|
414
|
+
|
|
415
|
+
- ``RECORD``: Record CSV from ``--record``
|
|
416
|
+
- ``-o/--output FILE``: HTML output path (default: ``RECORD`` with ``.html``)
|
|
417
|
+
- ``--traffic-pattern FILE``: Traffic-pattern JSON used during the test
|
|
418
|
+
- ``--json FILE``: Also write analysis results as JSON
|
|
419
|
+
- ``--png [DIR]`` / ``--svg [DIR]``: Export static plots (requires kaleido)
|
|
420
|
+
- ``--bin-ms MS``: Time-series bin size in milliseconds (default: auto)
|
|
421
|
+
- ``--title TITLE``: Report title
|
|
422
|
+
- ``--clock-offset MS``: Add this many milliseconds to one-way latency
|
|
423
|
+
(value from ``ipyrf offset`` run on the receiving host against the
|
|
424
|
+
sender). The HTML report can also change this after generation
|
|
425
|
+
|
|
426
|
+
Receive recording
|
|
427
|
+
-----------------
|
|
428
|
+
|
|
429
|
+
Pass ``--record PATH`` on the receiving side (a server, or a client with
|
|
430
|
+
``--reverse``) to write one CSV row per received UDP datagram or complete
|
|
431
|
+
TCP framed record (sequence, sender timestamp, receiver timestamp, size,
|
|
432
|
+
and traffic-pattern ``event_id``). UDP uses the sender sequence number so
|
|
433
|
+
loss and reordering stay visible. TCP assigns sequence in receive order
|
|
434
|
+
(1, 2, 3, …) because the stream has no packet sequence. Records are packed
|
|
435
|
+
into fixed-size in-memory chunks during the test so the receive path stays
|
|
436
|
+
free of CSV I/O. Chunks are allocated before the test starts (about 20 s of
|
|
437
|
+
1 Gbit/s traffic by default) so rotation does not stall the receive loop.
|
|
438
|
+
When the test ends, the CSV file is written to ``PATH``. It starts with a
|
|
439
|
+
``# ipyrf-record 1`` magic line and a ``# { ... }`` JSON comment describing
|
|
440
|
+
the run (protocol, sequence kind, addresses, optional traffic pattern),
|
|
441
|
+
then the header row and data (columns ``sequence``, ``size_bytes``,
|
|
442
|
+
``transmitted_ns``, ``received_ns``, ``event_id``).
|
|
443
|
+
One-way latency in nanoseconds is ``received_ns - transmitted_ns``.
|
|
444
|
+
That difference includes any clock offset between sender and receiver;
|
|
445
|
+
use ``ipyrf offset`` to measure it. ``event_id`` is ``0`` unless the
|
|
446
|
+
sender used ``--traffic-pattern``.
|
|
447
|
+
``ipyrf-report`` reads that metadata to label the run and to omit TCP
|
|
448
|
+
loss/reorder charts. Pass ``--traffic-pattern`` to override an embedded
|
|
449
|
+
pattern. Spreadsheet tools treat the ``#`` lines as extra rows; skip them
|
|
450
|
+
or use ``ipyrf-report``.
|
|
400
451
|
|
|
401
452
|
Quick local test (two terminals):
|
|
402
453
|
|
|
403
454
|
.. code-block:: bash
|
|
404
455
|
|
|
405
456
|
# Terminal 1 — server with recording
|
|
406
|
-
ipyrf udp server 0.0.0.0 --port 12345 --
|
|
457
|
+
ipyrf udp server 0.0.0.0 --port 12345 --record records.csv
|
|
458
|
+
# or: ipyrf tcp server 0.0.0.0 --port 12345 --record records.csv
|
|
407
459
|
|
|
408
460
|
# Terminal 2 — short paced client
|
|
409
461
|
ipyrf udp client 127.0.0.1 --port 12345 --bandwidth 50M --time 2 -l 1200
|
|
462
|
+
# or: ipyrf tcp client 127.0.0.1 --port 12345 --bandwidth 50M --time 2
|
|
410
463
|
|
|
411
|
-
When the client finishes, the server exits and ``
|
|
464
|
+
When the client finishes, the server exits and ``records.csv`` contains the
|
|
412
465
|
trace. Use ``--enable-latency`` on the client if you also want latency
|
|
413
|
-
stats in the server summary.
|
|
466
|
+
stats in the server summary. Turn the CSV into an interactive HTML report
|
|
467
|
+
with ``ipyrf-report`` (see below).
|
|
468
|
+
|
|
469
|
+
Reports (ipyrf-report)
|
|
470
|
+
----------------------
|
|
471
|
+
|
|
472
|
+
``ipyrf-report`` reads a ``--record`` CSV (including the JSON metadata
|
|
473
|
+
comment) and writes one self-contained interactive HTML file (Plotly.js is
|
|
474
|
+
embedded, so the file works offline). Pass ``--traffic-pattern`` to override
|
|
475
|
+
a pattern embedded in the record metadata; otherwise the report uses the
|
|
476
|
+
embedded pattern when present. Pass ``--clock-offset MS`` to add that many
|
|
477
|
+
milliseconds to one-way latency (the HTML header also has a clock-offset
|
|
478
|
+
field you can edit later without regenerating).
|
|
479
|
+
|
|
480
|
+
The report is laid out like a performance trace: KPI overview at the top,
|
|
481
|
+
then throughput, latency (p50 / p95 / p99), loss and sequence / reordering
|
|
482
|
+
when the recording is UDP, send vs receive spacing, and latency
|
|
483
|
+
distribution / ECDF.
|
|
484
|
+
|
|
485
|
+
.. code-block:: bash
|
|
486
|
+
|
|
487
|
+
ipyrf-report records.csv
|
|
488
|
+
ipyrf-report records.csv -o report.html --traffic-pattern trace.json
|
|
489
|
+
ipyrf-report records.csv --json report.json --bin-ms 10
|
|
490
|
+
ipyrf-report records.csv --png --svg
|
|
491
|
+
ipyrf-report records.csv --clock-offset 1.23
|
|
492
|
+
|
|
493
|
+
``-o`` defaults to the record path with a ``.html`` suffix. ``--png`` and
|
|
494
|
+
``--svg`` write individual plots next to the HTML (or to a directory you
|
|
495
|
+
pass); they require the optional ``kaleido`` extra:
|
|
496
|
+
|
|
497
|
+
.. code-block:: bash
|
|
498
|
+
|
|
499
|
+
python3 -m pip install 'ipyrf[report-export]'
|
|
500
|
+
|
|
501
|
+
Clock offset
|
|
502
|
+
------------
|
|
503
|
+
|
|
504
|
+
``ipyrf offset HOST`` measures the wall-clock offset between this machine
|
|
505
|
+
and a remote SSH host. It does not change either clock.
|
|
506
|
+
|
|
507
|
+
This is useful when comparing ``transmitted_ns`` and ``received_ns`` in a
|
|
508
|
+
``--record`` CSV from a two-host test. One-way latency is
|
|
509
|
+
``received_ns - transmitted_ns``. If you run ``ipyrf offset`` on the
|
|
510
|
+
receiving host against the sender, pass that value to
|
|
511
|
+
``ipyrf-report --clock-offset`` (or type it into the HTML report). That
|
|
512
|
+
adds the offset so latency is in the receiver's time base. If this host
|
|
513
|
+
sent and the remote recorded, negate the printed offset first.
|
|
514
|
+
|
|
515
|
+
The remote host needs ``python3`` (or pass ``--python``). SSH uses your
|
|
516
|
+
normal configuration and keys.
|
|
517
|
+
|
|
518
|
+
.. code-block:: bash
|
|
519
|
+
|
|
520
|
+
ipyrf offset user@rasp1
|
|
521
|
+
ipyrf offset user@rasp1 --samples 50 --interval 0.1
|
|
522
|
+
ipyrf offset rasp1 --json
|
|
523
|
+
ipyrf offset rasp1 --ssh-arg=-p --ssh-arg=2222
|
|
414
524
|
|
|
415
525
|
JSON logging
|
|
416
526
|
------------
|
|
@@ -9,9 +9,11 @@ Features
|
|
|
9
9
|
- JSON or human-readable output
|
|
10
10
|
- Optional bandwidth capping (TCP/UDP)
|
|
11
11
|
- UDP packet loss estimation
|
|
12
|
-
- Optional
|
|
12
|
+
- Optional receive-side recording of UDP datagrams and TCP framed records
|
|
13
|
+
- Interactive HTML reports from ``--record`` CSVs (``ipyrf-report``)
|
|
13
14
|
- Linux TCP congestion control selection (if available)
|
|
14
15
|
- Client ``--bind-dev`` to transmit via a specific network interface (Linux)
|
|
16
|
+
- Clock-offset measurement to a remote host over SSH (``ipyrf offset``)
|
|
15
17
|
|
|
16
18
|
Installation
|
|
17
19
|
------------
|
|
@@ -78,7 +80,7 @@ The project includes a comprehensive test suite using pytest:
|
|
|
78
80
|
Usage
|
|
79
81
|
-----
|
|
80
82
|
|
|
81
|
-
The package installs
|
|
83
|
+
The package installs console scripts named ``ipyrf`` and ``ipyrf-report``.
|
|
82
84
|
|
|
83
85
|
Quick examples
|
|
84
86
|
~~~~~~~~~~~~~~
|
|
@@ -88,6 +90,7 @@ TCP server:
|
|
|
88
90
|
.. code-block:: bash
|
|
89
91
|
|
|
90
92
|
ipyrf tcp server 0.0.0.0 --port 12345
|
|
93
|
+
ipyrf tcp server 0.0.0.0 --port 12345 --record records.csv
|
|
91
94
|
ipyrf tcp server 0.0.0.0 --port 12345 --trace-dir /var/traces
|
|
92
95
|
|
|
93
96
|
TCP client:
|
|
@@ -107,7 +110,7 @@ UDP server:
|
|
|
107
110
|
.. code-block:: bash
|
|
108
111
|
|
|
109
112
|
ipyrf udp server 0.0.0.0 --port 12345
|
|
110
|
-
ipyrf udp server 0.0.0.0 --port 12345 --
|
|
113
|
+
ipyrf udp server 0.0.0.0 --port 12345 --record records.csv
|
|
111
114
|
ipyrf udp server 0.0.0.0 --port 12345 --trace-dir /var/traces
|
|
112
115
|
|
|
113
116
|
UDP client (with bandwidth cap and optional payload size):
|
|
@@ -122,6 +125,13 @@ UDP client (with bandwidth cap and optional payload size):
|
|
|
122
125
|
ipyrf udp client 127.0.0.1 --port 12345 --bandwidth 50M --time 5 --reverse
|
|
123
126
|
ipyrf udp client 127.0.0.1 --port 12345 --traffic-pattern trace.json --reverse
|
|
124
127
|
|
|
128
|
+
Clock offset (this host vs a remote SSH machine):
|
|
129
|
+
|
|
130
|
+
.. code-block:: bash
|
|
131
|
+
|
|
132
|
+
ipyrf offset user@rasp1
|
|
133
|
+
ipyrf offset user@rasp1 --json
|
|
134
|
+
|
|
125
135
|
Reverse mode
|
|
126
136
|
------------
|
|
127
137
|
|
|
@@ -273,12 +283,16 @@ Top-level structure:
|
|
|
273
283
|
|
|
274
284
|
ipyrf [tcp|udp] [server|client] [OPTIONS]
|
|
275
285
|
ipyrf generate video -o FILE [OPTIONS]
|
|
286
|
+
ipyrf offset HOST [OPTIONS]
|
|
287
|
+
ipyrf-report RECORD [OPTIONS]
|
|
276
288
|
|
|
277
289
|
Common options (both protocols, both roles):
|
|
278
290
|
|
|
279
291
|
- ``--port``: Port (default 5201)
|
|
280
292
|
- ``--logfile``: Redirect output to a file
|
|
281
293
|
- ``--json_log``: Emit logs in JSON (newline-delimited)
|
|
294
|
+
- ``--record PATH``: Write received records to a CSV file after the test
|
|
295
|
+
(UDP datagrams or TCP framed records). On a client, requires ``--reverse``
|
|
282
296
|
|
|
283
297
|
TCP-specific options:
|
|
284
298
|
|
|
@@ -314,7 +328,6 @@ UDP-specific options:
|
|
|
314
328
|
is sent; the server must have the same file
|
|
315
329
|
- ``--loops N``: Replay ``--traffic-pattern`` N times (default 1)
|
|
316
330
|
- ``-l/--length``: UDP payload length (default 1200)
|
|
317
|
-
- ``--packet-record PATH``: UDP server: write received packet traces to a CSV file after the test
|
|
318
331
|
- ``--inactivity-timeout SECONDS``: UDP server: exit after this many seconds
|
|
319
332
|
without receiving packets (default 2.0)
|
|
320
333
|
- ``--trace-dir DIR``: UDP server: directory of traffic-pattern files for
|
|
@@ -337,33 +350,127 @@ Generate options:
|
|
|
337
350
|
- ``--duration``: Synthetic length in seconds (default 10), or optional
|
|
338
351
|
truncate when importing from ffprobe
|
|
339
352
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
+
Offset options:
|
|
354
|
+
|
|
355
|
+
- ``offset HOST``: Measure clock offset to ``HOST`` over SSH
|
|
356
|
+
- ``--samples N``: Number of round-trip samples (default 30)
|
|
357
|
+
- ``--interval SECONDS``: Delay between samples (default 0.2)
|
|
358
|
+
- ``--json``: Write a JSON summary to stdout
|
|
359
|
+
- ``--python CMD``: Python interpreter on the remote host (default
|
|
360
|
+
``python3``)
|
|
361
|
+
- ``--ssh-arg ARG``: Extra argument forwarded to ``ssh`` (repeatable)
|
|
362
|
+
|
|
363
|
+
Report options (``ipyrf-report``):
|
|
364
|
+
|
|
365
|
+
- ``RECORD``: Record CSV from ``--record``
|
|
366
|
+
- ``-o/--output FILE``: HTML output path (default: ``RECORD`` with ``.html``)
|
|
367
|
+
- ``--traffic-pattern FILE``: Traffic-pattern JSON used during the test
|
|
368
|
+
- ``--json FILE``: Also write analysis results as JSON
|
|
369
|
+
- ``--png [DIR]`` / ``--svg [DIR]``: Export static plots (requires kaleido)
|
|
370
|
+
- ``--bin-ms MS``: Time-series bin size in milliseconds (default: auto)
|
|
371
|
+
- ``--title TITLE``: Report title
|
|
372
|
+
- ``--clock-offset MS``: Add this many milliseconds to one-way latency
|
|
373
|
+
(value from ``ipyrf offset`` run on the receiving host against the
|
|
374
|
+
sender). The HTML report can also change this after generation
|
|
375
|
+
|
|
376
|
+
Receive recording
|
|
377
|
+
-----------------
|
|
378
|
+
|
|
379
|
+
Pass ``--record PATH`` on the receiving side (a server, or a client with
|
|
380
|
+
``--reverse``) to write one CSV row per received UDP datagram or complete
|
|
381
|
+
TCP framed record (sequence, sender timestamp, receiver timestamp, size,
|
|
382
|
+
and traffic-pattern ``event_id``). UDP uses the sender sequence number so
|
|
383
|
+
loss and reordering stay visible. TCP assigns sequence in receive order
|
|
384
|
+
(1, 2, 3, …) because the stream has no packet sequence. Records are packed
|
|
385
|
+
into fixed-size in-memory chunks during the test so the receive path stays
|
|
386
|
+
free of CSV I/O. Chunks are allocated before the test starts (about 20 s of
|
|
387
|
+
1 Gbit/s traffic by default) so rotation does not stall the receive loop.
|
|
388
|
+
When the test ends, the CSV file is written to ``PATH``. It starts with a
|
|
389
|
+
``# ipyrf-record 1`` magic line and a ``# { ... }`` JSON comment describing
|
|
390
|
+
the run (protocol, sequence kind, addresses, optional traffic pattern),
|
|
391
|
+
then the header row and data (columns ``sequence``, ``size_bytes``,
|
|
392
|
+
``transmitted_ns``, ``received_ns``, ``event_id``).
|
|
393
|
+
One-way latency in nanoseconds is ``received_ns - transmitted_ns``.
|
|
394
|
+
That difference includes any clock offset between sender and receiver;
|
|
395
|
+
use ``ipyrf offset`` to measure it. ``event_id`` is ``0`` unless the
|
|
396
|
+
sender used ``--traffic-pattern``.
|
|
397
|
+
``ipyrf-report`` reads that metadata to label the run and to omit TCP
|
|
398
|
+
loss/reorder charts. Pass ``--traffic-pattern`` to override an embedded
|
|
399
|
+
pattern. Spreadsheet tools treat the ``#`` lines as extra rows; skip them
|
|
400
|
+
or use ``ipyrf-report``.
|
|
353
401
|
|
|
354
402
|
Quick local test (two terminals):
|
|
355
403
|
|
|
356
404
|
.. code-block:: bash
|
|
357
405
|
|
|
358
406
|
# Terminal 1 — server with recording
|
|
359
|
-
ipyrf udp server 0.0.0.0 --port 12345 --
|
|
407
|
+
ipyrf udp server 0.0.0.0 --port 12345 --record records.csv
|
|
408
|
+
# or: ipyrf tcp server 0.0.0.0 --port 12345 --record records.csv
|
|
360
409
|
|
|
361
410
|
# Terminal 2 — short paced client
|
|
362
411
|
ipyrf udp client 127.0.0.1 --port 12345 --bandwidth 50M --time 2 -l 1200
|
|
412
|
+
# or: ipyrf tcp client 127.0.0.1 --port 12345 --bandwidth 50M --time 2
|
|
363
413
|
|
|
364
|
-
When the client finishes, the server exits and ``
|
|
414
|
+
When the client finishes, the server exits and ``records.csv`` contains the
|
|
365
415
|
trace. Use ``--enable-latency`` on the client if you also want latency
|
|
366
|
-
stats in the server summary.
|
|
416
|
+
stats in the server summary. Turn the CSV into an interactive HTML report
|
|
417
|
+
with ``ipyrf-report`` (see below).
|
|
418
|
+
|
|
419
|
+
Reports (ipyrf-report)
|
|
420
|
+
----------------------
|
|
421
|
+
|
|
422
|
+
``ipyrf-report`` reads a ``--record`` CSV (including the JSON metadata
|
|
423
|
+
comment) and writes one self-contained interactive HTML file (Plotly.js is
|
|
424
|
+
embedded, so the file works offline). Pass ``--traffic-pattern`` to override
|
|
425
|
+
a pattern embedded in the record metadata; otherwise the report uses the
|
|
426
|
+
embedded pattern when present. Pass ``--clock-offset MS`` to add that many
|
|
427
|
+
milliseconds to one-way latency (the HTML header also has a clock-offset
|
|
428
|
+
field you can edit later without regenerating).
|
|
429
|
+
|
|
430
|
+
The report is laid out like a performance trace: KPI overview at the top,
|
|
431
|
+
then throughput, latency (p50 / p95 / p99), loss and sequence / reordering
|
|
432
|
+
when the recording is UDP, send vs receive spacing, and latency
|
|
433
|
+
distribution / ECDF.
|
|
434
|
+
|
|
435
|
+
.. code-block:: bash
|
|
436
|
+
|
|
437
|
+
ipyrf-report records.csv
|
|
438
|
+
ipyrf-report records.csv -o report.html --traffic-pattern trace.json
|
|
439
|
+
ipyrf-report records.csv --json report.json --bin-ms 10
|
|
440
|
+
ipyrf-report records.csv --png --svg
|
|
441
|
+
ipyrf-report records.csv --clock-offset 1.23
|
|
442
|
+
|
|
443
|
+
``-o`` defaults to the record path with a ``.html`` suffix. ``--png`` and
|
|
444
|
+
``--svg`` write individual plots next to the HTML (or to a directory you
|
|
445
|
+
pass); they require the optional ``kaleido`` extra:
|
|
446
|
+
|
|
447
|
+
.. code-block:: bash
|
|
448
|
+
|
|
449
|
+
python3 -m pip install 'ipyrf[report-export]'
|
|
450
|
+
|
|
451
|
+
Clock offset
|
|
452
|
+
------------
|
|
453
|
+
|
|
454
|
+
``ipyrf offset HOST`` measures the wall-clock offset between this machine
|
|
455
|
+
and a remote SSH host. It does not change either clock.
|
|
456
|
+
|
|
457
|
+
This is useful when comparing ``transmitted_ns`` and ``received_ns`` in a
|
|
458
|
+
``--record`` CSV from a two-host test. One-way latency is
|
|
459
|
+
``received_ns - transmitted_ns``. If you run ``ipyrf offset`` on the
|
|
460
|
+
receiving host against the sender, pass that value to
|
|
461
|
+
``ipyrf-report --clock-offset`` (or type it into the HTML report). That
|
|
462
|
+
adds the offset so latency is in the receiver's time base. If this host
|
|
463
|
+
sent and the remote recorded, negate the printed offset first.
|
|
464
|
+
|
|
465
|
+
The remote host needs ``python3`` (or pass ``--python``). SSH uses your
|
|
466
|
+
normal configuration and keys.
|
|
467
|
+
|
|
468
|
+
.. code-block:: bash
|
|
469
|
+
|
|
470
|
+
ipyrf offset user@rasp1
|
|
471
|
+
ipyrf offset user@rasp1 --samples 50 --interval 0.1
|
|
472
|
+
ipyrf offset rasp1 --json
|
|
473
|
+
ipyrf offset rasp1 --ssh-arg=-p --ssh-arg=2222
|
|
367
474
|
|
|
368
475
|
JSON logging
|
|
369
476
|
------------
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ipyrf"
|
|
7
|
-
version = "2.
|
|
7
|
+
version = "2.1.0"
|
|
8
8
|
description = "A tiny iperf3-like tool with JSON output (TCP/UDP)"
|
|
9
9
|
readme = "README.rst"
|
|
10
10
|
requires-python = ">=3.8"
|
|
@@ -21,10 +21,13 @@ classifiers = [
|
|
|
21
21
|
"Topic :: System :: Networking",
|
|
22
22
|
"Topic :: System :: Benchmark",
|
|
23
23
|
]
|
|
24
|
-
dependencies = [
|
|
24
|
+
dependencies = [
|
|
25
|
+
"plotly>=5.18",
|
|
26
|
+
]
|
|
25
27
|
|
|
26
28
|
[project.optional-dependencies]
|
|
27
29
|
test = ["pytest>=7.0", "pytest-cov>=4.0"]
|
|
30
|
+
report-export = ["kaleido>=0.2"]
|
|
28
31
|
|
|
29
32
|
[project.urls]
|
|
30
33
|
Homepage = "https://github.com/steinwurf/ipyrf"
|
|
@@ -33,6 +36,7 @@ Issues = "https://github.com/steinwurf/ipyrf/issues"
|
|
|
33
36
|
|
|
34
37
|
[project.scripts]
|
|
35
38
|
ipyrf = "ipyrf.__main__:main"
|
|
39
|
+
ipyrf-report = "ipyrf.report.cli:main"
|
|
36
40
|
|
|
37
41
|
[tool.setuptools]
|
|
38
42
|
package-dir = {"" = "src"}
|