pytest: improve stragglers

A fix for the tests that took the longest:
- test_05: make the server close the HTTP/1.1 connection when
  simulating an error during a download. This eliminates waiting
  for a keepalive timeout
- test_02: pause tests with slightly smaller documents, eliminate
  special setup for HTTP/2. We test stream window handling now
  elsewhere already
- cli_hx_download: run look in 500ms steps instead of 1sec, resuming
  paused tranfers earlier.

Closes #19809
This commit is contained in:
Stefan Eissing 2025-12-02 14:26:31 +01:00 committed by Daniel Stenberg
parent 86b346443b
commit 9cf4a400d2
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
5 changed files with 7 additions and 57 deletions

View file

@ -164,8 +164,3 @@ Make a blocking, graceful shutdown of all remaining connections when
a multi handle is destroyed. This implicitly triggers for easy handles
that are run via easy_perform. The value of the environment variable
gives the shutdown timeout in milliseconds.
## `CURL_H2_STREAM_WIN_MAX`
Set to a positive 32-bit number to override the HTTP/2 stream window's
default of 10MB. Used in testing to verify correct window update handling.

View file

@ -111,9 +111,6 @@ struct cf_h2_ctx {
uint32_t goaway_error; /* goaway error code from server */
int32_t remote_max_sid; /* max id processed by server */
int32_t local_max_sid; /* max id processed by us */
#ifdef DEBUGBUILD
int32_t stream_win_max; /* max h2 stream window size */
#endif
BIT(initialized);
BIT(via_h1_upgrade);
BIT(conn_closed);
@ -139,18 +136,6 @@ static void cf_h2_ctx_init(struct cf_h2_ctx *ctx, bool via_h1_upgrade)
Curl_uint32_hash_init(&ctx->streams, 63, h2_stream_hash_free);
ctx->remote_max_sid = 2147483647;
ctx->via_h1_upgrade = via_h1_upgrade;
#ifdef DEBUGBUILD
{
const char *p = getenv("CURL_H2_STREAM_WIN_MAX");
ctx->stream_win_max = H2_STREAM_WINDOW_SIZE_MAX;
if(p) {
curl_off_t l;
if(!curlx_str_number(&p, &l, INT_MAX))
ctx->stream_win_max = (int32_t)l;
}
}
#endif
ctx->initialized = TRUE;
}
@ -330,15 +315,7 @@ static int32_t cf_h2_get_desired_local_win(struct Curl_cfilter *cf,
else if(avail < INT32_MAX)
return (int32_t)avail;
}
#ifdef DEBUGBUILD
{
struct cf_h2_ctx *ctx = cf->ctx;
CURL_TRC_CF(data, cf, "stream_win_max=%d", ctx->stream_win_max);
return ctx->stream_win_max;
}
#else
return H2_STREAM_WINDOW_SIZE_MAX;
#endif
}
static CURLcode cf_h2_update_local_win(struct Curl_cfilter *cf,

View file

@ -277,12 +277,10 @@ class TestDownload:
# download serial via lib client, pause/resume at different offsets
@pytest.mark.parametrize("pause_offset", [0, 10*1024, 100*1023, 640000])
@pytest.mark.parametrize("proto", ['http/1.1', 'h3'])
@pytest.mark.parametrize("proto", Env.http_protos())
def test_02_21_lib_serial(self, env: Env, httpd, nghttpx, proto, pause_offset):
if proto == 'h3' and not env.have_h3():
pytest.skip("h3 not supported")
count = 2
docname = 'data-10m'
docname = 'data-1m'
url = f'https://localhost:{env.https_port}/{docname}'
client = LocalClient(name='cli_hx_download', env=env)
if not client.exists():
@ -294,30 +292,6 @@ class TestDownload:
srcfile = os.path.join(httpd.docs_dir, docname)
self.check_downloads(client, srcfile, count)
# h2 download parallel via lib client, pause/resume at different offsets
# debug-override stream window size to reproduce #16955
@pytest.mark.parametrize("pause_offset", [0, 10*1024, 100*1023, 640000])
@pytest.mark.parametrize("swin_max", [0, 10*1024])
@pytest.mark.skipif(condition=not Env.have_h2_curl(), reason="curl without h2")
def test_02_21_h2_lib_serial(self, env: Env, httpd, pause_offset, swin_max):
proto = 'h2'
count = 2
docname = 'data-10m'
url = f'https://localhost:{env.https_port}/{docname}'
run_env = os.environ.copy()
run_env['CURL_DEBUG'] = 'multi,http/2'
if swin_max > 0:
run_env['CURL_H2_STREAM_WIN_MAX'] = f'{swin_max}'
client = LocalClient(name='cli_hx_download', env=env, run_env=run_env)
if not client.exists():
pytest.skip(f'example client not built: {client.name}')
r = client.run(args=[
'-n', f'{count}', '-P', f'{pause_offset}', '-V', proto, url
])
r.check_exit_code(0)
srcfile = os.path.join(httpd.docs_dir, docname)
self.check_downloads(client, srcfile, count)
# download via lib client, several at a time, pause/resume
@pytest.mark.parametrize("pause_offset", [100*1023])
@pytest.mark.parametrize("proto", Env.http_protos())

View file

@ -570,6 +570,10 @@ cleanup:
APR_BRIGADE_INSERT_TAIL(bb, b);
ap_pass_brigade(r->output_filters, bb);
}
if(rv == APR_ECONNRESET) {
r->connection->aborted = 1;
return rv;
}
return AP_FILTER_ERROR;
}

View file

@ -449,7 +449,7 @@ static CURLcode test_cli_hx_download(const char *URL)
if(still_running) {
/* wait for activity, timeout or "nothing" */
mc = curl_multi_poll(multi, NULL, 0, 1000, NULL);
mc = curl_multi_poll(multi, NULL, 0, 500, NULL);
}
if(mc)