mirror of
https://github.com/jcreek/CosmicClash.git
synced 2026-09-10 16:04:04 +00:00
2c648514ba
test_contracts.py required operation ID `recordPlayerConnected`, but
openapi.json names that endpoint `claimPlayerConnection` — the accurate
name, since POST /servers/{id}/connect claims a connection lease and
returns a generation. Align the test on the document and assert the set
difference, so a future mismatch names the missing operation instead of
reporting "False is not true".
test_observability_manifests.py copied only two of the four files the
checker reads, so it died on a missing kustomization.yaml before ever
reaching the mutated namespace. Copy the full fixture, split the
namespace and scrape-path mutations into separate cases so either
defect produces its own diagnostic, and add an unmutated-copy case so a
broken fixture can't make the mutation cases pass vacuously.
Neither suite was invoked by any Make target or workflow, which is why
both could sit red. Add them, plus test_threat_model.py, to
verify_multiplayer_local.sh.
70 lines
2.8 KiB
Python
70 lines
2.8 KiB
Python
from pathlib import Path
|
|
import subprocess
|
|
import sys
|
|
import tempfile
|
|
import unittest
|
|
|
|
|
|
ROOT = Path(__file__).parents[2]
|
|
CHECKER = ROOT / "scripts" / "verify_observability_manifests.py"
|
|
|
|
|
|
class ObservabilityManifestTest(unittest.TestCase):
|
|
def run_checker(self, directory=None):
|
|
command = [sys.executable, str(CHECKER)]
|
|
if directory is not None:
|
|
command += ["--directory", str(directory)]
|
|
return subprocess.run(command, cwd=ROOT, text=True, capture_output=True)
|
|
|
|
def test_checked_in_resources_match_service_and_metric_contract(self):
|
|
result = self.run_checker()
|
|
self.assertEqual(result.returncode, 0, result.stderr)
|
|
|
|
# Every file the checker opens, in the order it opens them. Copying only a
|
|
# subset makes it die on a missing file before it reaches the assertion
|
|
# under test, so the mutation is never actually exercised.
|
|
FIXTURE = (
|
|
"kustomization.yaml",
|
|
"prometheus-service-monitor.yaml",
|
|
"prometheus-allocator-service-monitor.yaml",
|
|
"prometheus-rules.yaml",
|
|
)
|
|
|
|
def build_fixture(self, target, mutate=None):
|
|
for name in self.FIXTURE:
|
|
text = (ROOT / "deploy/observability" / name).read_text()
|
|
if mutate is not None and name == "prometheus-service-monitor.yaml":
|
|
text = mutate(text)
|
|
(target / name).write_text(text)
|
|
|
|
def test_unmutated_fixture_copy_passes(self):
|
|
# Guards the two mutation tests below: if this fails, their non-zero
|
|
# exit proves nothing, because the fixture itself is broken.
|
|
with tempfile.TemporaryDirectory() as directory:
|
|
target = Path(directory)
|
|
self.build_fixture(target)
|
|
result = self.run_checker(target)
|
|
self.assertEqual(result.returncode, 0, result.stderr)
|
|
|
|
def test_checker_rejects_wrong_namespace(self):
|
|
with tempfile.TemporaryDirectory() as directory:
|
|
target = Path(directory)
|
|
# Widen the namespaceSelector only; metadata.namespace stays put so
|
|
# this isolates the scrape-scope check from the placement check.
|
|
self.build_fixture(target, lambda text: text.replace(" - cosmic-clash", " - default"))
|
|
result = self.run_checker(target)
|
|
self.assertNotEqual(result.returncode, 0)
|
|
self.assertIn("namespace", result.stderr)
|
|
|
|
def test_checker_rejects_broad_scrape_path(self):
|
|
with tempfile.TemporaryDirectory() as directory:
|
|
target = Path(directory)
|
|
self.build_fixture(target, lambda text: text.replace(" path: /metrics", " path: /"))
|
|
result = self.run_checker(target)
|
|
self.assertNotEqual(result.returncode, 0)
|
|
self.assertIn("path", result.stderr)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|