22import traceback
33from time import time
44
5+ import pytest
56from six import with_metaclass
7+ from six .moves import queue
68
79from reportportal_client import ReportPortalServiceAsync
810
911
10- def async_error_handler (exc_info ):
11- exc , msg , tb = exc_info
12- traceback .print_exception (exc , msg , tb )
13-
14-
1512def timestamp ():
1613 return str (int (time () * 1000 ))
1714
@@ -32,9 +29,14 @@ class PyTestServiceClass(with_metaclass(Singleton, object)):
3229
3330 def __init__ (self ):
3431 self .RP = None
32+ self .ignore_errors = True
33+ self ._errors = queue .Queue ()
3534
36- def init_service (self , endpoint , project , uuid , log_batch_size ):
35+ def init_service (self , endpoint , project , uuid , log_batch_size ,
36+ ignore_errors ):
37+ self ._errors = queue .Queue ()
3738 if self .RP is None :
39+ self .ignore_errors = ignore_errors
3840 logging .debug (
3941 msg = "ReportPortal - Init service: "
4042 "endpoint={0}, project={1}, uuid={2}" .
@@ -43,18 +45,37 @@ def init_service(self, endpoint, project, uuid, log_batch_size):
4345 endpoint = endpoint ,
4446 project = project ,
4547 token = uuid ,
46- error_handler = async_error_handler ,
47- log_batch_size = log_batch_size )
48+ error_handler = self .async_error_handler ,
49+ log_batch_size = log_batch_size
50+ )
4851 else :
4952 logging .debug ("The pytest is already initialized" )
5053 return self .RP
5154
55+ def async_error_handler (self , exc_info ):
56+ self .terminate_service ()
57+ self .RP = None
58+ self ._errors .put_nowait (exc_info )
59+
60+ def _stop_if_neccessary (self ):
61+ try :
62+ exc , msg , tb = self ._errors .get (False )
63+ traceback .print_exception (exc , msg , tb )
64+ if not self .ignore_errors :
65+ pytest .exit (msg )
66+ except queue .Empty :
67+ pass
68+
5269 def terminate_service (self ):
5370 if self .RP is not None :
5471 self .RP .terminate ()
5572
5673 def start_launch (
5774 self , launch_name , mode = None , tags = None , description = None ):
75+ self ._stop_if_neccessary ()
76+ if self .RP is None :
77+ return
78+
5879 sl_pt = {
5980 "name" : launch_name ,
6081 "start_time" : timestamp (),
@@ -69,6 +90,10 @@ def start_launch(
6990 "response_body=%s" , req_data )
7091
7192 def start_pytest_item (self , test_item = None ):
93+ self ._stop_if_neccessary ()
94+ if self .RP is None :
95+ return
96+
7297 start_rq = {
7398 "name" : self ._get_full_name (test_item ),
7499 "description" : self ._get_description (test_item ),
@@ -104,6 +129,10 @@ def _get_tags(self, test_item):
104129 return []
105130
106131 def finish_pytest_item (self , status , issue = None ):
132+ self ._stop_if_neccessary ()
133+ if self .RP is None :
134+ return
135+
107136 fta_rq = {
108137 "end_time" : timestamp (),
109138 "status" : status ,
@@ -116,6 +145,10 @@ def finish_pytest_item(self, status, issue=None):
116145 self .RP .finish_test_item (** fta_rq )
117146
118147 def finish_launch (self , launch = None , status = "rp_launch" ):
148+ self ._stop_if_neccessary ()
149+ if self .RP is None :
150+ return
151+
119152 # To finish launch session str parameter is needed
120153 fl_rq = {
121154 "end_time" : timestamp (),
@@ -126,6 +159,10 @@ def finish_launch(self, launch=None, status="rp_launch"):
126159 self .RP .finish_launch (** fl_rq )
127160
128161 def post_log (self , message , loglevel = 'INFO' , attachment = None ):
162+ self ._stop_if_neccessary ()
163+ if self .RP is None :
164+ return
165+
129166 if loglevel not in self ._loglevels :
130167 logging .warning ('Incorrect loglevel = %s. Force set to INFO. '
131168 'Avaliable levels: %s.' , loglevel , self ._loglevels )
0 commit comments