Skip to content

Commit 217f0e4

Browse files
icingbagder
authored andcommitted
pytest fixes and improvements
- fix test_17_20 flakiness: the test case did not have `nghttpx` in its parameters, causing it to no check if a reload was necessary. When that test ran behind one that gave nghttpx another certificate, eg. in parallel mode, it used the wrong pinned pubkey. - Have `env` provide lists of HTTP protocol versions available for testing. Replace parameterized tests on a fixed protocol list with the dynamic one from env. This makes checks for protocol availability in the test function bodies superfluous. refs curl#19489 Closes curl#19540
1 parent b3d4f17 commit 217f0e4

17 files changed

Lines changed: 191 additions & 630 deletions

tests/http/test_01_basic.py

Lines changed: 16 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,8 @@ def test_01_02_https_get(self, env: Env, httpd):
5555

5656
# simple https: GET, h2 wanted and got
5757
@pytest.mark.skipif(condition=not Env.have_ssl_curl(), reason="curl without SSL")
58+
@pytest.mark.skipif(condition=not Env.have_h2_curl(), reason="curl without h2")
5859
def test_01_03_h2_get(self, env: Env, httpd):
59-
if not env.have_h2_curl():
60-
pytest.skip("h2 not supported")
6160
curl = CurlClient(env=env)
6261
url = f'https://{env.domain1}:{env.https_port}/data.json'
6362
r = curl.http_get(url=url, extra_args=['--http2'])
@@ -66,9 +65,8 @@ def test_01_03_h2_get(self, env: Env, httpd):
6665

6766
# simple https: GET, h2 unsupported, fallback to h1
6867
@pytest.mark.skipif(condition=not Env.have_ssl_curl(), reason="curl without SSL")
68+
@pytest.mark.skipif(condition=not Env.have_h2_curl(), reason="curl without h2")
6969
def test_01_04_h2_unsupported(self, env: Env, httpd):
70-
if not env.have_h2_curl():
71-
pytest.skip("h2 not supported")
7270
curl = CurlClient(env=env)
7371
url = f'https://{env.domain2}:{env.https_port}/data.json'
7472
r = curl.http_get(url=url, extra_args=['--http2'])
@@ -86,12 +84,8 @@ def test_01_05_h3_get(self, env: Env, httpd, nghttpx):
8684

8785
# simple download, check connect/handshake timings
8886
@pytest.mark.skipif(condition=not Env.have_ssl_curl(), reason="curl without SSL")
89-
@pytest.mark.parametrize("proto", ['http/1.1', 'h2', 'h3'])
87+
@pytest.mark.parametrize("proto", Env.http_protos())
9088
def test_01_06_timings(self, env: Env, httpd, nghttpx, proto):
91-
if proto == 'h2' and not env.have_h2_curl():
92-
pytest.skip("h2 not supported")
93-
if proto == 'h3' and not env.have_h3():
94-
pytest.skip("h3 not supported")
9589
curl = CurlClient(env=env)
9690
url = f'https://{env.authority_for(env.domain1, proto)}/data.json'
9791
r = curl.http_download(urls=[url], alpn_proto=proto, with_stats=True)
@@ -103,13 +97,9 @@ def test_01_06_timings(self, env: Env, httpd, nghttpx, proto):
10397
assert r.stats[0]['time_appconnect'] > 0, f'{r.stats[0]}'
10498

10599
# simple https: HEAD
106-
@pytest.mark.parametrize("proto", ['http/1.1', 'h2', 'h3'])
100+
@pytest.mark.parametrize("proto", Env.http_protos())
107101
@pytest.mark.skipif(condition=not Env.have_ssl_curl(), reason="curl without SSL")
108102
def test_01_07_head(self, env: Env, httpd, nghttpx, proto):
109-
if proto == 'h2' and not env.have_h2_curl():
110-
pytest.skip("h2 not supported")
111-
if proto == 'h3' and not env.have_h3():
112-
pytest.skip("h3 not supported")
113103
curl = CurlClient(env=env)
114104
url = f'https://{env.authority_for(env.domain1, proto)}/data.json'
115105
r = curl.http_download(urls=[url], with_stats=True, with_headers=True,
@@ -122,9 +112,8 @@ def test_01_07_head(self, env: Env, httpd, nghttpx, proto):
122112
assert r.stats[0]['size_download'] == 0, f'{r.stats[0]}'
123113

124114
# http: GET for HTTP/2, see Upgrade:, 101 switch
115+
@pytest.mark.skipif(condition=not Env.have_h2_curl(), reason="curl without h2")
125116
def test_01_08_h2_upgrade(self, env: Env, httpd):
126-
if not env.have_h2_curl():
127-
pytest.skip("h2 not supported")
128117
curl = CurlClient(env=env)
129118
url = f'http://{env.domain1}:{env.http_port}/data.json'
130119
r = curl.http_get(url=url, extra_args=['--http2'])
@@ -136,9 +125,8 @@ def test_01_08_h2_upgrade(self, env: Env, httpd):
136125
assert r.json['server'] == env.domain1
137126

138127
# http: GET for HTTP/2 with prior knowledge
128+
@pytest.mark.skipif(condition=not Env.have_h2_curl(), reason="curl without h2")
139129
def test_01_09_h2_prior_knowledge(self, env: Env, httpd):
140-
if not env.have_h2_curl():
141-
pytest.skip("h2 not supported")
142130
curl = CurlClient(env=env)
143131
url = f'http://{env.domain1}:{env.http_port}/data.json'
144132
r = curl.http_get(url=url, extra_args=['--http2-prior-knowledge'])
@@ -149,9 +137,8 @@ def test_01_09_h2_prior_knowledge(self, env: Env, httpd):
149137
assert r.json['server'] == env.domain1
150138

151139
# http: strip TE header in HTTP/2 requests
140+
@pytest.mark.skipif(condition=not Env.have_h2_curl(), reason="curl without h2")
152141
def test_01_10_te_strip(self, env: Env, httpd):
153-
if not env.have_h2_curl():
154-
pytest.skip("h2 not supported")
155142
curl = CurlClient(env=env)
156143
url = f'https://{env.authority_for(env.domain1, "h2")}/data.json'
157144
r = curl.http_get(url=url, extra_args=['--http2', '-H', 'TE: gzip'])
@@ -164,12 +151,8 @@ def test_01_10_te_strip(self, env: Env, httpd):
164151
# send 48KB+ sized response headers to check we handle that correctly
165152
# larger than 64KB headers expose a bug in Apache HTTP/2 that is not
166153
# RSTing the stream correctly when its internal limits are exceeded.
167-
@pytest.mark.parametrize("proto", ['http/1.1', 'h2', 'h3'])
154+
@pytest.mark.parametrize("proto", Env.http_protos())
168155
def test_01_11_large_resp_headers(self, env: Env, httpd, proto):
169-
if proto == 'h2' and not env.have_h2_curl():
170-
pytest.skip("h2 not supported")
171-
if proto == 'h3' and not env.have_h3():
172-
pytest.skip("h3 not supported")
173156
curl = CurlClient(env=env)
174157
url = f'https://{env.authority_for(env.domain1, proto)}' \
175158
f'/curltest/tweak?x-hd={48 * 1024}'
@@ -181,10 +164,8 @@ def test_01_11_large_resp_headers(self, env: Env, httpd, proto):
181164
# http: response headers larger than what curl buffers for
182165
@pytest.mark.skipif(condition=not Env.httpd_is_at_least('2.4.64'),
183166
reason='httpd must be at least 2.4.64')
184-
@pytest.mark.parametrize("proto", ['http/1.1', 'h2'])
167+
@pytest.mark.parametrize("proto", Env.http_h1_h2_protos())
185168
def test_01_12_xlarge_resp_headers(self, env: Env, httpd, configures_httpd, proto):
186-
if proto == 'h2' and not env.have_h2_curl():
187-
pytest.skip("h2 not supported")
188169
httpd.set_extra_config('base', [
189170
f'H2MaxHeaderBlockLen {130 * 1024}',
190171
])
@@ -200,10 +181,8 @@ def test_01_12_xlarge_resp_headers(self, env: Env, httpd, configures_httpd, prot
200181
# http: 1 response header larger than what curl buffers for
201182
@pytest.mark.skipif(condition=not Env.httpd_is_at_least('2.4.64'),
202183
reason='httpd must be at least 2.4.64')
203-
@pytest.mark.parametrize("proto", ['http/1.1', 'h2'])
184+
@pytest.mark.parametrize("proto", Env.http_h1_h2_protos())
204185
def test_01_13_megalarge_resp_headers(self, env: Env, httpd, configures_httpd, proto):
205-
if proto == 'h2' and not env.have_h2_curl():
206-
pytest.skip("h2 not supported")
207186
httpd.set_extra_config('base', [
208187
'LogLevel http2:trace2',
209188
f'H2MaxHeaderBlockLen {130 * 1024}',
@@ -222,10 +201,8 @@ def test_01_13_megalarge_resp_headers(self, env: Env, httpd, configures_httpd, p
222201
# nghttp2 error -905: Too many CONTINUATION frames following a HEADER frame
223202
@pytest.mark.skipif(condition=not Env.httpd_is_at_least('2.4.64'),
224203
reason='httpd must be at least 2.4.64')
225-
@pytest.mark.parametrize("proto", ['http/1.1', 'h2'])
204+
@pytest.mark.parametrize("proto", Env.http_h1_h2_protos())
226205
def test_01_14_gigalarge_resp_headers(self, env: Env, httpd, configures_httpd, proto):
227-
if proto == 'h2' and not env.have_h2_curl():
228-
pytest.skip("h2 not supported")
229206
httpd.set_extra_config('base', [
230207
'LogLevel http2:trace2',
231208
f'H2MaxHeaderBlockLen {1024 * 1024}',
@@ -243,10 +220,8 @@ def test_01_14_gigalarge_resp_headers(self, env: Env, httpd, configures_httpd, p
243220
# http: one response header > 256 KB
244221
@pytest.mark.skipif(condition=not Env.httpd_is_at_least('2.4.64'),
245222
reason='httpd must be at least 2.4.64')
246-
@pytest.mark.parametrize("proto", ['http/1.1', 'h2'])
223+
@pytest.mark.parametrize("proto", Env.http_h1_h2_protos())
247224
def test_01_15_gigalarge_resp_headers(self, env: Env, httpd, configures_httpd, proto):
248-
if proto == 'h2' and not env.have_h2_curl():
249-
pytest.skip("h2 not supported")
250225
httpd.set_extra_config('base', [
251226
'LogLevel http2:trace2',
252227
f'H2MaxHeaderBlockLen {1024 * 1024}',
@@ -262,12 +237,8 @@ def test_01_15_gigalarge_resp_headers(self, env: Env, httpd, configures_httpd, p
262237
r.check_exit_code(100) # CURLE_TOO_LARGE
263238

264239
# http: invalid request headers, GET, issue #16998
265-
@pytest.mark.parametrize("proto", ['http/1.1', 'h2', 'h3'])
240+
@pytest.mark.parametrize("proto", Env.http_protos())
266241
def test_01_16_inv_req_get(self, env: Env, httpd, nghttpx, proto):
267-
if proto == 'h2' and not env.have_h2_curl():
268-
pytest.skip("h2 not supported")
269-
if proto == 'h3' and not env.have_h3():
270-
pytest.skip("h3 not supported")
271242
curl = CurlClient(env=env)
272243
url = f'https://{env.authority_for(env.domain1, proto)}/curltest/echo'
273244
r = curl.http_get(url=url, alpn_proto=proto, extra_args=[
@@ -287,10 +258,9 @@ def test_01_16_inv_req_get(self, env: Env, httpd, nghttpx, proto):
287258
pytest.param('gzip ;q=0.2;x="y,x", trailers', 'trailers', id='gzip+q+x+trailers'),
288259
pytest.param('gzip ;x="trailers", chunks', None, id='gzip+x+chunks'),
289260
])
261+
@pytest.mark.skipif(condition=not Env.have_h2_curl(), reason="curl without h2")
290262
def test_01_17_TE(self, env: Env, httpd, te_in, te_out):
291263
proto = 'h2'
292-
if not env.have_h2_curl():
293-
pytest.skip("h2 not supported")
294264
curl = CurlClient(env=env)
295265
url = f'https://{env.authority_for(env.domain1, proto)}/curltest/echo'
296266
r = curl.http_download(urls=[url], alpn_proto=proto, with_stats=True,
@@ -303,10 +273,9 @@ def test_01_17_TE(self, env: Env, httpd, te_in, te_out):
303273
assert 'request-te' not in r.responses[0]['header'], f'{r.responses[0]}'
304274

305275
# check that an existing https: connection is not reused for http:
276+
@pytest.mark.skipif(condition=not Env.have_h2_curl(), reason="curl without h2")
306277
def test_01_18_tls_reuse(self, env: Env, httpd):
307278
proto = 'h2'
308-
if not env.have_h2_curl():
309-
pytest.skip("h2 not supported")
310279
curl = CurlClient(env=env)
311280
url1 = f'https://{env.authority_for(env.domain1, proto)}/data.json'
312281
url2 = f'http://{env.authority_for(env.domain1, proto)}/data.json'
@@ -315,10 +284,9 @@ def test_01_18_tls_reuse(self, env: Env, httpd):
315284
assert r.total_connects == 2, f'{r.dump_logs()}'
316285

317286
# check that an existing http: connection is not reused for https:
287+
@pytest.mark.skipif(condition=not Env.have_h2_curl(), reason="curl without h2")
318288
def test_01_19_plain_reuse(self, env: Env, httpd):
319289
proto = 'h2'
320-
if not env.have_h2_curl():
321-
pytest.skip("h2 not supported")
322290
curl = CurlClient(env=env)
323291
url1 = f'http://{env.domain1}:{env.http_port}/data.json'
324292
url2 = f'https://{env.domain1}:{env.http_port}/data.json'

0 commit comments

Comments
 (0)