Skip to content

Commit

Permalink
Merge pull request #1061 from bluetech/scheduling-proto
Browse files Browse the repository at this point in the history
Add a Scheduling Protocol
  • Loading branch information
bluetech committed Apr 15, 2024
2 parents 91812bf + bf2dccc commit 5dfc590
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 10 deletions.
25 changes: 15 additions & 10 deletions src/xdist/dsession.py
Expand Up @@ -15,6 +15,7 @@
from xdist.scheduler import LoadGroupScheduling
from xdist.scheduler import LoadScheduling
from xdist.scheduler import LoadScopeScheduling
from xdist.scheduler import Scheduling
from xdist.scheduler import WorkStealingScheduling
from xdist.workermanage import NodeManager

Expand Down Expand Up @@ -97,17 +98,21 @@ def pytest_collection(self):
return True

@pytest.hookimpl(trylast=True)
def pytest_xdist_make_scheduler(self, config, log):
def pytest_xdist_make_scheduler(self, config, log) -> Scheduling | None:
dist = config.getvalue("dist")
schedulers = {
"each": EachScheduling,
"load": LoadScheduling,
"loadscope": LoadScopeScheduling,
"loadfile": LoadFileScheduling,
"loadgroup": LoadGroupScheduling,
"worksteal": WorkStealingScheduling,
}
return schedulers[dist](config, log)
if dist == "each":
return EachScheduling(config, log)
if dist == "load":
return LoadScheduling(config, log)
if dist == "loadscope":
return LoadScopeScheduling(config, log)
if dist == "loadfile":
return LoadFileScheduling(config, log)
if dist == "loadgroup":
return LoadGroupScheduling(config, log)
if dist == "worksteal":
return WorkStealingScheduling(config, log)
return None

@pytest.hookimpl
def pytest_runtestloop(self):
Expand Down
1 change: 1 addition & 0 deletions src/xdist/scheduler/__init__.py
Expand Up @@ -3,4 +3,5 @@
from xdist.scheduler.loadfile import LoadFileScheduling as LoadFileScheduling
from xdist.scheduler.loadgroup import LoadGroupScheduling as LoadGroupScheduling
from xdist.scheduler.loadscope import LoadScopeScheduling as LoadScopeScheduling
from xdist.scheduler.protocol import Scheduling as Scheduling
from xdist.scheduler.worksteal import WorkStealingScheduling as WorkStealingScheduling
3 changes: 3 additions & 0 deletions src/xdist/scheduler/each.py
Expand Up @@ -103,6 +103,9 @@ def mark_test_complete(self, node, item_index, duration=0):
def mark_test_pending(self, item):
raise NotImplementedError()

def remove_pending_tests_from_node(self, node, indices):
raise NotImplementedError()

def remove_node(self, node):
# KeyError if we didn't get an add_node() yet
pending = self.node2pending.pop(node)
Expand Down
3 changes: 3 additions & 0 deletions src/xdist/scheduler/load.py
Expand Up @@ -160,6 +160,9 @@ def mark_test_pending(self, item):
for node in self.node2pending:
self.check_schedule(node)

def remove_pending_tests_from_node(self, node, indices):
raise NotImplementedError()

def check_schedule(self, node, duration=0):
"""Maybe schedule new items on the node.
Expand Down
3 changes: 3 additions & 0 deletions src/xdist/scheduler/loadscope.py
Expand Up @@ -244,6 +244,9 @@ def mark_test_complete(self, node, item_index, duration=0):
def mark_test_pending(self, item):
raise NotImplementedError()

def remove_pending_tests_from_node(self, node, indices):
raise NotImplementedError()

def _assign_work_unit(self, node):
"""Assign a work unit to a node."""
assert self.workqueue
Expand Down
47 changes: 47 additions & 0 deletions src/xdist/scheduler/protocol.py
@@ -0,0 +1,47 @@
from __future__ import annotations

from typing import Protocol
from typing import Sequence

from xdist.workermanage import WorkerController


class Scheduling(Protocol):
@property
def nodes(self) -> list[WorkerController]: ...

@property
def collection_is_completed(self) -> bool: ...

@property
def tests_finished(self) -> bool: ...

@property
def has_pending(self) -> bool: ...

def add_node(self, node: WorkerController) -> None: ...

def add_node_collection(
self,
node: WorkerController,
collection: Sequence[str],
) -> None: ...

def mark_test_complete(
self,
node: WorkerController,
item_index: int,
duration: float = 0,
) -> None: ...

def mark_test_pending(self, item: str) -> None: ...

def remove_pending_tests_from_node(
self,
node: WorkerController,
indices: Sequence[int],
) -> None: ...

def remove_node(self, node: WorkerController) -> str | None: ...

def schedule(self) -> None: ...

0 comments on commit 5dfc590

Please sign in to comment.