33import argparse
44import json
55import os
6+ import pickle # nosec
67import time
78import traceback
89from collections .abc import Iterator
@@ -389,15 +390,59 @@ def pytest_configure(config: pytest.Config) -> None:
389390 config .cwl_results = cwl_results # type: ignore[attr-defined]
390391
391392
392- def pytest_sessionfinish (session : pytest .Session , exitstatus : int ) -> None :
393+ def _zip_results (
394+ cwl_results : list [tuple [dict [str , Any ], utils .TestResult ]],
395+ ) -> tuple [list [dict [str , Any ]], list [utils .TestResult ]]:
396+ tests , results = (list (item ) for item in zip (* cwl_results ))
397+ return tests , results
398+
399+
400+ def pytest_sessionfinish (session : pytest .Session ) -> None :
393401 """Generate badges."""
402+ cwl_badgedir = session .config .getoption ("cwl_badgedir" )
403+ if not cwl_badgedir :
404+ return
405+
394406 cwl_results = cast (
395407 list [tuple [dict [str , Any ], utils .TestResult ]],
396- getattr ( session .config , " cwl_results" , None ),
408+ session .config . cwl_results , # type: ignore[attr-defined]
397409 )
398- if not cwl_results :
399- return
400- tests , results = (list (item ) for item in zip (* cwl_results ))
410+
411+ if session .config .pluginmanager .has_plugin ("xdist" ):
412+ import xdist # type: ignore[import-untyped]
413+
414+ directory = cast (
415+ pytest .TempPathFactory ,
416+ session .config ._tmp_path_factory , # type: ignore[attr-defined]
417+ ).getbasetemp ()
418+ if xdist .is_xdist_worker (session ):
419+ if not cwl_results :
420+ return
421+ pickle_filename = f"cwltest_{ xdist .get_xdist_worker_id (session )} .pickle"
422+ with (directory .parent / pickle_filename ).open ("wb" ) as handle :
423+ pickle .dump (
424+ _zip_results (cwl_results ), handle , protocol = pickle .HIGHEST_PROTOCOL
425+ )
426+ return
427+
428+ if xdist .is_xdist_controller (session ):
429+ tests : list [dict [str , Any ]] = []
430+ results : list [utils .TestResult ] = []
431+ for pickle_filepath in directory .glob ("cwltest_*" ):
432+ with pickle_filepath .open ("rb" ) as handle :
433+ new_tests , new_results = pickle .load (handle ) # nosec
434+ tests .extend (new_tests )
435+ results .extend (new_results )
436+ else :
437+ if not cwl_results :
438+ return
439+ tests , results = _zip_results (cwl_results )
440+
441+ else :
442+ if not cwl_results :
443+ return
444+ tests , results = _zip_results (cwl_results )
445+
401446 (
402447 total ,
403448 passed ,
@@ -409,8 +454,8 @@ def pytest_sessionfinish(session: pytest.Session, exitstatus: int) -> None:
409454 nunsupported ,
410455 _ ,
411456 ) = utils .parse_results (results , tests )
412- if cwl_badgedir := session . config . getoption ( "cwl_badgedir" ):
413- utils .generate_badges (cwl_badgedir , ntotal , npassed , nfailures , nunsupported )
457+
458+ utils .generate_badges (cwl_badgedir , ntotal , npassed , nfailures , nunsupported )
414459
415460
416461def pytest_addhooks (pluginmanager : pytest .PytestPluginManager ) -> None :
0 commit comments