def test_base_service_process_request_picks_next_interaction_after_reaches_max_replays( dispatcher): request_set_config = MITMRequest( method='POST', url='http://mitm-manager.local/config', body='{"active_scenario": "test_scenario_replays_once_and_takes_next"}', headers=MITMHeaders({ 'Host': ['mitm-manager.local'], 'Accept': ['application/json'], })) same_request = MITMRequest(method='GET', url='https://host_a.local/api', headers=MITMHeaders({ 'Host': ['host_a.local'], 'Accept': ['application/json'], })) response_set_config = dispatcher.process_request(request_set_config) assert response_set_config.status_code == 201 response_1 = dispatcher.process_request(same_request) assert response_1.body == b'test_scenario_replays_ok/TestServiceA/0' response_2 = dispatcher.process_request(same_request) assert response_2.body == b'test_scenario_replays_ok/TestServiceA/1'
def test_base_service_process_request_scenario_raise_if_no_interaction( dispatcher): request_set_config = MITMRequest( method='POST', url='http://mitm-manager.local/config', body='{"active_scenario": "test_scenario_raise_if_no_interaction"}', headers=MITMHeaders({ 'Host': ['mitm-manager.local'], 'Accept': ['application/json'], })) request_service_1 = MITMRequest(method='GET', body='correct body content', url='https://host_a.local/api', headers=MITMHeaders({ 'Host': ['host_a.local'], 'Accept': ['application/json'], })) request_service_2 = MITMRequest(method='GET', url='http://host_b.local/api', headers=MITMHeaders({ 'Host': ['host_b.local'], 'Accept': ['application/json'], })) response_set_config = dispatcher.process_request(request_set_config) assert response_set_config.status_code == 201 response_service_1 = dispatcher.process_request(request_service_1) assert response_service_1.body == b'test_scenario_raise_if_no_interaction/TestServiceA/0' with raises(ScenarioNotInService): dispatcher.process_request(request_service_2)
def test_base_service_process_request_scenario1(dispatcher, request): request_set_config = MITMRequest( method='POST', url='http://mitm-manager.local/config', body='{"active_scenario": "test_scenario1"}', headers=MITMHeaders({ 'Host': ['mitm-manager.local'], 'Accept': ['application/json'], })) request_service_1 = MITMRequest(method='GET', url='https://host_a.local/api', headers=MITMHeaders({ 'Host': ['host_a.local'], 'Accept': ['application/json'], })) request_service_2 = MITMRequest(method='GET', url='https://host_b.local/api', headers=MITMHeaders({ 'Host': ['host_b.local'], 'Accept': ['application/json'], })) response_set_config = dispatcher.process_request(request_set_config) assert response_set_config.status_code == 201 response_service_1 = dispatcher.process_request(request_service_1) assert response_service_1.body == b'test_scenario1/TestServiceA/0' response_service_2 = dispatcher.process_request(request_service_2) assert response_service_2.body == b'test_scenario1/TestServiceB/0'
def test_base_service_handles_request(service: BaseService, request_: dict, handled: bool): request_ = MITMRequest( url=request_['url'], headers=MITMHeaders(request_['headers']), ) assert service.handles_request(request_) == handled
def test_management_service_get_services(dispatcher): result = dispatcher.process_request( MITMRequest(method='GET', url='http://mitm-manager.local/services', headers=MITMHeaders({ 'Host': ['mitm-manager.local'], 'Accept': ['application/json'], }))) expected = { 'services': [ { 'type': 'ManagementService', 'name': 'ManagementService', 'hosts_list': ['mitm-manager.local'], }, { 'type': 'BaseService', 'name': 'TestService', 'hosts_list': ['test-service.local'], }, ], } assert result.status_code == 200 assert json.loads(result.body) == expected
def test_dispatcher_process_request_fail_if_none_match(dispatcher): with raises(NoServicesForRequest): dispatcher.process_request( MITMRequest(url='http://test-service-z.local/does_not_exist', headers=MITMHeaders({ 'Accept': ['text/plain'], })))
def test_whitelist_service_defaults(service_url): dispatcher = Dispatcher() with pytest.raises(DoNotIntercept): dispatcher.process_request(MITMRequest( method='GET', url=service_url, ))
def test_management_service_set_recording_malformed_raises( management_service, request_body): request = MITMRequest(method='PUT', url='http://mitm-manager.local/record', body=request_body) with raises(InvalidRequest): management_service.set_recording(request)
def test_management_service_get_scenarios(fake_scenarios_dir, dispatcher): result = dispatcher.process_request( MITMRequest(method='GET', url='http://mitm-manager.local/scenarios', headers=MITMHeaders({ 'Host': ['mitm-manager.local'], 'Accept': ['application/json'], }))) expected = { 'scenario1': { 'responses': { 'A': ['1.yaml', '2.yaml'], } }, 'scenario2': { 'responses': { 'A': ['1.yaml'], 'B': ['1.yaml', '2.yaml', '3.yaml'], } }, } assert result.status_code == 200 assert json_loads(result.body) == expected
def test_dispatcher_process_request(dispatcher, url, message): result = dispatcher.process_request( MITMRequest(url=url, headers=MITMHeaders({ 'Accept': ['text/plain'], }))) assert result.body == message
def test_management_service_post_config_malformed_raises(management_service): with raises(InvalidRequest): management_service.put_config( MITMRequest( method='POST', url='http://mitm-manager.local/config', body='definitely not valid JSON', ))
def test_management_service_set_services_raises_invalid_request( management_service): service_update = MITMRequest(method='PUT', url='http://mitm-manager.local', body='not valid json') with raises(InvalidRequest): management_service.set_services(service_update)
def test_base_service_get_interactions_for_active_scenario(service: BaseService, scenarios_dir): expected_request_1 = MITMRequest( headers=MITMHeaders({ 'Accept': ['application/json'], 'Accept-Encoding': ['gzip, deflate'], 'Connection': ['keep-alive'], 'User-Agent': ['python-requests/2.18.4'] }), method='GET', url='https://host_a.local/api', ) expected_response_1 = MITMResponse( body='{"value": "response1"}', headers=MITMHeaders({ 'content-type': ['application/json; charset=UTF-8'] }), status_code=200, ) expected_request_2 = MITMRequest( body='{"value": "response2"}', headers=MITMHeaders({ 'Accept': ['application/json'], 'Accept-Encoding': ['gzip, deflate'], 'Connection': ['keep-alive'], 'User-Agent': ['python-requests/2.18.4'] }), method='POST', url='https://host_a.local/api', ) expected_response_2 = MITMResponse( headers=MITMHeaders({ 'content-type': ['application/json; charset=UTF-8'] }), status_code=201, ) interactions = service.get_interactions_for_active_scenario() assert len(interactions) == 2 assert interactions[0].request == expected_request_1 assert interactions[0].response == expected_response_1 assert interactions[1].request == expected_request_2 assert interactions[1].response == expected_response_2
def test_management_service_put_config_malformed_raises(management_service, request_body): request = MITMRequest( method='PUT', url='http://mitm-manager.local', body=request_body, ) with raises(InvalidRequest): management_service.put_config(request)
def test_whitelist_service_raises(dispatcher): with raises(DoNotIntercept): dispatcher.process_request( MITMRequest(method='GET', url='http://test-indexer:9200/records-hep/fake', body="{}", headers=MITMHeaders({ 'Host': ['test-indexer:9200'], 'Accept': ['application/json'], })))
def sample_request(request) -> MITMRequest: return MITMRequest( body='body content', headers=MITMHeaders({ 'Accept': ['text/plain'], 'Connection': ['keep-alive'], 'User-Agent': ['python-requests/2.18.4'] }), method='GET', url='https://domain.local/path;param?query=value', )
def test_management_service_post_and_put_config(dispatcher): post_config_request = MITMRequest( method='POST', url='http://mitm-manager.local/config', body='{"active_scenario": "a scenario", "another": "value"}', headers=MITMHeaders({ 'Host': ['mitm-manager.local'], 'Accept': ['application/json'], })) put_config_request = MITMRequest( method='PUT', url='http://mitm-manager.local/config', body='{"active_scenario": "another scenario"}', headers=MITMHeaders({ 'Host': ['mitm-manager.local'], 'Accept': ['application/json'], })) get_config_request = MITMRequest(method='GET', url='http://mitm-manager.local/config', headers=MITMHeaders({ 'Host': ['mitm-manager.local'], 'Accept': ['application/json'], })) expected_config = { 'active_scenario': 'another scenario', 'another': 'value', } post_req = dispatcher.process_request(post_config_request) assert post_req.status_code == 201 put_req = dispatcher.process_request(put_config_request) assert put_req.status_code == 204 result = dispatcher.process_request(get_config_request) assert result.status_code == 200 assert json_loads(result.body) == expected_config
def test_process_request_fails_on_unknown_request(service: BaseService, scenarios_dir): request = MITMRequest( body='{"value": "whatever"}', headers=MITMHeaders({ 'Accept': ['application/json'], }), method='PUT', url='https://host_a.local/this/path/is/not/handled', ) with raises(NoMatchingRecording): service.process_request(request)
def test_management_service_set_services_raises_invalid_service_params( management_service): service_update = MITMRequest(method='PUT', url='http://mitm-manager.local', body=json.dumps({ 'services': [{ 'type': 'BaseService', 'there is no such param': 42, }] })) with raises(InvalidServiceParams): management_service.set_services(service_update)
def test_get_service_interactions_raises(dispatcher: Dispatcher): request_set_config = MITMRequest( method='POST', url='http://mitm-manager.local/config', body='{"active_scenario": "test_scenario_replays_ok"}', headers=MITMHeaders({ 'Host': ['mitm-manager.local'], 'Accept': ['application/json'], })) request_inexistent_service_interactions = MITMRequest( method='GET', url='http://mitm-manager.local/service/InexistentService/interactions', headers=MITMHeaders({ 'Host': ['mitm-manager.local'], 'Accept': ['application/json'], })) response_set_config = dispatcher.process_request(request_set_config) assert response_set_config.status_code == 201 with raises(ServiceNotFound): dispatcher.process_request(request_inexistent_service_interactions)
def test_interaction_next_in_dir( tmpdir, interaction_dir_files: List[str], expected_next_interaction_name: str, ): interaction_dir = tmpdir.mkdir('interactions') for file_name in interaction_dir_files: interaction_dir.join(file_name).ensure() interaction_dir_path = Path(interaction_dir.strpath) result = Interaction.next_in_dir(directory=interaction_dir_path, request=MITMRequest( url='http://test.local/', method='GET'), response=MITMResponse(status_code=204)) expected_request = MITMRequest(url='http://test.local/', method='GET') expected_response = MITMResponse(status_code=204) assert expected_next_interaction_name == result.name assert expected_request == result.request assert expected_response == result.response
def test_base_service_process_request_scenario2_and_raise(dispatcher, request): request_set_config = MITMRequest( method='POST', url='http://mitm-manager.local/config', body='{"active_scenario": "test_scenario2"}', headers=MITMHeaders({ 'Host': ['mitm-manager.local'], 'Accept': ['application/json'], })) request_service_1 = MITMRequest(method='GET', body='correct body content', url='https://host_a.local/api', headers=MITMHeaders({ 'Host': ['host_a.local'], 'Accept': ['application/json'], })) request_service_2 = MITMRequest(method='GET', url='http://host_b.local/api', headers=MITMHeaders({ 'Host': ['host_b.local'], 'Accept': ['application/json'], })) with patch('requests.request') as request_func: response_set_config = dispatcher.process_request(request_set_config) assert response_set_config.status_code == 201 sleep(1) request_func.assert_called_once() response_service_1 = dispatcher.process_request(request_service_1) assert response_service_1.body == b'test_scenario2/TestServiceA/0' with raises(ScenarioNotFound): dispatcher.process_request(request_service_2)
def test_management_service_put_config(management_service): management_service.put_config( MITMRequest(url='http://mitm-manager.local/config', body='{"active_scenario": "a scenario"}')) result = management_service.config expected = { 'active_scenario': 'a scenario', 'a_setting': 'value', } assert expected == result for service in management_service.services: assert service.active_scenario == 'a scenario'
def test_base_service_process_request_test_scenario_replays_ok(dispatcher): request_set_config = MITMRequest( method='POST', url='http://mitm-manager.local/config', body='{"active_scenario": "test_scenario_replays_ok"}', headers=MITMHeaders({ 'Host': ['mitm-manager.local'], 'Accept': ['application/json'], })) request_service_1 = MITMRequest(method='GET', url='https://host_a.local/api', headers=MITMHeaders({ 'Host': ['host_a.local'], 'Accept': ['application/json'], })) request_service_2 = MITMRequest(method='GET', url='https://host_b.local/api', headers=MITMHeaders({ 'Host': ['host_b.local'], 'Accept': ['application/json'], })) response_set_config = dispatcher.process_request(request_set_config) assert response_set_config.status_code == 201 with patch('requests.request') as request: response_service_1 = dispatcher.process_request(request_service_1) assert response_service_1.body == b'test_scenario_replays_ok/TestServiceA/0' sleep(1) # Wait for the callback request.assert_called_once() response_service_2 = dispatcher.process_request(request_service_2) assert response_service_2.body == b'test_scenario_replays_ok/TestServiceB/0'
def test_management_service_get_config(dispatcher): result = dispatcher.process_request( MITMRequest(method='GET', url='http://mitm-manager.local/config', headers=MITMHeaders({ 'Host': ['mitm-manager.local'], 'Accept': ['application/json'], }))) expected = { 'active_scenario': 'default', } assert result.status_code == 200 assert json_loads(result.body) == expected
def test_management_service_set_services_raises_invalid_service_type( management_service): service_update = MITMRequest(method='PUT', url='http://mitm-manager.local', body=json.dumps({ 'services': [{ 'type': 'There is no such service type', 'name': 'UpdatedService', 'hosts_list': ['new_domain.local'], }] })) with raises(InvalidServiceType): management_service.set_services(service_update)
def test_should_replay_only_once(service: BaseService, scenarios_dir): interaction = service.get_interactions_for_active_scenario()[0] interaction.max_replays = 1 assert service.should_replay(interaction) request_1 = MITMRequest( headers=MITMHeaders({ 'Accept': ['application/json'], 'Accept-Encoding': ['gzip, deflate'], 'Connection': ['keep-alive'], 'User-Agent': ['python-requests/2.18.4'] }), method='GET', url='https://host_a.local/api', ) service.process_request(request_1) assert not service.should_replay(interaction)
def test_management_service_post_config(management_service): management_service.post_config( MITMRequest( method='POST', url='http://mitm-manager.local/config', body='{"active_scenario": "a scenario"}', )) result = management_service.config expected = { 'active_scenario': 'a scenario', } assert expected == result for service in management_service.services: assert service.active_scenario == 'a scenario'
def _test_match_request_data_generate_requests(test_data): params = [] ids = [] for scenario in test_data: _request = MITMRequest( method=scenario[0], body=scenario[1], url=scenario[2], headers=scenario[3], ) params.append(_request) ids.append(repr(_request)) return { 'argnames': '_request', 'argvalues': params, 'ids': ids, }
def test_management_service_set_recording(management_service, request_body, expected_state): expected_response = { 'enabled': expected_state, } result_response = management_service.set_recording( MITMRequest(method='PUT', url='http://mitm-manager.local/record', body=request_body)) result = management_service.is_recording assert expected_state == result for service in management_service.services: assert expected_state == service.is_recording assert expected_response == result_response