Files
ECC/tests/test_invariant_runner.py
T
a15c8e8533 ci: add Python CI job (ruff, mypy, pytest) for the llm-abstraction package (#2364)
* ci: add ruff + mypy to the Python CI job and fix pyproject tool config

The python-tests job runs pytest but not lint/type checks, and the ruff
and mypy configuration in pyproject.toml was silently broken, so neither
tool could run at all.

- add ruff and mypy steps to the existing python-tests job
- fix invalid pyproject keys: [tool.ruff] src-path -> src,
  [tool.mypy] src_paths -> mypy_path
- ignore ruff UP042 (the (str, Enum) mixin is intentional)
- resolve ruff findings (unused/unsorted imports) across src and tests
- fix mypy errors in tools/executor.py and prompt/builder.py

* fix(ci): satisfy Python lint after main refresh

---------

Co-authored-by: haelyra <49814733+haelyra@users.noreply.github.com>
2026-08-11 14:15:57 -04:00

66 lines
1.8 KiB
Python

import os
import sys
from pathlib import Path
import pytest
_SKILL_COMPLY_ROOT = Path(__file__).resolve().parent.parent / "skills" / "skill-comply"
if str(_SKILL_COMPLY_ROOT) not in sys.path:
sys.path.insert(0, str(_SKILL_COMPLY_ROOT))
from scripts.runner import _setup_sandbox # noqa: E402
from scripts.scenario_generator import Scenario # noqa: E402
_GLOBAL_MARKER = "/tmp/runner_test_pwned_marker"
@pytest.fixture(autouse=True)
def _remove_marker():
if os.path.exists(_GLOBAL_MARKER):
os.remove(_GLOBAL_MARKER)
yield
if os.path.exists(_GLOBAL_MARKER):
os.remove(_GLOBAL_MARKER)
@pytest.mark.parametrize(
"setup_commands,test_id",
[
(
("python -c \"import os; os.system('touch /tmp/runner_test_pwned_marker')\"",),
"python_interpreter",
),
(
("../../../../../../bin/sh -c 'touch /tmp/runner_test_pwned_marker'",),
"path_traversal",
),
(
("bash -c 'touch /tmp/runner_test_pwned_marker'",),
"non_allowlisted_binary",
),
(
("echo hello",),
"benign_echo",
),
],
ids=["python_interpreter", "path_traversal", "non_allowlisted_binary", "benign_echo"],
)
def test_setup_sandbox_blocks_dangerous_commands(setup_commands, test_id, tmp_path):
"""Invariant: _setup_sandbox must not execute disallowed commands."""
scenario = Scenario(
id=f"test-{test_id}",
level=1,
level_name="basic",
description="security test scenario",
prompt="",
setup_commands=setup_commands,
)
sandbox_dir = tmp_path / "sandbox"
_setup_sandbox(sandbox_dir, scenario)
assert not os.path.exists(_GLOBAL_MARKER), (
f"Arbitrary command execution detected for '{test_id}': "
f"marker file created at {_GLOBAL_MARKER}"
)