Skip to content

Commit 82b0967

Browse files
author
Jussi Kukkonen
authored
Merge pull request theupdateframework#1588 from sechkova/session-timeout
ngclient: handle timeout on session.get()
2 parents e6787ae + 7b61ad8 commit 82b0967

File tree

2 files changed

+25
-11
lines changed

2 files changed

+25
-11
lines changed

tests/test_fetcher_ng.py

+18-10
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,13 @@
1313
import unittest
1414
import tempfile
1515
import math
16+
import urllib3.exceptions
17+
import requests
1618

1719
from tests import utils
1820
from tuf import exceptions, unittest_toolbox
1921
from tuf.ngclient._internal.requests_fetcher import RequestsFetcher
22+
from unittest.mock import Mock, patch
2023

2124
logger = logging.getLogger(__name__)
2225

@@ -107,19 +110,24 @@ def test_http_error(self):
107110
self.fetcher.fetch(self.url)
108111
self.assertEqual(cm.exception.status_code, 404)
109112

110-
# Read timeout error
111-
def test_read_timeout(self):
112-
# Reduce the read socket timeout to speed up the test
113-
# while keeping the connect timeout
114-
default_socket_timeout = self.fetcher.socket_timeout
115-
self.fetcher.socket_timeout = (default_socket_timeout, 0.1)
116-
# Launch a new "slow retrieval" server sending one byte each 40s
117-
slow_server_process_handler = utils.TestServerProcess(log=logger, server='slow_retrieval_server.py')
118-
self.url = f"http://{utils.TEST_HOST_ADDRESS}:{str(slow_server_process_handler.port)}/{self.rel_target_filepath}"
113+
# Response read timeout error
114+
@patch.object(requests.Session, 'get')
115+
def test_response_read_timeout(self, mock_session_get):
116+
mock_response = Mock()
117+
attr = {'raw.read.side_effect': urllib3.exceptions.ReadTimeoutError(None, None, "Read timed out.")}
118+
mock_response.configure_mock(**attr)
119+
mock_session_get.return_value = mock_response
120+
119121
with self.assertRaises(exceptions.SlowRetrievalError):
120122
next(self.fetcher.fetch(self.url))
123+
mock_response.raw.read.assert_called_once()
121124

122-
slow_server_process_handler.clean()
125+
# Read/connect session timeout error
126+
@patch.object(requests.Session, 'get', side_effect=urllib3.exceptions.TimeoutError)
127+
def test_session_get_timeout(self, mock_session_get):
128+
with self.assertRaises(exceptions.SlowRetrievalError):
129+
self.fetcher.fetch(self.url)
130+
mock_session_get.assert_called_once()
123131

124132
# Simple bytes download
125133
def test_download_bytes(self):

tuf/ngclient/_internal/requests_fetcher.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,13 @@ def fetch(self, url: str) -> Iterator[bytes]:
7777
# requests as:
7878
# - connect timeout (max delay before first byte is received)
7979
# - read (gap) timeout (max delay between bytes received)
80-
response = session.get(url, stream=True, timeout=self.socket_timeout)
80+
try:
81+
response = session.get(
82+
url, stream=True, timeout=self.socket_timeout
83+
)
84+
except urllib3.exceptions.TimeoutError as e:
85+
raise exceptions.SlowRetrievalError from e
86+
8187
# Check response status.
8288
try:
8389
response.raise_for_status()

0 commit comments

Comments
 (0)