docs: synchronize MESSAGING.md, IMPROVEMENTS.md, implementation_plan.md and add D-31/D-32 freshness guards
This commit is contained in:
@@ -17,6 +17,7 @@ import sys
|
||||
import tempfile
|
||||
|
||||
import pytest
|
||||
import yaml
|
||||
|
||||
REPO_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
|
||||
|
||||
@@ -722,4 +723,89 @@ def test_d30_websocket_origin_policy_is_startable():
|
||||
assert "/mqtt" in full_conf, "nats.conf must document /mqtt WebSocket MQTT path (N-7)"
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# D-31 — Gitea CI checkout enables submodules for test jobs
|
||||
# --------------------------------------------------------------------------
|
||||
def test_d31_gitea_ci_submodules_in_test_job():
|
||||
gitmodules_path = os.path.join(REPO_ROOT, ".gitmodules")
|
||||
if not os.path.exists(gitmodules_path):
|
||||
return # Auto-disable when no submodules are configured
|
||||
|
||||
ci_path = os.path.join(REPO_ROOT, "deploy", "gitea-ci.yml")
|
||||
assert os.path.exists(ci_path), f"Gitea CI workflow missing at {ci_path}"
|
||||
|
||||
with open(ci_path, "r", encoding="utf-8") as f:
|
||||
ci_data = yaml.safe_load(f)
|
||||
|
||||
jobs = ci_data.get("jobs", {})
|
||||
assert jobs, f"No jobs defined in {ci_path}"
|
||||
|
||||
test_jobs_found = 0
|
||||
for job_name, job_data in jobs.items():
|
||||
if not isinstance(job_data, dict):
|
||||
continue
|
||||
steps = job_data.get("steps", [])
|
||||
|
||||
# Determine if this job runs pytest or test suites
|
||||
is_test_job = False
|
||||
for step in steps:
|
||||
if not isinstance(step, dict):
|
||||
continue
|
||||
run_cmd = step.get("run", "")
|
||||
if "pytest" in run_cmd or "tests/" in run_cmd:
|
||||
is_test_job = True
|
||||
break
|
||||
|
||||
if is_test_job:
|
||||
test_jobs_found += 1
|
||||
checkout_steps = [
|
||||
s for s in steps
|
||||
if isinstance(s, dict) and "actions/checkout" in str(s.get("uses", ""))
|
||||
]
|
||||
assert checkout_steps, f"Test job '{job_name}' has no actions/checkout step"
|
||||
for s in checkout_steps:
|
||||
with_opts = s.get("with", {}) or {}
|
||||
submodules_val = with_opts.get("submodules")
|
||||
assert submodules_val, (
|
||||
f"Job '{job_name}' checkout step must enable submodules (e.g. submodules: recursive) "
|
||||
f"to prevent test_deploy_freshness failures in CI, got: {submodules_val}"
|
||||
)
|
||||
|
||||
assert test_jobs_found > 0, (
|
||||
"Anti-void assertion: expected at least 1 test execution job running pytest in deploy/gitea-ci.yml"
|
||||
)
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# D-32 — MESSAGING.md documents all supported MQTT environment variables
|
||||
# --------------------------------------------------------------------------
|
||||
def test_d32_messaging_doc_covers_all_mqtt_env_vars():
|
||||
messaging_path = os.path.join(REPO_ROOT, "MESSAGING.md")
|
||||
assert os.path.exists(messaging_path), f"MESSAGING.md missing at {messaging_path}"
|
||||
|
||||
with open(messaging_path, "r", encoding="utf-8") as f:
|
||||
content = f.read()
|
||||
|
||||
doc_vars = set(re.findall(r'\b(MQTT_[A-Z0-9_]+)\b', content))
|
||||
assert doc_vars, "No MQTT_* variables found in MESSAGING.md"
|
||||
|
||||
expected_vars = {
|
||||
"MQTT_BROKER",
|
||||
"MQTT_PORT",
|
||||
"MQTT_TLS",
|
||||
"MQTT_USERNAME",
|
||||
"MQTT_PASSWORD",
|
||||
"MQTT_CA_CERTS",
|
||||
"MQTT_CERTFILE",
|
||||
"MQTT_KEYFILE",
|
||||
"MQTT_CLIENT_ID_PREFIX",
|
||||
"MQTT_KEEPALIVE",
|
||||
}
|
||||
|
||||
missing_vars = expected_vars - doc_vars
|
||||
assert not missing_vars, (
|
||||
f"MESSAGING.md is missing documentation for supported MQTT variables: {missing_vars}"
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user