106 lines
4.0 KiB
Python
106 lines
4.0 KiB
Python
"""Photon's part of the sidecar resolver.
|
|
|
|
The rungs themselves are covered by tests/gateway/test_sidecar_runtime.py.
|
|
What is Photon-specific, and tested here: the legacy ``PHOTON_SIDECAR_DIR``
|
|
override, and that neither the adapter nor the CLI resolves at import time.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
import plugins.platforms.photon.sidecar_paths as sidecar_paths
|
|
|
|
|
|
def test_legacy_override_still_works(tmp_path, monkeypatch) -> None:
|
|
"""``PHOTON_SIDECAR_DIR`` predates the shared resolver.
|
|
|
|
Operators set it, so it keeps working alongside the shared
|
|
``HERMES_PHOTON_SIDECAR_DIR``.
|
|
"""
|
|
override = tmp_path / "custom"
|
|
monkeypatch.delenv("HERMES_PHOTON_SIDECAR_DIR", raising=False)
|
|
monkeypatch.setenv("PHOTON_SIDECAR_DIR", str(override))
|
|
assert sidecar_paths.resolve_sidecar_dir(tmp_path / "src") == override
|
|
|
|
|
|
def test_shared_override_wins_over_the_legacy_one(tmp_path, monkeypatch) -> None:
|
|
"""Both set means the operator moved to the shared name. Honour it."""
|
|
shared = tmp_path / "shared"
|
|
monkeypatch.setenv("PHOTON_SIDECAR_DIR", str(tmp_path / "legacy"))
|
|
monkeypatch.setenv("HERMES_PHOTON_SIDECAR_DIR", str(shared))
|
|
assert sidecar_paths.resolve_sidecar_dir(tmp_path / "src") == shared
|
|
|
|
|
|
def test_the_source_dir_is_the_shipped_sidecar(monkeypatch) -> None:
|
|
"""A resolve with no argument reads the sidecar inside the plugin."""
|
|
monkeypatch.delenv("PHOTON_SIDECAR_DIR", raising=False)
|
|
monkeypatch.delenv("HERMES_PHOTON_SIDECAR_DIR", raising=False)
|
|
seen = {}
|
|
|
|
def _record(name, source):
|
|
seen["name"] = name
|
|
seen["source"] = source
|
|
return source
|
|
|
|
monkeypatch.setattr(sidecar_paths, "resolve_sidecar", _record)
|
|
sidecar_paths.resolve_sidecar_dir()
|
|
assert seen["name"] == "photon"
|
|
assert seen["source"] == sidecar_paths.SOURCE_SIDECAR_DIR
|
|
assert seen["source"].name == "sidecar"
|
|
|
|
|
|
def test_adapter_import_does_not_resolve_sidecar_dir(monkeypatch) -> None:
|
|
"""Importing the adapter must not probe the filesystem or copy files.
|
|
|
|
resolve_sidecar_dir() touch/unlink-probes the source tree and may copy
|
|
files to HERMES_HOME; the adapter and CLI resolve lazily on first use so
|
|
a bare import (plugin discovery, `hermes --help`, test collection) has
|
|
no filesystem side effects.
|
|
"""
|
|
import importlib
|
|
|
|
from plugins.platforms.photon import adapter as photon_adapter
|
|
from plugins.platforms.photon import cli as photon_cli
|
|
|
|
def _boom(*args, **kwargs): # pragma: no cover - failure path
|
|
raise AssertionError("resolve_sidecar_dir called at import time")
|
|
|
|
monkeypatch.setattr(sidecar_paths, "resolve_sidecar_dir", _boom)
|
|
try:
|
|
importlib.reload(photon_adapter)
|
|
importlib.reload(photon_cli)
|
|
# Nothing resolved yet.
|
|
assert photon_adapter._SIDECAR_DIR is None
|
|
assert photon_cli._SIDECAR_DIR is None
|
|
# First real use resolves (and would call resolve_sidecar_dir).
|
|
with pytest.raises(AssertionError, match="import time"):
|
|
photon_adapter._sidecar_dir()
|
|
# A monkeypatched _SIDECAR_DIR (the pattern existing tests use) is
|
|
# honored without touching the resolver.
|
|
monkeypatch.setattr(photon_adapter, "_SIDECAR_DIR", Path("/tmp/x"))
|
|
assert photon_adapter._sidecar_dir() == Path("/tmp/x")
|
|
assert photon_adapter._npm_error_log() == Path("/tmp/x/.photon-npm-error.log")
|
|
finally:
|
|
# Restore real bindings for any later test importing these modules.
|
|
monkeypatch.undo()
|
|
importlib.reload(photon_adapter)
|
|
importlib.reload(photon_cli)
|
|
|
|
|
|
def test_dir_writable_probe(tmp_path) -> None:
|
|
"""Re-exported for the adapter, which gates npm on it."""
|
|
assert sidecar_paths.dir_writable(tmp_path) is True
|
|
ro = tmp_path / "ro"
|
|
ro.mkdir()
|
|
ro.chmod(0o555)
|
|
try:
|
|
if os.geteuid() == 0: # pragma: no cover - root ignores perms
|
|
pytest.skip("root bypasses directory permissions")
|
|
assert sidecar_paths.dir_writable(ro) is False
|
|
finally:
|
|
ro.chmod(0o755)
|