We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
e.g. for Python 3.8
❯ tox -r -e py38 py38: remove tox env folder /home/jugmac00/Canonical/sources/talisker/.tox/py38 py38: install_deps> python -I -m pip install . -r /home/jugmac00/Canonical/sources/talisker/requirements.tests.txt py38: commands[0]> py.test -v --cov=talisker --no-success-flaky-report ============================= test session starts ============================== platform linux -- Python 3.8.10, pytest-4.6.9, py-1.11.0, pluggy-0.13.1 -- /home/jugmac00/Canonical/sources/talisker/.tox/py38/bin/python cachedir: .tox/py38/.pytest_cache rootdir: /home/jugmac00/Canonical/sources/talisker, inifile: setup.cfg, testpaths: tests, docs plugins: postgresql-1.4.1, cov-2.8.1, timeout-1.3.4, flaky-3.6.1, xdist-1.31.0, forked-1.6.0 collected 225 items / 9 skipped / 216 selected tests/test_config.py::test_config_defaults PASSED [ 0%] tests/test_config.py::test_config_colour PASSED [ 0%] tests/test_config.py::test_logstatus_config PASSED [ 1%] tests/test_config.py::test_debuglog_config PASSED [ 1%] tests/test_config.py::test_query_threshold_config PASSED [ 2%] tests/test_config.py::test_explain_sql_config PASSED [ 2%] tests/test_config.py::test_request_timeout_config PASSED [ 3%] tests/test_config.py::test_sanitised_keys_config PASSED [ 3%] tests/test_config.py::test_id_header_config PASSED [ 4%] tests/test_config.py::test_load_env_config_filters PASSED [ 4%] tests/test_config.py::test_load_env_config_file PASSED [ 4%] tests/test_config.py::test_git PASSED [ 5%] tests/test_config.py::test_bzr PASSED [ 5%] tests/test_config.py::test_bzr_version_info_py2 SKIPPED [ 6%] tests/test_config.py::test_version_info PASSED [ 6%] tests/test_config.py::test_setup_py PASSED [ 7%] tests/test_context.py::test_context_api PASSED [ 7%] tests/test_context.py::test_null_context PASSED [ 8%] tests/test_context.py::test_context_thread PASSED [ 8%] tests/test_context.py::test_context_gevent PASSED [ 8%] tests/test_context.py::test_context_eventlet SKIPPED [ 9%] tests/test_context.py::test_context_asyncio PASSED [ 9%] tests/test_context.py::test_stack_basic PASSED [ 10%] tests/test_context.py::test_stack_context_manager PASSED [ 10%] tests/test_context.py::test_stack_dict_arg PASSED [ 11%] tests/test_context.py::test_stack_unwind PASSED [ 11%] tests/test_context.py::test_null_context_stack PASSED [ 12%] tests/test_context.py::test_does_not_use_or_modify_dict PASSED [ 12%] tests/test_context.py::test_tracking PASSED [ 12%] tests/test_context.py::test_request_timeout PASSED [ 13%] tests/test_functional.py::test_gunicorn_sync_worker SKIPPED [ 13%] tests/test_functional.py::test_gunicorn_gevent_worker SKIPPED [ 14%] tests/test_functional.py::test_gunicorn_eventlet_worker SKIPPED [ 14%] tests/test_functional.py::test_gunicorn_status_interface SKIPPED [ 15%] tests/test_functional.py::test_flask_app SKIPPED [ 15%] tests/test_functional.py::test_django_app SKIPPED [ 16%] tests/test_functional.py::test_gunicorn_timeout SKIPPED [ 16%] tests/test_functional.py::test_celery_basic SKIPPED [ 16%] tests/test_functional.py::test_multiprocess_metrics SKIPPED [ 17%] tests/test_functional.py::test_prometheus_lock_timeouts SKIPPED [ 17%] tests/test_init.py::test_run_entrypoint PASSED [ 18%] tests/test_init.py::test_module_entrypoint PASSED [ 18%] tests/test_init.py::test_run_sysexit PASSED [ 19%] tests/test_init.py::test_gunicorn_entrypoint SKIPPED [ 19%] tests/test_init.py::test_celery_entrypoint SKIPPED [ 20%] tests/test_init.py::test_gunicorn_eventlet_entrypoint SKIPPED [ 20%] tests/test_init.py::test_gunicorn_gevent_entrypoint SKIPPED [ 20%] tests/test_logging.py::test_logging_context_ctx PASSED [ 21%] tests/test_logging.py::test_logging_context_push PASSED [ 21%] tests/test_logging.py::test_set_logging_context PASSED [ 22%] tests/test_logging.py::test_extra_logging PASSED [ 22%] tests/test_logging.py::test_make_record_no_extra PASSED [ 23%] tests/test_logging.py::test_make_record_global_extra PASSED [ 23%] tests/test_logging.py::test_make_record_context_extra PASSED [ 24%] tests/test_logging.py::test_make_record_all_extra PASSED [ 24%] tests/test_logging.py::test_make_record_extra_renamed PASSED [ 24%] tests/test_logging.py::test_make_record_context_renamed PASSED [ 25%] tests/test_logging.py::test_make_record_ordering PASSED [ 25%] tests/test_logging.py::test_make_record_protected PASSED [ 26%] tests/test_logging.py::test_logger_collects_raven_breadcrumbs SKIPPED [ 26%] tests/test_logging.py::test_formatter_no_args PASSED [ 27%] tests/test_logging.py::test_formatter_escapes_quotes PASSED [ 27%] tests/test_logging.py::test_formatter_escapes_newlines PASSED [ 28%] tests/test_logging.py::test_formatter_with_extra PASSED [ 28%] tests/test_logging.py::test_formatter_with_exception PASSED [ 28%] tests/test_logging.py::test_formatter_large_msg PASSED [ 29%] tests/test_logging.py::test_formatter_protected PASSED [ 29%] tests/test_logging.py::test_coloured_formatter PASSED [ 30%] tests/test_logging.py::test_configure PASSED [ 30%] tests/test_logging.py::test_configure_twice PASSED [ 31%] tests/test_logging.py::test_configure_debug_log_bad_file PASSED [ 31%] tests/test_logging.py::test_configure_debug_log PASSED [ 32%] tests/test_logging.py::test_configure_coloured PASSED [ 32%] tests/test_logging.py::test_clean_message PASSED [ 32%] tests/test_logging.py::test_logfmt_key[hi-hi0] PASSED [ 33%] tests/test_logging.py::test_logfmt_key[hi-hi1] PASSED [ 33%] tests/test_logging.py::test_logfmt_key[hi hi-hi_hi] PASSED [ 34%] tests/test_logging.py::test_logfmt_key[hi.hi-hi_hi] PASSED [ 34%] tests/test_logging.py::test_logfmt_key[hi=hi-hi_hi] PASSED [ 35%] tests/test_logging.py::test_logfmt_key[hi"hi-hi\\"hi] PASSED [ 35%] tests/test_logging.py::test_logfmt_key[1-1] PASSED [ 36%] tests/test_logging.py::test_logfmt_key[input7-None] PASSED [ 36%] tests/test_logging.py::test_logfmt_key[True-None] PASSED [ 36%] tests/test_logging.py::test_logfmt_key[False-None] PASSED [ 37%] tests/test_logging.py::test_logfmt_key[hi\nhi\nhi-hi___] PASSED [ 37%] tests/test_logging.py::test_logfmt_key_truncate PASSED [ 38%] tests/test_logging.py::test_logfmt_value[hi-hi0] PASSED [ 38%] tests/test_logging.py::test_logfmt_value[10-"10"] PASSED [ 39%] tests/test_logging.py::test_logfmt_value[hi-hi1] PASSED [ 39%] tests/test_logging.py::test_logfmt_value[ hi "hi" -"hi \\"hi\\""] PASSED [ 40%] tests/test_logging.py::test_logfmt_value[True-true] PASSED [ 40%] tests/test_logging.py::test_logfmt_value[False-false] PASSED [ 40%] tests/test_logging.py::test_logfmt_value[1-1] PASSED [ 41%] tests/test_logging.py::test_logfmt_value[input7-"<class 'dict'>"] PASSED [ 41%] tests/test_logging.py::test_logfmt_value[input8-"<class 'list'>"] PASSED [ 42%] tests/test_logging.py::test_logfmt_value[hi\nhi\nhi-hi...] PASSED [ 42%] tests/test_logging.py::test_logfmt_value_truncate PASSED [ 43%] tests/test_logging.py::test_logfmt_atoms[input0-expected0] PASSED [ 43%] tests/test_logging.py::test_logfmt_atoms[input1-expected1] PASSED [ 44%] tests/test_logging.py::test_logfmt_atoms[input2-expected2] PASSED [ 44%] tests/test_logging.py::test_logfmt_atoms[input3-expected3] PASSED [ 44%] tests/test_logging.py::test_logfmt_atoms[input4-expected4] PASSED [ 45%] tests/test_logging.py::test_logfmt_atoms[input5-expected5] PASSED [ 45%] tests/test_logging.py::test_logfmt_atoms[input6-expected6] PASSED [ 46%] tests/test_logging.py::test_logfmt_atoms[input7-expected7] PASSED [ 46%] tests/test_logging.py::test_logfmt_atoms_subdict PASSED [ 47%] tests/test_logging.py::test_string_needs_quoting[string-False] PASSED [ 47%] tests/test_logging.py::test_string_needs_quoting[space space-True] PASSED [ 48%] tests/test_logging.py::test_string_needs_quoting[foo=bar-True] PASSED [ 48%] tests/test_logging.py::test_string_needs_quoting["hi"-True] PASSED [ 48%] tests/test_logging.py::test_string_needs_quoting[\\tescaped-True] PASSED [ 49%] tests/test_logging.py::test_string_needs_quoting[1234567890-True] PASSED [ 49%] tests/test_logging.py::test_string_needs_quoting[1234567890a-False] PASSED [ 50%] tests/test_logging.py::test_string_needs_quoting[12.34-True] PASSED [ 50%] tests/test_logging.py::test_string_needs_quoting[12.34.56-False] PASSED [ 51%] tests/test_logging.py::test_safe_string[test-test] PASSED [ 51%] tests/test_logging.py::test_safe_string[newline\nnewline-newline...] PASSED [ 52%] tests/test_logging.py::test_safe_string[longlonglong-longlon...] PASSED [ 52%] tests/test_logging.py::test_safe_string["quote"-\\"quote\\"] PASSED [ 52%] tests/test_render.py::test_content_simple_string PASSED [ 53%] tests/test_render.py::test_content_escaped PASSED [ 53%] tests/test_render.py::test_content_not_escaped PASSED [ 54%] tests/test_render.py::test_content_disabled PASSED [ 54%] tests/test_render.py::test_link PASSED [ 55%] tests/test_render.py::test_table PASSED [ 55%] tests/test_render.py::test_preformatted PASSED [ 56%] tests/test_requests.py::test_collect_metadata PASSED [ 56%] tests/test_requests.py::test_collect_metadata_hostname PASSED [ 56%] tests/test_requests.py::test_collect_metadata_request_body PASSED [ 57%] tests/test_requests.py::test_collect_metadata_querystring PASSED [ 57%] tests/test_requests.py::test_collect_metadata_with_response PASSED [ 58%] tests/test_requests.py::test_metric_hook PASSED [ 58%] tests/test_requests.py::test_metric_hook_user_name PASSED [ 59%] tests/test_requests.py::test_metric_hook_registered_endpoint PASSED [ 59%] tests/test_requests.py::test_configured_session PASSED [ 60%] tests/test_requests.py::test_configured_session_http_error PASSED [ 60%] tests/test_requests.py::test_configured_session_connection_error PASSED [ 60%] tests/test_requests.py::test_configured_session_with_user_name PASSED [ 61%] tests/test_requests.py::test_adapter_balances PASSED [ 61%] tests/test_requests.py::test_adapter_requires_consistent_http_scheme PASSED [ 62%] tests/test_requests.py::test_adapter_adds_default_timeout PASSED [ 62%] tests/test_requests.py::test_adapter_respects_context_timeout PASSED [ 63%] tests/test_requests.py::test_adapter_raises_when_context_deadline_exceeded PASSED [ 63%] tests/test_requests.py::test_adapter_default_no_retries PASSED [ 64%] tests/test_requests.py::test_adapter_retry_on_errors[urllib3_error0-ConnectionError] PASSED [ 64%] tests/test_requests.py::test_adapter_retry_on_errors[urllib3_error1-ConnectionError] PASSED [ 64%] tests/test_requests.py::test_adapter_no_retry_on_read_timeout PASSED [ 65%] tests/test_requests.py::test_adapter_retry_on_status_raises FAILED [ 65%] tests/test_requests.py::test_adapter_retry_on_status_returns_when_no_raise FAILED [ 66%] tests/test_requests.py::test_adapter_retry_on_status_header FAILED [ 66%] tests/test_requests.py::test_adapter_exceptions_match_default[None-response0] PASSED [ 67%] tests/test_requests.py::test_adapter_exceptions_match_default[retry1-response1] PASSED [ 67%] tests/test_requests.py::test_adapter_exceptions_match_default[retry2-response2] PASSED [ 68%] tests/test_requests.py::test_adapter_timeout_formats PASSED [ 68%] tests/test_requests.py::test_adapter_bad_timeout_raises PASSED [ 68%] tests/test_requests.py::test_adapter_callsite_retries PASSED [ 69%] tests/test_requests.py::test_threadlocal_threading PASSED [ 69%] tests/test_requests.py::test_threadlocal_forking PASSED [ 70%] tests/test_requests.py::test_talisker_adapter_proxy_config_is_used PASSED [ 70%] tests/test_requests.py::test_talisker_adapter_no_proxy_works_normally PASSED [ 71%] tests/test_requests.py::test_talisker_adapter_no_proxy_works_with_new_url PASSED [ 71%] tests/test_statsd.py::test_parse_statsd_dsn_host PASSED [ 72%] tests/test_statsd.py::test_parse_statsd_dsn_port PASSED [ 72%] tests/test_statsd.py::test_parse_statsd_dsn_prefix PASSED [ 72%] tests/test_statsd.py::test_parse_statsd_dsn_prefix_with_slashes PASSED [ 73%] tests/test_statsd.py::test_parse_statsd_dsn_size PASSED [ 73%] tests/test_statsd.py::test_parse_statsd_dsn_ipv6 PASSED [ 74%] tests/test_statsd.py::test_dummyclient_basic PASSED [ 74%] tests/test_statsd.py::test_dummyclient_pipeline PASSED [ 75%] tests/test_statsd.py::test_dummyclient_nested_pipeline PASSED [ 75%] tests/test_statsd.py::test_dummyclient_collect PASSED [ 76%] tests/test_statsd.py::test_no_network XFAIL [ 76%] tests/test_statsd.py::test_dummyclient_memory PASSED [ 76%] tests/test_statsd.py::test_metric_list PASSED [ 77%] tests/test_testing.py::test_log_record_list PASSED [ 77%] tests/test_testing.py::test_log_record_list_parse PASSED [ 78%] tests/test_testing.py::test_test_context SKIPPED [ 78%] tests/test_testing.py::test_serverprocess_success PASSED [ 79%] tests/test_testing.py::test_serverprocess_failure PASSED [ 79%] tests/test_testing.py::test_serverprocess_output PASSED [ 80%] tests/test_testing.py::test_serverprocess_output_wait PASSED [ 80%] tests/test_testing.py::test_gunicornprocess_success SKIPPED [ 80%] tests/test_testing.py::test_gunicornprocess_bad_app PASSED [ 81%] tests/test_testing.py::test_log_record_list_no_extra PASSED [ 81%] tests/test_util.py::test_sanitize_url PASSED [ 82%] tests/test_util.py::test_get_rounded_ms PASSED [ 82%] tests/test_util.py::test_get_root_exception_implicit PASSED [ 83%] tests/test_util.py::test_get_root_exception_explicit PASSED [ 83%] tests/test_util.py::test_get_root_exception_mixed PASSED [ 84%] tests/test_util.py::test_get_errno_fields_permissions PASSED [ 84%] tests/test_util.py::test_get_errno_fields_connection PASSED [ 84%] tests/test_util.py::test_get_errno_fields_dns PASSED [ 85%] tests/test_util.py::test_local_forking PASSED [ 85%] tests/test_util.py::test_local_threading PASSED [ 86%] tests/test_wsgi.py::test_error_response_handler PASSED [ 86%] tests/test_wsgi.py::test_error_response_handler_devel PASSED [ 87%] tests/test_wsgi.py::test_wsgi_request_start_response PASSED [ 87%] tests/test_wsgi.py::test_wsgi_request_soft_timeout_default SKIPPED [ 88%] tests/test_wsgi.py::test_wsgi_request_soft_explicit SKIPPED [ 88%] tests/test_wsgi.py::test_wsgi_request_soft_explicit_viewname SKIPPED [ 88%] tests/test_wsgi.py::test_wsgi_request_wrap_response PASSED [ 89%] tests/test_wsgi.py::test_wsgi_request_wrap_file PASSED [ 89%] tests/test_wsgi.py::test_wsgi_request_wrap_error_in_iterator[Exception] PASSED [ 90%] tests/test_wsgi.py::test_wsgi_request_wrap_error_in_iterator[RequestTimeout] PASSED [ 90%] tests/test_wsgi.py::test_wsgi_request_wrap_error_headers_sent PASSED [ 91%] tests/test_wsgi.py::test_wsgi_request_wrap_no_body PASSED [ 91%] tests/test_wsgi.py::test_wsgi_request_log PASSED [ 92%] tests/test_wsgi.py::test_wsgi_request_log_error PASSED [ 92%] tests/test_wsgi.py::test_wsgi_request_log_timeout PASSED [ 92%] tests/test_wsgi.py::test_wsgi_request_metrics PASSED [ 93%] tests/test_wsgi.py::test_wsgi_request_metrics_timeout PASSED [ 93%] tests/test_wsgi.py::test_middleware_basic PASSED [ 94%] tests/test_wsgi.py::test_middleware_sets_deadlines PASSED [ 94%] tests/test_wsgi.py::test_middleware_sets_header_deadline PASSED [ 95%] tests/test_wsgi.py::test_middleware_error_before_start_response[Exception] PASSED [ 95%] tests/test_wsgi.py::test_middleware_error_before_start_response[RequestTimeout] PASSED [ 96%] tests/test_wsgi.py::test_middleware_error_after_start_response[Exception] PASSED [ 96%] tests/test_wsgi.py::test_middleware_error_after_start_response[RequestTimeout] PASSED [ 96%] tests/test_wsgi.py::test_middleware_preserves_file_wrapper PASSED [ 97%] tests/test_wsgi.py::test_middleware_debug_middleware_error PASSED [ 97%] tests/test_wsgi.py::test_middleware_debug_middleware PASSED [ 98%] tests/test_wsgi.py::test_middleware_debug_middleware_no_content PASSED [ 98%] tests/test_wsgi.py::test_middleware_debug PASSED [ 99%] tests/test_wsgi.py::test_middleware_debug_invalid_ip PASSED [ 99%] tests/test_wsgi.py::test_wrap PASSED [100%] =================================== FAILURES =================================== _____________________ test_adapter_retry_on_status_raises ______________________ mock_urllib3 = <tests.test_requests.Urllib3Mock object at 0x7fe49ba40d90> backends = <itertools.cycle object at 0x7fe49ba521c0> def test_adapter_retry_on_status_raises(mock_urllib3, backends): session = requests.Session() retry = urllib3.Retry(3, backoff_factor=1, status_forcelist=[503]) adapter = talisker.requests.TaliskerAdapter( backend_iter=backends, max_retries=retry, ) session.mount('http://name', adapter) mock_urllib3.set_response('OH NOES', '503 Service Unavailable') with pytest.raises(requests.exceptions.RetryError): > session.get('http://name/foo') /home/jugmac00/Canonical/sources/talisker/tests/test_requests.py:610: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /home/jugmac00/Canonical/sources/talisker/.tox/py38/lib/python3.8/site-packages/requests/sessions.py:602: in get return self.request("GET", url, **kwargs) /home/jugmac00/Canonical/sources/talisker/.tox/py38/lib/python3.8/site-packages/requests/sessions.py:589: in request resp = self.send(prep, **send_kwargs) /home/jugmac00/Canonical/sources/talisker/.tox/py38/lib/python3.8/site-packages/requests/sessions.py:703: in send r = adapter.send(request, **kwargs) /home/jugmac00/Canonical/sources/talisker/talisker/requests.py:468: in send return self._send(request, *args, **kwargs) /home/jugmac00/Canonical/sources/talisker/talisker/requests.py:522: in _send request._retry = request._retry.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=3, connect=None, read=None, redirect=None, status=None) method = 'GET', url = 'http://1.2.3.4:8000/foo' response = <http.client.HTTPResponse object at 0x7fe49ba4cc70>, error = None _pool = None, _stacktrace = None def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Retry: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 > elif response and response.get_redirect_location(): E AttributeError: 'HTTPResponse' object has no attribute 'get_redirect_location' /home/jugmac00/Canonical/sources/talisker/.tox/py38/lib/python3.8/site-packages/urllib3/util/retry.py:479: AttributeError ------------------------------ Captured log call ------------------------------- DEBUG urllib3.connectionpool:connectionpool.py:244 Starting new HTTP connection (1): 1.2.3.4:8000 ______________ test_adapter_retry_on_status_returns_when_no_raise ______________ mock_urllib3 = <tests.test_requests.Urllib3Mock object at 0x7fe49b9e8b20> backends = <itertools.cycle object at 0x7fe49b97f4c0> def test_adapter_retry_on_status_returns_when_no_raise(mock_urllib3, backends): session = requests.Session() retry = urllib3.Retry( 3, backoff_factor=1, status_forcelist=[503], raise_on_status=False, ) adapter = talisker.requests.TaliskerAdapter( backend_iter=backends, max_retries=retry, ) session.mount('http://name', adapter) mock_urllib3.set_response('OH NOES', '503 Service Unavailable') > response = session.get('http://name/foo') /home/jugmac00/Canonical/sources/talisker/tests/test_requests.py:632: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /home/jugmac00/Canonical/sources/talisker/.tox/py38/lib/python3.8/site-packages/requests/sessions.py:602: in get return self.request("GET", url, **kwargs) /home/jugmac00/Canonical/sources/talisker/.tox/py38/lib/python3.8/site-packages/requests/sessions.py:589: in request resp = self.send(prep, **send_kwargs) /home/jugmac00/Canonical/sources/talisker/.tox/py38/lib/python3.8/site-packages/requests/sessions.py:703: in send r = adapter.send(request, **kwargs) /home/jugmac00/Canonical/sources/talisker/talisker/requests.py:468: in send return self._send(request, *args, **kwargs) /home/jugmac00/Canonical/sources/talisker/talisker/requests.py:522: in _send request._retry = request._retry.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=3, connect=None, read=None, redirect=None, status=None) method = 'GET', url = 'http://1.2.3.4:8000/foo' response = <http.client.HTTPResponse object at 0x7fe49b97b6d0>, error = None _pool = None, _stacktrace = None def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Retry: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 > elif response and response.get_redirect_location(): E AttributeError: 'HTTPResponse' object has no attribute 'get_redirect_location' /home/jugmac00/Canonical/sources/talisker/.tox/py38/lib/python3.8/site-packages/urllib3/util/retry.py:479: AttributeError ------------------------------ Captured log call ------------------------------- DEBUG urllib3.connectionpool:connectionpool.py:244 Starting new HTTP connection (1): 1.2.3.4:8000 _____________________ test_adapter_retry_on_status_header ______________________ mock_urllib3 = <tests.test_requests.Urllib3Mock object at 0x7fe49b80b610> backends = <itertools.cycle object at 0x7fe49b8ccf40> def test_adapter_retry_on_status_header(mock_urllib3, backends): session = requests.Session() retry = urllib3.Retry(3, backoff_factor=1, status_forcelist=[503]) adapter = talisker.requests.TaliskerAdapter( backend_iter=backends, max_retries=retry, ) session.mount('http://name', adapter) headers = {'Retry-After': '1'} mock_urllib3.set_response( 'OH NOES', '503 Service Unavailable', headers) with pytest.raises(requests.exceptions.RetryError): > session.get('http://name/foo') /home/jugmac00/Canonical/sources/talisker/tests/test_requests.py:658: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /home/jugmac00/Canonical/sources/talisker/.tox/py38/lib/python3.8/site-packages/requests/sessions.py:602: in get return self.request("GET", url, **kwargs) /home/jugmac00/Canonical/sources/talisker/.tox/py38/lib/python3.8/site-packages/requests/sessions.py:589: in request resp = self.send(prep, **send_kwargs) /home/jugmac00/Canonical/sources/talisker/.tox/py38/lib/python3.8/site-packages/requests/sessions.py:703: in send r = adapter.send(request, **kwargs) /home/jugmac00/Canonical/sources/talisker/talisker/requests.py:468: in send return self._send(request, *args, **kwargs) /home/jugmac00/Canonical/sources/talisker/talisker/requests.py:522: in _send request._retry = request._retry.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=3, connect=None, read=None, redirect=None, status=None) method = 'GET', url = 'http://1.2.3.4:8000/foo' response = <http.client.HTTPResponse object at 0x7fe49b802550>, error = None _pool = None, _stacktrace = None def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Retry: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 > elif response and response.get_redirect_location(): E AttributeError: 'HTTPResponse' object has no attribute 'get_redirect_location' /home/jugmac00/Canonical/sources/talisker/.tox/py38/lib/python3.8/site-packages/urllib3/util/retry.py:479: AttributeError ------------------------------ Captured log call ------------------------------- DEBUG urllib3.connectionpool:connectionpool.py:244 Starting new HTTP connection (1): 1.2.3.4:8000 ---------- coverage: platform linux, python 3.8.10-final-0 ----------- Name Stmts Miss Cover ---------------------------------------------------------------------------------------------------------------------------- /home/jugmac00/Canonical/sources/talisker/.tox/py38/lib/python3.8/site-packages/talisker/__init__.py 144 85 41% /home/jugmac00/Canonical/sources/talisker/.tox/py38/lib/python3.8/site-packages/talisker/__main__.py 3 0 100% /home/jugmac00/Canonical/sources/talisker/.tox/py38/lib/python3.8/site-packages/talisker/celery.py 128 128 0% /home/jugmac00/Canonical/sources/talisker/.tox/py38/lib/python3.8/site-packages/talisker/config.py 223 52 77% /home/jugmac00/Canonical/sources/talisker/.tox/py38/lib/python3.8/site-packages/talisker/context.py 230 135 41% /home/jugmac00/Canonical/sources/talisker/.tox/py38/lib/python3.8/site-packages/talisker/django.py 30 30 0% /home/jugmac00/Canonical/sources/talisker/.tox/py38/lib/python3.8/site-packages/talisker/endpoints.py 197 197 0% /home/jugmac00/Canonical/sources/talisker/.tox/py38/lib/python3.8/site-packages/talisker/flask.py 64 64 0% /home/jugmac00/Canonical/sources/talisker/.tox/py38/lib/python3.8/site-packages/talisker/gunicorn.py 89 89 0% /home/jugmac00/Canonical/sources/talisker/.tox/py38/lib/python3.8/site-packages/talisker/logs.py 252 82 67% /home/jugmac00/Canonical/sources/talisker/.tox/py38/lib/python3.8/site-packages/talisker/metrics.py 82 40 51% /home/jugmac00/Canonical/sources/talisker/.tox/py38/lib/python3.8/site-packages/talisker/postgresql.py 124 124 0% /home/jugmac00/Canonical/sources/talisker/.tox/py38/lib/python3.8/site-packages/talisker/prometheus.py 111 111 0% /home/jugmac00/Canonical/sources/talisker/.tox/py38/lib/python3.8/site-packages/talisker/render.py 175 175 0% /home/jugmac00/Canonical/sources/talisker/.tox/py38/lib/python3.8/site-packages/talisker/requests.py 294 245 17% /home/jugmac00/Canonical/sources/talisker/.tox/py38/lib/python3.8/site-packages/talisker/sentry.py 252 204 19% /home/jugmac00/Canonical/sources/talisker/.tox/py38/lib/python3.8/site-packages/talisker/statsd.py 58 29 50% /home/jugmac00/Canonical/sources/talisker/.tox/py38/lib/python3.8/site-packages/talisker/testing.py 327 327 0% /home/jugmac00/Canonical/sources/talisker/.tox/py38/lib/python3.8/site-packages/talisker/util.py 155 59 62% /home/jugmac00/Canonical/sources/talisker/.tox/py38/lib/python3.8/site-packages/talisker/wsgi.py 330 330 0% /home/jugmac00/Canonical/sources/talisker/talisker/__init__.py 144 118 18% /home/jugmac00/Canonical/sources/talisker/talisker/__main__.py 3 3 0% /home/jugmac00/Canonical/sources/talisker/talisker/celery.py 128 86 33% /home/jugmac00/Canonical/sources/talisker/talisker/config.py 223 18 92% /home/jugmac00/Canonical/sources/talisker/talisker/context.py 230 27 88% /home/jugmac00/Canonical/sources/talisker/talisker/django.py 30 30 0% /home/jugmac00/Canonical/sources/talisker/talisker/endpoints.py 197 131 34% /home/jugmac00/Canonical/sources/talisker/talisker/flask.py 64 64 0% /home/jugmac00/Canonical/sources/talisker/talisker/gunicorn.py 89 89 0% /home/jugmac00/Canonical/sources/talisker/talisker/logs.py 252 11 96% /home/jugmac00/Canonical/sources/talisker/talisker/metrics.py 82 23 72% /home/jugmac00/Canonical/sources/talisker/talisker/postgresql.py 124 124 0% /home/jugmac00/Canonical/sources/talisker/talisker/prometheus.py 111 81 27% /home/jugmac00/Canonical/sources/talisker/talisker/render.py 175 10 94% /home/jugmac00/Canonical/sources/talisker/talisker/requests.py 294 20 93% /home/jugmac00/Canonical/sources/talisker/talisker/sentry.py 252 196 22% /home/jugmac00/Canonical/sources/talisker/talisker/statsd.py 58 3 95% /home/jugmac00/Canonical/sources/talisker/talisker/testing.py 327 80 76% /home/jugmac00/Canonical/sources/talisker/talisker/util.py 155 27 83% /home/jugmac00/Canonical/sources/talisker/talisker/wsgi.py 330 47 86% ---------------------------------------------------------------------------------------------------------------------------- TOTAL 6536 3694 43% ========= 3 failed, 199 passed, 31 skipped, 1 xfailed in 6.02 seconds ========== py38: exit 1 (6.75 seconds) /home/jugmac00/Canonical/sources/talisker> py.test -v --cov=talisker --no-success-flaky-report pid=3414916 py38: FAIL code 1 (15.55=setup[8.81]+cmd[6.75] seconds) evaluation failed :( (15.61 seconds)
The text was updated successfully, but these errors were encountered:
Successfully merging a pull request may close this issue.
e.g. for Python 3.8
The text was updated successfully, but these errors were encountered: