18d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi"""Tests for google3.cloud.bigscience.apitools.base.py.batch.""" 28d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 38d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoiimport textwrap 48d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 58d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoiimport mock 68d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoifrom six.moves import http_client 78d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoifrom six.moves.urllib import parse 88d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoiimport unittest2 98d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 108d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoifrom apitools.base.py import batch 118d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoifrom apitools.base.py import exceptions 128d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoifrom apitools.base.py import http_wrapper 138d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 148d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 158d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoiclass FakeCredentials(object): 168d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 178d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def __init__(self): 188d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.num_refreshes = 0 198d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 208d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def refresh(self, _): 218d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.num_refreshes += 1 228d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 238d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 248d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoiclass FakeHttp(object): 258d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 268d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi class FakeRequest(object): 278d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 288d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def __init__(self, credentials=None): 298d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi if credentials is not None: 308d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.credentials = credentials 318d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 328d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def __init__(self, credentials=None): 338d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.request = FakeHttp.FakeRequest(credentials=credentials) 348d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 358d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 368d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoiclass FakeService(object): 378d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 388d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """A service for testing.""" 398d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 408d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def GetMethodConfig(self, _): 418d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return {} 428d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 438d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def GetUploadConfig(self, _): 448d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return {} 458d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 468d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # pylint: disable=unused-argument 478d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def PrepareHttpRequest( 488d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self, method_config, request, global_params, upload_config): 498d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return global_params['desired_request'] 508d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # pylint: enable=unused-argument 518d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 528d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def ProcessHttpResponse(self, _, http_response): 538d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return http_response 548d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 558d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 568d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoiclass BatchTest(unittest2.TestCase): 578d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 588d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def assertUrlEqual(self, expected_url, provided_url): 598d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 608d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def parse_components(url): 618d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi parsed = parse.urlsplit(url) 628d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi query = parse.parse_qs(parsed.query) 638d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return parsed._replace(query=''), query 648d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 658d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi expected_parse, expected_query = parse_components(expected_url) 668d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi provided_parse, provided_query = parse_components(provided_url) 678d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 688d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertEqual(expected_parse, provided_parse) 698d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertEqual(expected_query, provided_query) 708d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 718d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def __ConfigureMock(self, mock_request, expected_request, response): 728d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 738d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi if isinstance(response, list): 748d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi response = list(response) 758d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 768d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def CheckRequest(_, request, **unused_kwds): 778d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertUrlEqual(expected_request.url, request.url) 788d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertEqual(expected_request.http_method, request.http_method) 798d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi if isinstance(response, list): 808d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return response.pop(0) 818d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi else: 828d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return response 838d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 848d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi mock_request.side_effect = CheckRequest 858d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 868d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def testRequestServiceUnavailable(self): 878d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi mock_service = FakeService() 888d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 898d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi desired_url = 'https://www.example.com' 908d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi batch_api_request = batch.BatchApiRequest(batch_url=desired_url, 918d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi retryable_codes=[]) 928d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # The request to be added. The actual request sent will be somewhat 938d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # larger, as this is added to a batch. 948d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi desired_request = http_wrapper.Request(desired_url, 'POST', { 958d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'content-type': 'multipart/mixed; boundary="None"', 968d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'content-length': 80, 978d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi }, 'x' * 80) 988d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 998d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi with mock.patch.object(http_wrapper, 'MakeRequest', 1008d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi autospec=True) as mock_request: 1018d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.__ConfigureMock( 1028d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi mock_request, 1038d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi http_wrapper.Request(desired_url, 'POST', { 1048d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'content-type': 'multipart/mixed; boundary="None"', 1058d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'content-length': 419, 1068d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi }, 'x' * 419), 1078d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi http_wrapper.Response({ 1088d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'status': '200', 1098d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'content-type': 'multipart/mixed; boundary="boundary"', 1108d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi }, textwrap.dedent("""\ 1118d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi --boundary 1128d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi content-type: text/plain 1138d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi content-id: <id+0> 1148d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1158d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi HTTP/1.1 503 SERVICE UNAVAILABLE 1168d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi nope 1178d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi --boundary--"""), None)) 1188d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1198d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi batch_api_request.Add( 1208d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi mock_service, 'unused', None, 1218d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi global_params={'desired_request': desired_request}) 1228d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1238d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi api_request_responses = batch_api_request.Execute( 1248d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi FakeHttp(), sleep_between_polls=0) 1258d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1268d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertEqual(1, len(api_request_responses)) 1278d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1288d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # Make sure we didn't retry non-retryable code 503. 1298d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertEqual(1, mock_request.call_count) 1308d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1318d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertTrue(api_request_responses[0].is_error) 1328d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertIsNone(api_request_responses[0].response) 1338d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertIsInstance(api_request_responses[0].exception, 1348d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi exceptions.HttpError) 1358d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1368d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def testSingleRequestInBatch(self): 1378d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi mock_service = FakeService() 1388d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1398d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi desired_url = 'https://www.example.com' 1408d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi batch_api_request = batch.BatchApiRequest(batch_url=desired_url) 1418d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # The request to be added. The actual request sent will be somewhat 1428d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # larger, as this is added to a batch. 1438d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi desired_request = http_wrapper.Request(desired_url, 'POST', { 1448d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'content-type': 'multipart/mixed; boundary="None"', 1458d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'content-length': 80, 1468d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi }, 'x' * 80) 1478d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1488d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi with mock.patch.object(http_wrapper, 'MakeRequest', 1498d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi autospec=True) as mock_request: 1508d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.__ConfigureMock( 1518d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi mock_request, 1528d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi http_wrapper.Request(desired_url, 'POST', { 1538d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'content-type': 'multipart/mixed; boundary="None"', 1548d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'content-length': 419, 1558d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi }, 'x' * 419), 1568d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi http_wrapper.Response({ 1578d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'status': '200', 1588d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'content-type': 'multipart/mixed; boundary="boundary"', 1598d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi }, textwrap.dedent("""\ 1608d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi --boundary 1618d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi content-type: text/plain 1628d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi content-id: <id+0> 1638d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1648d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi HTTP/1.1 200 OK 1658d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi content 1668d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi --boundary--"""), None)) 1678d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1688d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi batch_api_request.Add(mock_service, 'unused', None, { 1698d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'desired_request': desired_request, 1708d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi }) 1718d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1728d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi api_request_responses = batch_api_request.Execute(FakeHttp()) 1738d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1748d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertEqual(1, len(api_request_responses)) 1758d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertEqual(1, mock_request.call_count) 1768d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1778d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertFalse(api_request_responses[0].is_error) 1788d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1798d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi response = api_request_responses[0].response 1808d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertEqual({'status': '200'}, response.info) 1818d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertEqual('content', response.content) 1828d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertEqual(desired_url, response.request_url) 1838d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1848d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def testRefreshOnAuthFailure(self): 1858d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi mock_service = FakeService() 1868d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1878d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi desired_url = 'https://www.example.com' 1888d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi batch_api_request = batch.BatchApiRequest(batch_url=desired_url) 1898d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # The request to be added. The actual request sent will be somewhat 1908d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # larger, as this is added to a batch. 1918d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi desired_request = http_wrapper.Request(desired_url, 'POST', { 1928d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'content-type': 'multipart/mixed; boundary="None"', 1938d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'content-length': 80, 1948d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi }, 'x' * 80) 1958d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1968d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi with mock.patch.object(http_wrapper, 'MakeRequest', 1978d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi autospec=True) as mock_request: 1988d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.__ConfigureMock( 1998d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi mock_request, 2008d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi http_wrapper.Request(desired_url, 'POST', { 2018d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'content-type': 'multipart/mixed; boundary="None"', 2028d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'content-length': 419, 2038d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi }, 'x' * 419), [ 2048d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi http_wrapper.Response({ 2058d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'status': '200', 2068d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'content-type': 'multipart/mixed; boundary="boundary"', 2078d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi }, textwrap.dedent("""\ 2088d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi --boundary 2098d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi content-type: text/plain 2108d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi content-id: <id+0> 2118d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 2128d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi HTTP/1.1 401 UNAUTHORIZED 2138d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Invalid grant 2148d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 2158d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi --boundary--"""), None), 2168d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi http_wrapper.Response({ 2178d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'status': '200', 2188d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'content-type': 'multipart/mixed; boundary="boundary"', 2198d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi }, textwrap.dedent("""\ 2208d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi --boundary 2218d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi content-type: text/plain 2228d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi content-id: <id+0> 2238d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 2248d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi HTTP/1.1 200 OK 2258d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi content 2268d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi --boundary--"""), None) 2278d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi ]) 2288d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 2298d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi batch_api_request.Add(mock_service, 'unused', None, { 2308d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'desired_request': desired_request, 2318d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi }) 2328d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 2338d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi credentials = FakeCredentials() 2348d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi api_request_responses = batch_api_request.Execute( 2358d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi FakeHttp(credentials=credentials), sleep_between_polls=0) 2368d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 2378d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertEqual(1, len(api_request_responses)) 2388d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertEqual(2, mock_request.call_count) 2398d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertEqual(1, credentials.num_refreshes) 2408d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 2418d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertFalse(api_request_responses[0].is_error) 2428d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 2438d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi response = api_request_responses[0].response 2448d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertEqual({'status': '200'}, response.info) 2458d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertEqual('content', response.content) 2468d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertEqual(desired_url, response.request_url) 2478d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 2488d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def testNoAttempts(self): 2498d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi desired_url = 'https://www.example.com' 2508d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi batch_api_request = batch.BatchApiRequest(batch_url=desired_url) 2518d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi batch_api_request.Add(FakeService(), 'unused', None, { 2528d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'desired_request': http_wrapper.Request(desired_url, 'POST', { 2538d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'content-type': 'multipart/mixed; boundary="None"', 2548d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'content-length': 80, 2558d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi }, 'x' * 80), 2568d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi }) 2578d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi api_request_responses = batch_api_request.Execute(None, max_retries=0) 2588d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertEqual(1, len(api_request_responses)) 2598d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertIsNone(api_request_responses[0].response) 2608d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertIsNone(api_request_responses[0].exception) 2618d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 2628d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def _DoTestConvertIdToHeader(self, test_id, expected_result): 2638d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi batch_request = batch.BatchHttpRequest('https://www.example.com') 2648d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertEqual( 2658d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi expected_result % batch_request._BatchHttpRequest__base_id, 2668d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi batch_request._ConvertIdToHeader(test_id)) 2678d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 2688d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def testConvertIdSimple(self): 2698d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self._DoTestConvertIdToHeader('blah', '<%s+blah>') 2708d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 2718d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def testConvertIdThatNeedsEscaping(self): 2728d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self._DoTestConvertIdToHeader('~tilde1', '<%s+%%7Etilde1>') 2738d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 2748d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def _DoTestConvertHeaderToId(self, header, expected_id): 2758d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi batch_request = batch.BatchHttpRequest('https://www.example.com') 2768d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertEqual(expected_id, 2778d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi batch_request._ConvertHeaderToId(header)) 2788d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 2798d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def testConvertHeaderToIdSimple(self): 2808d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self._DoTestConvertHeaderToId('<hello+blah>', 'blah') 2818d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 2828d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def testConvertHeaderToIdWithLotsOfPlus(self): 2838d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self._DoTestConvertHeaderToId('<a+++++plus>', 'plus') 2848d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 2858d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def _DoTestConvertInvalidHeaderToId(self, invalid_header): 2868d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi batch_request = batch.BatchHttpRequest('https://www.example.com') 2878d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertRaises(exceptions.BatchError, 2888d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi batch_request._ConvertHeaderToId, invalid_header) 2898d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 2908d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def testHeaderWithoutAngleBrackets(self): 2918d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self._DoTestConvertInvalidHeaderToId('1+1') 2928d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 2938d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def testHeaderWithoutPlus(self): 2948d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self._DoTestConvertInvalidHeaderToId('<HEADER>') 2958d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 2968d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def testSerializeRequest(self): 2978d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi request = http_wrapper.Request(body='Hello World', headers={ 2988d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'content-type': 'protocol/version', 2998d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi }) 3008d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi expected_serialized_request = '\n'.join([ 3018d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'GET HTTP/1.1', 3028d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'Content-Type: protocol/version', 3038d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'MIME-Version: 1.0', 3048d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'content-length: 11', 3058d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'Host: ', 3068d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi '', 3078d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'Hello World', 3088d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi ]) 3098d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi batch_request = batch.BatchHttpRequest('https://www.example.com') 3108d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertEqual(expected_serialized_request, 3118d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi batch_request._SerializeRequest(request)) 3128d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 3138d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def testSerializeRequestPreservesHeaders(self): 3148d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # Now confirm that if an additional, arbitrary header is added 3158d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # that it is successfully serialized to the request. Merely 3168d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # check that it is included, because the order of the headers 3178d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # in the request is arbitrary. 3188d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi request = http_wrapper.Request(body='Hello World', headers={ 3198d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'content-type': 'protocol/version', 3208d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'key': 'value', 3218d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi }) 3228d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi batch_request = batch.BatchHttpRequest('https://www.example.com') 3238d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertTrue( 3248d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'key: value\n' in batch_request._SerializeRequest(request)) 3258d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 3268d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def testSerializeRequestNoBody(self): 3278d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi request = http_wrapper.Request(body=None, headers={ 3288d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'content-type': 'protocol/version', 3298d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi }) 3308d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi expected_serialized_request = '\n'.join([ 3318d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'GET HTTP/1.1', 3328d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'Content-Type: protocol/version', 3338d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'MIME-Version: 1.0', 3348d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'Host: ', 335cef7893435aa41160dd1255c43cb8498279738ccChris Craik '', 336cef7893435aa41160dd1255c43cb8498279738ccChris Craik '', 3378d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi ]) 3388d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi batch_request = batch.BatchHttpRequest('https://www.example.com') 3398d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertEqual(expected_serialized_request, 3408d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi batch_request._SerializeRequest(request)) 3418d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 3428d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def testDeserializeRequest(self): 3438d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi serialized_payload = '\n'.join([ 3448d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'GET HTTP/1.1', 3458d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'Content-Type: protocol/version', 3468d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'MIME-Version: 1.0', 3478d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'content-length: 11', 3488d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'key: value', 3498d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'Host: ', 3508d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi '', 3518d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'Hello World', 3528d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi ]) 3538d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi example_url = 'https://www.example.com' 3548d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi expected_response = http_wrapper.Response({ 3558d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'content-length': str(len('Hello World')), 3568d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'Content-Type': 'protocol/version', 3578d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'key': 'value', 3588d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'MIME-Version': '1.0', 3598d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'status': '', 3608d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'Host': '' 3618d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi }, 'Hello World', example_url) 3628d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 3638d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi batch_request = batch.BatchHttpRequest(example_url) 3648d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertEqual( 3658d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi expected_response, 3668d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi batch_request._DeserializeResponse(serialized_payload)) 3678d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 3688d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def testNewId(self): 3698d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi batch_request = batch.BatchHttpRequest('https://www.example.com') 3708d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 3718d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi for i in range(100): 3728d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertEqual(str(i), batch_request._NewId()) 3738d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 3748d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def testAdd(self): 3758d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi batch_request = batch.BatchHttpRequest('https://www.example.com') 3768d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 3778d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi for x in range(100): 3788d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi batch_request.Add(http_wrapper.Request(body=str(x))) 3798d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 3808d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi for key in batch_request._BatchHttpRequest__request_response_handlers: 3818d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi value = batch_request._BatchHttpRequest__request_response_handlers[ 3828d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi key] 3838d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertEqual(key, value.request.body) 3848d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertFalse(value.request.url) 3858d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertEqual('GET', value.request.http_method) 3868d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertIsNone(value.response) 3878d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertIsNone(value.handler) 3888d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 3898d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def testInternalExecuteWithFailedRequest(self): 3908d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi with mock.patch.object(http_wrapper, 'MakeRequest', 3918d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi autospec=True) as mock_request: 3928d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.__ConfigureMock( 3938d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi mock_request, 3948d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi http_wrapper.Request('https://www.example.com', 'POST', { 3958d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'content-type': 'multipart/mixed; boundary="None"', 3968d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'content-length': 80, 3978d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi }, 'x' * 80), 3988d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi http_wrapper.Response({'status': '300'}, None, None)) 3998d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 4008d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi batch_request = batch.BatchHttpRequest('https://www.example.com') 4018d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 4028d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertRaises( 4038d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi exceptions.HttpError, batch_request._Execute, None) 4048d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 4058d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def testInternalExecuteWithNonMultipartResponse(self): 4068d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi with mock.patch.object(http_wrapper, 'MakeRequest', 4078d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi autospec=True) as mock_request: 4088d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.__ConfigureMock( 4098d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi mock_request, 4108d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi http_wrapper.Request('https://www.example.com', 'POST', { 4118d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'content-type': 'multipart/mixed; boundary="None"', 4128d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'content-length': 80, 4138d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi }, 'x' * 80), 4148d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi http_wrapper.Response({ 4158d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'status': '200', 4168d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'content-type': 'blah/blah' 4178d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi }, '', None)) 4188d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 4198d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi batch_request = batch.BatchHttpRequest('https://www.example.com') 4208d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 4218d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertRaises( 4228d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi exceptions.BatchError, batch_request._Execute, None) 4238d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 4248d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def testInternalExecute(self): 4258d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi with mock.patch.object(http_wrapper, 'MakeRequest', 4268d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi autospec=True) as mock_request: 4278d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.__ConfigureMock( 4288d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi mock_request, 4298d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi http_wrapper.Request('https://www.example.com', 'POST', { 4308d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'content-type': 'multipart/mixed; boundary="None"', 4318d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'content-length': 583, 4328d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi }, 'x' * 583), 4338d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi http_wrapper.Response({ 4348d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'status': '200', 4358d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'content-type': 'multipart/mixed; boundary="boundary"', 4368d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi }, textwrap.dedent("""\ 4378d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi --boundary 4388d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi content-type: text/plain 4398d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi content-id: <id+2> 4408d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 4418d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi HTTP/1.1 200 OK 4428d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Second response 4438d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 4448d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi --boundary 4458d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi content-type: text/plain 4468d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi content-id: <id+1> 4478d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 4488d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi HTTP/1.1 401 UNAUTHORIZED 4498d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi First response 4508d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 4518d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi --boundary--"""), None)) 4528d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 4538d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi test_requests = { 4548d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi '1': batch.RequestResponseAndHandler( 4558d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi http_wrapper.Request(body='first'), None, None), 4568d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi '2': batch.RequestResponseAndHandler( 4578d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi http_wrapper.Request(body='second'), None, None), 4588d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi } 4598d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 4608d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi batch_request = batch.BatchHttpRequest('https://www.example.com') 4618d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi batch_request._BatchHttpRequest__request_response_handlers = ( 4628d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi test_requests) 4638d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 4648d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi batch_request._Execute(FakeHttp()) 4658d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 4668d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi test_responses = ( 4678d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi batch_request._BatchHttpRequest__request_response_handlers) 4688d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 4698d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertEqual(http_client.UNAUTHORIZED, 4708d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi test_responses['1'].response.status_code) 4718d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertEqual(http_client.OK, 4728d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi test_responses['2'].response.status_code) 4738d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 4748d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertIn( 4758d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'First response', test_responses['1'].response.content) 4768d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertIn( 4778d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'Second response', test_responses['2'].response.content) 4788d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 4798d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def testPublicExecute(self): 4808d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 4818d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def LocalCallback(response, exception): 4828d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertEqual({'status': '418'}, response.info) 4838d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertEqual('Teapot', response.content) 4848d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertIsNone(response.request_url) 4858d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertIsInstance(exception, exceptions.HttpError) 4868d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 4878d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi global_callback = mock.Mock() 4888d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi batch_request = batch.BatchHttpRequest( 4898d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 'https://www.example.com', global_callback) 4908d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 4918d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi with mock.patch.object(batch.BatchHttpRequest, '_Execute', 4928d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi autospec=True) as mock_execute: 4938d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi mock_execute.return_value = None 4948d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 4958d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi test_requests = { 4968d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi '0': batch.RequestResponseAndHandler( 4978d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi None, 4988d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi http_wrapper.Response({'status': '200'}, 'Hello!', None), 4998d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi None), 5008d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi '1': batch.RequestResponseAndHandler( 5018d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi None, 5028d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi http_wrapper.Response({'status': '418'}, 'Teapot', None), 5038d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi LocalCallback), 5048d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi } 5058d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 5068d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi batch_request._BatchHttpRequest__request_response_handlers = ( 5078d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi test_requests) 5088d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi batch_request.Execute(None) 5098d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 5108d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # Global callback was called once per handler. 5118d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.assertEqual(len(test_requests), global_callback.call_count) 512