Files
nova-platform/tests/test_engine_boundary.py
CIAgent 2443909362 docs(milestone): complete v1.0-nova-platform (release v0.1.6)
---ci---
project: nova-platform
milestone: v1.0
status: complete
requirements:
  covered: [REQ-01,REQ-02,REQ-03,REQ-04,REQ-05,REQ-06,REQ-07,REQ-08,REQ-09,REQ-10,REQ-11,REQ-12,REQ-13,REQ-14,REQ-15,REQ-16,REQ-17,REQ-18,REQ-19,REQ-20,REQ-21,REQ-22,REQ-23,REQ-24,REQ-25,REQ-26,REQ-27,REQ-28,REQ-29,REQ-30,REQ-31,REQ-32,REQ-33,REQ-34,REQ-35,REQ-36,REQ-37,REQ-38]
  partial: []
---/ci---

v1.0 milestone complete: simplified infrastructure-delivery platform
derived from Nova (acdl). 6 phases (P0-P5 + P6 final). 38 REQ-IDs.
38 decisions (D-001..D-038). 76 tests pass. Engine boundary holds.
Happy paths green (check-only + CI). 13 L1 + 2 L2 modules. 5 terraform
roots. Shell reproducibility. Zero OOS files.

Tags: v0.1.0 (P0) → v0.1.1..v0.1.5 (P1..P5) → v0.1.6 (P6 = milestone
release on v0.1 patch line).
2026-08-25 02:18:35 +00:00

128 lines
4.4 KiB
Python

"""Engine-boundary test — REQ-09, D-034.
Verifies no engine-specific *logic* (HCL strings, aws_ resource types,
terraform CLI calls, module/provider/resource block declarations) leaks
outside adapters/terraform/.
Scans .py files in core/, schemas/, contracts/, tests/, scripts/, root.
EXCLUDES adapters/terraform/ (the boundary), modules/, .tf/.md/.json data
files (per D-034).
To avoid false positives on docstrings/comments that *mention* "Terraform"
conceptually, the test strips comments + docstrings before scanning.
The forbidden terms are checked as *code-level* tokens: aws_<word>,
`module "`, `provider "`, `resource "` (HCL block declarations that
would indicate actual HCL emission outside the adapter). The bare word
"terraform" is NOT forbidden (it appears in import paths like
`adapters.terraform` and docstrings); only `terraform ` followed by a
block brace or CLI invocation is.
"""
import ast
import re
from pathlib import Path
import pytest
from tests.conftest import ROOT
# Forbidden as code-level patterns (not in strings/comments):
# - aws_<word>: AWS resource type prefixes (e.g. aws_s3_bucket)
# - 'module "': HCL module block declaration
# - 'provider "': HCL provider block declaration
# - 'resource "': HCL resource block declaration
# - terraform init/plan/apply: CLI invocations
FORBIDDEN_PATTERNS = [
re.compile(r'\baws_[a-z_]+'),
re.compile(r'module\s+"'),
re.compile(r'provider\s+"'),
re.compile(r'resource\s+"'),
re.compile(r'\bterraform\s+(init|plan|apply|validate|destroy)\b'),
]
EXCLUDE_DIRS = {
"adapters/terraform",
".venv",
"__pycache__",
".ciagent",
".git",
"modules",
"terraform",
"docs",
}
# Test files that legitimately reference engine terms to verify the
# boundary/adapter (they assert HCL output contains 'module "' etc.).
# These are part of the boundary enforcement, not engine logic leaks.
EXCLUDE_FILES = {
"tests/test_terraform_adapter.py",
"tests/test_engine_boundary.py",
}
def _strip_docstrings_and_comments(source):
"""Remove docstrings + comments from Python source, return code only."""
try:
tree = ast.parse(source)
except SyntaxError:
return source
lines = source.splitlines(keepends=True)
# Collect line ranges of docstring nodes
docstring_ranges = set()
for node in ast.walk(tree):
if isinstance(node, (ast.Expr,)) and isinstance(node.value, ast.Constant) and isinstance(node.value.value, str):
for ln in range(node.lineno, node.end_lineno + 1):
docstring_ranges.add(ln)
if isinstance(node, ast.Constant) and isinstance(node.value, str) and node.lineno == getattr(node, "end_lineno", None):
# standalone string used as docstring at module/class level
pass
out = []
for i, line in enumerate(lines, start=1):
if i in docstring_ranges:
continue
# strip inline comments
stripped = re.sub(r'#.*$', '', line)
out.append(stripped)
return "".join(out)
def _scan_files():
for path in ROOT.rglob("*.py"):
rel = path.relative_to(ROOT)
rel_str = str(rel)
if any(rel_str.startswith(ex) for ex in EXCLUDE_DIRS):
continue
if any(part in EXCLUDE_DIRS for part in rel.parts):
continue
if rel_str in EXCLUDE_FILES:
continue
yield path
def _forbidden_matches(code):
matches = []
for pat in FORBIDDEN_PATTERNS:
found = pat.findall(code)
if found:
matches.extend(found)
return matches
class TestEngineBoundary:
@pytest.mark.parametrize("path", list(_scan_files()),
ids=[str(p.relative_to(ROOT)) for p in _scan_files()])
def test_no_engine_logic(self, path):
source = path.read_text()
code = _strip_docstrings_and_comments(source)
matches = _forbidden_matches(code)
assert not matches, (
f"{path.relative_to(ROOT)} contains forbidden engine logic: {matches}. "
f"Engine-specific code must live ONLY in adapters/terraform/."
)
def test_boundary_scans_files(self):
files = list(_scan_files())
assert len(files) > 0, "engine-boundary test must scan at least one .py file"
for f in files:
assert "adapters/terraform" not in str(f.relative_to(ROOT)), \
f"adapters/terraform/ must be excluded but found {f}"