From 7391d7f7a2b3ee6a9ea6368b6f7dfe2054ca024d Mon Sep 17 00:00:00 2001 From: Dmitrii Iurco Date: Thu, 7 May 2026 15:13:27 -0400 Subject: [PATCH] Add e2e latency consistency test for WireGuard tunnel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sends 50 pings at 0.2s intervals through the cell-to-cell tunnel and asserts that ≤5% exceed 3× the median RTT (floor 15ms). Catches server-side packet processing regressions on wired paths. Co-Authored-By: Claude Sonnet 4.6 --- tests/e2e/wg/test_cell_to_cell_routing.py | 27 +++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/tests/e2e/wg/test_cell_to_cell_routing.py b/tests/e2e/wg/test_cell_to_cell_routing.py index c58040c..f1c8555 100644 --- a/tests/e2e/wg/test_cell_to_cell_routing.py +++ b/tests/e2e/wg/test_cell_to_cell_routing.py @@ -401,6 +401,33 @@ class TestCellToCellRouting: f'Cell1 web (Caddy) at {url} not reachable via tunnel: {e}' ) + def test_tunnel_latency_consistency(self, wg_setup): + """WireGuard tunnel has no significant latency spikes on a local wired network. + + Sends 50 pings at 0.2s intervals to cell2's WG server IP. Pass condition: + ≤ 5% of pings (≤ 2 out of 50) exceed max(3× median RTT, 15ms). + """ + cell2_wg_ip = wg_setup['cell2_wg_ip'] + r = _run(['ping', '-c', '50', '-i', '0.2', '-W', '2', cell2_wg_ip], timeout=25) + assert r.returncode == 0, f'All pings to {cell2_wg_ip} failed: {r.stderr}' + + rtts = [float(m.group(1)) for m in re.finditer(r'time=([\d.]+) ms', r.stdout)] + assert len(rtts) >= 40, ( + f'Too few ping replies ({len(rtts)}/50) — packet loss may mask latency issues' + ) + + sorted_rtts = sorted(rtts) + median = sorted_rtts[len(sorted_rtts) // 2] + spike_threshold = max(median * 3.0, 15.0) + spikes = [rtt for rtt in rtts if rtt > spike_threshold] + spike_ratio = len(spikes) / len(rtts) + + assert spike_ratio <= 0.05, ( + f'Latency spikes: {len(spikes)}/{len(rtts)} packets ({spike_ratio:.0%}) ' + f'exceeded {spike_threshold:.1f}ms (3× median {median:.1f}ms). ' + f'Spike values: {[f"{s:.1f}ms" for s in sorted(spikes)]}' + ) + def test_cross_cell_domain_accessible(self, wg_setup): """A service domain from cell1 is resolvable via cell2's DNS and HTTP-reachable.