99import math
1010import datetime
1111import typing
12+ import enum
1213
1314import _pytest .outcomes
1415import _pytest .unittest
3940g_critical_msg_count_key = pytest .StashKey [int ]()
4041
4142
43+ # /////////////////////////////////////////////////////////////////////////////
44+ # T_TEST_PROCESS_KIND
45+
46+ class T_TEST_PROCESS_KIND (enum .Enum ):
47+ Master = 1
48+ Worker = 2
49+
50+
51+ # /////////////////////////////////////////////////////////////////////////////
52+ # T_TEST_PROCESS_MODE
53+
54+ class T_TEST_PROCESS_MODE (enum .Enum ):
55+ Collect = 1
56+ ExecTests = 2
57+
58+
59+ # /////////////////////////////////////////////////////////////////////////////
60+
61+ g_test_process_kind :typing .Optional [T_TEST_PROCESS_KIND ]= None
62+ g_test_process_mode :typing .Optional [T_TEST_PROCESS_MODE ]= None
63+
64+ g_worker_log_is_created :typing .Optional [bool ]= None
65+
66+
4267# /////////////////////////////////////////////////////////////////////////////
4368# TestConfigPropNames
4469
@@ -857,13 +882,37 @@ def helper__print_test_list2(tests: typing.List[T_TUPLE__str_int]) -> None:
857882
858883
859884# /////////////////////////////////////////////////////////////////////////////
885+ # SUMMARY BUILDER
886+
887+
888+ @pytest .hookimpl (trylast = True )
889+ def pytest_sessionfinish ():
890+ #
891+ # NOTE: It should execute after logging.pytest_sessionfinish
892+ #
893+
894+ global g_test_process_kind # noqa: F824
895+ global g_test_process_mode # noqa: F824
896+ global g_worker_log_is_created # noqa: F824
860897
898+ assert g_test_process_kind is not None
899+ assert type (g_test_process_kind )== T_TEST_PROCESS_KIND # noqa: E721
861900
862- @pytest .fixture (autouse = True ,scope = "session" )
863- def run_after_tests (request :pytest .FixtureRequest ):
864- assert isinstance (request ,pytest .FixtureRequest )
901+ if g_test_process_kind == T_TEST_PROCESS_KIND .Master :
902+ return
903+
904+ assert g_test_process_kind == T_TEST_PROCESS_KIND .Worker
865905
866- yield
906+ assert g_test_process_mode is not None
907+ assert type (g_test_process_mode )== T_TEST_PROCESS_MODE # noqa: E721
908+
909+ if g_test_process_mode == T_TEST_PROCESS_MODE .Collect :
910+ return
911+
912+ assert g_test_process_mode == T_TEST_PROCESS_MODE .ExecTests
913+
914+ assert type (g_worker_log_is_created )== bool # noqa: E721
915+ assert g_worker_log_is_created
867916
868917C_LINE1 = "---------------------------"
869918
@@ -975,8 +1024,33 @@ def LOCAL__print_test_list2(
9751024# /////////////////////////////////////////////////////////////////////////////
9761025
9771026
1027+ def helper__detect_test_process_kind (config :pytest .Config )-> T_TEST_PROCESS_KIND :
1028+ assert isinstance (config ,pytest .Config )
1029+
1030+ #
1031+ # xdist' master process registers DSession plugin.
1032+ #
1033+ p = config .pluginmanager .get_plugin ("dsession" )
1034+
1035+ if p is not None :
1036+ return T_TEST_PROCESS_KIND .Master
1037+
1038+ return T_TEST_PROCESS_KIND .Worker
1039+
1040+
1041+ # ------------------------------------------------------------------------
1042+ def helper__detect_test_process_mode (config :pytest .Config )-> T_TEST_PROCESS_MODE :
1043+ assert isinstance (config ,pytest .Config )
1044+
1045+ if config .getvalue ("collectonly" ):
1046+ return T_TEST_PROCESS_MODE .Collect
1047+
1048+ return T_TEST_PROCESS_MODE .ExecTests
1049+
1050+
1051+ # ------------------------------------------------------------------------
9781052@pytest .hookimpl (trylast = True )
979- def pytest_configure (config :pytest .Config )-> None :
1053+ def helper__pytest_configure__logging (config :pytest .Config )-> None :
9801054assert isinstance (config ,pytest .Config )
9811055
9821056log_name = TestStartupData .GetCurrentTestWorkerSignature ()
@@ -993,7 +1067,45 @@ def pytest_configure(config: pytest.Config) -> None:
9931067assert logging_plugin is not None
9941068assert isinstance (logging_plugin ,_pytest .logging .LoggingPlugin )
9951069
996- logging_plugin .set_log_path (os .path .join (log_dir ,log_name ))
1070+ log_file_path = os .path .join (log_dir ,log_name )
1071+ assert log_file_path is not None
1072+ assert type (log_file_path )== str # noqa: E721
9971073
1074+ logging_plugin .set_log_path (log_file_path )
1075+ return
1076+
1077+
1078+ # ------------------------------------------------------------------------
1079+ @pytest .hookimpl (trylast = True )
1080+ def pytest_configure (config :pytest .Config )-> None :
1081+ assert isinstance (config ,pytest .Config )
1082+
1083+ global g_test_process_kind
1084+ global g_test_process_mode
1085+ global g_worker_log_is_created
1086+
1087+ assert g_test_process_kind is None
1088+ assert g_test_process_mode is None
1089+ assert g_worker_log_is_created is None
1090+
1091+ g_test_process_mode = helper__detect_test_process_mode (config )
1092+ g_test_process_kind = helper__detect_test_process_kind (config )
1093+
1094+ assert type (g_test_process_kind )== T_TEST_PROCESS_KIND # noqa: E721
1095+ assert type (g_test_process_mode )== T_TEST_PROCESS_MODE # noqa: E721
1096+
1097+ if g_test_process_kind == T_TEST_PROCESS_KIND .Master :
1098+ pass
1099+ else :
1100+ assert g_test_process_kind == T_TEST_PROCESS_KIND .Worker
1101+
1102+ if g_test_process_mode == T_TEST_PROCESS_MODE .Collect :
1103+ g_worker_log_is_created = False
1104+ else :
1105+ assert g_test_process_mode == T_TEST_PROCESS_MODE .ExecTests
1106+ helper__pytest_configure__logging (config )
1107+ g_worker_log_is_created = True
1108+
1109+ return
9981110
9991111# /////////////////////////////////////////////////////////////////////////////