def test_403(self): self.mock_httplib2([ ({ 'uri': 'http://localhost/123' }, (httplib2.Response({ 'status': 403, 'reason': 'Auth error' }), 'Auth error')), ]) with self.assertRaises(net.AuthError): net.request('http://localhost/123')
def test_404(self): self.mock_httplib2([ ({ 'uri': 'http://localhost/123' }, (httplib2.Response({ 'status': 404, 'reason': 'Not found' }), 'Not found')), ]) with self.assertRaises(net.NotFoundError): net.request('http://localhost/123')
def test_legitimate_cloud_endpoints_404_is_not_retried(self): self.mock_httplib2([ ({ 'uri': 'http://localhost/_ah/api/blah' }, (httplib2.Response({ 'status': 404, 'reason': 'Not found', 'Content-Type': 'application/json' }), '{}')), ]) with self.assertRaises(net.NotFoundError): net.request('http://localhost/_ah/api/blah')
def rpc(req): """Sends an asynchronous pRPC request. This API is low level. Most users should use Client class instead. Args: req (Request): a pRPC request. Returns the response message if the RPC status code is OK. Otherwise raises an Error. """ # The protocol is documented in # https://godoc.org/go.chromium.org/luci/grpc/prpc#hdr-Protocol # Ensure timeout is set, such that we use same values for deadline # parameter in net.request_async and X-Prpc-Timeout value are same. # Default to 10s, which is the default used in net.request_async. timeout = req.timeout or 10 headers = (req.metadata or {}).copy() headers['Content-Type'] = _BINARY_MEDIA_TYPE headers['Accept'] = _BINARY_MEDIA_TYPE headers['X-Prpc-Timeout'] = '%dS' % timeout try: res_bytes = net.request( url='http%s://%s/prpc/%s/%s' % ( '' if req.insecure else 's', req.hostname, req.service_name, req.method_name, ), method='POST', payload=req.request_message.SerializeToString(), headers=headers, include_auth=req.include_auth, deadline=timeout, max_attempts=req.max_attempts or 4, ) # Unfortunately, net module does not expose headers of HTTP 200 # responses. # Assume (HTTP OK => pRPC OK). except net.Error as ex: # net.Error means HTTP status code was not 200. try: code = codes.INT_TO_CODE[int(ex.headers['X-Prpc-Grpc-Code'])] except (ValueError, KeyError, TypeError): raise ProtocolError( 'response does not contain a valid X-Prpc-Grpc-Code header') msg = ex.response.decode('utf-8', 'ignore') raise RpcError(msg, code, ex.headers) # Status code is OK. # Parse the response and return it. res = req.response_message res.ParseFromString(res_bytes) return res
def test_gives_up_retrying(self): self.mock_httplib2([ ({ 'uri': 'http://localhost/123' }, (httplib2.Response({ 'status': 500, 'reason': 'server error' }), 'server error')), ({ 'uri': 'http://localhost/123' }, (httplib2.Response({ 'status': 500, 'reason': 'server error' }), 'server error')), ({ 'uri': 'http://localhost/123' }, (httplib2.Response({}), 'response body')), ]) with self.assertRaises(net.Error): net.request('http://localhost/123', max_attempts=2)
def test_crappy_cloud_endpoints_404_is_retried(self): self.mock_httplib2([ ({ 'uri': 'http://localhost/_ah/api/blah' }, (httplib2.Response({ 'status': 404, 'reason': 'Not found' }), 'Not found')), ({ 'uri': 'http://localhost/_ah/api/blah' }, (httplib2.Response({}), 'response body')), ]) response = net.request('http://localhost/_ah/api/blah') self.assertEqual('response body', response)
def test_retries_transient_errors(self): self.mock_httplib2([ ({ 'uri': 'http://localhost/123' }, httplib2.HttpLib2Error()), ({ 'uri': 'http://localhost/123' }, (httplib2.Response({ 'status': 408, 'reason': 'client timeout', }), 'client timeout')), ({ 'uri': 'http://localhost/123' }, (httplib2.Response({ 'status': 500, 'reason': 'server error', }), 'server error')), ({ 'uri': 'http://localhost/123' }, (httplib2.Response({}), 'response body')), ]) response = net.request('http://localhost/123', max_attempts=4) self.assertEqual('response body', response)
def test_request_works(self): self.mock_httplib2([ ({ 'headers': { 'Accept': 'text/plain', 'Authorization': 'Bearer token' }, 'method': 'POST', 'body': 'post body', 'uri': 'http://localhost/123?a=%3D&b=%26', }, (httplib2.Response({}), 'response body')), ]) response = net.request(url='http://localhost/123', method='POST', payload='post body', params={ 'a': '=', 'b': '&' }, headers={'Accept': 'text/plain'}, include_auth=True, deadline=123, max_attempts=5) self.assertEqual('response body', response)