pytest: test 07_70 stabilize (curl_ngtcp2)

We recently allowed a larger send buffer in ngtcp2 streams. This allowed
curl to send more early data then previously when the server was slow in
performing the handshake. This led to flaky test failures when the
amount of early data was larger than expected.

Change test expectations to allow for varying amount of early data.

Ref: #20112
Closes #20161
This commit is contained in:
Stefan Eissing 2026-01-02 12:46:35 +01:00 committed by Viktor Szakats
parent ac06643f71
commit 2c32ab12a0
No known key found for this signature in database
GPG Key ID: B5ABD165E2AEF201
2 changed files with 21 additions and 22 deletions

View File

@ -72,9 +72,9 @@
#define QUIC_MAX_STREAMS (256 * 1024)
#define QUIC_HANDSHAKE_TIMEOUT (10 * NGTCP2_SECONDS)
/* A stream window is the maximum amount we need to buffer for
* each active transfer.
* Chunk size is large enough to take a full DATA frame */
/* We announce a small window size in transport param to the server,
* and grow that immediately to max when no rate limit is in place.
* We need to start small as we are not able to decrease it. */
#define H3_STREAM_WINDOW_SIZE_INITIAL (32 * 1024)
#define H3_STREAM_WINDOW_SIZE_MAX (10 * 1024 * 1024)
#define H3_CONN_WINDOW_SIZE_MAX (100 * H3_STREAM_WINDOW_SIZE_MAX)
@ -90,10 +90,10 @@
* spares. Memory consumption goes down when streams run empty,
* have a large upload done, etc. */
#define H3_STREAM_POOL_SPARES 2
/* Receive and Send max number of chunks just follows from the
* chunk size and window size */
/* The max amount of un-acked upload data we keep around per stream */
#define H3_STREAM_SEND_BUFFER_MAX (10 * 1024 * 1024)
#define H3_STREAM_SEND_CHUNKS \
(H3_STREAM_WINDOW_SIZE_MAX / H3_STREAM_CHUNK_SIZE)
(H3_STREAM_SEND_BUFFER_MAX / H3_STREAM_CHUNK_SIZE)
/*
* Store ngtcp2 version info in this buffer.

View File

@ -639,21 +639,18 @@ class TestUpload:
])
r.check_exit_code(0)
# nghttpx is the only server we have that supports TLS early data and
# has a limit of 16k it announces
# nghttpx is the only server we have that supports TLS early data
@pytest.mark.skipif(condition=not Env.have_nghttpx(), reason="no nghttpx")
@pytest.mark.parametrize("proto,upload_size,exp_early", [
pytest.param('http/1.1', 100, 203, id='h1-small-body'),
pytest.param('http/1.1', 10*1024, 10345, id='h1-medium-body'),
pytest.param('http/1.1', 32*1024, 16384, id='h1-limited-body'),
pytest.param('h2', 10*1024, 10378, id='h2-medium-body'),
pytest.param('h2', 32*1024, 16384, id='h2-limited-body'),
pytest.param('h3', 1024, 1126, id='h3-small-body'),
pytest.param('h3', 1024 * 1024, 131177, id='h3-limited-body'),
# h3: limited+body (long app data). The 0RTT size is limited by
# our sendbuf size of 128K.
@pytest.mark.parametrize("proto,upload_size", [
pytest.param('http/1.1', 100, id='h1-small-body'),
pytest.param('http/1.1', 10*1024, id='h1-medium-body'),
pytest.param('http/1.1', 32*1024, id='h1-limited-body'),
pytest.param('h2', 10*1024, id='h2-medium-body'),
pytest.param('h2', 32*1024, id='h2-limited-body'),
pytest.param('h3', 1024, id='h3-small-body'),
pytest.param('h3', 1024 * 1024, id='h3-limited-body'),
])
def test_07_70_put_earlydata(self, env: Env, httpd, nghttpx, proto, upload_size, exp_early):
def test_07_70_put_earlydata(self, env: Env, httpd, nghttpx, proto, upload_size):
if not env.curl_can_early_data():
pytest.skip('TLS earlydata not implemented')
if proto == 'h2' and not env.have_h2_curl():
@ -693,10 +690,12 @@ class TestUpload:
m = re.match(r'^\[t-(\d+)] EarlyData: (-?\d+)', line)
if m:
earlydata[int(m.group(1))] = int(m.group(2))
# 1st transfer did not use early data
assert earlydata[0] == 0, f'{earlydata}\n{r.dump_logs()}'
# depending on cpu load, curl might not upload as much before
# the handshake starts and early data stops.
assert 0 < earlydata[1] <= exp_early, f'{earlydata}\n{r.dump_logs()}'
# depending on cpu load, the amount of early data might differ.
# when the server is slow, we might send more. when curl is slow,
# we might send less before the server handshakes.
assert 0 < earlydata[1] <= (upload_size + 1024), f'{earlydata}\n{r.dump_logs()}'
def check_downloads(self, client, r, source: List[str], count: int,
complete: bool = True):