Files
wehub-resource-sync 4b6817381b
Benchmark image — build + push to ECR (any adapter) / build + push (push) Waiting to run
CI / quality (ubuntu-latest) (push) Waiting to run
CI / test (tools-runtime) (push) Waiting to run
CI / test (e2e-general) (push) Waiting to run
CI / test (cli-runtime) (push) Waiting to run
CI / test (e2e-provider-and-openclaw) (push) Waiting to run
CI / test (integrations-and-misc) (push) Waiting to run
CI / coverage-report (push) Blocked by required conditions
CI / test-kubernetes (push) Waiting to run
CI / should-run-thorough (push) Waiting to run
CI / test-thorough (cloudwatch-demo) (push) Blocked by required conditions
CI / test-thorough (flink-ecs) (push) Blocked by required conditions
CI / test-thorough (upstream-lambda) (push) Blocked by required conditions
CI / test-thorough (prefect-ecs-fargate) (push) Blocked by required conditions
CodeQL / Analyze (python) (push) Waiting to run
Release / build-binaries (zip, opensre.exe, onefile, windows-latest, windows-x64) (push) Blocked by required conditions
Release / publish-release (push) Blocked by required conditions
Release / publish-main-release (push) Blocked by required conditions
Release / prepare (push) Waiting to run
Release / verify (push) Blocked by required conditions
Release / build-python-dist (push) Blocked by required conditions
Release / build-binaries (tar.gz, opensre, onedir, macos-15-intel, darwin-x64) (push) Blocked by required conditions
Release / build-binaries (tar.gz, opensre, onedir, macos-latest, darwin-arm64) (push) Blocked by required conditions
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04, linux-x64) (push) Blocked by required conditions
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04-arm, linux-arm64) (push) Blocked by required conditions
Synthetic Deterministic Tests / Synthetic offline (deterministic) (push) Waiting to run
Interactive Shell Live (PR + post-merge) / turn-checks (no-LLM) (push) Waiting to run
Interactive Shell Live (PR + post-merge) / turn-live shard ${{ matrix.shard_index }} (push) Waiting to run
CI (OpenClaw E2E) / openclaw test (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:10:45 +08:00

254 lines
10 KiB
Python

from __future__ import annotations
from pathlib import Path
import pytest
from surfaces.cli.tests.discover import (
_comment_map_for_makefile,
_discover_rds_synthetic_scenarios,
discover_make_targets,
discover_rca_files,
load_test_catalog,
)
def test_load_test_catalog_includes_make_targets_and_rca_fixtures() -> None:
catalog = load_test_catalog()
assert catalog.find("make:test-cov") is not None
assert catalog.find("make:demo") is not None
assert catalog.find("rca:pipeline_error_in_logs") is not None
def test_load_test_catalog_excludes_synthetic_suite_for_now() -> None:
catalog = load_test_catalog()
assert catalog.find("suite:rds_postgres") is None
def test_comment_map_for_makefile_parses_comments_and_resets_buffers(tmp_path: Path) -> None:
makefile = tmp_path / "Makefile"
makefile.write_text(
"# first line\n"
"# second line\n"
"test-cov:\n"
"\tpytest\n"
"\n"
"# this should be ignored\n"
"SHELL := /bin/bash\n"
"# cloudwatch description\n"
"cloudwatch-demo:\n"
"\tpytest\n"
"test-full:\n"
"\tpytest\n",
encoding="utf-8",
)
comments = _comment_map_for_makefile(makefile)
assert comments["test-cov"] == "first line second line"
assert comments["cloudwatch-demo"] == "cloudwatch description"
assert comments["test-full"] == ""
def test_discover_make_targets_finds_target_at_line_one(
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
"""Regression guard: re.MULTILINE regex must match a target with no preceding newline."""
makefile = tmp_path / "Makefile"
makefile.write_text("test-cov:\n\tpytest\n\ntest-full:\n\tpytest --full\n", encoding="utf-8")
monkeypatch.setattr("surfaces.cli.tests.discover.MAKEFILE_PATH", makefile)
items = discover_make_targets()
ids = [item.id for item in items]
assert "make:test-cov" in ids
def test_discover_make_targets_skips_targets_missing_from_makefile(
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
makefile = tmp_path / "Makefile"
makefile.write_text("test-cov:\n\tpytest\n\ndeploy:\n\tpython deploy.py\n", encoding="utf-8")
monkeypatch.setattr("surfaces.cli.tests.discover.MAKEFILE_PATH", makefile)
ids = [item.id for item in discover_make_targets()]
assert set(ids) == {"make:test-cov", "make:deploy"}
assert "make:test-full" not in ids
def test_discover_make_targets_applies_comment_and_metadata(
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
makefile = tmp_path / "Makefile"
makefile.write_text(
"# Grafana integration checks\ntest-grafana:\n\tpytest tests/integrations\n",
encoding="utf-8",
)
monkeypatch.setattr("surfaces.cli.tests.discover.MAKEFILE_PATH", makefile)
items = discover_make_targets()
assert len(items) == 1
item = items[0]
assert item.id == "make:test-grafana"
assert item.description == "Grafana integration checks"
assert item.tags == ("test", "grafana")
assert item.requirements.env_vars == ("ANTHROPIC_API_KEY", "OPENAI_API_KEY")
# ---------------------------------------------------------------------------
# Bundled-binary degradation (regression for #1078)
#
# the release PyInstaller build collects only runtime data files, so at runtime
# in a PyInstaller-bundled ``opensre`` binary the ``tests/`` tree, ``Makefile``,
# and ``tests/e2e/rca`` directory are absent. Each ``discover_*`` helper must
# return cleanly so ``opensre tests`` and ``opensre tests list`` keep working
# against whatever data files *are* bundled, instead of crashing with
# ``FileNotFoundError`` from a raw ``iterdir()`` / ``read_text()`` call.
# ---------------------------------------------------------------------------
def _patch_discover_paths(
monkeypatch: pytest.MonkeyPatch,
*,
repo_root: Path | None = None,
makefile: Path | None = None,
rca_dir: Path | None = None,
synthetic_dir: Path | None = None,
cloudopsbench_dir: Path | None = None,
) -> None:
"""Helper: monkeypatch any subset of the discover module's path constants.
Corpus directories live in :mod:`surfaces.cli.tests.discover`.
"""
if repo_root is not None:
monkeypatch.setattr("surfaces.cli.tests.discover.REPO_ROOT", repo_root)
if makefile is not None:
monkeypatch.setattr("surfaces.cli.tests.discover.MAKEFILE_PATH", makefile)
if rca_dir is not None:
monkeypatch.setattr("surfaces.cli.tests.discover.RCA_DIR", rca_dir)
if synthetic_dir is not None:
monkeypatch.setattr("surfaces.cli.tests.discover.SYNTHETIC_SCENARIOS_DIR", synthetic_dir)
if cloudopsbench_dir is not None:
monkeypatch.setattr("surfaces.cli.tests.discover.CLOUDOPSBENCH_DIR", cloudopsbench_dir)
class TestDiscoverGracefulOnMissingSource:
def test_rds_synthetic_returns_empty_when_dir_missing(
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
"""The reported #1078 crash: ``iterdir()`` on a missing path."""
_patch_discover_paths(monkeypatch, synthetic_dir=tmp_path / "missing-rds-postgres")
assert _discover_rds_synthetic_scenarios() == []
def test_make_targets_returns_empty_when_makefile_missing(
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
"""``discover_make_targets`` was the next class-of-bug landmine —
``MAKEFILE_PATH.read_text()`` would also raise ``FileNotFoundError``
in the same bundled-binary scenario."""
_patch_discover_paths(monkeypatch, makefile=tmp_path / "Makefile")
assert discover_make_targets() == []
def test_rca_files_returns_empty_when_dir_missing(
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
"""``Path.glob`` on a missing parent already returned an empty
iterator on CPython, but the explicit guard documents the contract
and protects against future stdlib churn."""
_patch_discover_paths(monkeypatch, rca_dir=tmp_path / "rca-not-here")
assert discover_rca_files() == []
def test_load_test_catalog_does_not_crash_with_no_sources(
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
"""Full-degradation contract: bundled binary with *no* data files
must still produce a (possibly empty) catalog and not raise."""
empty = tmp_path / "empty"
empty.mkdir()
_patch_discover_paths(
monkeypatch,
repo_root=empty,
makefile=empty / "Makefile",
rca_dir=empty / "rca",
synthetic_dir=empty / "rds_postgres",
cloudopsbench_dir=empty / "cloudopsbench",
)
catalog = load_test_catalog()
# No exception, returns an empty catalog (no make/rca/synthetic items).
assert catalog.find("make:test-cov") is None
assert catalog.find("rca:pipeline_error_in_logs") is None
assert all(not item.id.startswith("synthetic:") for item in catalog.all_items())
def test_rds_synthetic_still_discovers_when_dir_present(
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
"""Sanity: the existence guard must not break the source-checkout
path. With one scenario directory on disk, the helper must still
emit one catalog item."""
scenarios_dir = tmp_path / "rds_postgres"
(scenarios_dir / "001-replication-lag").mkdir(parents=True)
_patch_discover_paths(monkeypatch, synthetic_dir=scenarios_dir)
items = _discover_rds_synthetic_scenarios()
assert len(items) == 1
assert items[0].id == "synthetic:001-replication-lag"
def test_rds_synthetic_returns_empty_when_dir_present_but_empty(
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
"""Edge case from gap analysis: directory exists but is empty —
``iterdir()`` is fine, and the function must return ``[]``."""
scenarios_dir = tmp_path / "rds_postgres"
scenarios_dir.mkdir(parents=True)
_patch_discover_paths(monkeypatch, synthetic_dir=scenarios_dir)
assert _discover_rds_synthetic_scenarios() == []
def test_rds_synthetic_skips_underscore_and_pycache_entries(
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
"""The existing ``startswith('_')`` filter must skip ``__pycache__``
and any other underscore-prefixed sibling. It must also skip stray
files at the top level (only directories become catalog items)."""
scenarios_dir = tmp_path / "rds_postgres"
(scenarios_dir / "001-real-scenario").mkdir(parents=True)
(scenarios_dir / "__pycache__").mkdir()
(scenarios_dir / "_template").mkdir()
(scenarios_dir / "README.md").write_text("not a scenario")
_patch_discover_paths(monkeypatch, synthetic_dir=scenarios_dir)
items = _discover_rds_synthetic_scenarios()
ids = [item.id for item in items]
assert ids == ["synthetic:001-real-scenario"]
def test_rds_synthetic_enriches_display_name_from_scenario_yml(
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
"""Happy YAML path: ``scenario.yml`` with a ``failure_mode`` field
produces the ``"<id> [<mode>]"`` display name."""
scenarios_dir = tmp_path / "rds_postgres"
scenario = scenarios_dir / "001-replication-lag"
scenario.mkdir(parents=True)
(scenario / "scenario.yml").write_text("failure_mode: replication-lag\n")
_patch_discover_paths(monkeypatch, synthetic_dir=scenarios_dir)
items = _discover_rds_synthetic_scenarios()
assert len(items) == 1
assert items[0].display_name == "001-replication-lag [replication-lag]"
def test_rds_synthetic_tolerates_malformed_scenario_yml(
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
"""Defensive YAML parse: malformed ``scenario.yml`` must not crash
discovery — fall back to the bare directory name as display name."""
scenarios_dir = tmp_path / "rds_postgres"
scenario = scenarios_dir / "002-broken-yaml"
scenario.mkdir(parents=True)
(scenario / "scenario.yml").write_text(":::not yaml:::\n - [unbalanced\n")
_patch_discover_paths(monkeypatch, synthetic_dir=scenarios_dir)
items = _discover_rds_synthetic_scenarios()
assert len(items) == 1
assert items[0].display_name == "002-broken-yaml"