From 1ba8df927e34c93b7772c6a7508fef0db4300833 Mon Sep 17 00:00:00 2001 From: Vinyak Date: Thu, 4 Jun 2026 20:17:28 +0000 Subject: [PATCH 1/4] test: Fix L0_http large JSON string size limit check (TRI-1378) Use a payload just over the 64MB default limit instead of ~2GB so the server returns the expected JSON size error rather than rejecting the request at INT32 Content-Length parsing. --- qa/L0_http/http_input_size_limit_test.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/qa/L0_http/http_input_size_limit_test.py b/qa/L0_http/http_input_size_limit_test.py index aed855dd69..3b5a9aeb50 100755 --- a/qa/L0_http/http_input_size_limit_test.py +++ b/qa/L0_http/http_input_size_limit_test.py @@ -503,9 +503,10 @@ def test_large_string_in_json(self): """Test JSON request with large string input""" model = "simple_identity" - # Create a string that is larger (large payload about 2GB) than the default limit of 64MB - # (2^31 + 64) elements * 1 bytes = 2GB + 64 bytes = 2,147,483,712 bytes - large_string_size = 2 * GIB + 64 + # Create a string larger than the default 64MB limit but well below INT32 + # Content-Length max (~2GB) so the server validates JSON size, not header + # parsing. + large_string_size = DEFAULT_LIMIT_BYTES + OFFSET_ELEMENTS large_string = "A" * large_string_size payload = { From a3ab6d87b9f626f5b5788572ca38579cbdb4dc96 Mon Sep 17 00:00:00 2001 From: Vinyak Date: Fri, 5 Jun 2026 01:54:48 +0000 Subject: [PATCH 2/4] test: Tighten L0_http JSON size boundary test (TRI-1378) Per Yingge's review feedback on the initial fix: - Use byte-precise +1 boundary instead of OFFSET_ELEMENTS (32 bytes). - Add complementary "exactly at limit succeeds" case so the test guards both sides of the boundary, matching the pattern used by test_default_limit_raw_binary. Body is constructed manually with json.dumps and posted with data= so the total HTTP body length is exact (no wrapper-overhead drift). --- qa/L0_http/http_input_size_limit_test.py | 67 ++++++++++++++---------- 1 file changed, 39 insertions(+), 28 deletions(-) diff --git a/qa/L0_http/http_input_size_limit_test.py b/qa/L0_http/http_input_size_limit_test.py index 3b5a9aeb50..0b1885eba7 100755 --- a/qa/L0_http/http_input_size_limit_test.py +++ b/qa/L0_http/http_input_size_limit_test.py @@ -499,54 +499,65 @@ def test_large_input_json(self): f"Expected shape {[1, shape_size]}, got {result['outputs'][0]['shape']}", ) - def test_large_string_in_json(self): - """Test JSON request with large string input""" - model = "simple_identity" - - # Create a string larger than the default 64MB limit but well below INT32 - # Content-Length max (~2GB) so the server validates JSON size, not header - # parsing. - large_string_size = DEFAULT_LIMIT_BYTES + OFFSET_ELEMENTS - large_string = "A" * large_string_size - + def _build_string_body_of_size(self, target_size): + """Build a JSON inference request body that is exactly target_size bytes.""" payload = { "inputs": [ { "name": "INPUT0", "datatype": "BYTES", "shape": [1, 1], - "data": [large_string], + "data": [""], } ] } + overhead = len(json.dumps(payload)) + pad = target_size - overhead + assert pad >= 0, "target_size smaller than payload overhead" + payload["inputs"][0]["data"] = ["A" * pad] + body = json.dumps(payload) + assert len(body) == target_size, (len(body), target_size) + return body + def test_large_string_in_json(self): + """Verify the server's JSON size limit at the byte boundary. + + Uses a body well below the INT32 Content-Length max (~2GB) so the + server's JSON-size check fires deterministically rather than failing + in Content-Length header parsing. + """ + model = "simple_identity" headers = {"Content-Type": "application/json"} + + # 1 byte over the 64 MiB default limit must be rejected with the + # size-limit error. + body_over = self._build_string_body_of_size(DEFAULT_LIMIT_BYTES + 1) response = requests.post( - self._get_infer_url(model), headers=headers, json=payload + self._get_infer_url(model), data=body_over, headers=headers ) - - # Should fail with 400 bad request self.assertEqual( 400, response.status_code, - "Expected error code for oversized JSON request, got: {}".format( - response.status_code + "Expected 400 for body of DEFAULT_LIMIT_BYTES + 1, got: {} ({!r})".format( + response.status_code, response.content[:200] ), ) - - # Verify error message error_msg = response.content.decode() - self.assertIn( - "request JSON size of ", - error_msg, - ) - self.assertIn( - " bytes exceeds the maximum allowed input size of ", - error_msg, + self.assertIn("request JSON size of ", error_msg) + self.assertIn(" bytes exceeds the maximum allowed input size of ", error_msg) + self.assertIn("Use --http-max-input-size to increase the limit.", error_msg) + + # Exactly at the limit must pass the size check. + body_at = self._build_string_body_of_size(DEFAULT_LIMIT_BYTES) + response = requests.post( + self._get_infer_url(model), data=body_at, headers=headers ) - self.assertIn( - "Use --http-max-input-size to increase the limit.", - error_msg, + self.assertEqual( + 200, + response.status_code, + "Expected 200 for body of exactly DEFAULT_LIMIT_BYTES, got: {} ({!r})".format( + response.status_code, response.content[:200] + ), ) def _create_compressed_payload(self, target_size): From 6a74ad115965a66daf5ed4fd01ca010378ed082c Mon Sep 17 00:00:00 2001 From: Vinyak Date: Fri, 5 Jun 2026 05:41:12 +0000 Subject: [PATCH 3/4] test: Address review feedback on L0_http JSON size boundary test - Rename _build_string_body_of_size -> _build_json_string_body_of_size (more specific name, JSON is the operative format) - Drop PR-specific commentary from the test docstring and inline comments; keep only documentation that's useful when reading the test itself Per review on #8819. --- qa/L0_http/http_input_size_limit_test.py | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/qa/L0_http/http_input_size_limit_test.py b/qa/L0_http/http_input_size_limit_test.py index 0b1885eba7..af4fb1e83a 100755 --- a/qa/L0_http/http_input_size_limit_test.py +++ b/qa/L0_http/http_input_size_limit_test.py @@ -499,7 +499,7 @@ def test_large_input_json(self): f"Expected shape {[1, shape_size]}, got {result['outputs'][0]['shape']}", ) - def _build_string_body_of_size(self, target_size): + def _build_json_string_body_of_size(self, target_size): """Build a JSON inference request body that is exactly target_size bytes.""" payload = { "inputs": [ @@ -520,18 +520,11 @@ def _build_string_body_of_size(self, target_size): return body def test_large_string_in_json(self): - """Verify the server's JSON size limit at the byte boundary. - - Uses a body well below the INT32 Content-Length max (~2GB) so the - server's JSON-size check fires deterministically rather than failing - in Content-Length header parsing. - """ + """Verify the server's JSON size limit at the byte boundary.""" model = "simple_identity" headers = {"Content-Type": "application/json"} - # 1 byte over the 64 MiB default limit must be rejected with the - # size-limit error. - body_over = self._build_string_body_of_size(DEFAULT_LIMIT_BYTES + 1) + body_over = self._build_json_string_body_of_size(DEFAULT_LIMIT_BYTES + 1) response = requests.post( self._get_infer_url(model), data=body_over, headers=headers ) @@ -547,8 +540,7 @@ def test_large_string_in_json(self): self.assertIn(" bytes exceeds the maximum allowed input size of ", error_msg) self.assertIn("Use --http-max-input-size to increase the limit.", error_msg) - # Exactly at the limit must pass the size check. - body_at = self._build_string_body_of_size(DEFAULT_LIMIT_BYTES) + body_at = self._build_json_string_body_of_size(DEFAULT_LIMIT_BYTES) response = requests.post( self._get_infer_url(model), data=body_at, headers=headers ) From f9b4e0b014bdcb8c6ee0ef4a15a744afa5934079 Mon Sep 17 00:00:00 2001 From: Vinyak Date: Fri, 5 Jun 2026 22:46:59 +0000 Subject: [PATCH 4/4] test: Use unittest assertions and requests json= in L0_http boundary helper Apply review feedback on test_large_string_in_json: - Replace bare assert with self.assertGreaterEqual / self.assertEqual so failures surface through unittest's reporting. - Build the request via requests.post(json=payload) instead of dumping the body and passing data=, which is more explicit about the content type and lets requests handle the Content-Type header. - Rename helper to _build_payload_of_json_size since it now returns the payload dict instead of a serialized body. --- qa/L0_http/http_input_size_limit_test.py | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/qa/L0_http/http_input_size_limit_test.py b/qa/L0_http/http_input_size_limit_test.py index af4fb1e83a..19433d8310 100755 --- a/qa/L0_http/http_input_size_limit_test.py +++ b/qa/L0_http/http_input_size_limit_test.py @@ -499,8 +499,8 @@ def test_large_input_json(self): f"Expected shape {[1, shape_size]}, got {result['outputs'][0]['shape']}", ) - def _build_json_string_body_of_size(self, target_size): - """Build a JSON inference request body that is exactly target_size bytes.""" + def _build_payload_of_json_size(self, target_size): + """Build an inference request payload whose JSON serialization is exactly target_size bytes.""" payload = { "inputs": [ { @@ -513,21 +513,17 @@ def _build_json_string_body_of_size(self, target_size): } overhead = len(json.dumps(payload)) pad = target_size - overhead - assert pad >= 0, "target_size smaller than payload overhead" + self.assertGreaterEqual(pad, 0, "target_size smaller than payload overhead") payload["inputs"][0]["data"] = ["A" * pad] - body = json.dumps(payload) - assert len(body) == target_size, (len(body), target_size) - return body + self.assertEqual(len(json.dumps(payload)), target_size) + return payload def test_large_string_in_json(self): """Verify the server's JSON size limit at the byte boundary.""" model = "simple_identity" - headers = {"Content-Type": "application/json"} - body_over = self._build_json_string_body_of_size(DEFAULT_LIMIT_BYTES + 1) - response = requests.post( - self._get_infer_url(model), data=body_over, headers=headers - ) + payload_over = self._build_payload_of_json_size(DEFAULT_LIMIT_BYTES + 1) + response = requests.post(self._get_infer_url(model), json=payload_over) self.assertEqual( 400, response.status_code, @@ -540,10 +536,8 @@ def test_large_string_in_json(self): self.assertIn(" bytes exceeds the maximum allowed input size of ", error_msg) self.assertIn("Use --http-max-input-size to increase the limit.", error_msg) - body_at = self._build_json_string_body_of_size(DEFAULT_LIMIT_BYTES) - response = requests.post( - self._get_infer_url(model), data=body_at, headers=headers - ) + payload_at = self._build_payload_of_json_size(DEFAULT_LIMIT_BYTES) + response = requests.post(self._get_infer_url(model), json=payload_at) self.assertEqual( 200, response.status_code,