|
1 | 1 | import base64
|
| 2 | +import json |
2 | 3 | import os
|
3 | 4 | import tempfile
|
| 5 | +import string |
4 | 6 |
|
5 | 7 | from tornado.testing import AsyncHTTPTestCase
|
6 | 8 |
|
@@ -458,6 +460,67 @@ def test_evaluation_enabled(self):
|
458 | 460 | )
|
459 | 461 | self.assertEqual(200, response.code)
|
460 | 462 |
|
| 463 | +class TestEvaluationPlaneHandlerMaxRequestSize(AsyncHTTPTestCase): |
| 464 | + @classmethod |
| 465 | + def setUpClass(cls): |
| 466 | + prefix = "__TestEvaluationPlaneHandlerMaxRequestSize_" |
| 467 | + |
| 468 | + # create config file |
| 469 | + cls.config_file = tempfile.NamedTemporaryFile( |
| 470 | + mode="w+t", prefix=prefix, suffix=".conf", delete=False |
| 471 | + ) |
| 472 | + cls.config_file.write( |
| 473 | + "[TabPy]\n" |
| 474 | + "TABPY_MAX_REQUEST_SIZE_MB = 1" |
| 475 | + ) |
| 476 | + cls.config_file.close() |
| 477 | + |
| 478 | + @classmethod |
| 479 | + def tearDownClass(cls): |
| 480 | + os.remove(cls.config_file.name) |
| 481 | + |
| 482 | + def get_app(self): |
| 483 | + self.app = TabPyApp(self.config_file.name) |
| 484 | + return self.app._create_tornado_web_app() |
| 485 | + |
| 486 | + def create_large_payload(self): |
| 487 | + num_chars = 2 * 1024 * 1024 # 2MB Size |
| 488 | + large_string = string.printable * (num_chars // len(string.printable)) |
| 489 | + large_string += string.printable[:num_chars % len(string.printable)] |
| 490 | + payload = { |
| 491 | + "data": { "_arg1": [1, large_string] }, |
| 492 | + "script": "return _arg1" |
| 493 | + } |
| 494 | + return json.dumps(payload).encode('utf-8') |
| 495 | + |
| 496 | + def test_evaluation_payload_exceeds_max_request_size(self): |
| 497 | + response = self.fetch( |
| 498 | + "/evaluate", |
| 499 | + method="POST", |
| 500 | + body=self.create_large_payload() |
| 501 | + ) |
| 502 | + self.assertEqual(413, response.code) |
| 503 | + |
| 504 | + def test_evaluation_max_request_size_not_applied(self): |
| 505 | + self.app.max_request_size = None |
| 506 | + response = self.fetch( |
| 507 | + "/evaluate", |
| 508 | + method="POST", |
| 509 | + body=self.create_large_payload() |
| 510 | + ) |
| 511 | + self.assertEqual(200, response.code) |
| 512 | + self.assertEqual(1, json.loads(response.body)[0]) |
| 513 | + |
| 514 | + def test_no_content_length_header_present(self): |
| 515 | + response = self.fetch( |
| 516 | + "/evaluate", |
| 517 | + method="POST", |
| 518 | + allow_nonstandard_methods=True |
| 519 | + ) |
| 520 | + message = json.loads(response.body)["message"] |
| 521 | + # Ensure it reaches script processing stage in EvaluationPlaneHandler.post |
| 522 | + self.assertEqual("Error processing script", message) |
| 523 | + |
461 | 524 |
|
462 | 525 | class TestEvaluationPlaneHandlerDefault(AsyncHTTPTestCase):
|
463 | 526 | @classmethod
|
|
0 commit comments