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 """

Roundup Issue Tracker: http://roundup-tracker.org/