22# and/or modify it under the terms of the GPL licence
33
44import logging
5-
6- from .service import PyTestService
5+ import dill as pickle
6+ import pytest
7+ import time
8+ from pytest_reportportal import LAUNCH_WAIT_TIMEOUT
9+ from .service import PyTestServiceClass
710from .listener import RPReportListener
811
912try :
1417 PYTEST_HAS_LOGGING_PLUGIN = False
1518
1619
20+ def is_master (config ):
21+ """
22+ True if the code running the given pytest.config object is running in a xdist master
23+ node or not running xdist at all.
24+ """
25+ return not hasattr (config , 'slaveinput' )
26+
27+
28+ @pytest .mark .optionalhook
29+ def pytest_configure_node (node ):
30+ node .slaveinput ['py_test_service' ] = pickle .dumps (node .config .py_test_service )
31+
32+
1733def pytest_sessionstart (session ):
1834 if session .config .getoption ('--collect-only' , default = False ) is True :
1935 return
2036
21- PyTestService .init_service (
22- project = session .config .getini ('rp_project' ),
23- endpoint = session .config .getini ('rp_endpoint' ),
24- uuid = session .config .getini ('rp_uuid' ),
25- log_batch_size = int (session .config .getini ('rp_log_batch_size' )),
26- ignore_errors = bool (session .config .getini ('rp_ignore_errors' )),
27- ignored_tags = session .config .getini ('rp_ignore_tags' ),
28- )
37+ if is_master (session .config ):
38+ session .config .py_test_service .init_service (
39+ project = session .config .getini ('rp_project' ),
40+ endpoint = session .config .getini ('rp_endpoint' ),
41+ uuid = session .config .getini ('rp_uuid' ),
42+ log_batch_size = int (session .config .getini ('rp_log_batch_size' )),
43+ ignore_errors = bool (session .config .getini ('rp_ignore_errors' )),
44+ ignored_tags = session .config .getini ('rp_ignore_tags' ),
45+ )
46+
47+ session .config .py_test_service .start_launch (
48+ session .config .option .rp_launch ,
49+ tags = session .config .getini ('rp_launch_tags' ),
50+ description = session .config .getini ('rp_launch_description' ),
51+ )
52+ if session .config .pluginmanager .hasplugin ('xdist' ):
53+ wait_launch (session .config .py_test_service .RP .rp_client )
2954
30- PyTestService .start_launch (
31- session .config .option .rp_launch ,
32- tags = session .config .getini ('rp_launch_tags' ),
33- description = session .config .option .rp_launch_description ,
34- )
55+
56+ def wait_launch (rp_client ):
57+ timeout = time .time () + LAUNCH_WAIT_TIMEOUT
58+ while not rp_client .launch_id :
59+ if time .time () > timeout :
60+ raise Exception ("Launch not found" )
61+ time .sleep (1 )
3562
3663
3764def pytest_sessionfinish (session ):
@@ -40,7 +67,8 @@ def pytest_sessionfinish(session):
4067
4168 # FixMe: currently method of RP api takes the string parameter
4269 # so it is hardcoded
43- PyTestService .finish_launch (status = 'RP_Launch' )
70+ if is_master (session .config ):
71+ session .config .py_test_service .finish_launch (status = 'RP_Launch' )
4472
4573
4674def pytest_configure (config ):
@@ -49,30 +77,33 @@ def pytest_configure(config):
4977 if not config .option .rp_launch_description :
5078 config .option .rp_launch_description = config .getini ('rp_launch_description' )
5179
52- if config .pluginmanager .hasplugin ('xdist' ):
53- raise Exception (
54- "pytest report portal is not compatible with 'xdist' plugin." )
80+ if is_master (config ):
81+ config .py_test_service = PyTestServiceClass ()
82+ else :
83+ config .py_test_service = pickle .loads (config .slaveinput ['py_test_service' ])
84+ config .py_test_service .RP .listener .start ()
5585
5686 # set Pytest_Reporter and configure it
5787
5888 if PYTEST_HAS_LOGGING_PLUGIN :
5989 # This check can go away once we support pytest >= 3.3
6090 try :
6191 config ._reporter = RPReportListener (
92+ config .py_test_service ,
6293 _pytest .logging .get_actual_log_level (config , 'rp_log_level' )
6394 )
6495 except TypeError :
6596 # No log level set either in INI or CLI
66- config ._reporter = RPReportListener ()
97+ config ._reporter = RPReportListener (config . py_test_service )
6798 else :
68- config ._reporter = RPReportListener ()
99+ config ._reporter = RPReportListener (config . py_test_service )
69100
70101 if hasattr (config , '_reporter' ):
71102 config .pluginmanager .register (config ._reporter )
72103
73104
74105def pytest_unconfigure (config ):
75- PyTestService .terminate_service ()
106+ config . py_test_service .terminate_service ()
76107
77108 if hasattr (config , '_reporter' ):
78109 reporter = config ._reporter
0 commit comments