Example #1
0
  def test_media_io_base_next_chunk_no_retry_403_not_configured(self):
    fd = BytesIO(b"i am png")
    upload = MediaIoBaseUpload(
        fd=fd, mimetype='image/png', chunksize=500, resumable=True)

    http = HttpMockSequence([
        ({'status': '403'}, NOT_CONFIGURED_RESPONSE),
        ({'status': '200'}, '{}')
        ])

    model = JsonModel()
    uri = u'https://www.googleapis.com/someapi/v1/upload/?foo=bar'
    method = u'POST'
    request = HttpRequest(
        http,
        model.response,
        uri,
        method=method,
        headers={},
        resumable=upload)

    request._rand = lambda: 1.0
    request._sleep =  mock.MagicMock()

    with self.assertRaises(HttpError):
      request.execute(num_retries=3)
    request._sleep.assert_not_called()
    def test_retry(self):
        num_retries = 5
        resp_seq = [({'status': '500'}, '')] * (num_retries - 3)
        resp_seq.append(({'status': '403'}, RATE_LIMIT_EXCEEDED_RESPONSE))
        resp_seq.append(({'status': '403'}, USER_RATE_LIMIT_EXCEEDED_RESPONSE))
        resp_seq.append(({'status': '429'}, ''))
        resp_seq.append(({'status': '200'}, '{}'))

        http = HttpMockSequence(resp_seq)
        model = JsonModel()
        uri = u'https://www.googleapis.com/someapi/v1/collection/?foo=bar'
        method = u'POST'
        request = HttpRequest(http,
                              model.response,
                              uri,
                              method=method,
                              body=u'{}',
                              headers={'content-type': 'application/json'})

        sleeptimes = []
        request._sleep = lambda x: sleeptimes.append(x)
        request._rand = lambda: 10

        request.execute(num_retries=num_retries)

        self.assertEqual(num_retries, len(sleeptimes))
        for retry_num in range(num_retries):
            self.assertEqual(10 * 2**(retry_num + 1), sleeptimes[retry_num])
    def test_no_retry_fails_fast(self):
        http = HttpMockSequence([({
            'status': '500'
        }, ''), ({
            'status': '200'
        }, '{}')])
        model = JsonModel()
        uri = u'https://www.googleapis.com/someapi/v1/collection/?foo=bar'
        method = u'POST'
        request = HttpRequest(http,
                              model.response,
                              uri,
                              method=method,
                              body=u'{}',
                              headers={'content-type': 'application/json'})

        request._rand = lambda: 1.0
        request._sleep = lambda _: self.fail(
            'sleep should not have been called.')

        try:
            request.execute()
            self.fail('Should have raised an exception.')
        except HttpError:
            pass
    def test_media_io_base_next_chunk_retries(self):
        try:
            import io
        except ImportError:
            return

        f = open(datafile('small.png'), 'r')
        fd = io.BytesIO(f.read())
        upload = MediaIoBaseUpload(fd=fd,
                                   mimetype='image/png',
                                   chunksize=500,
                                   resumable=True)

        # Simulate 5XXs for both the request that creates the resumable upload and
        # the upload itself.
        http = HttpMockSequence([
            ({
                'status': '500'
            }, ''),
            ({
                'status': '500'
            }, ''),
            ({
                'status': '503'
            }, ''),
            ({
                'status': '200',
                'location': 'location'
            }, ''),
            ({
                'status': '500'
            }, ''),
            ({
                'status': '500'
            }, ''),
            ({
                'status': '503'
            }, ''),
            ({
                'status': '200'
            }, '{}'),
        ])

        model = JsonModel()
        uri = u'https://www.googleapis.com/someapi/v1/upload/?foo=bar'
        method = u'POST'
        request = HttpRequest(http,
                              model.response,
                              uri,
                              method=method,
                              headers={},
                              resumable=upload)

        sleeptimes = []
        request._sleep = lambda x: sleeptimes.append(x)
        request._rand = lambda: 10

        request.execute(num_retries=3)
        self.assertEqual([20, 40, 80, 20, 40, 80], sleeptimes)
    def test_good_response_wo_data(self):
        model = JsonModel(data_wrapper=False)
        resp = httplib2.Response({"status": "200"})
        resp.reason = "OK"
        content = '{"foo": "is good"}'

        content = model.response(resp, content)
        self.assertEqual(content, {"foo": "is good"})
    def test_no_content_response(self):
        model = JsonModel(data_wrapper=False)
        resp = httplib2.Response({"status": "204"})
        resp.reason = "No Content"
        content = ""

        content = model.response(resp, content)
        self.assertEqual(content, {})
    def test_no_content_response(self):
        model = JsonModel(data_wrapper=False)
        resp = httplib2.Response({'status': '204'})
        resp.reason = 'No Content'
        content = ''

        content = model.response(resp, content)
        self.assertEqual(content, {})
    def test_good_response_wo_data_str(self):
        model = JsonModel(data_wrapper=False)
        resp = httplib2.Response({'status': '200'})
        resp.reason = 'OK'
        content = '"data goes here"'

        content = model.response(resp, content)
        self.assertEqual(content, 'data goes here')
    def test_good_response_wo_data(self):
        model = JsonModel(data_wrapper=False)
        resp = httplib2.Response({'status': '200'})
        resp.reason = 'OK'
        content = '{"foo": "is good"}'

        content = model.response(resp, content)
        self.assertEqual(content, {'foo': 'is good'})
Example #10
0
    def test_good_response(self):
        model = JsonModel(data_wrapper=True)
        resp = httplib2.Response({'status': '200'})
        resp.reason = 'OK'
        content = '{"data": "is good"}'

        content = model.response(resp, content)
        self.assertEqual(content, 'is good')
    def test_good_response_wo_data_str(self):
        model = JsonModel(data_wrapper=False)
        resp = httplib2.Response({"status": "200"})
        resp.reason = "OK"
        content = '"data goes here"'

        content = model.response(resp, content)
        self.assertEqual(content, "data goes here")
 def get(self, project, snapshot):
     if snapshot == valid_snapshot_name:
         http = HttpMock('tests/data/gcp/snapshots.get.json',
                         {'status': '200'})
         model = JsonModel()
         uri = 'some_uri'
         method = 'GET'
         return HttpRequest(http,
                            model.response,
                            uri,
                            method=method,
                            headers={})
     elif snapshot == not_found_snapshot_name:
         http = HttpMock('tests/data/gcp/snapshots.get.notfound.json',
                         {'status': '404'})
         model = JsonModel()
         uri = 'some_uri'
         method = 'GET'
         return HttpRequest(http,
                            model.response,
                            uri,
                            method=method,
                            headers={})
     elif snapshot == invalid_snapshot_name:
         http = HttpMock('tests/data/gcp/snapshots.get.forbidden.json',
                         {'status': '403'})
         model = JsonModel()
         uri = 'some_uri'
         method = 'GET'
         return HttpRequest(http,
                            model.response,
                            uri,
                            method=method,
                            headers={})
     if snapshot == delete_snapshot_name:
         http = HttpMock('tests/data/gcp/snapshots.get.notfound.json',
                         {'status': '404'})
         model = JsonModel()
         uri = 'some_uri'
         method = 'GET'
         return HttpRequest(http,
                            model.response,
                            uri,
                            method=method,
                            headers={})
 def test_no_data_wrapper_deserialize_raise_type_error(self):
     buffer = io.StringIO()
     buffer.write('String buffer')
     model = JsonModel(data_wrapper=False)
     resp = httplib2.Response({"status": "500"})
     resp.reason = "The JSON object must be str, bytes or bytearray, not StringIO"
     content = buffer
     with self.assertRaises(TypeError):
         model.response(resp, content)
Example #14
0
 def test_retry_connection_errors_non_resumable(self):
     model = JsonModel()
     request = HttpRequest(
         HttpMockWithErrors(3, {'status': '200'}, '{"foo": "bar"}'),
         model.response, u'https://www.example.com/json_api_endpoint')
     request._sleep = lambda _x: 0  # do nothing
     request._rand = lambda: 10
     response = request.execute(num_retries=3)
     self.assertEqual({u'foo': u'bar'}, response)
Example #15
0
 def test_error_response(self):
     http = HttpMock(datafile('bad_request.json'), {'status': '400'})
     model = JsonModel()
     request = HttpRequest(
         http,
         model.response,
         'https://www.googleapis.com/someapi/v1/collection/?foo=bar',
         method='GET',
         headers={})
     self.assertRaises(HttpError, request.execute)
Example #16
0
 def test_no_retry_connection_errors(self):
     model = JsonModel()
     request = HttpRequest(
         HttpMockWithNonRetriableErrors(1, {'status': '200'},
                                        '{"foo": "bar"}'), model.response,
         u'https://www.example.com/json_api_endpoint')
     request._sleep = lambda _x: 0  # do nothing
     request._rand = lambda: 10
     with self.assertRaises(socket.error):
         response = request.execute(num_retries=3)
 def get(self, project, zone, operation):
     if operation == valid_operation_id:
         http = HttpMock(
             'tests/data/gcp/zoneOperations.get.json', {'status': '200'})
         model = JsonModel()
         uri = 'some_uri'
         method = 'GET'
         return HttpRequest(
             http,
             model.response,
             uri,
             method=method,
             headers={}
         )
     elif operation == pending_operation_id:
         http = HttpMock(
             'tests/data/gcp/zoneOperations.get.running.json', {'status': '200'})
         model = JsonModel()
         uri = 'some_uri'
         method = 'GET'
         return HttpRequest(
             http,
             model.response,
             uri,
             method=method,
             headers={}
         )
     elif operation == error_operation_id:
         http = HttpMock(
             'tests/data/gcp/zoneOperations.get.error.json', {'status': '200'})
         model = JsonModel()
         uri = 'some_uri'
         method = 'GET'
         return HttpRequest(
             http,
             model.response,
             uri,
             method=method,
             headers={}
         )
     else:
         return None
 def aggregatedList(self, project, filter=None):
     http = HttpMock('tests/data/gcp/instances.aggregatedList.json',
                     {'status': '200'})
     model = JsonModel()
     uri = 'some_uri'
     method = 'GET'
     return HttpRequest(http,
                        model.response,
                        uri,
                        method=method,
                        headers={})
Example #19
0
    def test_bad_response(self):
        model = JsonModel(data_wrapper=False)
        resp = httplib2.Response({'status': '401'})
        resp.reason = 'Unauthorized'
        content = '{"error": {"message": "not authorized"}}'

        try:
            content = model.response(resp, content)
            self.fail('Should have thrown an exception')
        except HttpError, e:
            self.assertTrue('not authorized' in str(e))
 def delete(self, project, zone, disk):
     if disk == delete_disk_name or disk == valid_disk_name:
         http = HttpMock('tests/data/gcp/disks.delete.json',
                         {'status': '200'})
         model = JsonModel()
         uri = 'some_uri'
         method = 'DELETE'
         return HttpRequest(http,
                            model.response,
                            uri,
                            method=method,
                            headers={})
 def delete(self, project, snapshot):
     if snapshot == delete_snapshot_name or snapshot == valid_snapshot_name:
         http = HttpMock('tests/data/gcp/snapshots.delete.json',
                         {'status': '200'})
         model = JsonModel()
         uri = 'some_uri'
         method = 'DELETE'
         return HttpRequest(http,
                            model.response,
                            uri,
                            method=method,
                            headers={})
    def test_user_agent(self):
        model = JsonModel(data_wrapper=False)

        headers = {"user-agent": "my-test-app/1.23.4"}
        path_params = {}
        query_params = {}
        body = {}

        headers, unused_params, unused_query, body = model.request(
            headers, path_params, query_params, body)

        self.assertEqual(headers["user-agent"], "my-test-app/1.23.4 (gzip)")
 def detachDisk(self, project, zone, instance, deviceName):
     if instance == valid_vm_id:
         http = HttpMock('tests/data/gcp/instances.detachDisk.json',
                         {'status': '200'})
         model = JsonModel()
         uri = 'some_uri'
         method = 'POST'
         return HttpRequest(http,
                            model.response,
                            uri,
                            method=method,
                            headers={})
Example #24
0
def build_from_document(service,
                        base=None,
                        future=None,
                        http=None,
                        developerKey=None,
                        model=None,
                        requestBuilder=HttpRequest):
    """Create a Resource for interacting with an API.

  Same as `build()`, but constructs the Resource object from a discovery
  document that is it given, as opposed to retrieving one over HTTP.

  Args:
    service: string or object, the JSON discovery document describing the API.
      The value passed in may either be the JSON string or the deserialized
      JSON.
    base: string, base URI for all HTTP requests, usually the discovery URI.
      This parameter is no longer used as rootUrl and servicePath are included
      within the discovery document. (deprecated)
    future: string, discovery document with future capabilities (deprecated).
    http: httplib2.Http, An instance of httplib2.Http or something that acts
      like it that HTTP requests will be made through.
    developerKey: string, Key for controlling API usage, generated
      from the API Console.
    model: Model class instance that serializes and de-serializes requests and
      responses.
    requestBuilder: Takes an http request and packages it up to be executed.

  Returns:
    A Resource object with methods for interacting with the service.
  """

    # future is no longer used.
    future = {}

    if isinstance(service, basestring):
        service = simplejson.loads(service)
    base = urlparse.urljoin(service['rootUrl'], service['servicePath'])
    schema = Schemas(service)

    if model is None:
        features = service.get('features', [])
        model = JsonModel('dataWrapper' in features)
    return Resource(http=http,
                    baseUrl=base,
                    model=model,
                    developerKey=developerKey,
                    requestBuilder=requestBuilder,
                    resourceDesc=service,
                    rootDesc=service,
                    schema=schema)
 def createSnapshot(self, project, zone, disk, body):
     if disk == valid_disk_name:
         http = HttpMock('tests/data/gcp/disks.createSnapshot.json',
                         {'status': '200'})
         model = JsonModel()
         uri = 'some_uri'
         method = 'POST'
         return HttpRequest(http,
                            model.response,
                            uri,
                            method=method,
                            headers={})
     elif disk == invalid_disk_name:
         http = HttpMock('tests/data/gcp/disks.createSnapshot1.json',
                         {'status': '200'})
         model = JsonModel()
         uri = 'some_uri'
         method = 'POST'
         return HttpRequest(http,
                            model.response,
                            uri,
                            method=method,
                            headers={})
 def get(self, project, zone, instance):
     if instance == valid_vm_id:
         http = HttpMock('tests/data/gcp/instances.get.json',
                         {'status': '200'})
         model = JsonModel()
         uri = 'some_uri'
         method = 'GET'
         return HttpRequest(http,
                            model.response,
                            uri,
                            method=method,
                            headers={})
     else:
         return None
    def test_logging(self):
        class MockLogging(object):
            def __init__(self):
                self.info_record = []
                self.debug_record = []

            def info(self, message, *args):
                self.info_record.append(message % args)

            def debug(self, message, *args):
                self.debug_record.append(message % args)

        class MockResponse(dict):
            def __init__(self, items):
                super(MockResponse, self).__init__()
                self.status = items["status"]
                for key, value in six.iteritems(items):
                    self[key] = value

        old_logging = googleapiclient.model.LOGGER
        googleapiclient.model.LOGGER = MockLogging()
        googleapiclient.model.dump_request_response = True
        model = JsonModel()
        request_body = {"field1": "value1", "field2": "value2"}
        body_string = model.request({}, {}, {}, request_body)[-1]
        json_body = json.loads(body_string)
        self.assertEqual(request_body, json_body)

        response = {
            "status": 200,
            "response_field_1": "response_value_1",
            "response_field_2": "response_value_2",
        }
        response_body = model.response(MockResponse(response), body_string)
        self.assertEqual(request_body, response_body)
        self.assertEqual(
            googleapiclient.model.LOGGER.info_record[:2],
            ["--request-start--", "-headers-start-"],
        )
        self.assertTrue("response_field_1: response_value_1" in
                        googleapiclient.model.LOGGER.info_record)
        self.assertTrue("response_field_2: response_value_2" in
                        googleapiclient.model.LOGGER.info_record)
        self.assertEqual(
            json.loads(googleapiclient.model.LOGGER.info_record[-2]),
            request_body)
        self.assertEqual(googleapiclient.model.LOGGER.info_record[-1],
                         "--response-end--")
        googleapiclient.model.LOGGER = old_logging
    def test_json_body_data_wrapper(self):
        model = JsonModel(data_wrapper=True)

        headers = {}
        path_params = {}
        query_params = {}
        body = {}

        headers, unused_params, query, body = model.request(
            headers, path_params, query_params, body)

        self.assertEqual(headers["accept"], "application/json")
        self.assertEqual(headers["content-type"], "application/json")
        self.assertNotEqual(query, "")
        self.assertEqual(body, '{"data": {}}')
    def test_json_no_body(self):
        model = JsonModel(data_wrapper=False)

        headers = {}
        path_params = {}
        query_params = {}
        body = None

        headers, unused_params, query, body = model.request(
            headers, path_params, query_params, body)

        self.assertEqual(headers["accept"], "application/json")
        self.assertTrue("content-type" not in headers)
        self.assertNotEqual(query, "")
        self.assertEqual(body, None)
Example #30
0
    def test_json_body(self):
        model = JsonModel(data_wrapper=False)

        headers = {}
        path_params = {}
        query_params = {}
        body = {}

        headers, unused_params, query, body = model.request(
            headers, path_params, query_params, body)

        self.assertEqual(headers['accept'], 'application/json')
        self.assertEqual(headers['content-type'], 'application/json')
        self.assertNotEqual(query, '')
        self.assertEqual(body, '{}')