2424from _pytest .python import Class , Function , Instance , Module
2525from _pytest .unittest import TestCaseFunction , UnitTestCase
2626
27- from reportportal_client import ReportPortalServiceAsync
27+ from reportportal_client import ReportPortalService
2828from six import with_metaclass
2929from six .moves import queue
3030
@@ -74,12 +74,15 @@ def __call__(cls, *args, **kwargs):
7474class PyTestServiceClass (with_metaclass (Singleton , object )):
7575
7676 def __init__ (self ):
77- self .RP = None
77+ self .rp = None
78+ self .rp_supports_parameters = True
7879 try :
7980 pkg_resources .get_distribution ('reportportal_client >= 3.2.0' )
80- self .RP_SUPPORTS_PARAMETERS = True
8181 except pkg_resources .VersionConflict :
82- self .RP_SUPPORTS_PARAMETERS = False
82+ self .rp_supports_parameters = False
83+
84+ self .log_item_id = None
85+ self .parent_item_id = None
8386
8487 self .ignore_errors = True
8588 self .ignored_tags = []
@@ -93,64 +96,57 @@ def init_service(self, endpoint, project, uuid, log_batch_size,
9396 ignore_errors , ignored_tags , verify_ssl = True ,
9497 retries = 0 ):
9598 self ._errors = queue .Queue ()
96- if self .RP is None :
99+ if self .rp is None :
97100 self .ignore_errors = ignore_errors
98- if self .RP_SUPPORTS_PARAMETERS :
101+ if self .rp_supports_parameters :
99102 self .ignored_tags = list (set (ignored_tags ).union ({'parametrize' }))
100103 else :
101104 self .ignored_tags = ignored_tags
102105 log .debug ('ReportPortal - Init service: endpoint=%s, '
103106 'project=%s, uuid=%s' , endpoint , project , uuid )
104- self .RP = ReportPortalServiceAsync (
107+ self .rp = ReportPortalService (
105108 endpoint = endpoint ,
106109 project = project ,
107110 token = uuid ,
108- error_handler = self .async_error_handler ,
109111 retries = retries ,
110- log_batch_size = log_batch_size ,
111112 verify_ssl = verify_ssl
112113 )
113- if self .RP and hasattr (self .RP . rp_client , "get_project_settings" ):
114- self .project_settings = self .RP . rp_client .get_project_settings ()
114+ if self .rp and hasattr (self .rp , "get_project_settings" ):
115+ self .project_settings = self .rp .get_project_settings ()
115116 else :
116117 self .project_settings = None
117118 self .issue_types = self .get_issue_types ()
118119 else :
119120 log .debug ('The pytest is already initialized' )
120- return self .RP
121+ return self .rp
121122
122123 def async_error_handler (self , exc_info ):
123- self .terminate_service (nowait = True )
124- self .RP = None
124+ self .rp = None
125125 self ._errors .put_nowait (exc_info )
126126
127- def terminate_service (self , nowait = False ):
128- if self .RP is not None :
129- self .RP .terminate (nowait )
130- self .RP = None
131-
132- def start_launch (self , launch_name ,
127+ def start_launch (self ,
128+ launch_name ,
133129 mode = None ,
134- tags = None ,
135- description = None ):
130+ description = None ,
131+ ** kwargs ):
136132 self ._stop_if_necessary ()
137- if self .RP is None :
133+ if self .rp is None :
138134 return
139135
140136 sl_pt = {
141137 'name' : launch_name ,
142138 'start_time' : timestamp (),
143139 'description' : description ,
144140 'mode' : mode ,
145- 'tags' : tags
146141 }
147142 log .debug ('ReportPortal - Start launch: equest_body=%s' , sl_pt )
148- req_data = self .RP .start_launch (** sl_pt )
149- log .debug ('ReportPortal - Launch started: response_body=%s' , req_data )
143+ item_id = self .rp .start_launch (** sl_pt )
144+ log .debug ('ReportPortal - Launch started: id=%s' , item_id )
145+ return item_id
150146
151147 def collect_tests (self , session ):
152148 self ._stop_if_necessary ()
153- if self .RP is None :
149+ if self .rp is None :
154150 return
155151
156152 hier_dirs = False
@@ -209,7 +205,7 @@ def collect_tests(self, session):
209205
210206 def start_pytest_item (self , test_item = None ):
211207 self ._stop_if_necessary ()
212- if self .RP is None :
208+ if self .rp is None :
213209 return
214210
215211 for part in self ._item_parts [test_item ]:
@@ -220,37 +216,42 @@ def start_pytest_item(self, test_item=None):
220216 payload = {
221217 'name' : self ._get_item_name (part ),
222218 'description' : self ._get_item_description (part ),
223- 'tags' : self ._get_item_tags (part ),
224219 'start_time' : timestamp (),
225- 'item_type' : 'SUITE'
220+ 'item_type' : 'SUITE' ,
221+ 'parent_item_id' : self .parent_item_id
226222 }
227223 log .debug ('ReportPortal - Start Suite: request_body=%s' , payload )
228- self .RP .start_test_item (** payload )
224+ item_id = self .rp .start_test_item (** payload )
225+ self .log_item_id = item_id
226+ self .parent_item_id = item_id
227+ self ._hier_parts [part ]["item_id" ] = item_id
229228
230229 start_rq = {
231230 'name' : self ._get_item_name (test_item ),
232231 'description' : self ._get_item_description (test_item ),
233- 'tags' : self ._get_item_tags (test_item ),
234232 'start_time' : timestamp (),
235- 'item_type' : 'STEP'
233+ 'item_type' : 'TEST' ,
234+ 'parent_item_id' : self .parent_item_id
236235 }
237- if self .RP_SUPPORTS_PARAMETERS :
236+ if self .rp_supports_parameters :
238237 start_rq ['parameters' ] = self ._get_parameters (test_item )
239238
240239 log .debug ('ReportPortal - Start TestItem: request_body=%s' , start_rq )
241- self .RP .start_test_item (** start_rq )
240+ item_id = self .rp .start_test_item (** start_rq )
241+ self .log_item_id = item_id
242+ return item_id
242243
243244 def is_item_update_supported (self ):
244245 """Check item update API call client support."""
245- return hasattr (self .RP , "update_test_item" )
246+ return hasattr (self .rp , "update_test_item" )
246247
247248 def update_pytest_item (self , test_item = None ):
248249 """Make item update API call.
249250
250251 :param test_item: pytest test item
251252 """
252253 self ._stop_if_necessary ()
253- if self .RP is None :
254+ if self .rp is None :
254255 return
255256
256257 # if update_test_item is not supported in client
@@ -263,23 +264,25 @@ def update_pytest_item(self, test_item=None):
263264 'tags' : self ._get_item_tags (test_item ),
264265 }
265266 log .debug ('ReportPortal - Update TestItem: request_body=%s' , start_rq )
266- self .RP .update_test_item (** start_rq )
267+ self .rp .update_test_item (** start_rq )
267268
268- def finish_pytest_item (self , test_item , status , issue = None ):
269+ def finish_pytest_item (self , test_item , item_id , status , issue = None ):
269270 self ._stop_if_necessary ()
270- if self .RP is None :
271+ if self .rp is None :
271272 return
272273
273274 fta_rq = {
274275 'end_time' : timestamp (),
275276 'status' : status ,
276- 'issue' : issue
277+ 'issue' : issue ,
278+ 'item_id' : item_id
277279 }
278280
279281 log .debug ('ReportPortal - Finish TestItem: request_body=%s' , fta_rq )
280- self .RP .finish_test_item (** fta_rq )
281282
282283 parts = self ._item_parts [test_item ]
284+ if not parts :
285+ self .rp .finish_test_item (** fta_rq )
283286 while len (parts ) > 0 :
284287 part = parts .pop ()
285288 if status == "FAILED" :
@@ -290,14 +293,15 @@ def finish_pytest_item(self, test_item, status, issue=None):
290293 payload = {
291294 'end_time' : timestamp (),
292295 'issue' : issue ,
296+ 'item_id' : self ._hier_parts [part ]["item_id" ],
293297 'status' : part ._rp_result
294298 }
295299 log .debug ('ReportPortal - End TestSuite: request_body=%s' , payload )
296- self .RP .finish_test_item (** payload )
300+ self .rp .finish_test_item (** payload )
297301
298- def finish_launch (self , status = 'rp_launch' , force = False ):
302+ def finish_launch (self , status = None , ** kwargs ):
299303 self ._stop_if_necessary ()
300- if self .RP is None :
304+ if self .rp is None :
301305 return
302306
303307 # To finish launch session str parameter is needed
@@ -306,14 +310,11 @@ def finish_launch(self, status='rp_launch', force=False):
306310 'status' : status
307311 }
308312 log .debug ('ReportPortal - Finish launch: request_body=%s' , fl_rq )
309- if not force :
310- self .RP .finish_launch (** fl_rq )
311- else :
312- self .RP .stop_launch (** fl_rq )
313+ self .rp .finish_launch (** fl_rq )
313314
314315 def post_log (self , message , loglevel = 'INFO' , attachment = None ):
315316 self ._stop_if_necessary ()
316- if self .RP is None :
317+ if self .rp is None :
317318 return
318319
319320 if loglevel not in self ._loglevels :
@@ -327,7 +328,7 @@ def post_log(self, message, loglevel='INFO', attachment=None):
327328 'level' : loglevel ,
328329 'attachment' : attachment ,
329330 }
330- self .RP . log ( ** sl_rq )
331+ self .rp . log_batch (( sl_rq ,), item_id = self . log_item_id )
331332
332333 def _stop_if_necessary (self ):
333334 try :
0 commit comments