Skip to content

Commit 58630ce

Browse files
Implement a simple polling for get_launch_info()
1 parent 912715a commit 58630ce

File tree

2 files changed

+127
-12
lines changed

2 files changed

+127
-12
lines changed

reportportal_client/service.py

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
"""
1616

1717
import json
18+
from time import sleep
19+
1820
import requests
1921
import uuid
2022
import logging
@@ -27,7 +29,6 @@
2729

2830
from .errors import ResponseError, EntryCreatedError, OperationCompletionError
2931

30-
3132
POST_LOGBATCH_RETRY_COUNT = 10
3233
logger = logging.getLogger(__name__)
3334
logger.addHandler(logging.NullHandler())
@@ -253,31 +254,55 @@ def finish_launch(self, end_time, status=None, **kwargs):
253254
logger.debug("finish_launch - ID: %s", self.launch_id)
254255
return _get_msg(r)
255256

256-
def get_launch_info(self):
257+
def get_launch_info(self, max_retries=5):
257258
"""Get the current launch information.
258259
260+
Perform "max_retries" attempts to get current launch information
261+
with 0.5 second sleep between them.
262+
263+
:param int max_retries: Number of retries to get launch information.
259264
:return dict: launch information
260265
"""
266+
if self.launch_id is None:
267+
return {}
268+
261269
url = uri_join(self.base_url_v1, "launch/uuid", self.launch_id)
262-
launch_info = _get_json(self.session.get(
263-
url=url, verify=self.verify_ssl))
264-
logger.debug("get_launch_info - ID: %s", self.launch_id)
265-
logger.debug("get_launch_info - Launch info: %s", launch_info)
270+
271+
for _ in range(max_retries):
272+
logger.debug("get_launch_info - ID: %s", self.launch_id)
273+
resp = self.session.get(url=url, verify=self.verify_ssl)
274+
275+
if resp.status_code == 200:
276+
launch_info = _get_json(resp)
277+
logger.debug("get_launch_info - Launch info: %s", launch_info)
278+
break
279+
280+
logger.debug("get_launch_info - Launch info: Response code %s\n%s",
281+
resp.status_code, resp.text)
282+
sleep(0.5)
283+
else:
284+
logger.warning("get_launch_info - Launch info: "
285+
"Failed to fetch launch ID from the API.")
286+
launch_info = {}
287+
266288
return launch_info
267289

268-
def get_launch_ui_id(self):
290+
def get_launch_ui_id(self, max_retries=5):
269291
"""Get UI ID of the current launch.
270292
271293
:return str: UI ID of the given launch.
294+
None if UI ID has not been found.
272295
"""
273-
return self.get_launch_info()["id"]
296+
return self.get_launch_info(max_retries=max_retries).get("id")
274297

275-
def get_launch_ui_url(self):
298+
def get_launch_ui_url(self, max_retries=5):
276299
"""Get UI URL of the current launch.
277300
278-
:return str: launch URL.
301+
If UI ID can`t be found after max_retries, return URL of all launches.
302+
303+
:return str: launch URL or all launches URL.
279304
"""
280-
ui_id = self.get_launch_ui_id()
305+
ui_id = self.get_launch_ui_id(max_retries=max_retries) or ""
281306
path = "ui/#{0}/launches/all/{1}".format(self.project, ui_id)
282307
url = uri_join(self.endpoint, path)
283308
logger.debug("get_launch_ui_url - ID: %s", self.launch_id)

tests/test_service.py

Lines changed: 91 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,12 @@ def test_get_launch_info(self, rp_service, monkeypatch):
108108
object with mocked session.
109109
:param monkeypatch: Pytest fixture to safely set/delete an attribute
110110
"""
111-
mock_get = mock.Mock(return_value={'id': 112})
111+
mock_resp = mock.Mock()
112+
mock_resp.status_code = 200
113+
114+
mock_get = mock.Mock(return_value=mock_resp)
112115
monkeypatch.setattr(rp_service.session, 'get', mock_get)
116+
monkeypatch.setattr(rp_service, 'launch_id', '1234-cafe')
113117

114118
launch_id = rp_service.get_launch_info()
115119
mock_get.assert_called_once_with(
@@ -118,6 +122,64 @@ def test_get_launch_info(self, rp_service, monkeypatch):
118122
verify=rp_service.verify_ssl)
119123
assert launch_id == {'id': 112}
120124

125+
def test_get_launch_info_launch_id_none(self, rp_service, monkeypatch):
126+
"""Test get launch information for a non started launch.
127+
128+
:param rp_service: Pytest fixture that represents ReportPortalService
129+
object with mocked session.
130+
:param monkeypatch: Pytest fixture to safely set/delete an attribute
131+
"""
132+
mock_get = mock.Mock()
133+
monkeypatch.setattr(rp_service.session, 'get', mock_get)
134+
monkeypatch.setattr(rp_service, 'launch_id', None)
135+
136+
launch_info = rp_service.get_launch_info()
137+
mock_get.assert_not_called()
138+
assert launch_info == {}
139+
140+
@mock.patch('reportportal_client.service.sleep', mock.Mock())
141+
@mock.patch('reportportal_client.service._get_json',
142+
mock.Mock(return_value={"errorCode": 4041}))
143+
def test_get_launch_info_wrong_launch_id(self, rp_service, monkeypatch):
144+
"""Test get launch information for a non existed launch.
145+
146+
:param rp_service: Pytest fixture that represents ReportPortalService
147+
object with mocked session.
148+
:param monkeypatch: Pytest fixture to safely set/delete an attribute
149+
"""
150+
mock_get = mock.Mock()
151+
monkeypatch.setattr(rp_service.session, 'get', mock_get)
152+
monkeypatch.setattr(rp_service, 'launch_id', '1234')
153+
154+
launch_info = rp_service.get_launch_info()
155+
expect(mock_get.call_count == 5)
156+
expect(launch_info == {})
157+
assert_expectations()
158+
159+
@mock.patch('reportportal_client.service.sleep', mock.Mock())
160+
@mock.patch('reportportal_client.service._get_json',
161+
mock.Mock(return_value={'id': 112}))
162+
def test_get_launch_info_1st_failed(self, rp_service, monkeypatch):
163+
"""Test get launch information with 1st attempt failed.
164+
165+
:param rp_service: Pytest fixture that represents ReportPortalService
166+
object with mocked session.
167+
:param monkeypatch: Pytest fixture to safely set/delete an attribute
168+
"""
169+
mock_resp1 = mock.Mock()
170+
mock_resp1.status_code = 404
171+
mock_resp2 = mock.Mock()
172+
mock_resp2.status_code = 200
173+
mock_get = mock.Mock()
174+
mock_get.side_effect = [mock_resp1, mock_resp2]
175+
monkeypatch.setattr(rp_service.session, 'get', mock_get)
176+
monkeypatch.setattr(rp_service, 'launch_id', '1234')
177+
178+
launch_info = rp_service.get_launch_info()
179+
expect(mock_get.call_count == 2)
180+
expect(launch_info == {'id': 112})
181+
assert_expectations()
182+
121183
def test_get_launch_ui_id(self, rp_service, monkeypatch):
122184
"""Test get launch UI ID.
123185
@@ -131,6 +193,19 @@ def test_get_launch_ui_id(self, rp_service, monkeypatch):
131193
mock_get_launch_info)
132194
assert rp_service.get_launch_ui_id() == 113
133195

196+
def test_get_launch_ui_no_id(self, rp_service, monkeypatch):
197+
"""Test get launch UI ID when no ID has been retrieved.
198+
199+
:param rp_service: Pytest fixture that represents ReportPortalService
200+
object with mocked session.
201+
:param monkeypatch: Pytest fixture to safely set/delete an attribute
202+
"""
203+
mock_get_launch_info = mock.Mock(return_value={})
204+
monkeypatch.setattr(rp_service,
205+
'get_launch_info',
206+
mock_get_launch_info)
207+
assert rp_service.get_launch_ui_id() is None
208+
134209
def test_get_launch_ui_url(self, rp_service, monkeypatch):
135210
"""Test get launch UI URL.
136211
@@ -146,6 +221,21 @@ def test_get_launch_ui_url(self, rp_service, monkeypatch):
146221
assert url == '{0}/ui/#{1}/launches/all/1'.format(rp_service.endpoint,
147222
rp_service.project)
148223

224+
def test_get_launch_ui_url_no_id(self, rp_service, monkeypatch):
225+
"""Test get launch UI URL no ID has been retrieved.
226+
227+
:param rp_service: Pytest fixture that represents ReportPortalService
228+
object with mocked session.
229+
:param monkeypatch: Pytest fixture to safely set/delete an attribute
230+
"""
231+
mock_get_launch_ui_id = mock.Mock(return_value=0)
232+
monkeypatch.setattr(rp_service,
233+
'get_launch_ui_id',
234+
mock_get_launch_ui_id)
235+
url = rp_service.get_launch_ui_url()
236+
assert url == '{0}/ui/#{1}/launches/all'.format(rp_service.endpoint,
237+
rp_service.project)
238+
149239
@mock.patch('platform.system', mock.Mock(return_value='linux'))
150240
@mock.patch('platform.machine', mock.Mock(return_value='Windows-PC'))
151241
@mock.patch('platform.processor', mock.Mock(return_value='amd'))

0 commit comments

Comments
 (0)