Skip to content

Commit a3baaef

Browse files
authored
Merge pull request #172 from rb1/master
Add a timeout to HTTP POST connects and reads
2 parents db66fbb + f654350 commit a3baaef

File tree

2 files changed

+58
-21
lines changed

2 files changed

+58
-21
lines changed

reportportal_client/service.py

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ def __init__(self,
167167
verify_ssl=True,
168168
retries=None,
169169
max_pool_size=50,
170+
http_timeout=(10, 10),
170171
**kwargs):
171172
"""Init the service class.
172173
@@ -181,6 +182,9 @@ def __init__(self,
181182
verify_ssl: option to not verify ssl certificates
182183
max_pool_size: option to set the maximum number of
183184
connections to save in the pool.
185+
http_timeout: a float in seconds for the connect and read
186+
timeout. Use a Tuple to specific connect and
187+
read separately.
184188
"""
185189
self._batch_logs = []
186190
self.endpoint = endpoint
@@ -190,6 +194,7 @@ def __init__(self,
190194
self.is_skipped_an_issue = is_skipped_an_issue
191195
self.base_url_v1 = uri_join(self.endpoint, "api/v1", self.project)
192196
self.base_url_v2 = uri_join(self.endpoint, "api/v2", self.project)
197+
self.http_timeout = http_timeout
193198

194199
self.session = requests.Session()
195200
if retries:
@@ -228,7 +233,13 @@ def start_launch(self,
228233
"rerunOf": rerunOf
229234
}
230235
url = uri_join(self.base_url_v2, "launch")
231-
r = self.session.post(url=url, json=data, verify=self.verify_ssl)
236+
r = self.session.request(
237+
method='POST',
238+
url=url,
239+
json=data,
240+
verify=self.verify_ssl,
241+
timeout=self.http_timeout
242+
)
232243
self.launch_id = _get_id(r)
233244
logger.debug("start_launch - ID: %s", self.launch_id)
234245
return self.launch_id
@@ -270,7 +281,11 @@ def get_launch_info(self, max_retries=5):
270281

271282
for _ in range(max_retries):
272283
logger.debug("get_launch_info - ID: %s", self.launch_id)
273-
resp = self.session.get(url=url, verify=self.verify_ssl)
284+
resp = self.session.request(
285+
method='GET',
286+
url=url,
287+
verify=self.verify_ssl,
288+
timeout=self.http_timeout)
274289

275290
if resp.status_code == 200:
276291
launch_info = _get_json(resp)
@@ -355,7 +370,13 @@ def start_test_item(self,
355370
url = uri_join(self.base_url_v2, "item", parent_item_id)
356371
else:
357372
url = uri_join(self.base_url_v2, "item")
358-
r = self.session.post(url=url, json=data, verify=self.verify_ssl)
373+
r = self.session.request(
374+
method='POST',
375+
url=url,
376+
json=data,
377+
verify=self.verify_ssl,
378+
timeout=self.http_timeout
379+
)
359380

360381
item_id = _get_id(r)
361382
logger.debug("start_test_item - ID: %s", item_id)
@@ -423,8 +444,11 @@ def get_item_id_by_uuid(self, uuid):
423444
:return str: Test item id
424445
"""
425446
url = uri_join(self.base_url_v1, "item", "uuid", uuid)
426-
return _get_json(self.session.get(
427-
url=url, verify=self.verify_ssl))["id"]
447+
return _get_json(self.session.request(
448+
method='GET',
449+
url=url,
450+
verify=self.verify_ssl,
451+
timeout=self.http_timeout))["id"]
428452

429453
def get_project_settings(self):
430454
"""
@@ -433,7 +457,12 @@ def get_project_settings(self):
433457
:return: json body
434458
"""
435459
url = uri_join(self.base_url_v1, "settings")
436-
r = self.session.get(url=url, json={}, verify=self.verify_ssl)
460+
r = self.session.request(
461+
method='GET',
462+
url=url,
463+
json={},
464+
verify=self.verify_ssl,
465+
timeout=self.http_timeout)
437466
logger.debug("settings")
438467
return _get_json(r)
439468

@@ -509,10 +538,12 @@ def _log_batch(self, log_data, force=False):
509538
files.extend(attachments)
510539
for i in range(POST_LOGBATCH_RETRY_COUNT):
511540
try:
512-
r = self.session.post(
541+
r = self.session.request(
542+
method='POST',
513543
url=url,
514544
files=files,
515-
verify=self.verify_ssl
545+
verify=self.verify_ssl,
546+
timeout=self.http_timeout
516547
)
517548
logger.debug("log_batch response: %s", r.text)
518549
self._batch_logs = []

tests/test_service.py

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -109,15 +109,17 @@ def test_get_launch_info(self, rp_service, monkeypatch):
109109
mock_resp = mock.Mock()
110110
mock_resp.status_code = 200
111111

112-
mock_get = mock.Mock(return_value=mock_resp)
113-
monkeypatch.setattr(rp_service.session, 'get', mock_get)
112+
mock_request = mock.Mock(return_value=mock_resp)
113+
monkeypatch.setattr(rp_service.session, 'request', mock_request)
114114
monkeypatch.setattr(rp_service, 'launch_id', '1234-cafe')
115115

116116
launch_id = rp_service.get_launch_info()
117-
mock_get.assert_called_once_with(
117+
mock_request.assert_called_once_with(
118+
method='GET',
118119
url='{0}/launch/uuid/{1}'.format(rp_service.base_url_v1,
119120
rp_service.launch_id),
120-
verify=rp_service.verify_ssl)
121+
verify=rp_service.verify_ssl,
122+
timeout=(10, 10))
121123
assert launch_id == {'id': 112}
122124

123125
def test_get_launch_info_launch_id_none(self, rp_service, monkeypatch):
@@ -145,12 +147,12 @@ def test_get_launch_info_wrong_launch_id(self, rp_service, monkeypatch):
145147
object with mocked session.
146148
:param monkeypatch: Pytest fixture to safely set/delete an attribute
147149
"""
148-
mock_get = mock.Mock()
149-
monkeypatch.setattr(rp_service.session, 'get', mock_get)
150+
mock_request = mock.Mock()
151+
monkeypatch.setattr(rp_service.session, 'request', mock_request)
150152
monkeypatch.setattr(rp_service, 'launch_id', '1234')
151153

152154
launch_info = rp_service.get_launch_info()
153-
expect(mock_get.call_count == 5)
155+
expect(mock_request.call_count == 5)
154156
expect(launch_info == {})
155157
assert_expectations()
156158

@@ -168,13 +170,13 @@ def test_get_launch_info_1st_failed(self, rp_service, monkeypatch):
168170
mock_resp1.status_code = 404
169171
mock_resp2 = mock.Mock()
170172
mock_resp2.status_code = 200
171-
mock_get = mock.Mock()
172-
mock_get.side_effect = [mock_resp1, mock_resp2]
173-
monkeypatch.setattr(rp_service.session, 'get', mock_get)
173+
mock_request = mock.Mock()
174+
mock_request.side_effect = [mock_resp1, mock_resp2]
175+
monkeypatch.setattr(rp_service.session, 'request', mock_request)
174176
monkeypatch.setattr(rp_service, 'launch_id', '1234')
175177

176178
launch_info = rp_service.get_launch_info()
177-
expect(mock_get.call_count == 2)
179+
expect(mock_request.call_count == 2)
178180
expect(launch_info == {'id': 112})
179181
assert_expectations()
180182

@@ -255,9 +257,11 @@ def test_start_item(self, rp_service):
255257
'testCaseId': None,
256258
'retry': False},
257259
url='http://endpoint/api/v2/project/item',
260+
method='POST',
261+
timeout=(10, 10),
258262
verify=True)
259263

260-
rp_service.session.post.assert_called_with(**expected_result)
264+
rp_service.session.request.assert_called_with(**expected_result)
261265
assert rp_start == 123
262266

263267
start_item_optional = [
@@ -301,6 +305,8 @@ def test_start_item_code_optional_params(self, rp_service, field_name,
301305
'testCaseId': None,
302306
'retry': False},
303307
url='http://endpoint/api/v2/project/item',
308+
method='POST',
309+
timeout=(10, 10),
304310
verify=True)
305311
expected_result['json'][expected_name] = expected_value
306-
rp_service.session.post.assert_called_with(**expected_result)
312+
rp_service.session.request.assert_called_with(**expected_result)

0 commit comments

Comments
 (0)