2222# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2323# SOFTWARE.
2424
25- """Pytest Fixtures for supporting the PARALLEL_MONO_SCOPE Test Distribution Mode .
25+ """Pytest Fixtures for supporting users of isoscope scheduling .
2626
27- NOTE: These fixtures are NOT compatible with any other Test Distribution Modes .
27+ NOTE: These fixtures are NOT compatible with any other xdist schedulers .
2828
2929NOTE: DO NOT IMPORT this module. It needs to be loaded via pytest's
3030`conftest.pytest_plugins` mechanism. Pytest doc discourages importing fixtures
4646import filelock
4747import pytest
4848
49- from utils . common . parallel_mono_scope_utils import (
50- ParallelMonoScopeFixture ,
49+ from xdist . iso_scheduling_utils import (
50+ IsoSchedulingFixture ,
5151 DistributedSetupCoordinator ,
5252 DistributedSetupContext ,
5353 DistributedTeardownContext ,
6363
6464
6565@pytest .fixture (scope = 'session' )
66- def parallel_mono_scope (
66+ def iso_scheduling (
6767 tmp_path_factory : pytest .TempPathFactory ,
6868 testrun_uid : str ,
6969 worker_id : str
70- ) -> ParallelMonoScopeFixture :
70+ ) -> IsoSchedulingFixture :
7171 """A session-scoped pytest fixture for coordinating setup/teardown of test
72- scope/class which is executing in the parallel_mono_scope Test Distribution
73- Mode.
72+ scope/class which is executing under isoscope scheduling.
7473
75- NOTE: Each XDist remote worker is running its own Pytest Session.
74+ Based on the filelock idea described in section
75+ "Making session-scoped fixtures execute only once" of
76+ https://pytest-xdist.readthedocs.io/en/stable/how-to.html.
77+
78+ NOTE: Each XDist remote worker is running its own Pytest Session, so we want
79+ only the worker that starts its session first to execute the setup logic and
80+ only the worker that finishes its session last to execute the teardown logic
81+ using a form of distributed coordination. This way, setup is executed exactly
82+ once before any worker executes any of the scope's tests, and teardown is
83+ executed only after the last worker finishes test execution.
7684
7785 USAGE EXAMPLE:
7886
@@ -82,24 +90,23 @@ def parallel_mono_scope(
8290 import pytest
8391
8492 if TYPE_CHECKING:
85- from utils.common.parallel_mono_scope_utils import (
86- ParallelMonoScopeFixture ,
93+ from xdist.iso_scheduling_utils import (
94+ IsoSchedulingFixture ,
8795 DistributedSetupContext,
8896 DistributedTeardownContext
8997 )
9098
91- @pytest.mark.parallel_mono_scope
92- class TestDeng12345ParallelMonoScope:
99+ class TestSomething:
93100
94101 @classmethod
95102 @pytest.fixture(scope='class', autouse=True)
96103 def distributed_setup_and_teardown(
97104 cls,
98- parallel_mono_scope: ParallelMonoScopeFixture :
105+ iso_scheduling: IsoSchedulingFixture :
99106 request: pytest.FixtureRequest):
100107
101108 # Distributed Setup and Teardown
102- with parallel_mono_scope .coordinate_setup_teardown(
109+ with iso_scheduling .coordinate_setup_teardown(
103110 setup_request=request) as coordinator:
104111 # Distributed Setup
105112 coordinator.maybe_call_setup(cls.patch_system_under_test)
@@ -126,12 +133,13 @@ def revert_system_under_test(
126133 # Fetch state from `teardown_context.client_dir` and revert
127134 # changes made by `patch_system_under_test()`.
128135
129- perms, tc_ids = generate_tests(
130- os.path.realpath(__file__),
131- TestDistributionModeEnum.PARALLEL_MONO_SCOPE)
136+ def test_case1(self)
137+ ...
138+
139+ def test_case2(self)
140+ ...
132141
133- @pytest.mark.parametrize('test_data', perms, ids=tc_ids)
134- def test_case(self, test_data: dict[str, dict])
142+ def test_case3(self)
135143 ...
136144 ```
137145
@@ -146,17 +154,17 @@ def test_case(self, test_data: dict[str, dict])
146154 yields an instance of `DistributedSetupCoordinator` for the current
147155 Pytest Session.
148156 """
149- return _ParallelMonoScopeFixtureImpl (tmp_path_factory = tmp_path_factory ,
150- testrun_uid = testrun_uid ,
151- worker_id = worker_id )
157+ return _IsoSchedulingFixtureImpl (tmp_path_factory = tmp_path_factory ,
158+ testrun_uid = testrun_uid ,
159+ worker_id = worker_id )
152160
153161
154- class _ParallelMonoScopeFixtureImpl ( ParallelMonoScopeFixture ):
162+ class _IsoSchedulingFixtureImpl ( IsoSchedulingFixture ):
155163 """Context manager yielding a new instance of the implementation of the
156164 `DistributedSetupCoordinator` interface.
157165
158- An instance of _ParallelMonoScopeFixtureImpl is returned by our pytest
159- fixture `parallel_mono_scope `.
166+ An instance of _IsoSchedulingFixtureImpl is returned by our pytest
167+ fixture `iso_scheduling `.
160168 """
161169 # pylint: disable=too-few-public-methods
162170
@@ -206,11 +214,11 @@ def coordinate_setup_teardown(
206214
207215
208216class _DistributedSetupCoordinatorImpl (DistributedSetupCoordinator ):
209- """Distributed scope/class setup/teardown coordination for the
210- `parallel_mono_scope` Test Distribution Mode .
217+ """Distributed scope/class setup/teardown coordination for isoscope
218+ scheduling .
211219
212220 NOTE: do not instantiate this class directly. Use the
213- `parallel_mono_scope ` fixture instead!
221+ `iso_scheduling ` fixture instead!
214222
215223 """
216224 _DISTRIBUTED_SETUP_ROOT_DIR_LINK_NAME = 'distributed_setup'
@@ -257,7 +265,7 @@ def maybe_call_setup(
257265 Process-safe.
258266
259267 Call `maybe_call_setup` from the pytest setup-teardown fixture of your
260- `PARALLEL_MONO_SCOPE` test (typically test class) if it needs to
268+ isoscope-scheduled test (typically test class) if it needs to
261269 initialize a resource which is common to all of its test cases which may
262270 be executing in different XDist worker processes (such as a subnet in
263271 `subnet.xml`).
@@ -272,8 +280,7 @@ def maybe_call_setup(
272280 :return: An instance of `DistributedSetupContext` which MUST be passed
273281 in the corresponding call to `maybe_call_teardown`.
274282
275- :raise parallel_mono_scope.CoordinationTimeoutError: If attempt to
276- acquire the lock times out.
283+ :raise CoordinationTimeoutError: If attempt to acquire the lock times out.
277284 """
278285 # `maybe_call_setup()` may be called only once per instance of
279286 # `_SetupCoordinator`
@@ -307,7 +314,7 @@ def maybe_call_teardown(
307314 tests for your test scope. Process-safe.
308315
309316 Call `maybe_call_teardown` from the pytest setup-teardown fixture of
310- your `PARALLEL_MONO_SCOPE` test (typically test class) if it needs to
317+ your isoscope-scheduled test (typically test class) if it needs to
311318 initialize a resource which is common to all of its test cases which may
312319 be executing in different XDist worker processes (such as a subnet in
313320 `subnet.xml`).
@@ -320,8 +327,7 @@ def maybe_call_teardown(
320327 invoked.
321328 :param timeout: Lock acquisition timeout in seconds
322329
323- :raise parallel_mono_scope.CoordinationTimeoutError: If attempt to
324- acquire the lock times out.
330+ :raise CoordinationTimeoutError: If attempt to acquire the lock times out.
325331 """
326332 # Make sure `maybe_call_setup()` was already called on this instance
327333 # of `_SetupCoordinator`
@@ -359,8 +365,7 @@ def wrapper(*args, **kwargs):
359365
360366class _DistributedSetupCoordinationImpl :
361367 """Low-level implementation of Context Managers for Coordinating
362- Distributed Setup and Teardown for the `parallel_mono_scope`
363- Test Distribution Mode.
368+ Distributed Setup and Teardown for users of isoscope scheduling.
364369 """
365370 _ROOT_STATE_FILE_NAME = 'root_state.json'
366371 _ROOT_LOCK_FILE_NAME = 'lock'
@@ -426,7 +431,7 @@ def acquire_distributed_setup(
426431 timeout : float
427432 ) -> Generator [DistributedSetupContext , None , None ]:
428433 """Low-level implementation of Context Manager for Coordinating
429- Distributed Setup for the `parallel_mono_scope` Test Distribution Mode .
434+ Distributed Setup for isoscope scheduling .
430435
431436 :param root_context_dir: Scope/class-specific root directory for
432437 saving this context manager's state. This directory is common to
@@ -436,8 +441,7 @@ def acquire_distributed_setup(
436441 directly by the calling setup-teardown fixture.
437442 :param timeout: Lock acquisition timeout in seconds
438443
439- :raise parallel_mono_scope.CoordinationTimeoutError: If attempt to
440- acquire the lock times out.
444+ :raise CoordinationTimeoutError: If attempt to acquire the lock times out.
441445 """
442446 #
443447 # Before control passes to the managed code block
@@ -502,16 +506,14 @@ def acquire_distributed_teardown(
502506 timeout : float
503507 ) -> Generator [DistributedTeardownContext , None , None ]:
504508 """Low-level implementation of Context Manager for Coordinating
505- Distributed Teardown for the `parallel_mono_scope` Test Distribution
506- Mode.
509+ Distributed Teardown for the isoscope scheduling.
507510
508511 :param setup_context: The instance of `DistributedSetupContext` that was
509512 yielded by the corresponding use of the
510513 `_distributed_setup_permission` context manager.
511514 :param timeout: Lock acquisition timeout in seconds
512515
513- :raise parallel_mono_scope.CoordinationTimeoutError: If attempt to
514- acquire the lock times out.
516+ :raise CoordinationTimeoutError: If attempt to acquire the lock times out.
515517 """
516518 #
517519 # Before control passes to the managed code block
0 commit comments