← Files NGS Analysis WorkbenchARCHIVED FILE
tests/test_native_approval.py
6.9 KB · Sep 30, 2026 · 23:20 UTC
from __future__ import annotations
import json
import os
import sys
import tempfile
import unittest
from pathlib import Path
from unittest import mock
PLUGIN_ROOT = Path(__file__).resolve().parents[1]
MCP_ROOT = PLUGIN_ROOT / "mcp"
if str(MCP_ROOT) not in sys.path:
sys.path.insert(0, str(MCP_ROOT))
from ngs_workbench_mcp import approved_execution, plan_registry # noqa: E402
from ngs_workbench_mcp.workflows import nextflow as nfcore # noqa: E402
_plan_catalog_workflow = nfcore.plan_remote_run
def _plan_with_catalog_source(*args: object, **kwargs: object) -> dict[str, object]:
kwargs.setdefault("workflow", "nf-core/demo")
return _plan_catalog_workflow(*args, **kwargs)
nfcore.plan_remote_run = _plan_with_catalog_source
def ready() -> dict[str, object]:
return {
"ok": True,
"status": "ready",
"scope": "executable_presence_only",
"commands": [
{"name": "nextflow", "path": "/runtime/nextflow"},
{"name": "docker", "path": "/runtime/docker"},
],
"blockers": [],
"docker": {
"path": "/runtime/docker",
"daemon_reachable": True,
"server_os": "linux",
"server_arch": "amd64",
},
}
class NativeApprovalTests(unittest.TestCase):
def _registered_nfcore_plan(self, workspace: Path) -> dict[str, object]:
with mock.patch.object(nfcore, "assess_nfcore_readiness", return_value=ready()):
plan = nfcore.plan_remote_run(
"fastq_qc",
str(workspace / "execution"),
"test,docker",
display_name="Public example FASTQ QC",
revision="1.2.0",
run_id="nfcore-fastq-qc-native-approval",
)
return plan_registry.register_plan("nextflow", plan)
def test_plan_registration_is_immutable_and_has_no_workspace_effects(self) -> None:
with tempfile.TemporaryDirectory() as temporary:
root = Path(temporary)
workspace = root / "workspace"
state_dir = root / "state"
workspace.mkdir()
with mock.patch.dict(
os.environ,
{"NGS_ANALYSIS_WORKBENCH_STATE_DIR": str(state_dir)},
):
registered = self._registered_nfcore_plan(workspace)
binding, loaded = plan_registry.load_approved_plan(
str(registered["plan_name"]),
str(registered["plan_id"]),
str(registered["plan_checksum"]),
)
self.assertEqual(binding, "nextflow")
self.assertEqual(loaded.request.display_name, "Public example FASTQ QC")
self.assertNotIn("approval_arguments", registered)
self.assertNotIn("checksum", registered)
self.assertEqual(
registered["plan_id"],
f"ngs-plan-{str(registered['plan_checksum']).removeprefix('sha256:')[:16]}",
)
self.assertFalse((workspace / "execution").exists())
self.assertTrue((state_dir / "plans" / f"{registered['plan_id']}.json").is_file())
def test_registered_plan_tampering_is_rejected(self) -> None:
with tempfile.TemporaryDirectory() as temporary:
root = Path(temporary)
workspace = root / "workspace"
state_dir = root / "state"
workspace.mkdir()
with mock.patch.dict(
os.environ,
{"NGS_ANALYSIS_WORKBENCH_STATE_DIR": str(state_dir)},
):
registered = self._registered_nfcore_plan(workspace)
path = state_dir / "plans" / f"{registered['plan_id']}.json"
record = json.loads(path.read_text(encoding="utf-8"))
record["plan"]["request"]["profile"] = "test,singularity"
path.write_text(json.dumps(record), encoding="utf-8")
with self.assertRaisesRegex(ValueError, "approved checksum"):
plan_registry.load_approved_plan(
str(registered["plan_name"]),
str(registered["plan_id"]),
str(registered["plan_checksum"]),
)
def test_execute_plan_rejects_unknown_identity_before_dispatch(self) -> None:
with tempfile.TemporaryDirectory() as temporary:
state_dir = Path(temporary) / "state"
with mock.patch.dict(
os.environ,
{"NGS_ANALYSIS_WORKBENCH_STATE_DIR": str(state_dir)},
):
with mock.patch.object(approved_execution.daemon_client, "execute") as execute:
with self.assertRaisesRegex(ValueError, "unknown plan_id"):
approved_execution.execute_registered_plan(
"Unknown plan",
"ngs-plan-0123456789abcdef",
f"sha256:{'0' * 64}",
)
execute.assert_not_called()
def test_execute_plan_rejects_input_drift_before_workspace_writes(self) -> None:
with tempfile.TemporaryDirectory() as temporary:
root = Path(temporary)
workspace = root / "workspace"
state_dir = root / "state"
workspace.mkdir()
sample_sheet = workspace / "samplesheet.csv"
sample_sheet.write_text(
"sample,fastq_1\nS1,/data/r1.fastq.gz\n",
encoding="utf-8",
)
with mock.patch.dict(
os.environ,
{"NGS_ANALYSIS_WORKBENCH_STATE_DIR": str(state_dir)},
):
with mock.patch.object(nfcore, "assess_nfcore_readiness", return_value=ready()):
planned = nfcore.plan_remote_run(
"rnaseq",
str(workspace / "execution"),
"docker",
sample_sheet=str(sample_sheet),
revision="3.26.0",
run_id="nfcore-rnaseq-native-drift",
)
registered = plan_registry.register_plan("nextflow", planned)
sample_sheet.write_text(
"sample,fastq_1\nS2,/data/changed.fastq.gz\n",
encoding="utf-8",
)
with mock.patch.object(approved_execution.daemon_client, "execute") as execute:
result = approved_execution.execute_registered_plan(
str(registered["plan_name"]),
str(registered["plan_id"]),
str(registered["plan_checksum"]),
)
self.assertFalse(result["ok"])
self.assertIn("checksum", str(result["errors"][0]))
execute.assert_not_called()
self.assertFalse((workspace / "execution").exists())
if __name__ == "__main__":
unittest.main()
SHA-256: 077426eb9d97e4127a9ef5b4d2cf42ce915d51b67db870d561d6a68d0bd4258d