Mercurial > p > roundup > code
comparison test/test_liveserver.py @ 8438:98e17dd0197f
test - fix parsing of integer param values
CI broke on the string '1\r#' expecting a 400 but got a 200 in
test_element_url_param_accepting_integer_values().
The #, & characters mark a url fragment or start of another parameter
and not part of the value. In a couple of tests, I parse the
hypothesis generated value to remove a # or & and anything after. Then
I set the value to the preceding string. If the string starts with #
or &, the value is set to "0" as the server ignores the parameter and
returns 200. "0" is a value that asserts that status is 200.
The code doing this parsing was different (and broken) between
test_element_url_param_accepting_integer_values
and
test_class_url_param_accepting_integer_values
It's now consistent and if it finds a & or #, it actually tests the
resulting value/status rather than skipping the test.
| author | John Rouillard <rouilj@ieee.org> |
|---|---|
| date | Thu, 28 Aug 2025 12:39:38 -0400 |
| parents | cc3edb260c1b |
| children |
comparison
equal
deleted
inserted
replaced
| 8437:b57cdcfe46d6 | 8438:98e17dd0197f |
|---|---|
| 254 # 10 seconds. | 254 # 10 seconds. |
| 255 fuzz_deadline = int(os.environ.get('pytest_fuzz_timeout', 0)) or 10000 | 255 fuzz_deadline = int(os.environ.get('pytest_fuzz_timeout', 0)) or 10000 |
| 256 | 256 |
| 257 @given(sampled_from(['@verbose', '@page_size', '@page_index']), | 257 @given(sampled_from(['@verbose', '@page_size', '@page_index']), |
| 258 text(min_size=1)) | 258 text(min_size=1)) |
| 259 @example("@verbose", "0\r#") | |
| 259 @example("@verbose", "1#") | 260 @example("@verbose", "1#") |
| 260 @example("@verbose", "#1stuff") | 261 @example("@verbose", "#1stuff") |
| 261 @example("@verbose", "0 #stuff") | 262 @example("@verbose", "0 #stuff") |
| 262 @settings(max_examples=_max_examples, | 263 @settings(max_examples=_max_examples, |
| 263 deadline=fuzz_deadline) # in ms | 264 deadline=fuzz_deadline) # in ms |
| 269 url = '%s/rest/data/status' % (self.url_base()) | 270 url = '%s/rest/data/status' % (self.url_base()) |
| 270 query = '%s=%s' % (param, value) | 271 query = '%s=%s' % (param, value) |
| 271 f = session.get(url, params=query) | 272 f = session.get(url, params=query) |
| 272 try: | 273 try: |
| 273 # test case '0 #', '0#', '12345#stuff' '12345&stuff' | 274 # test case '0 #', '0#', '12345#stuff' '12345&stuff' |
| 274 match = re.match(r'(^[0-9]*\s*)[#&]', value) | 275 # Normalize like a server does by breaking value at |
| 276 # # or & as these mark a fragment or subsequent | |
| 277 # query arg and are not part of the value. | |
| 278 match = re.match(r'^(.*)[#&]', value) | |
| 275 if match is not None: | 279 if match is not None: |
| 276 value = match[1] | 280 value = match[1] |
| 277 elif int(value) >= 0: | 281 # parameter is ignored by server if empty. |
| 282 # so set it to 0 to force 200 status code. | |
| 283 if value == "": | |
| 284 value = "0" | |
| 285 | |
| 286 if int(value) >= 0: | |
| 278 self.assertEqual(f.status_code, 200) | 287 self.assertEqual(f.status_code, 200) |
| 279 except ValueError: | 288 except ValueError: |
| 280 # test case '#' '#0', '&', '&anything here really' | 289 # test case '#' '#0', '&', '&anything here really' |
| 281 if value[0] in ('#', '&'): | 290 if value[0] in ('#', '&'): |
| 282 self.assertEqual(f.status_code, 200) | 291 self.assertEqual(f.status_code, 200) |
| 283 else: | 292 else: |
| 284 # invalid value for param | 293 # invalid value for param |
| 285 self.assertEqual(f.status_code, 400) | 294 self.assertEqual(f.status_code, 400) |
| 286 | 295 |
| 287 @given(sampled_from(['@verbose']), text(min_size=1)) | 296 @given(sampled_from(['@verbose']), text(min_size=1)) |
| 297 @example("@verbose", "0\r#") | |
| 288 @example("@verbose", "10#") | 298 @example("@verbose", "10#") |
| 289 @example("@verbose", u'Ø\U000dd990') | 299 @example("@verbose", u'Ø\U000dd990') |
| 290 @settings(max_examples=_max_examples, | 300 @settings(max_examples=_max_examples, |
| 291 deadline=fuzz_deadline) # in ms | 301 deadline=fuzz_deadline) # in ms |
| 292 def test_element_url_param_accepting_integer_values(self, param, value): | 302 def test_element_url_param_accepting_integer_values(self, param, value): |
| 296 url = '%s/rest/data/status/1' % (self.url_base()) | 306 url = '%s/rest/data/status/1' % (self.url_base()) |
| 297 query = '%s=%s' % (param, value) | 307 query = '%s=%s' % (param, value) |
| 298 f = session.get(url, params=query) | 308 f = session.get(url, params=query) |
| 299 try: | 309 try: |
| 300 # test case '0#' '12345#stuff' '12345&stuff' | 310 # test case '0#' '12345#stuff' '12345&stuff' |
| 301 match = re.match('(^[0-9]*)[#&]', value) | 311 # Normalize like a server does by breaking value at |
| 312 # # or & as these mark a fragment or subsequent | |
| 313 # query arg and are not part of the value. | |
| 314 match = re.match(r'^(.*)[#&]', value) | |
| 302 if match is not None: | 315 if match is not None: |
| 303 value = match[1] | 316 value = match[1] |
| 304 elif int(value) >= 0: | 317 # parameter is ignored by server if empty. |
| 318 # so set it to 0 to force 200 status code. | |
| 319 if value == "": | |
| 320 value = "0" | |
| 321 | |
| 322 if int(value) >= 0: | |
| 305 self.assertEqual(f.status_code, 200) | 323 self.assertEqual(f.status_code, 200) |
| 306 except ValueError: | 324 except ValueError: |
| 307 # test case '#' '#0', '&', '&anything here really' | 325 # test case '#' '#0', '&', '&anything here really' |
| 308 if value[0] in ('#', '&'): | 326 if value[0] in ('#', '&'): |
| 309 self.assertEqual(f.status_code, 200) | 327 self.assertEqual(f.status_code, 200) |
