diff --git a/Makefile b/Makefile index 0a61e924d..771fe116d 100644 --- a/Makefile +++ b/Makefile @@ -31,8 +31,7 @@ PYTHON := $(VENV_PY) # (which correctly skips non-x86_64 Linux) ever runs. Gating on x86_64 also # keeps this coherent with the STT arch decision (aarch64-linux uses the # parakeet.cpp CPU/Vulkan bundle). Everything non-x86_64 falls to the CPU -# `journal-cpu` group, whose onnxruntime has aarch64 wheels. Guarded by -# tests/test_makefile_journal_extra.py. +# `journal-cpu` group, whose onnxruntime has aarch64 wheels. JOURNAL_VARIANT ?= $(shell if [ "$$(uname -m)" = "x86_64" ] && nvidia-smi -L >/dev/null 2>&1; then echo cuda; else echo cpu; fi) # Dev install groups: install exactly ONE journal leaf for this host. diff --git a/tests/test_check_extras_consistency.py b/tests/test_check_extras_consistency.py deleted file mode 100644 index cc412ca82..000000000 --- a/tests/test_check_extras_consistency.py +++ /dev/null @@ -1,147 +0,0 @@ -# SPDX-License-Identifier: AGPL-3.0-only -# Copyright (c) 2026 sol pbc - -import shutil -from pathlib import Path - -from scripts.check_extras_consistency import _check_models_pin, main - -REPO_ROOT = Path(__file__).resolve().parent.parent - - -def test_check_models_pin_accepts_exact_pin(): - extras = { - "journal-host": [ - "solstone-journal-models==1.0.0", - "solstone[pdf]", - ] - } - - assert _check_models_pin(extras, "1.0.0") == [] - - -def test_check_models_pin_reports_missing_pin(): - extras = {"journal-host": ["solstone[pdf]"]} - - errors = _check_models_pin(extras, "1.0.0") - - assert errors - assert "exactly one solstone-journal-models== pin; found 0" in errors[0] - - -def test_check_models_pin_reports_wrong_version(): - extras = {"journal-host": ["solstone-journal-models==0.9.0"]} - - errors = _check_models_pin(extras, "1.0.0") - - assert errors - assert "solstone-journal-models==1.0.0" in errors[0] - assert "solstone-journal-models==0.9.0" in errors[0] - - -def _repo_copy(tmp_path: Path) -> Path: - root = tmp_path / "repo" - root.mkdir() - for filename in ("pyproject.toml", "Makefile"): - shutil.copy2(REPO_ROOT / filename, root / filename) - for package in ( - "solstone-journal", - "solstone-journal-cuda", - "solstone-journal-models", - ): - target = root / "packages" / package - target.mkdir(parents=True) - shutil.copy2( - REPO_ROOT / "packages" / package / "pyproject.toml", - target / "pyproject.toml", - ) - return root - - -def _replace_once(path: Path, old: str, new: str) -> None: - text = path.read_text(encoding="utf-8") - assert old in text - path.write_text(text.replace(old, new, 1), encoding="utf-8") - - -def test_check_extras_consistency_accepts_repo(): - assert main(REPO_ROOT) == 0 - - -def test_check_extras_consistency_rejects_journal_tombstone_extra_dep(tmp_path): - root = _repo_copy(tmp_path) - _replace_once( - root / "pyproject.toml", - 'journal = ["solstone-journal-host==0.7.0"]', - 'journal = ["solstone-journal-host==0.7.0", "onnxruntime"]', - ) - - assert main(root) != 0 - - -def test_check_extras_consistency_rejects_cpu_leaf_gpu_runtime(tmp_path): - root = _repo_copy(tmp_path) - _replace_once( - root / "packages" / "solstone-journal" / "pyproject.toml", - "dependencies = [\n", - 'dependencies = [\n "onnxruntime-gpu>=1.25.0",\n', - ) - - assert main(root) != 0 - - -def test_check_extras_consistency_rejects_cuda_leaf_cpu_runtime(tmp_path): - root = _repo_copy(tmp_path) - _replace_once( - root / "packages" / "solstone-journal-cuda" / "pyproject.toml", - "dependencies = [\n", - 'dependencies = [\n "onnxruntime>=1.20.0,!=1.24.1",\n', - ) - - assert main(root) != 0 - - -def test_check_extras_consistency_rejects_leaf_cross_dependency(tmp_path): - root = _repo_copy(tmp_path) - _replace_once( - root / "packages" / "solstone-journal" / "pyproject.toml", - "dependencies = [\n", - 'dependencies = [\n "solstone-journal-cuda",\n', - ) - - assert main(root) != 0 - - -def test_check_extras_consistency_rejects_missing_uv_override(tmp_path): - root = _repo_copy(tmp_path) - path = root / "pyproject.toml" - text = path.read_text(encoding="utf-8") - start = text.index("[tool.uv]\n") - end = text.index("[tool.uv.workspace]\n") - path.write_text(text[:start] + text[end:], encoding="utf-8") - - assert main(root) != 0 - - -def test_check_extras_consistency_rejects_makefile_old_extra_spelling(tmp_path): - root = _repo_copy(tmp_path) - path = root / "Makefile" - path.write_text( - path.read_text(encoding="utf-8") + "\n# old spelling: --extra journal\n", - encoding="utf-8", - ) - - assert main(root) != 0 - - -def test_check_extras_consistency_rejects_old_host_workspace_member(tmp_path): - root = _repo_copy(tmp_path) - old_leaf_name = "host" - old_host_member = f"packages/solstone-journal-{old_leaf_name}" - _replace_once( - root / "pyproject.toml", - 'members = ["packages/solstone-journal", "packages/solstone-journal-cuda", "packages/solstone-journal-models"]', - f'members = ["{old_host_member}", "packages/solstone-journal-models"]', - ) - - assert main(root) != 0 diff --git a/tests/test_check_wheel_contents.py b/tests/test_check_wheel_contents.py deleted file mode 100644 index c270c7957..000000000 --- a/tests/test_check_wheel_contents.py +++ /dev/null @@ -1,95 +0,0 @@ -# SPDX-License-Identifier: AGPL-3.0-only -# Copyright (c) 2026 sol pbc - -from __future__ import annotations - -import hashlib -import importlib.util -import sys -import zipfile -from pathlib import Path - - -def _load_check_wheel_contents(): - script_path = ( - Path(__file__).resolve().parents[1] / "scripts" / "check_wheel_contents.py" - ) - spec = importlib.util.spec_from_file_location( - "check_wheel_contents_test", script_path - ) - assert spec is not None - assert spec.loader is not None - module = importlib.util.module_from_spec(spec) - sys.modules[spec.name] = module - spec.loader.exec_module(module) - return module - - -def _sha256(data: bytes) -> str: - return hashlib.sha256(data).hexdigest() - - -def _write_wheel(path: Path, members: dict[str, bytes]) -> None: - with zipfile.ZipFile(path, "w") as wheel: - for member, data in members.items(): - wheel.writestr(member, data) - - -def test_check_dist_passes_clean_split(tmp_path: Path): - check_wheel_contents = _load_check_wheel_contents() - expected = {"a.onnx": _sha256(b"a"), "b.onnx": _sha256(b"b")} - _write_wheel(tmp_path / "solstone-1.0.0-py3-none-any.whl", {"pkg/data.txt": b"ok"}) - _write_wheel( - tmp_path / "solstone_journal_models-1.0.0-py3-none-any.whl", - { - "solstone_journal_models/assets/a.onnx": b"a", - "solstone_journal_models/assets/b.onnx": b"b", - }, - ) - - assert check_wheel_contents.check_dist(tmp_path, expected, 100_000) == [] - - -def test_check_dist_fails_when_base_wheel_carries_onnx(tmp_path: Path): - check_wheel_contents = _load_check_wheel_contents() - expected = {"a.onnx": _sha256(b"a")} - _write_wheel( - tmp_path / "solstone-1.0.0-py3-none-any.whl", - {"solstone/observe/assets/a.onnx": b"a"}, - ) - _write_wheel( - tmp_path / "solstone_journal_models-1.0.0-py3-none-any.whl", - {"solstone_journal_models/assets/a.onnx": b"a"}, - ) - - errors = check_wheel_contents.check_dist(tmp_path, expected, 100_000) - - assert errors - assert any("base wheel contains ONNX members" in error for error in errors) - - -def test_check_dist_fails_on_models_digest_mismatch(tmp_path: Path): - check_wheel_contents = _load_check_wheel_contents() - expected = {"a.onnx": _sha256(b"expected")} - _write_wheel(tmp_path / "solstone-1.0.0-py3-none-any.whl", {"pkg/data.txt": b"ok"}) - _write_wheel( - tmp_path / "solstone_journal_models-1.0.0-py3-none-any.whl", - {"solstone_journal_models/assets/a.onnx": b"actual"}, - ) - - errors = check_wheel_contents.check_dist(tmp_path, expected, 100_000) - - assert errors - assert any("sha256 mismatch" in error for error in errors) - - -def test_check_dist_fails_when_models_wheel_missing(tmp_path: Path): - check_wheel_contents = _load_check_wheel_contents() - _write_wheel(tmp_path / "solstone-1.0.0-py3-none-any.whl", {"pkg/data.txt": b"ok"}) - - errors = check_wheel_contents.check_dist( - tmp_path, {"a.onnx": _sha256(b"a")}, 100_000 - ) - - assert errors - assert any("no solstone_journal_models wheel found" in error for error in errors) diff --git a/tests/test_makefile_cli_migration.py b/tests/test_makefile_cli_migration.py deleted file mode 100644 index 366738c16..000000000 --- a/tests/test_makefile_cli_migration.py +++ /dev/null @@ -1,26 +0,0 @@ -# SPDX-License-Identifier: AGPL-3.0-only -# Copyright (c) 2026 sol pbc - -from __future__ import annotations - -import re -from pathlib import Path - -from solstone.think.sol_cli import COMMANDS - - -def test_makefile_uses_journal_for_service_tagged_commands() -> None: - text = Path("Makefile").read_text(encoding="utf-8") - service_commands = sorted( - name for name, command in COMMANDS.items() if command.surface == "service" - ) - pattern = re.compile( - r"\$\(VENV_BIN\)/sol\s+(" + "|".join(map(re.escape, service_commands)) + r")\b" - ) - - assert pattern.findall(text) == [] - assert "$(VENV_BIN)/journal supervisor" in text - assert "$(VENV_BIN)/journal install-models" in text - assert "$(VENV_BIN)/journal service logs -f" in text - assert "journal service uninstall" in text - assert "sol skills uninstall" in text diff --git a/tests/test_makefile_journal_extra.py b/tests/test_makefile_journal_extra.py deleted file mode 100644 index d0e930b29..000000000 --- a/tests/test_makefile_journal_extra.py +++ /dev/null @@ -1,117 +0,0 @@ -# SPDX-License-Identifier: AGPL-3.0-only -# Copyright (c) 2026 sol pbc -"""Guard: `make install` selects the CUDA journal group only on x86_64. - -The Makefile derives JOURNAL_GROUP from JOURNAL_VARIANT, auto-detected -from the host (`uname -m` + `nvidia-smi`). The CUDA variant resolves -onnxruntime-gpu, which ships NO aarch64 wheel on PyPI — so an aarch64 NVIDIA -host (DGX Spark / GB10) that picked `cuda` would die in the `.installed` -`uv sync` before the per-arch `install` guard ever runs. This test pins the -arch -> group mapping so the x86_64 gate can't silently regress (the build- -manifest analog of test_llama_server_pins_cover_expected_platforms). - -It resolves JOURNAL_GROUP the way the Makefile actually would on a given host -by shimming `uname` and `nvidia-smi` onto PATH and asking make to expand the -variable through a tiny `include`-the-real-Makefile helper (portable across -GNU make 3.81+, no `--eval` dependency). -""" - -from __future__ import annotations - -import os -import re -import shutil -import subprocess -import tempfile -from pathlib import Path - -import pytest - -REPO_ROOT = Path(__file__).resolve().parent.parent -MAKEFILE = REPO_ROOT / "Makefile" -REAL_UNAME = shutil.which("uname") or "/usr/bin/uname" - -pytestmark = pytest.mark.skipif(shutil.which("make") is None, reason="make not on PATH") - - -def _shim(path: Path, body: str) -> None: - path.write_text(body, encoding="utf-8") - path.chmod(0o755) - - -def _resolve_journal_group(arch: str, *, nvidia: bool) -> str: - """Return the Makefile's JOURNAL_GROUP as it would resolve on a host whose - `uname -m` is ``arch`` and where `nvidia-smi -L` does (``nvidia``) or does - not exit 0 — both faked via PATH shims.""" - with tempfile.TemporaryDirectory() as d: - bindir = Path(d) - # `uname -m` -> faked arch; every other uname call (e.g. `-s`, used at - # parse time) delegates to the real binary so the Makefile still parses. - _shim( - bindir / "uname", - f'#!/bin/sh\nif [ "$1" = "-m" ]; then echo "{arch}"; ' - f'else exec "{REAL_UNAME}" "$@"; fi\n', - ) - _shim( - bindir / "nvidia-smi", - "#!/bin/sh\nexit 0\n" if nvidia else "#!/bin/sh\nexit 127\n", - ) - # No-op uv shim: keeps the parse-time `ifndef UV` guard satisfied even - # where uv isn't installed. The print target never invokes it. - _shim(bindir / "uv", "#!/bin/sh\nexit 0\n") - # Emit the value on its own marker line so extraction tolerates any - # surrounding decoration make may add to stdout. - helper = bindir / "print-journal-group.mk" - helper.write_text( - f"include {MAKEFILE}\n" - "__journal_group__:\n" - "\t@printf 'JOURNAL_GROUP=[%s]\\n' '$(JOURNAL_GROUP)'\n", - encoding="utf-8", - ) - # Run the nested make hermetically: drop any recursive-make state the - # parent (e.g. `make ci`) exported, or it inherits the jobserver and - # prints `Entering/Leaving directory` onto our captured stdout. - env = { - k: v - for k, v in os.environ.items() - if k not in ("MAKEFLAGS", "MAKELEVEL", "MFLAGS", "MAKEOVERRIDES") - } - env["PATH"] = f"{bindir}{os.pathsep}{os.environ['PATH']}" - result = subprocess.run( - ["make", "--no-print-directory", "-f", str(helper), "__journal_group__"], - cwd=REPO_ROOT, - env=env, - capture_output=True, - text=True, - check=True, - ) - match = re.search(r"^JOURNAL_GROUP=\[(.*)\]$", result.stdout, re.MULTILINE) - assert match is not None, ( - f"could not read JOURNAL_GROUP from make output\n" - f"stdout: {result.stdout!r}\nstderr: {result.stderr!r}" - ) - return match.group(1) - - -@pytest.mark.parametrize( - ("arch", "nvidia", "expected"), - [ - # x86_64 + NVIDIA is the ONLY cell that gets the CUDA (onnxruntime-gpu) - # bundle — the existing x86_64 install path with its CUDA validation. - ("x86_64", True, "journal-cuda"), - ("x86_64", False, "journal-cpu"), - # aarch64 NVIDIA (DGX Spark / GB10) must fall to the CPU bundle: there - # is no aarch64 onnxruntime-gpu wheel. This is the regression the gate - # prevents — `nvidia-smi` succeeding must NOT force `cuda` here. - ("aarch64", True, "journal-cpu"), - ("aarch64", False, "journal-cpu"), - # macOS arm64 stays on the CPU bundle (parakeet uses the CoreML helper); - # nvidia-smi is absent there, but the gate holds even if it weren't. - ("arm64", True, "journal-cpu"), - ("arm64", False, "journal-cpu"), - ], -) -def test_journal_group_selects_cuda_only_on_x86_64( - arch: str, nvidia: bool, expected: str -) -> None: - assert _resolve_journal_group(arch, nvidia=nvidia) == expected diff --git a/tests/test_provider_cache_seed.py b/tests/test_provider_cache_seed.py deleted file mode 100644 index 7eac36924..000000000 --- a/tests/test_provider_cache_seed.py +++ /dev/null @@ -1,283 +0,0 @@ -# SPDX-License-Identifier: AGPL-3.0-only -# Copyright (c) 2026 sol pbc - -from __future__ import annotations - -import errno -import os -import sys -from pathlib import Path - -import pytest - -from solstone.think import install_models, provider_cache_seed - -ProviderFile = tuple[str, str, bytes] - - -def _write_provider_files(root: Path, files: tuple[ProviderFile, ...]) -> Path: - cache = root / "journal" / "cache" / "providers" - for provider, relpath, content in files: - target = cache / provider / relpath - target.parent.mkdir(parents=True, exist_ok=True) - target.write_bytes(content) - return cache - - -def _regular_files(root: Path) -> list[Path]: - if not root.exists(): - return [] - return sorted(path for path in root.rglob("*") if path.is_file()) - - -def _configure_seed( - monkeypatch: pytest.MonkeyPatch, - current_root: Path, - *, - sibling_roots: list[Path] | None = None, - packaged: bool = False, -) -> None: - monkeypatch.delenv("SOLSTONE_PROVIDER_CACHE_SEED_SOURCE", raising=False) - monkeypatch.setattr( - provider_cache_seed, "get_journal", lambda: str(current_root / "journal") - ) - monkeypatch.setattr( - provider_cache_seed, "get_project_root", lambda: str(current_root) - ) - monkeypatch.setattr(provider_cache_seed, "is_packaged_install", lambda: packaged) - monkeypatch.setattr( - provider_cache_seed, - "_sibling_worktrees", - lambda _root: list(sibling_roots or []), - ) - - -def _assert_hardlink(source: Path, target: Path) -> None: - source_stat = os.stat(source) - target_stat = os.stat(target) - assert target_stat.st_ino == source_stat.st_ino - assert target_stat.st_nlink >= 2 - - -def test_seed_provider_cache_success_hardlinks_sibling_files( - monkeypatch: pytest.MonkeyPatch, - tmp_path: Path, - capsys: pytest.CaptureFixture[str], -): - current_root = tmp_path / "current" - sibling_root = tmp_path / "sibling" - files = ( - ("rerank", "rev/onnx/model.onnx", b"rerank-model"), - ("rerank", "rev/tokenizer.json", b"tokenizer"), - ("rfdetr", "engine/65c0ffcc/rfdetr-cli", b"rfdetr-cli"), - ("rfdetr", "model/rev/rfdetr-nano-f16.gguf", b"rfdetr-model"), - ) - sibling_cache = _write_provider_files(sibling_root, files) - _configure_seed(monkeypatch, current_root, sibling_roots=[sibling_root]) - - result = provider_cache_seed.seed_provider_cache() - - assert result.seeded is True - assert result.file_count == len(files) - assert result.byte_count == sum( - len(content) for _provider, _relpath, content in files - ) - assert result.source == sibling_cache - current_cache = current_root / "journal" / "cache" / "providers" - for provider, relpath, _content in files: - _assert_hardlink( - sibling_cache / provider / relpath, current_cache / provider / relpath - ) - assert "provider cache: seeded 4 files" in capsys.readouterr().out - - -def test_seed_provider_cache_cross_device_skips_without_files( - monkeypatch: pytest.MonkeyPatch, - tmp_path: Path, - capsys: pytest.CaptureFixture[str], -): - current_root = tmp_path / "current" - sibling_root = tmp_path / "sibling" - _write_provider_files( - sibling_root, - (("rerank", "rev/onnx/model.onnx", b"rerank-model"),), - ) - _configure_seed(monkeypatch, current_root, sibling_roots=[sibling_root]) - - def raise_exdev(_src: Path, _dst: Path) -> None: - raise OSError(errno.EXDEV, "cross-device link") - - monkeypatch.setattr(provider_cache_seed.os, "link", raise_exdev) - - result = provider_cache_seed.seed_provider_cache() - - assert result.seeded is False - assert result.reason == "cross-device" - assert _regular_files(current_root / "journal" / "cache" / "providers") == [] - assert "is on a different filesystem, will download" in capsys.readouterr().out - - -def test_seed_provider_cache_no_sibling_skips( - monkeypatch: pytest.MonkeyPatch, - tmp_path: Path, - capsys: pytest.CaptureFixture[str], -): - current_root = tmp_path / "current" - _configure_seed(monkeypatch, current_root, sibling_roots=[]) - - result = provider_cache_seed.seed_provider_cache() - - assert result.seeded is False - assert result.reason == "no-source" - assert _regular_files(current_root / "journal" / "cache" / "providers") == [] - assert "no sibling checkout with a populated cache" in capsys.readouterr().out - - -def test_seed_provider_cache_partial_cache_hardlinks_available_providers( - monkeypatch: pytest.MonkeyPatch, - tmp_path: Path, -): - current_root = tmp_path / "current" - sibling_root = tmp_path / "sibling" - files = ( - ("rerank", "rev/onnx/model.onnx", b"rerank-model"), - ("ced", "v0.1.0/.ced-install.json", b"{}"), - ) - sibling_cache = _write_provider_files(sibling_root, files) - _configure_seed(monkeypatch, current_root, sibling_roots=[sibling_root]) - - result = provider_cache_seed.seed_provider_cache() - - assert result.seeded is True - assert result.file_count == len(files) - current_cache = current_root / "journal" / "cache" / "providers" - for provider, relpath, _content in files: - _assert_hardlink( - sibling_cache / provider / relpath, current_cache / provider / relpath - ) - assert not (current_cache / "rfdetr").exists() - - -def test_seed_provider_cache_local_already_populated_skips_before_sibling_lookup( - monkeypatch: pytest.MonkeyPatch, - tmp_path: Path, - capsys: pytest.CaptureFixture[str], -): - current_root = tmp_path / "current" - existing = ( - _write_provider_files( - current_root, - (("rerank", "existing.txt", b"local"),), - ) - / "rerank" - / "existing.txt" - ) - monkeypatch.delenv("SOLSTONE_PROVIDER_CACHE_SEED_SOURCE", raising=False) - monkeypatch.setattr( - provider_cache_seed, "get_journal", lambda: str(current_root / "journal") - ) - monkeypatch.setattr( - provider_cache_seed, - "_sibling_worktrees", - lambda _root: pytest.fail("sibling lookup should not run"), - ) - - result = provider_cache_seed.seed_provider_cache() - - assert result.seeded is False - assert result.reason == "local-populated" - assert existing.read_bytes() == b"local" - assert "local cache already populated" in capsys.readouterr().out - - -def test_seed_provider_cache_env_override_precedes_git_worktrees( - monkeypatch: pytest.MonkeyPatch, - tmp_path: Path, -): - current_root = tmp_path / "current" - override_root = tmp_path / "override" - sibling_root = tmp_path / "sibling" - override_cache = _write_provider_files( - override_root, - (("rerank", "override.bin", b"override"),), - ) - _write_provider_files( - sibling_root, - (("rfdetr", "sibling.bin", b"sibling"),), - ) - _configure_seed(monkeypatch, current_root, sibling_roots=[sibling_root]) - monkeypatch.setenv("SOLSTONE_PROVIDER_CACHE_SEED_SOURCE", str(override_root)) - - result = provider_cache_seed.seed_provider_cache() - - assert result.seeded is True - assert result.source == override_cache - current_cache = current_root / "journal" / "cache" / "providers" - _assert_hardlink( - override_cache / "rerank" / "override.bin", - current_cache / "rerank" / "override.bin", - ) - assert not (current_cache / "rfdetr" / "sibling.bin").exists() - - -def test_seed_provider_cache_never_raises_unexpected_error( - monkeypatch: pytest.MonkeyPatch, - tmp_path: Path, - capsys: pytest.CaptureFixture[str], -): - current_root = tmp_path / "current" - sibling_root = tmp_path / "sibling" - _write_provider_files( - sibling_root, - (("rerank", "rev/onnx/model.onnx", b"rerank-model"),), - ) - _configure_seed(monkeypatch, current_root, sibling_roots=[sibling_root]) - monkeypatch.setattr( - provider_cache_seed, - "_hardlink_tree", - lambda _src, _dst: (_ for _ in ()).throw(RuntimeError("boom")), - ) - - result = provider_cache_seed.seed_provider_cache() - - assert result.seeded is False - assert result.reason == "error" - assert "unexpected error: boom" in capsys.readouterr().out - - -def test_install_models_seeds_only_default_mode( - monkeypatch: pytest.MonkeyPatch, - tmp_path: Path, -): - calls: list[str] = [] - paths = { - "binary_cpu": tmp_path / "cpu", - "binary_vulkan": tmp_path / "vulkan", - "model": tmp_path / "model", - } - monkeypatch.delenv(install_models.JOURNAL_VARIANT_ENV, raising=False) - monkeypatch.setattr(install_models, "_platform_info", lambda: ("linux", "x86_64")) - monkeypatch.setattr(install_models, "_detect_linux_variant", lambda: "cpu") - monkeypatch.setattr(install_models, "_verify_bundled_assets", lambda: None) - monkeypatch.setattr( - install_models, "_install_rerank_model", lambda *, check, force: 0 - ) - monkeypatch.setattr( - install_models, "_install_ced_assets", lambda *, check, force: 0 - ) - monkeypatch.setattr( - install_models, "_install_rfdetr_model", lambda *, check, force: 0 - ) - monkeypatch.setattr(install_models, "_check_linux_cpp_ready", lambda: paths) - monkeypatch.setattr( - install_models, "seed_provider_cache", lambda: calls.append("seed") - ) - - monkeypatch.setattr(sys, "argv", ["sol install-models"]) - assert install_models.main() == 0 - assert calls == ["seed"] - - calls.clear() - monkeypatch.setattr(sys, "argv", ["sol install-models", "--check"]) - assert install_models.main() == 0 - assert calls == [] diff --git a/tests/test_render_packaging.py b/tests/test_render_packaging.py deleted file mode 100644 index 59bcc49c8..000000000 --- a/tests/test_render_packaging.py +++ /dev/null @@ -1,48 +0,0 @@ -# SPDX-License-Identifier: AGPL-3.0-only -# Copyright (c) 2026 sol pbc - -import shutil -from pathlib import Path - -from scripts.render_packaging import check - -REPO_ROOT = Path(__file__).resolve().parent.parent - - -def _repo_copy(tmp_path: Path) -> Path: - root = tmp_path / "repo" - root.mkdir() - shutil.copy2(REPO_ROOT / "pyproject.toml", root / "pyproject.toml") - for package in ("solstone-journal", "solstone-journal-cuda"): - target = root / "packages" / package - target.mkdir(parents=True) - shutil.copy2( - REPO_ROOT / "packages" / package / "pyproject.toml", - target / "pyproject.toml", - ) - return root - - -def test_render_packaging_check_accepts_repo(): - assert check(root=REPO_ROOT) == 0 - - -def test_render_packaging_check_reports_leaf_version_drift(tmp_path, capsys): - root = _repo_copy(tmp_path) - # Derive the live root version so this test survives release bumps. - import tomllib - - root_version = tomllib.loads((root / "pyproject.toml").read_text(encoding="utf-8"))[ - "project" - ]["version"] - cpu_pyproject = root / "packages" / "solstone-journal" / "pyproject.toml" - text = cpu_pyproject.read_text(encoding="utf-8") - assert f'version = "{root_version}"' in text - cpu_pyproject.write_text( - text.replace(f'version = "{root_version}"', 'version = "0.0.0"', 1), - encoding="utf-8", - ) - - assert check(root=root) == 1 - captured = capsys.readouterr() - assert "packages/solstone-journal/pyproject.toml" in captured.out diff --git a/tests/test_sol.py b/tests/test_sol.py index ef8a1ccfa..9a00594de 100644 --- a/tests/test_sol.py +++ b/tests/test_sol.py @@ -7,7 +7,6 @@ import logging import os import subprocess import sys -import tomllib from pathlib import Path from unittest.mock import MagicMock, patch @@ -497,20 +496,6 @@ class TestMain: assert path != "" assert path.endswith("/journal") - def test_main_root_command(self, monkeypatch, capsys): - """Test 'root' command prints the project root directory.""" - monkeypatch.setattr(sys, "argv", ["sol", "root"]) - - sol.main() - - captured = capsys.readouterr() - path = captured.out.strip() - assert path != "" - # root should NOT end with /journal — that's --path - assert not path.endswith("/journal") - # root is the repo root regardless of checkout location or dir name - assert path == str(REPO_ROOT) - def test_main_unknown_command_exits(self, monkeypatch): """Test that unknown command exits with code 1.""" monkeypatch.setattr(sys, "argv", ["sol", "unknown-command"]) @@ -567,75 +552,6 @@ class TestCommandRegistry: assert "services" not in sol.COMMANDS assert "services" not in sol.service_help_group().commands - def test_pyproject_scripts_split_thin_base_and_host(self): - """Root ships thin scripts; both journal leaves own service scripts.""" - root_pyproject = tomllib.loads( - (REPO_ROOT / "pyproject.toml").read_text(encoding="utf-8") - ) - leaf_pyprojects = [ - tomllib.loads( - (REPO_ROOT / "packages" / name / "pyproject.toml").read_text( - encoding="utf-8" - ) - ) - for name in ("solstone-journal", "solstone-journal-cuda") - ] - root_scripts = root_pyproject["project"]["scripts"] - - assert set(root_scripts) == {"sol", "solstone"} - assert root_scripts["sol"] == "solstone.think.sol_cli:main" - assert root_scripts["solstone"] == "solstone.think.sol_cli:main" - assert "journal" not in root_scripts - assert "mlx-vlm-server" not in root_scripts - - for leaf_pyproject in leaf_pyprojects: - leaf_scripts = leaf_pyproject["project"]["scripts"] - assert set(leaf_scripts) == {"journal", "mlx-vlm-server"} - assert leaf_scripts["journal"] == "solstone.think.sol_cli:journal_main" - assert ( - leaf_scripts["mlx-vlm-server"] - == "solstone.think.providers.mlx_server:main" - ) - - def test_pyproject_declares_journal_parakeet_dependencies(self): - """The journal host keeps ONNX runtime deps out of the thin base.""" - pyproject = tomllib.loads( - (REPO_ROOT / "pyproject.toml").read_text(encoding="utf-8") - ) - base = pyproject["project"]["dependencies"] - cpu_leaf = tomllib.loads( - (REPO_ROOT / "packages" / "solstone-journal" / "pyproject.toml").read_text( - encoding="utf-8" - ) - ) - cuda_leaf = tomllib.loads( - ( - REPO_ROOT / "packages" / "solstone-journal-cuda" / "pyproject.toml" - ).read_text(encoding="utf-8") - ) - cpu_deps = cpu_leaf["project"]["dependencies"] - cuda_deps = cuda_leaf["project"]["dependencies"] - - # The thin base carries no ONNX / STT runtime. - assert not any("onnxruntime" in dep or "onnx-asr" in dep for dep in base), ( - "thin base must not carry the transcription runtime" - ) - - # The CPU leaf pulls the CPU onnxruntime floor. - assert "onnxruntime>=1.20.0,!=1.24.1" in cpu_deps - assert ( - "onnxruntime>=1.25.0,!=1.24.1; sys_platform == 'linux' and platform_machine == 'x86_64'" - in cpu_deps - ) - assert "onnxruntime-gpu>=1.25.0" not in cpu_deps - - # The CUDA leaf swaps in the GPU runtime and never the CPU onnxruntime. - assert "onnxruntime-gpu>=1.25.0" in cuda_deps - assert not any( - dep.split(";")[0].strip() == "onnxruntime>=1.20.0,!=1.24.1" - for dep in cuda_deps - ) - def test_every_registry_entry_has_surface_tag(self): """All commands and aliases declare the CLI surface they belong to.""" valid_surfaces = {"access", "service", "universal"} diff --git a/tests/test_sol_call_redirect_sweep.py b/tests/test_sol_call_redirect_sweep.py deleted file mode 100644 index ae2a7102b..000000000 --- a/tests/test_sol_call_redirect_sweep.py +++ /dev/null @@ -1,95 +0,0 @@ -# SPDX-License-Identifier: AGPL-3.0-only -# Copyright (c) 2026 sol pbc - -from __future__ import annotations - -import re -import subprocess -from pathlib import Path - -EXCLUDED_DIRS = {".git", ".venv", "build", "dist"} -TEXT_SUFFIXES = { - ".html", - ".json", - ".md", - ".py", - ".sh", - ".toml", - ".txt", - ".yml", - ".yaml", -} -ROOT_TEXT_FILES = { - "AGENTS.md", - "CONTRIBUTING.md", - "INSTALL.md", - "Makefile", - "README.md", -} -REQUIRED_TRACKED_PATHS = { - Path("journal/AGENTS.md"), - Path("tests/fixtures/journal/AGENTS.md"), - Path("tests/fixtures/journal/identity/partner.md"), - Path("tests/baselines/api/thinking/providers.json"), -} -BAN_PATTERNS = ( - re.compile(r"sol call " r"(navigate|routines|identity)\b"), - re.compile(r"sol call settings providers " r"install"), -) - - -def _tracked_files() -> list[Path]: - result = subprocess.run( - ["git", "ls-files"], - check=True, - capture_output=True, - text=True, - ) - return [Path(line) for line in result.stdout.splitlines() if line.strip()] - - -def _is_text_surface(path: Path) -> bool: - if any(part in EXCLUDED_DIRS for part in path.parts): - return False - if path.name == "CHANGELOG.md": - return False - if path.name in ROOT_TEXT_FILES: - return True - return path.suffix in TEXT_SUFFIXES - - -def _candidate_files() -> list[Path]: - files = sorted( - path for path in _tracked_files() if path.exists() and _is_text_surface(path) - ) - missing = REQUIRED_TRACKED_PATHS - set(files) - assert missing == set() - return files - - -def test_old_sol_call_local_paths_are_not_documented() -> None: - matches = [] - for path in _candidate_files(): - text = path.read_text(encoding="utf-8") - for line_number, line in enumerate(text.splitlines(), start=1): - for pattern in BAN_PATTERNS: - if pattern.search(line): - matches.append(f"{path}:{line_number}: {line}") - - assert matches == [] - - -def test_old_sol_call_ban_regex_precision() -> None: - survivors = ( - "sol call settings identity", - "sol call settings providers show", - "sol call settings providers set-generate", - "sol call settings providers set-cogitate", - ) - matches = [ - survivor - for survivor in survivors - if any(pattern.search(survivor) is not None for pattern in BAN_PATTERNS) - ] - - assert matches == []