Mercurial > p > roundup > code
comparison test/rest_common.py @ 5656:d26d2590cd8c
Implement different workaround for https://bugs.python.org/issue27777
suggested by jsm/Joseph Myers.
Subclass cgi.FieldStorage into BinaryFieldStorage and use that class
rather then monkey patching cgi.FieldStorage.make_file. This should
eliminate race conditions issues inherent with the prior way I tried
to do it by flipping the class method back and forth at runtime.
Also import new class into rest_common.py and use it in place of old
mechanism.
| author | John Rouillard <rouilj@ieee.org> |
|---|---|
| date | Tue, 19 Mar 2019 21:58:49 -0400 |
| parents | 207e0f5d551c |
| children | a4bb88a1a643 a7211712b110 |
comparison
equal
deleted
inserted
replaced
| 5655:207e0f5d551c | 5656:d26d2590cd8c |
|---|---|
| 397 if mode not in ('brokenheader', 'brokenetag', 'none'): | 397 if mode not in ('brokenheader', 'brokenetag', 'none'): |
| 398 self.assertEqual(self.dummy_client.response_code, 200) | 398 self.assertEqual(self.dummy_client.response_code, 200) |
| 399 else: | 399 else: |
| 400 self.assertEqual(self.dummy_client.response_code, 412) | 400 self.assertEqual(self.dummy_client.response_code, 412) |
| 401 | 401 |
| 402 def make_file(self, arg=None): | |
| 403 ''' work around https://bugs.python.org/issue27777 ''' | |
| 404 import tempfile | |
| 405 return tempfile.TemporaryFile("wb+") | |
| 406 | |
| 407 def testDispatch(self): | 402 def testDispatch(self): |
| 408 """ | 403 """ |
| 409 run changes through rest dispatch(). This also tests | 404 run changes through rest dispatch(). This also tests |
| 410 sending json payload through code as dispatch is the | 405 sending json payload through code as dispatch is the |
| 411 code that changes json payload into something we can | 406 code that changes json payload into something we can |
| 412 process. | 407 process. |
| 413 """ | 408 """ |
| 414 | |
| 415 # Override the make_file so it is always set to binary | |
| 416 # read mode. This is needed so we can send a json | |
| 417 # body. | |
| 418 saved_make_file = cgi.FieldStorage.make_file | |
| 419 cgi.FieldStorage.make_file = self.make_file | |
| 420 | 409 |
| 421 # TEST #1 | 410 # TEST #1 |
| 422 # PUT: joe's 'realname' using json data. | 411 # PUT: joe's 'realname' using json data. |
| 423 # simulate: /rest/data/user/<id>/realname | 412 # simulate: /rest/data/user/<id>/realname |
| 424 # use etag in header | 413 # use etag in header |
| 436 self.headers=headers | 425 self.headers=headers |
| 437 # we need to generate a FieldStorage the looks like | 426 # we need to generate a FieldStorage the looks like |
| 438 # FieldStorage(None, None, 'string') rather than | 427 # FieldStorage(None, None, 'string') rather than |
| 439 # FieldStorage(None, None, []) | 428 # FieldStorage(None, None, []) |
| 440 body_file=BytesIO(body) # FieldStorage needs a file | 429 body_file=BytesIO(body) # FieldStorage needs a file |
| 441 form = cgi.FieldStorage(body_file, | 430 form = client.BinaryFieldStorage(body_file, |
| 442 headers=headers, | 431 headers=headers, |
| 443 environ=env) | 432 environ=env) |
| 444 self.server.client.request.headers.get=self.get_header | 433 self.server.client.request.headers.get=self.get_header |
| 445 results = self.server.dispatch('PUT', | 434 results = self.server.dispatch('PUT', |
| 446 "/rest/data/user/%s/realname"%self.joeid, | 435 "/rest/data/user/%s/realname"%self.joeid, |
| 463 "CONTENT_LENGTH": len(body), | 452 "CONTENT_LENGTH": len(body), |
| 464 "REQUEST_METHOD": "PUT", | 453 "REQUEST_METHOD": "PUT", |
| 465 } | 454 } |
| 466 self.headers=None # have FieldStorage get len from env. | 455 self.headers=None # have FieldStorage get len from env. |
| 467 body_file=BytesIO(body) # FieldStorage needs a file | 456 body_file=BytesIO(body) # FieldStorage needs a file |
| 468 form = cgi.FieldStorage(body_file, | 457 form = client.BinaryFieldStorage(body_file, |
| 469 headers=None, | 458 headers=None, |
| 470 environ=env) | 459 environ=env) |
| 471 self.server.client.request.headers.get=self.get_header | 460 self.server.client.request.headers.get=self.get_header |
| 472 | 461 |
| 473 headers={"accept": "application/json", | 462 headers={"accept": "application/json", |
| 542 "content-type": env['CONTENT_TYPE'], | 531 "content-type": env['CONTENT_TYPE'], |
| 543 "content-length": len(body) | 532 "content-length": len(body) |
| 544 } | 533 } |
| 545 self.headers=headers | 534 self.headers=headers |
| 546 body_file=BytesIO(body) # FieldStorage needs a file | 535 body_file=BytesIO(body) # FieldStorage needs a file |
| 547 form = cgi.FieldStorage(body_file, | 536 form = client.BinaryFieldStorage(body_file, |
| 548 headers=headers, | 537 headers=headers, |
| 549 environ=env) | 538 environ=env) |
| 550 self.server.client.request.headers.get=self.get_header | 539 self.server.client.request.headers.get=self.get_header |
| 551 results = self.server.dispatch('PATCH', | 540 results = self.server.dispatch('PATCH', |
| 552 "/rest/data/user/%s"%self.joeid, | 541 "/rest/data/user/%s"%self.joeid, |
| 563 body=s2b('{ "address": "%s", "@etag": "%s"}'%( | 552 body=s2b('{ "address": "%s", "@etag": "%s"}'%( |
| 564 stored_results['data']['attributes']['address'], | 553 stored_results['data']['attributes']['address'], |
| 565 etag)) | 554 etag)) |
| 566 # reuse env and headers from prior test. | 555 # reuse env and headers from prior test. |
| 567 body_file=BytesIO(body) # FieldStorage needs a file | 556 body_file=BytesIO(body) # FieldStorage needs a file |
| 568 form = cgi.FieldStorage(body_file, | 557 form = client.BinaryFieldStorage(body_file, |
| 569 headers=headers, | 558 headers=headers, |
| 570 environ=env) | 559 environ=env) |
| 571 self.server.client.request.headers.get=self.get_header | 560 self.server.client.request.headers.get=self.get_header |
| 572 results = self.server.dispatch('PATCH', | 561 results = self.server.dispatch('PATCH', |
| 573 "/rest/data/user/%s"%self.joeid, | 562 "/rest/data/user/%s"%self.joeid, |
| 596 "content-type": env['CONTENT_TYPE'], | 585 "content-type": env['CONTENT_TYPE'], |
| 597 "content-length": len(body) | 586 "content-length": len(body) |
| 598 } | 587 } |
| 599 self.headers=headers | 588 self.headers=headers |
| 600 body_file=BytesIO(body) # FieldStorage needs a file | 589 body_file=BytesIO(body) # FieldStorage needs a file |
| 601 form = cgi.FieldStorage(body_file, | 590 form = client.BinaryFieldStorage(body_file, |
| 602 headers=headers, | 591 headers=headers, |
| 603 environ=env) | 592 environ=env) |
| 604 self.server.client.request.headers.get=self.get_header | 593 self.server.client.request.headers.get=self.get_header |
| 605 results = self.server.dispatch('POST', | 594 results = self.server.dispatch('POST', |
| 606 "/rest/data/issue", | 595 "/rest/data/issue", |
| 615 self.assertEqual(self.dummy_client.response_code, 200) | 604 self.assertEqual(self.dummy_client.response_code, 200) |
| 616 self.assertEqual(results['data']['attributes']['title'], | 605 self.assertEqual(results['data']['attributes']['title'], |
| 617 'foo bar') | 606 'foo bar') |
| 618 del(self.headers) | 607 del(self.headers) |
| 619 | 608 |
| 620 # reset the make_file method in the class | |
| 621 cgi.FieldStorage.make_file = saved_make_file | |
| 622 | |
| 623 def testPut(self): | 609 def testPut(self): |
| 624 """ | 610 """ |
| 625 Change joe's 'realname' | 611 Change joe's 'realname' |
| 626 Check if we can't change admin's detail | 612 Check if we can't change admin's detail |
| 627 """ | 613 """ |
