fix dash test runner
This commit is contained in:
@@ -57,6 +57,7 @@ DEFAULT_MAX_LOG_LINES = 4000
|
|||||||
_MAX_LINE_CHARS = 4000
|
_MAX_LINE_CHARS = 4000
|
||||||
DEFAULT_COLLECT_TIMEOUT = 120.0
|
DEFAULT_COLLECT_TIMEOUT = 120.0
|
||||||
DEFAULT_RUN_TIMEOUT = 1800.0
|
DEFAULT_RUN_TIMEOUT = 1800.0
|
||||||
|
PYTHON_ENV_VAR = "MESHNET_PYTHON"
|
||||||
|
|
||||||
_NODE_ID_RE = re.compile(r"^[\w./\[\]:,= @-]+$")
|
_NODE_ID_RE = re.compile(r"^[\w./\[\]:,= @-]+$")
|
||||||
|
|
||||||
@@ -98,6 +99,23 @@ def _real_inference_enabled() -> bool:
|
|||||||
return os.environ.get(REAL_INFERENCE_ENV_VAR) == "1"
|
return os.environ.get(REAL_INFERENCE_ENV_VAR) == "1"
|
||||||
|
|
||||||
|
|
||||||
|
def _test_python() -> str:
|
||||||
|
"""Return the project interpreter configured by the machine env file.
|
||||||
|
|
||||||
|
The tracker may run from a lightweight service environment while the test
|
||||||
|
suite needs the project's full environment (including SDK dependencies).
|
||||||
|
``meshnet_tracker.cli`` loads ``.env.<hostname>`` before constructing the
|
||||||
|
server, so use its explicit interpreter selection for child pytest runs.
|
||||||
|
Direct users of ``TestRunManager`` retain the normal interpreter fallback.
|
||||||
|
"""
|
||||||
|
configured = os.environ.get(PYTHON_ENV_VAR, "").strip()
|
||||||
|
if configured:
|
||||||
|
python = Path(configured).expanduser()
|
||||||
|
if python.is_file() and os.access(python, os.X_OK):
|
||||||
|
return str(python)
|
||||||
|
return sys.executable
|
||||||
|
|
||||||
|
|
||||||
class TestRunManager:
|
class TestRunManager:
|
||||||
"""Collects pytest node IDs and runs one fixed target at a time."""
|
"""Collects pytest node IDs and runs one fixed target at a time."""
|
||||||
|
|
||||||
@@ -145,7 +163,7 @@ class TestRunManager:
|
|||||||
if self._collected_at is not None and not refresh:
|
if self._collected_at is not None and not refresh:
|
||||||
return self._collection_snapshot_locked()
|
return self._collection_snapshot_locked()
|
||||||
|
|
||||||
cmd = [sys.executable, "-m", "pytest", "--collect-only", "-q", "-p", "no:cacheprovider"]
|
cmd = [_test_python(), "-m", "pytest", "--collect-only", "-q", "-p", "no:cacheprovider"]
|
||||||
if not _real_inference_enabled():
|
if not _real_inference_enabled():
|
||||||
for name in sorted(
|
for name in sorted(
|
||||||
p.name for p in (self.repo_root / "tests").glob("test_real_*.py")
|
p.name for p in (self.repo_root / "tests").glob("test_real_*.py")
|
||||||
@@ -216,7 +234,7 @@ class TestRunManager:
|
|||||||
with self._lock:
|
with self._lock:
|
||||||
if self._run is not None and self._run["status"] == "running":
|
if self._run is not None and self._run["status"] == "running":
|
||||||
raise RunInProgressError("a test run is already in progress")
|
raise RunInProgressError("a test run is already in progress")
|
||||||
cmd = [sys.executable, "-m", "pytest", "-q", "-p", "no:cacheprovider", *pytest_args]
|
cmd = [_test_python(), "-m", "pytest", "-q", "-p", "no:cacheprovider", *pytest_args]
|
||||||
self._stdout = deque(maxlen=self.max_log_lines)
|
self._stdout = deque(maxlen=self.max_log_lines)
|
||||||
self._stderr = deque(maxlen=self.max_log_lines)
|
self._stderr = deque(maxlen=self.max_log_lines)
|
||||||
process = subprocess.Popen( # noqa: S603 — fixed argv, no shell
|
process = subprocess.Popen( # noqa: S603 — fixed argv, no shell
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import pytest
|
|||||||
from meshnet_node.model_backend import (
|
from meshnet_node.model_backend import (
|
||||||
InsufficientVRAMError,
|
InsufficientVRAMError,
|
||||||
PartialModelLoadUnsupported,
|
PartialModelLoadUnsupported,
|
||||||
ShardCacheMiss,
|
KVCacheMiss,
|
||||||
TensorPayload,
|
TensorPayload,
|
||||||
TorchModelShard,
|
TorchModelShard,
|
||||||
_call_layer,
|
_call_layer,
|
||||||
@@ -629,7 +629,7 @@ def test_shard_cache_decode_miss_is_explicit():
|
|||||||
torch = pytest.importorskip("torch")
|
torch = pytest.importorskip("torch")
|
||||||
shard = _fake_cache_shard(torch)
|
shard = _fake_cache_shard(torch)
|
||||||
|
|
||||||
with pytest.raises(ShardCacheMiss):
|
with pytest.raises(KVCacheMiss):
|
||||||
shard._run_layers(
|
shard._run_layers(
|
||||||
torch.zeros((1, 1, 2), dtype=torch.bfloat16),
|
torch.zeros((1, 1, 2), dtype=torch.bfloat16),
|
||||||
torch.ones((1, 5), dtype=torch.long),
|
torch.ones((1, 5), dtype=torch.long),
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ constructed without an explicit ``repo_root``.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
import sys
|
||||||
import time
|
import time
|
||||||
import urllib.error
|
import urllib.error
|
||||||
import urllib.request
|
import urllib.request
|
||||||
@@ -16,7 +17,7 @@ import pytest
|
|||||||
from meshnet_tracker.accounts import AccountStore
|
from meshnet_tracker.accounts import AccountStore
|
||||||
from meshnet_tracker.server import TrackerServer
|
from meshnet_tracker.server import TrackerServer
|
||||||
from meshnet_tracker.test_runner import TestRunManager as RunManager
|
from meshnet_tracker.test_runner import TestRunManager as RunManager
|
||||||
from meshnet_tracker.test_runner import discover_repo_root
|
from meshnet_tracker.test_runner import _test_python, discover_repo_root
|
||||||
|
|
||||||
|
|
||||||
def _make_repo(tmp_path: Path) -> Path:
|
def _make_repo(tmp_path: Path) -> Path:
|
||||||
@@ -119,6 +120,16 @@ def test_enable_flag_constructs_runner_against_real_repo(monkeypatch):
|
|||||||
assert (tracker._test_runner.repo_root / "tests" / "conftest.py").is_file()
|
assert (tracker._test_runner.repo_root / "tests" / "conftest.py").is_file()
|
||||||
|
|
||||||
|
|
||||||
|
def test_runner_uses_configured_project_python(monkeypatch, tmp_path):
|
||||||
|
python = tmp_path / "python"
|
||||||
|
python.touch(mode=0o755)
|
||||||
|
monkeypatch.setenv("MESHNET_PYTHON", str(python))
|
||||||
|
assert _test_python() == str(python)
|
||||||
|
|
||||||
|
monkeypatch.setenv("MESHNET_PYTHON", str(tmp_path / "missing-python"))
|
||||||
|
assert _test_python() == sys.executable
|
||||||
|
|
||||||
|
|
||||||
def test_collection_lists_tests_and_excludes_real_inference(tmp_path, monkeypatch):
|
def test_collection_lists_tests_and_excludes_real_inference(tmp_path, monkeypatch):
|
||||||
monkeypatch.delenv("MESHNET_ENABLE_REAL_INFERENCE_TESTS", raising=False)
|
monkeypatch.delenv("MESHNET_ENABLE_REAL_INFERENCE_TESTS", raising=False)
|
||||||
tracker, port, admin, _user = _start_tracker(tmp_path)
|
tracker, port, admin, _user = _start_tracker(tmp_path)
|
||||||
|
|||||||
Reference in New Issue
Block a user