fix nagle time delay for macOS-Issue #9064
What changed, and why it matters
This change only adjusts a test that measures network timing behavior. It makes the test more flexible so it passes on macOS, where a particular network delay (called Nagle delay) is shorter than on Linux. There is no change to the actual Core Lightning software that users run, and no security issue is present.
No security action needed. This is a test-only change improving cross-platform CI reliability.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit modifies tests/test_connection.py::test_no_delay. The test previously hard-coded an assumption that TCP Nagle delay is ~200ms (Linux behavior) and asserted a strict time saving when disabling Nagle. On macOS loopback the Nagle timer can be much shorter, causing the assertion to fail (issue #9064). The patch probes the per-RTT Nagle overhead with 10 round trips first, then either asserts the full expected saving if it exceeds 0.5s, or only asserts that disabling Nagle is not slower. This is purely a test-suite robustness fix.
Changed components
tests/test_connection.pyInspect captured patch +43 / −22
diff --git a/tests/test_connection.py b/tests/test_connection.py
index c1abc69c..313978d8 100644
--- a/tests/test_connection.py
+++ b/tests/test_connection.py
@@ -4604,15 +4604,23 @@ def test_no_delay(node_factory):
'channel': scid
}
- # Test with nagle
- start = time.time()
- for _ in range(100):
- phash = random.randbytes(32).hex()
- l1.rpc.sendpay([routestep], phash)
- with pytest.raises(RpcError, match="WIRE_INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS"):
- l1.rpc.waitsendpay(phash)
- end = time.time()
- nagle_time = end - start
+ def do_round_trips(n):
+ start = time.time()
+ for _ in range(n):
+ phash = random.randbytes(32).hex()
+ l1.rpc.sendpay([routestep], phash)
+ with pytest.raises(RpcError, match="WIRE_INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS"):
+ l1.rpc.waitsendpay(phash)
+ return time.time() - start
+
+ # Probe the actual per-RTT Nagle overhead on this platform with a small
+ # sample (10 trips), then scale up for the full run. Linux's TCP Nagle
+ # timer fires after ~200ms; macOS/loopback may be much shorter.
+ PROBE = 10
+ probe_nagle = do_round_trips(PROBE)
+
+ # Test with nagle (full run)
+ nagle_time = do_round_trips(100)
del l1.daemon.opts['dev-keep-nagle']
del l2.daemon.opts['dev-keep-nagle']
@@ -4620,19 +4628,32 @@ def test_no_delay(node_factory):
l2.restart()
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
- # Test without nagle
- start = time.time()
- for _ in range(100):
- phash = random.randbytes(32).hex()
- l1.rpc.sendpay([routestep], phash)
- with pytest.raises(RpcError, match="WIRE_INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS"):
- l1.rpc.waitsendpay(phash)
- end = time.time()
- normal_time = end - start
-
- # 100 round trips, average delay 1/2 of 200ms -> 10 seconds extra.
- # Make it half that for variance.
- assert normal_time < nagle_time - 100 * (0.2 / 2) / 2
+ # Probe without nagle
+ probe_normal = do_round_trips(PROBE)
+
+ # Test without nagle (full run)
+ normal_time = do_round_trips(100)
+
+ # Estimate the per-RTT Nagle delay from the probe; average delay is half
+ # the timer period. Use half again as variance margin (same logic as the
+ # original 200ms assumption). If the platform shows no measurable Nagle
+ # effect (e.g. macOS loopback with a very short timer) the expected saving
+ # rounds down to zero and we only assert directional ordering.
+ per_rtt_delay = max(0.0, (probe_nagle - probe_normal) / PROBE)
+ expected_saving = 100 * per_rtt_delay / 2
+
+ print(f"Nagle probe: {probe_nagle:.3f}s nagle, {probe_normal:.3f}s normal, "
+ f"per-RTT overhead ~{per_rtt_delay * 1000:.1f}ms, "
+ f"expected saving {expected_saving:.2f}s")
+
+ if expected_saving > 0.5:
+ # Platform shows a meaningful Nagle effect: assert the full saving.
+ assert normal_time < nagle_time - expected_saving
+ else:
+ # Platform Nagle delay is too small to measure reliably (e.g. macOS);
+ # just assert that disabling Nagle is not slower.
+ assert normal_time <= nagle_time + 1.0
+
def test_listpeerchannels_by_scid(node_factory):
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.