test(e2e): widen the fast-path RTT bound to 100 ms via harness.FAST_RTT_MS

The 'impairment cleared' asserts used avg < 50 on three-packet IOS pings;
the unimpaired baseline is 20-45 ms with 4 ms quantization, and host
scheduling jitter pushed averages to 54/56 in two full-suite runs
(esw, dynamips) — a margin, not an impairment (the qdisc asserts pass,
success is 100 %). The contrasted delayed regime is >= 150 ms, so a
100 ms bound still separates the two cleanly. Docker's sub-millisecond
veth asserts keep their 50 ms bound (three orders of magnitude of
headroom, never observed to flake).
This commit is contained in:
YueGuobin 2026-10-05 23:41:10 +08:00
parent f21d7be99c
commit f688e654e1
No known key found for this signature in database
7 changed files with 18 additions and 9 deletions

View File

@ -727,6 +727,15 @@ def configure_ios(console, hostname, eth_ip=None, serial_ip=None, clock=False, e
console.run("end")
# "No impairment applied" RTT bound for the fast-path asserts of the
# kernel-datapath scenarios: an unimpaired link measures ~20-45 ms on the
# IOS-based nodes (4 ms-quantized RTT; host scheduling jitter has pushed
# three-packet averages to 56 measured), while the delayed regime those
# asserts contrast against is >= 150 ms. 100 separates the two with
# headroom for a blip.
FAST_RTT_MS = 100
def ping(console, target, repeat=3, timeout=1):
"""Run an IOS ping; returns {success, avg, raw} (success in percent)."""
out = console.run(f"ping {target} repeat {repeat} timeout {timeout}", timeout=repeat * timeout + 20)

View File

@ -167,7 +167,7 @@ def test_dynamips_kernel_datapath():
compute.call("PUT", f"/projects/{pid}/links/{lid}", {"filters": {}})
assert "netem" not in harness.qdiscs(t1), harness.qdiscs(t1)
fast = harness.wait_ping(c1, "10.1.1.2")
assert fast["success"] == 100 and fast["avg"] < 50, fast
assert fast["success"] == 100 and fast["avg"] < harness.FAST_RTT_MS, fast
# suspend: anchor admin-down, traffic dead; resume restores it
compute.call("PUT", f"/projects/{pid}/links/{lid}", {"suspend": True})

View File

@ -269,7 +269,7 @@ def test_ethernet_switch_cascade_kernel_datapath():
compute.call("PUT", f"/projects/{pid}/links/{cascade['link_id']}", {"filters": {}})
assert "netem" not in harness.qdiscs(e0) and "netem" not in harness.qdiscs(e1)
fast = harness.wait_ping(c1, IP10 % 2)
assert fast["success"] == 100 and fast["avg"] < 50, fast
assert fast["success"] == 100 and fast["avg"] < harness.FAST_RTT_MS, fast
# suspend: both ends admin-down, both VLANs die; resume restores.
compute.call("PUT", f"/projects/{pid}/links/{cascade['link_id']}", {"suspend": True})

View File

@ -236,7 +236,7 @@ def test_ethernet_switch_kernel_fast_path():
compute.call("PUT", f"/projects/{pid}/links/{link1['link_id']}", {"filters": {}})
assert "netem" not in harness.qdiscs(a1)
fast = harness.wait_ping(c1, "10.1.1.2")
assert fast["success"] == 100 and fast["avg"] < 50, fast
assert fast["success"] == 100 and fast["avg"] < harness.FAST_RTT_MS, fast
# The same single-owned impairment on link2 — created switch-first,
# the order whose peer NIO update runs LAST. The passive end's empty
@ -252,7 +252,7 @@ def test_ethernet_switch_kernel_fast_path():
compute.call("PUT", f"/projects/{pid}/links/{link2['link_id']}", {"filters": {}})
assert "netem" not in harness.qdiscs(a2)
fast2 = harness.wait_ping(c1, "10.1.1.2")
assert fast2["success"] == 100 and fast2["avg"] < 50, fast2
assert fast2["success"] == 100 and fast2["avg"] < harness.FAST_RTT_MS, fast2
# suspend: the anchor admin-downs, the link is dead; resume restores
compute.call("PUT", f"/projects/{pid}/links/{link1['link_id']}", {"suspend": True})

View File

@ -179,7 +179,7 @@ def test_iol_docker_kernel_datapath():
compute.call("PUT", f"/projects/{pid}/links/{lid}", {"filters": {}})
assert "netem" not in harness.qdiscs(a1), harness.qdiscs(a1)
fast = harness.wait_ping(c1, "10.1.1.2")
assert fast["success"] == 100 and fast["avg"] < 50, fast
assert fast["success"] == 100 and fast["avg"] < harness.FAST_RTT_MS, fast
# Classifier spot check on the container's TAP anchor (the Docker
# suite runs the full matrix on veth host ends): cls_bpf match-drop

View File

@ -196,7 +196,7 @@ def test_iou_kernel_datapath():
compute.call("PUT", f"/projects/{pid}/links/{lid}", {"filters": {}})
assert "netem" not in harness.qdiscs(a1), harness.qdiscs(a1)
fast = harness.wait_ping(c1, "10.1.1.2")
assert fast["success"] == 100 and fast["avg"] < 50, fast
assert fast["success"] == 100 and fast["avg"] < harness.FAST_RTT_MS, fast
# Classifier spot check on a TAP anchor (the Docker suite runs the
# full matrix on veth host ends): cls_bpf match-drop and the eBPF
@ -300,7 +300,7 @@ def test_iou_kernel_datapath():
assert survivor["avg"] >= 150, (baseline, survivor)
compute.call("PUT", f"/projects/{pid}/links/{lid}", {"filters": {}})
cleared = harness.ping(c1, "10.1.1.2", repeat=3)
assert cleared["success"] == 100 and cleared["avg"] < 50, (baseline, cleared)
assert cleared["success"] == 100 and cleared["avg"] < harness.FAST_RTT_MS, (baseline, cleared)
c1.close()
c2.close()
@ -380,7 +380,7 @@ def test_iou_relay_control():
assert delayed["avg"] >= 150, (relay_ping, delayed)
compute.call("PUT", f"/projects/{pid}/links/{lid}", {"filters": {}})
fast = harness.ping(c1, "10.1.1.2", repeat=3)
assert fast["success"] == 100 and fast["avg"] < 50, (relay_ping, fast)
assert fast["success"] == 100 and fast["avg"] < harness.FAST_RTT_MS, (relay_ping, fast)
# frequency_drop shares one counter between the port's two
# directions: on an alternating ping stream one whole direction dies

View File

@ -187,7 +187,7 @@ def test_qemu_kernel_datapath():
compute.call("PUT", f"/projects/{pid}/links/{lid}", {"filters": {}})
assert "netem" not in harness.qdiscs(a1), harness.qdiscs(a1)
fast = harness.wait_ping(c1, "10.1.1.2")
assert fast["success"] == 100 and fast["avg"] < 50, fast
assert fast["success"] == 100 and fast["avg"] < harness.FAST_RTT_MS, fast
# suspend: anchor admin-down — the e1000 loses carrier, the bridge
# port is disabled and nothing crosses; resume restores