Skip to content

feat: Improve retry on some HTTP errors #550

feat: Improve retry on some HTTP errors

feat: Improve retry on some HTTP errors #550

GitHub Actions / Test Results failed Oct 4, 2024 in 0s

1 fail, 1 skipped, 210 pass in 1m 41s

212 tests  ±0   210 ✅  - 1   1m 41s ⏱️ -5s
  1 suites ±0     1 💤 ±0 
  1 files   ±0     1 ❌ +1 

Results for commit 10af4a8. ± Comparison against earlier commit ca2d05a.

Annotations

Check warning on line 0 in tests.test_action

See this annotation in the file changed.

@github-actions github-actions / Test Results

test_generic_api_action (tests.test_action) failed

artifacts/Unit Test Results/junit.xml [took 0s]
Raw output
requests_mock.exceptions.NoMockAddress: No mock address: GET http://base_url/resource/fake_uuid/count?param=number
storage = PosixPath('/tmp/tmppz3jhblf')

    def test_generic_api_action(storage):
        def init_action():
            action = GenericAPIAction(data_path=storage)
            action.verb = "get"
            action.endpoint = "resource/{uuid}/count"
            action.query_parameters = ["param"]
            action.module.configuration = {"base_url": "http://base_url/"}
            action._wait_param = lambda: wait_none()
            return action
    
        # success
        action = init_action()
        expected_response = {"count": 10}
        arguments = {"uuid": "fake_uuid"}
        with requests_mock.Mocker() as mock:
            mock.get("http://base_url/resource/fake_uuid/count", json=expected_response)
    
            results: dict = action.run(arguments)
    
            assert results == expected_response
            assert mock.call_count == 1
            history = mock.request_history
            assert history[0].method == "GET"
            assert history[0].url == "http://base_url/resource/fake_uuid/count"
    
        # success
        action = init_action()
        arguments = {"uuid": "fake_uuid", "param": "number"}
        with requests_mock.Mocker() as mock:
            mock.get("http://base_url/resource/fake_uuid/count", json=expected_response)
    
            results: dict = action.run(arguments)
    
            assert results == expected_response
            assert mock.call_count == 1
            history = mock.request_history
            assert history[0].method == "GET"
            assert history[0].url == "http://base_url/resource/fake_uuid/count?param=number"
    
        # success with no content
        action = init_action()
        arguments = {"uuid": "fake_uuid", "param": "number"}
        with requests_mock.Mocker() as mock:
            mock.get("http://base_url/resource/fake_uuid/count", status_code=204)
    
            results: dict = action.run(arguments)
    
            assert results is None
            assert mock.call_count == 1
            history = mock.request_history
            assert history[0].method == "GET"
            assert history[0].url == "http://base_url/resource/fake_uuid/count?param=number"
    
        # error on action.run
        action = init_action()
        with requests_mock.Mocker() as mock:
            pytest.raises(KeyError, action.run, {})
    
            assert mock.call_count == 0
    
        # timeout on request then success
        action = init_action()
        arguments = {"uuid": "fake_uuid", "param": "number"}
        with patch("requests.request") as mock:
            mock.side_effect = [Timeout, Mock(json=Mock(return_value=expected_response))]
            results: dict = action.run(arguments)
    
            assert results == expected_response
            assert mock.call_count == 2
            mock.assert_called_with(
                "get",
                "http://base_url/resource/fake_uuid/count?param=number",
                json=arguments,
                headers={"Accept": "application/json"},
                timeout=5,
            )
    
        # error http code
        action = init_action()
        with requests_mock.Mocker() as mock:
            mock.get("http://base_url/resource/fake_uuid/count", status_code=500, json={})
            results: dict = action.run({"uuid": "fake_uuid", "param": "number"})
    
            assert results is None
            assert mock.call_count == 10
    
        action = init_action()
        with requests_mock.Mocker() as mock:
            mock.get("http://base_url/resource/fake_uuid/count", status_code=400, json={})
            results: dict = action.run({"uuid": "fake_uuid", "param": "number"})
    
            assert results is None
            assert mock.call_count == 1
    
        action = init_action()
        with requests_mock.Mocker() as mock:
            mock.delete(
                "http://base_url/resource/fake_uuid/count",
                [{"status_code": 503}, {"status_code": 404}],
            )
>           results: dict = action.run({"uuid": "fake_uuid", "param": "number"})

tests/test_action.py:341: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
pydantic/decorator.py:40: in pydantic.decorator.validate_arguments.validate.wrapper_function
    ???
pydantic/decorator.py:134: in pydantic.decorator.ValidatedFunction.call
    ???
pydantic/decorator.py:206: in pydantic.decorator.ValidatedFunction.execute
    ???
sekoia_automation/action.py:343: in run
    for attempt in Retrying(
.venv/lib/python3.12/site-packages/tenacity/__init__.py:443: in __iter__
    do = self.iter(retry_state=retry_state)
.venv/lib/python3.12/site-packages/tenacity/__init__.py:376: in iter
    result = action(retry_state)
.venv/lib/python3.12/site-packages/tenacity/__init__.py:398: in <lambda>
    self._add_action_func(lambda rs: rs.outcome.result())
/opt/hostedtoolcache/Python/3.12.6/x64/lib/python3.12/concurrent/futures/_base.py:449: in result
    return self.__get_result()
/opt/hostedtoolcache/Python/3.12.6/x64/lib/python3.12/concurrent/futures/_base.py:401: in __get_result
    raise self._exception
sekoia_automation/action.py:349: in run
    response: Response = requests.request(
.venv/lib/python3.12/site-packages/requests/api.py:59: in request
    return session.request(method=method, url=url, **kwargs)
.venv/lib/python3.12/site-packages/requests/sessions.py:589: in request
    resp = self.send(prep, **send_kwargs)
.venv/lib/python3.12/site-packages/requests_mock/mocker.py:185: in _fake_send
    return _original_send(session, request, **kwargs)
.venv/lib/python3.12/site-packages/requests/sessions.py:703: in send
    r = adapter.send(request, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <requests_mock.adapter.Adapter object at 0x7fae100b18b0>
request = <requests_mock.request._RequestObjectProxy object at 0x7fae100c19d0>
kwargs = {'cert': None, 'proxies': OrderedDict(), 'stream': False, 'timeout': 5, ...}
matcher = <requests_mock.adapter._Matcher object at 0x7fae0eac86b0>, resp = None

    def send(self, request, **kwargs):
        request = _RequestObjectProxy(request,
                                      case_sensitive=self._case_sensitive,
                                      **kwargs)
        self._add_to_history(request)
    
        for matcher in reversed(self._matchers):
            try:
                resp = matcher(request)
            except Exception:
                request._matcher = weakref.ref(matcher)
                raise
    
            if resp is not None:
                request._matcher = weakref.ref(matcher)
                resp.connection = self
                logger.debug('{} {} {}'.format(request._request.method,
                                               request._request.url,
                                               resp.status_code))
                return resp
    
>       raise exceptions.NoMockAddress(request)
E       requests_mock.exceptions.NoMockAddress: No mock address: GET http://base_url/resource/fake_uuid/count?param=number

.venv/lib/python3.12/site-packages/requests_mock/adapter.py:261: NoMockAddress

Check notice on line 0 in .github

See this annotation in the file changed.

@github-actions github-actions / Test Results

1 skipped test found

There is 1 skipped test, see "Raw output" for the name of the skipped test.
Raw output
tests.test_storage ‑ test_get_data_path_for_remote_storage

Check notice on line 0 in .github

See this annotation in the file changed.

@github-actions github-actions / Test Results

212 tests found

There are 212 tests, see "Raw output" for the full list of tests.
Raw output
tests.aio.helpers.http.test_http_client_session ‑ test_http_client_get_data
tests.aio.helpers.http.test_http_client_session ‑ test_http_client_get_data_async_limiter
tests.aio.helpers.http.test_http_token_refresher ‑ test_token_refresher_1
tests.aio.helpers.http.test_http_token_refresher ‑ test_token_refresher_2
tests.aio.helpers.http.test_http_token_refresher ‑ test_token_refresher_with_token
tests.aio.helpers.http.test_http_utils ‑ test_save_response_to_temporary_file
tests.aio.helpers.test_aws ‑ test_aws_client_get_session
tests.aio.helpers.test_aws ‑ test_aws_client_init
tests.aio.helpers.test_file_utils ‑ test_csv_file_content
tests.aio.helpers.test_file_utils ‑ test_delete_file
tests.aio.test_connector ‑ test_async_connector_client_session
tests.aio.test_connector ‑ test_async_connector_push_multiple_events
tests.aio.test_connector ‑ test_async_connector_push_single_event
tests.aio.test_connector ‑ test_async_connector_raise_error
tests.aio.test_connector ‑ test_async_connector_rate_limiter
tests.connectors.test_connector ‑ test_check_http_default_headers
tests.connectors.test_connector ‑ test_chunk_events
tests.connectors.test_connector ‑ test_chunk_events_discard_too_long_message
tests.connectors.test_connector ‑ test_chunk_events_exceed_size
tests.connectors.test_connector ‑ test_connector_configuration
tests.connectors.test_connector ‑ test_connector_configuration_file_not_found
tests.connectors.test_connector ‑ test_forward_events
tests.connectors.test_connector ‑ test_push_event_to_intake_custom_url
tests.connectors.test_connector ‑ test_push_event_to_intake_custom_url_configuration
tests.connectors.test_connector ‑ test_push_event_to_intake_with_2_events
tests.connectors.test_connector ‑ test_push_event_to_intake_with_chunks
tests.connectors.test_connector ‑ test_push_event_to_intake_with_chunks_executor_stopped
tests.connectors.test_connector ‑ test_push_events_to_intake_invalid_intake_key
tests.connectors.test_connector ‑ test_push_events_to_intakes_api_failed
tests.connectors.test_connector ‑ test_push_events_to_intakes_api_failed_retried
tests.connectors.test_connector ‑ test_push_events_to_intakes_no_events
tests.connectors.test_connector ‑ test_query_exception_api
tests.connectors.test_connector ‑ test_send_records
tests.connectors.test_connector ‑ test_send_records_to_file
tests.connectors.test_workers ‑ test_create_workers
tests.connectors.test_workers ‑ test_start_workers
tests.connectors.test_workers ‑ test_stop_worker
tests.connectors.test_workers ‑ test_stop_workers
tests.connectors.test_workers ‑ test_supervise_workers
tests.http.aio.examples.test_bearer_token_auth_client ‑ test_get_events_example_method
tests.http.aio.test_http_client ‑ test_complete_configurable_async_http_client
tests.http.aio.test_http_client ‑ test_rate_limited_workflow_async_http_client
tests.http.aio.test_http_client ‑ test_rate_limited_workflow_async_http_client_1
tests.http.aio.test_http_client ‑ test_retry_workflow_delete_async_http_client
tests.http.aio.test_http_client ‑ test_retry_workflow_get_async_http_client
tests.http.aio.test_http_client ‑ test_retry_workflow_head_async_http_client
tests.http.aio.test_http_client ‑ test_retry_workflow_patch_async_http_client
tests.http.aio.test_http_client ‑ test_retry_workflow_post_async_http_client
tests.http.aio.test_http_client ‑ test_retry_workflow_put_async_http_client
tests.http.aio.test_http_client ‑ test_simple_workflow_async_http_client
tests.http.aio.test_http_token_refresher ‑ test_token_refresher_1
tests.http.aio.test_http_token_refresher ‑ test_token_refresher_2
tests.http.aio.test_http_token_refresher ‑ test_token_refresher_with_token
tests.http.sync.examples.test_bearer_token_auth_client ‑ test_get_events_example_method
tests.http.sync.examples.test_oauth_token_auth_client ‑ test_get_events_example_method
tests.http.sync.test_http_client ‑ test_complete_configurable_http_client
tests.http.sync.test_http_client ‑ test_simple_workflow_sync_http_client
tests.http.sync.test_http_client ‑ test_simple_workflow_sync_http_client_rate_limit
tests.http.sync.test_http_client ‑ test_simple_workflow_sync_http_client_retry
tests.http.test_rate_limiter ‑ test_rate_limiter_config_create_with_defaults
tests.http.test_rate_limiter ‑ test_rate_limiter_config_create_with_none_max_rate
tests.http.test_rate_limiter ‑ test_rate_limiter_config_create_with_none_time_period
tests.http.test_rate_limiter ‑ test_rate_limiter_config_create_with_values
tests.http.test_retry ‑ test_retry_policy_create_with_defaults
tests.http.test_retry ‑ test_retry_policy_create_with_empty_status_forcelist
tests.http.test_retry ‑ test_retry_policy_create_with_none_backoff_factor
tests.http.test_retry ‑ test_retry_policy_create_with_none_max_retries
tests.http.test_retry ‑ test_retry_policy_create_with_none_status_forcelist
tests.http.test_retry ‑ test_retry_policy_create_with_values
tests.loguru.test_loguru_config ‑ test_config_assemble_log_lvl
tests.loguru.test_loguru_config ‑ test_config_default_values
tests.loguru.test_loguru_formatters ‑ test_formatted_record_empty
tests.loguru.test_loguru_formatters ‑ test_formatted_record_non_empty
tests.loguru.test_loguru_handler ‑ test_logging_emit_with_existing_loguru_level
tests.loguru.test_loguru_handler ‑ test_logging_log_message
tests.metrics.test_prometheus_exporter ‑ test_prometheus_exporter
tests.scripts.test_files_generator ‑ test_files_generator
tests.scripts.test_files_generator ‑ test_files_generator_wrong_module_path
tests.scripts.test_sync_library ‑ test_get_module_docker_name
tests.scripts.test_sync_library ‑ test_get_module_logo
tests.scripts.test_sync_library ‑ test_load_module_docker_image_not_found
tests.scripts.test_sync_library ‑ test_no_module_404
tests.scripts.test_sync_library ‑ test_no_module_other_code
tests.scripts.test_sync_library ‑ test_no_module_success
tests.scripts.test_sync_library ‑ test_registry_check_custom_success
tests.scripts.test_sync_library ‑ test_registry_check_default_fail
tests.scripts.test_sync_library ‑ test_registry_check_default_success
tests.scripts.test_sync_library ‑ test_registry_check_not_found
tests.scripts.test_sync_library ‑ test_with_module
tests.scripts.test_sync_library ‑ test_with_module_invalid_name
tests.test_action ‑ test_action_error
tests.test_action ‑ test_action_execute_with_get_secrets
tests.test_action ‑ test_action_json_argument
tests.test_action ‑ test_action_json_argument_missing
tests.test_action ‑ test_action_json_result
tests.test_action ‑ test_action_json_result_same_as_argument
tests.test_action ‑ test_action_logs
tests.test_action ‑ test_action_outputs
tests.test_action ‑ test_action_results_invalid
tests.test_action ‑ test_action_results_with_secrets_update
tests.test_action ‑ test_action_send_result_client_error
tests.test_action ‑ test_action_send_result_conflict
tests.test_action ‑ test_action_with_arguments_model
tests.test_action ‑ test_action_with_results_model
tests.test_action ‑ test_add_secrets_dict
tests.test_action ‑ test_add_secrets_object
tests.test_action ‑ test_all
tests.test_action ‑ test_exception_handler
tests.test_action ‑ test_generic_api_action
tests.test_action ‑ test_validate_results_none
tests.test_checkpoint ‑ test_checkpoint_cursor
tests.test_checkpoint ‑ test_checkpoint_datetime_old
tests.test_checkpoint ‑ test_checkpoint_datetime_subkey
tests.test_checkpoint ‑ test_checkpoint_datetime_without_data
tests.test_checkpoint ‑ test_checkpoint_timestamp_milliseconds_old
tests.test_checkpoint ‑ test_checkpoint_timestamp_milliseconds_without_data
tests.test_checkpoint ‑ test_checkpoint_timestamp_seconds
tests.test_checkpoint ‑ test_checkpoint_timestamp_seconds_old
tests.test_checkpoint ‑ test_checkpoint_timestamp_seconds_without_data
tests.test_cli ‑ test_generate_documentation
tests.test_cli ‑ test_generate_documentation_invalid_documentation_path
tests.test_cli ‑ test_generate_documentation_invalid_module_path
tests.test_cli ‑ test_generate_documentation_invalid_modules_path
tests.test_cli ‑ test_generate_documentation_specific_module
tests.test_cli ‑ test_new_module
tests.test_cli ‑ test_openapi_to_module
tests.test_cli ‑ test_openapi_to_module_no_title
tests.test_cli ‑ test_openapi_url_to_module
tests.test_cli ‑ test_synchronize_library
tests.test_cli ‑ test_update_sdk_version
tests.test_cli ‑ test_update_sdk_version_error
tests.test_config ‑ test_load_config_env
tests.test_config ‑ test_load_config_env_json
tests.test_config ‑ test_load_config_env_json_encoded
tests.test_config ‑ test_load_config_file
tests.test_config ‑ test_load_config_file_json
tests.test_config ‑ test_load_config_not_found_error
tests.test_config ‑ test_load_config_not_found_ok
tests.test_module ‑ test_abstract_module_item
tests.test_module ‑ test_command
tests.test_module ‑ test_command_no_arg
tests.test_module ‑ test_configuration_as_model
tests.test_module ‑ test_configuration_setter
tests.test_module ‑ test_configuration_setter_add_secret_not_required
tests.test_module ‑ test_configuration_setter_add_secret_required
tests.test_module ‑ test_configuration_setter_as_model
tests.test_module ‑ test_configuration_setter_missing_required_secret
tests.test_module ‑ test_connector_configuration_uuid
tests.test_module ‑ test_init_sentry
tests.test_module ‑ test_load_config_file_not_exists
tests.test_module ‑ test_load_config_json
tests.test_module ‑ test_load_config_text
tests.test_module ‑ test_no_command
tests.test_module ‑ test_node_run_uuid
tests.test_module ‑ test_playbook_run_uuid
tests.test_module ‑ test_playbook_uuid
tests.test_module ‑ test_register_execute_command
tests.test_module ‑ test_register_execute_default
tests.test_module ‑ test_register_no_command
tests.test_module ‑ test_trigger_configuration_uuid
tests.test_storage ‑ test_get_data_path_for_local_storage
tests.test_storage ‑ test_get_data_path_for_local_storage_sub_folder
tests.test_storage ‑ test_get_data_path_for_remote_storage
tests.test_storage ‑ test_get_s3_data_path
tests.test_storage ‑ test_get_tls_client_credentials
tests.test_storage ‑ test_get_tls_client_credentials_not_set
tests.test_storage ‑ test_persistentjson
tests.test_storage ‑ test_temp_directory
tests.test_storage ‑ test_write_basic
tests.test_storage ‑ test_write_json
tests.test_storage ‑ test_write_temp
tests.test_timer ‑ test_timer
tests.test_trigger ‑ test_callback_url
tests.test_trigger ‑ test_configuration_errors_are_critical
tests.test_trigger ‑ test_get_secrets
tests.test_trigger ‑ test_intake_url
tests.test_trigger ‑ test_is_error_critical_errors
tests.test_trigger ‑ test_is_error_critical_time_since_last_event
tests.test_trigger ‑ test_logs_url
tests.test_trigger ‑ test_module_community_uuid
tests.test_trigger ‑ test_module_configuration
tests.test_trigger ‑ test_secrets_url
tests.test_trigger ‑ test_send_event
tests.test_trigger ‑ test_send_event_4xx_error
tests.test_trigger ‑ test_send_event_too_many_failures
tests.test_trigger ‑ test_token
tests.test_trigger ‑ test_too_many_errors_critical_log
tests.test_trigger ‑ test_trigger_configuration
tests.test_trigger ‑ test_trigger_configuration_as_model
tests.test_trigger ‑ test_trigger_configuration_setter
tests.test_trigger ‑ test_trigger_directory
tests.test_trigger ‑ test_trigger_directory_does_not_exist
tests.test_trigger ‑ test_trigger_event_normalization
tests.test_trigger ‑ test_trigger_execute
tests.test_trigger ‑ test_trigger_liveness
tests.test_trigger ‑ test_trigger_liveness_error
tests.test_trigger ‑ test_trigger_liveness_heartbeat_error
tests.test_trigger ‑ test_trigger_liveness_not_found
tests.test_trigger ‑ test_trigger_log
tests.test_trigger ‑ test_trigger_log_batch_full
tests.test_trigger ‑ test_trigger_log_critical_only_once
tests.test_trigger ‑ test_trigger_log_retry
tests.test_trigger ‑ test_trigger_log_severity
tests.test_trigger ‑ test_trigger_log_time_elapsed
tests.test_trigger ‑ test_trigger_s3_client_error_int
tests.test_trigger ‑ test_trigger_s3_client_error_str
tests.test_trigger ‑ test_trigger_s3_connection_error
tests.test_trigger ‑ test_trigger_s3_server_error_int
tests.test_trigger ‑ test_trigger_s3_server_error_str
tests.test_trigger ‑ test_trigger_send_client_error
tests.test_trigger ‑ test_trigger_send_server_error
tests.test_trigger ‑ test_trigger_stop