def test_should_update_temp_response_with_actual(self): req = _make_test_request(self.SERVICE_NAME, self.FAKE_OPERATION_ID) temp_response = sc_messages.AllocateQuotaResponse( operationId=self.FAKE_OPERATION_ID) real_response = sc_messages.AllocateQuotaResponse( operationId=self.FAKE_OPERATION_ID, quotaMetrics=[sc_messages.MetricValueSet( metricName=u'a_float', metricValues=[ metric_value.create( labels={ u'key1': u'value1', u'key2': u'value2'}, doubleValue=1.1, ), ] )] ) agg = self.agg agg.allocate_quota(req) signature = quota_request.sign(req.allocateQuotaRequest) with agg._cache as cache: item = cache[signature] expect(item.response).to(equal(temp_response)) expect(item.is_in_flight).to(be_true) agg.add_response(req, real_response) item = cache[signature] expect(item.response).to(equal(real_response)) expect(item.is_in_flight).to(be_false)
def test_expiration(self): req = _make_test_request(self.SERVICE_NAME, self.FAKE_OPERATION_ID) temp_response = sc_messages.AllocateQuotaResponse( operationId=self.FAKE_OPERATION_ID) real_response = sc_messages.AllocateQuotaResponse( operationId=self.FAKE_OPERATION_ID, quotaMetrics=[sc_messages.MetricValueSet( metricName=u'a_float', metricValues=[ metric_value.create( labels={ u'key1': u'value1', u'key2': u'value2'}, doubleValue=1.1, ), ] )] ) agg = self.agg agg.allocate_quota(req) assert len(agg.flush()) == 1 agg.add_response(req, real_response) signature = quota_request.sign(req.allocateQuotaRequest) with agg._cache as cache, agg._out as out: assert len(out) == 0 assert signature in cache self.timer.tick() self.timer.tick() assert len(agg.flush()) == 0 assert len(out) == 0 assert signature in cache self.timer.tick() # expired at 3rd second assert len(agg.flush()) == 0 assert len(out) == 0 assert signature not in cache
def test_should_send_quota_requests_with_no_param(self): wrappee = _DummyWsgiApp() control_client = mock.MagicMock(spec=client.Client) given = { u'wsgi.url_scheme': u'http', u'PATH_INFO': u'/uvw/method2/with_no_param', u'REMOTE_ADDR': u'192.168.0.3', u'HTTP_HOST': u'localhost', u'HTTP_REFERER': u'example.myreferer.com', u'REQUEST_METHOD': u'GET'} dummy_response = sc_messages.CheckResponse( operationId=u'fake_operation_id') wrapped = wsgi.add_all(wrappee, self.PROJECT_ID, control_client, loader=service.Loaders.ENVIRONMENT) control_client.check.return_value = dummy_response control_client.allocate_quota.side_effect = lambda req: sc_messages.AllocateQuotaResponse( operationId=req.allocateQuotaRequest.allocateOperation.operationId) wrapped(given, _dummy_start_response) expect(control_client.check.called).to(be_true) req = control_client.check.call_args[0][0] expect(req.checkRequest.operation.consumerId).to( equal(u'project:middleware-with-params')) expect(control_client.report.called).to(be_true) expect(control_client.allocate_quota.called).to(be_true)
def test_request_extraction_with_aggregation(self): req = _make_test_request(self.SERVICE_NAME, self.FAKE_OPERATION_ID) req = req.allocateQuotaRequest req.allocateOperation.quotaMetrics = [ sc_messages.MetricValueSet( metricName=u'a_float', metricValues=[ metric_value.create( labels={ u'key1': u'value1', u'key2': u'value2'}, int64Value=12, ), ] ) ] resp = sc_messages.AllocateQuotaResponse( operationId=self.FAKE_OPERATION_ID) item = quota_request.CachedItem(req, resp, self.SERVICE_NAME, None) expect(item._op_aggregator).to(be_none) item.aggregate(req) item.aggregate(req) extracted = item.extract_request() op = extracted.allocateQuotaRequest.allocateOperation expect(op.quotaMetrics[0].metricValues[0].int64Value).to(equal(24))
def test_should_return_none_initially_as_req_is_not_cached(self): req = _make_test_request(self.SERVICE_NAME, self.FAKE_OPERATION_ID) fake_response = sc_messages.AllocateQuotaResponse( operationId=self.FAKE_OPERATION_ID) agg = self.agg actual = agg.allocate_quota(req) expect(actual).to(equal(fake_response))
def test_request_extraction_no_aggregation(self): req = _make_test_request(self.SERVICE_NAME, self.FAKE_OPERATION_ID) a_req = req.allocateQuotaRequest resp = sc_messages.AllocateQuotaResponse( operationId=self.FAKE_OPERATION_ID) item = quota_request.CachedItem(a_req, resp, self.SERVICE_NAME, None) expect(item._op_aggregator).to(be_none) expect(item.extract_request()).to(equal(req))
def test_should_return_dummy_response_if_transport_fails(self, dummy_thread_class): self._subject.start() dummy_request = _make_dummy_quota_request(self.PROJECT_ID, self.SERVICE_NAME) dummy_response = sc_messages.AllocateQuotaResponse( operationId=dummy_request.allocateQuotaRequest.allocateOperation.operationId) self._mock_transport.services.AllocateQuota.side_effect = exceptions.Error() expect(self._subject.allocate_quota(dummy_request)).to(equal(dummy_response))
def test_should_not_cache_responses(self): req = _make_test_request(self.SERVICE_NAME) fake_response = sc_messages.AllocateQuotaResponse( operationId=self.FAKE_OPERATION_ID) agg = self.agg expect(agg.allocate_quota(req)).to(be_none) agg.add_response(req, fake_response) expect(agg.allocate_quota(req)).to(be_none) agg.clear() expect(agg.allocate_quota(req)).to(be_none)
def test_should_include_project_id_in_error_text_when_needed(self): resp = sc_messages.AllocateQuotaResponse( allocateErrors = [ sc_messages.QuotaError( code=sc_messages.QuotaError.CodeValueValuesEnum.PROJECT_DELETED) ] ) code, got = quota_request.convert_response(resp, self.PROJECT_ID) want = u'Project %s has been deleted' % (self.PROJECT_ID,) expect(code).to(equal(httplib.FORBIDDEN)) expect(got).to(equal(want))
def test_should_include_detail_in_error_text_when_needed(self): detail = u'details, details, details' resp = sc_messages.AllocateQuotaResponse( allocateErrors = [ sc_messages.QuotaError( code=sc_messages.QuotaError.CodeValueValuesEnum.OUT_OF_RANGE, description=detail) ] ) code, got = quota_request.convert_response(resp, self.PROJECT_ID) expect(code).to(equal(httplib.INTERNAL_SERVER_ERROR)) assert got.endswith(detail)
def test_aggregated_requests_should_be_sent_on_flush(self): req = _make_test_request(self.SERVICE_NAME, self.FAKE_OPERATION_ID) signature = quota_request.sign(req.allocateQuotaRequest) agg = self.agg agg.allocate_quota(req) expect(len(agg.flush())).to(equal(1)) # initial request simple_response = sc_messages.AllocateQuotaResponse( operationId=self.FAKE_OPERATION_ID) agg.add_response(req, simple_response) agg.allocate_quota(req) agg.allocate_quota(req) expect(len(agg.flush())).to(equal(1)) # aggregated next two requests
def test_should_not_send_the_request_if_cached(self, dummy_thread_class): t = self._mock_transport self._subject.start() dummy_request = _make_dummy_quota_request(self.PROJECT_ID, self.SERVICE_NAME) dummy_response = sc_messages.AllocateQuotaResponse( operationId=dummy_request.allocateQuotaRequest.allocateOperation.operationId) t.services.AllocateQuota.return_value = dummy_response expect(self._subject.allocate_quota(dummy_request)).to(equal(dummy_response)) t.reset_mock() expect(self._subject.allocate_quota(dummy_request)).to(equal(dummy_response)) expect(t.services.AllocateQuota.called).to(be_false)
def test_should_cache_responses(self): req = _make_test_request(self.SERVICE_NAME, self.FAKE_OPERATION_ID) temp_response = sc_messages.AllocateQuotaResponse( operationId=self.FAKE_OPERATION_ID) real_response = sc_messages.AllocateQuotaResponse( operationId=self.FAKE_OPERATION_ID, quotaMetrics=[sc_messages.MetricValueSet( metricName=u'a_float', metricValues=[ metric_value.create( labels={ u'key1': u'value1', u'key2': u'value2'}, doubleValue=1.1, ), ] )] ) agg = self.agg expect(agg.allocate_quota(req)).to(equal(temp_response)) agg.add_response(req, real_response) expect(agg.allocate_quota(req)).to(equal(real_response))
def test_request_aggregation(self): req = _make_test_request(self.SERVICE_NAME, self.FAKE_OPERATION_ID) req = req.allocateQuotaRequest resp = sc_messages.AllocateQuotaResponse( operationId=self.FAKE_OPERATION_ID) item = quota_request.CachedItem(req, resp, self.SERVICE_NAME, None) expect(item._op_aggregator).to(be_none) with mock.patch.object(quota_request, 'QuotaOperationAggregator') as QOA: agg = QOA.return_value item.aggregate(req) expect(item._op_aggregator).to(be(agg)) QOA.assert_called_once_with(req.allocateOperation) item.aggregate(req) agg.merge_operation.assert_called_once_with(req.allocateOperation)
def test_handle_out_of_quota(control_client, test_app): quota_resp = sc_messages.AllocateQuotaResponse(allocateErrors=[ sc_messages.QuotaError( code=quota_request._QuotaErrors.RESOURCE_EXHAUSTED, description=u'details') ]) check_resp = sc_messages.CheckResponse(operationId=u'fake_operation_id') control_client.check.return_value = check_resp control_client.allocate_quota.return_value = quota_resp url = '/uvw/method2/with_no_param' resp = test_app.get(url, expect_errors=True) expected_status, expected_detail = quota_request._QUOTA_ERROR_CONVERSION[ quota_request._QuotaErrors.RESOURCE_EXHAUSTED] assert resp.status_code == expected_status assert resp.content_type == 'application/json' assert expected_detail in resp.json['message']
def test_should_be_ok_with_no_errors(self): code, message = quota_request.convert_response( sc_messages.AllocateQuotaResponse(), self.PROJECT_ID) expect(code).to(equal(httplib.OK)) expect(message).to(equal(u''))