def test_basic_transport(): """ it should get transport from config it should call rate_limit_func on _make_request """ config = Config() config.createFromAPIKey("AAAAAAAAAAAAAAAAA") config["transport"] = "basic" resource = BaseResource(config) assert resource._config == config assert isinstance(resource._transport, BasicTransport) resource._transport._opener.open = mock.Mock() resource._transport._opener.open.return_value = MockResponse(200, {}) resource._transport._rate_limit_func = mock.Mock() res = resource._make_request("GET", "my_path") assert res == {} resource._transport._rate_limit_func.assert_called_once_with({ "by": "customer", "limit": 10, "period": 1, "remaining": 100 })
def test_basic_transport_pagination(): config = Config() config.createFromAPIKey("AAAAAAAAAAAAAAAAA") config["transport"] = "basic" config["follow_pagination"] = True resource = BaseResource(config) resource._transport._opener.open = mock.Mock() resource._transport._opener.open.side_effect = [ MockResponse(200, [{ "1st": "" }], {"Link": "<http://a.co/b>; rel=next;"}), MockResponse(200, [{ "2nd": "" }], {"Link": "<http://a.co/c>; rel=next;"}), MockResponse(200, [{ "3rd": "" }]), ] resource._transport._rate_limit_func = mock.Mock() def pagination_handler(jsonOut, next_json): jsonOut.extend(next_json) return jsonOut res = resource._make_request("GET", "my_path", pagination_handler=pagination_handler) assert res == [{"1st": ""}, {"2nd": ""}, {"3rd": ""}]
def test_rate_limiting_strategies(): """ it should set the right func from config """ config = Config() config.createFromAPIKey("AAAAAAAAAAAAAAAAA") resource = BaseResource(config) rate_limit_func_name = resource._transport._rate_limit_func.__name__ assert rate_limit_func_name == "default_rate_limit_func" config["rate_limit_strategy"] = "solo" resource = BaseResource(config) rate_limit_func_name = resource._transport._rate_limit_func.__name__ assert rate_limit_func_name == "solo_rate_limit_func" config["rate_limit_strategy"] = "concurrent" config["parallelism"] = 11 resource = BaseResource(config) rate_limit_func_name = resource._transport._rate_limit_func.__name__ assert rate_limit_func_name == "concurrent_rate_limit_func"
def test_twisted_transport(): """ it should get transport from config """ config = Config() config.createFromAPIKey("AAAAAAAAAAAAAAAAA") config["transport"] = "twisted" resource = BaseResource(config) assert resource._config == config assert isinstance(resource._transport, TwistedTransport)
def test_twisted(): """ basic test exercising rate-limiting, pagination, and response flow during a request. """ from twisted.internet import defer, reactor config = Config() config.createFromAPIKey("AAAAAAAAAAAAAAAAA") config["transport"] = "twisted" config["follow_pagination"] = True resource = BaseResource(config) assert resource._config == config assert isinstance(resource._transport, TwistedTransport) # setup mocks # rate-limiting resource._transport._rate_limit_func = mock.Mock() # first response d1 = defer.Deferred() d1.addCallback(lambda x: MockResponse( headers={"Link": ["<http://a.co/b>; rel=next;"]}, body=[{ "1st": "" }], )) reactor.callLater(0, d1.callback, None) # second response d2 = defer.Deferred() d2.addCallback(lambda x: MockResponse(body=[{"2nd": ""}])) reactor.callLater(0, d2.callback, None) resource._transport.agent.request = mock.Mock(side_effect=[d1, d2]) # pagination def _pagination_handler(jsonOut, next_json): # don't mutate args, since assertions operate on references to them out = deepcopy(jsonOut) out.extend(next_json) return out pagination_handler = mock.Mock(side_effect=_pagination_handler) # callbacks def _cb(result): reactor.stop() def _eb(err): reactor.stop() cb = mock.Mock(side_effect=_cb) eb = mock.Mock(side_effect=_eb) @defer.inlineCallbacks def req(): result = yield resource._make_request( "GET", "my_path", pagination_handler=pagination_handler) defer.returnValue(result) # call our deferred request and add callbacks res = req() res.addCallbacks(cb, eb) # RUN THE LOOP reactor.run() # check our work # we made two requests resource._transport.agent.request.call_count == 2 # we hit our rate-limit function twice, once per request call_args_list = resource._transport._rate_limit_func.call_args_list assert len(call_args_list) == 2 for c in call_args_list: args, kwargs = c assert args == ({ "by": "customer", "limit": 10, "period": 1, "remaining": 100 }, ) assert kwargs == {} # we hit our pagination_handler once, to put the two results together pagination_handler.assert_called_once_with([{"1st": ""}], [{"2nd": ""}]) # our final result is correct cb.assert_called_once_with([{"1st": ""}, {"2nd": ""}]) # errback was not called eb.assert_not_called()