"""Unit tests for the WC1 realm-lifecycle predicate (runner/harness/sso.py). Pure-Python: no real keycloak. Tests `realms_to_reap`, the concurrency-safe predicate that decides which per-run realms ("-<6hex>") are orphans to reap given the set of live app-stack hexes. The admin-API ops (list/delete/reap) are exercised by real e2e against the warm keycloak (W0.4). """ from __future__ import annotations import os import sys sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "..", "runner")) from harness import sso # noqa: E402 def test_reap_skips_master(): assert sso.realms_to_reap(["master"], set()) == [] def test_reap_skips_non_pattern_realms(): # Realms not matching "-<6hex>" (e.g. an operator-created realm) are never reaped. assert sso.realms_to_reap(["master", "myrealm", "production"], set()) == [] def test_reap_orphan_when_hex_not_live(): realms = ["master", "lasuite-docs-0a6fb2", "cryptpad-deadbe"] # No live stacks -> both per-run realms are orphans. assert sso.realms_to_reap(realms, set()) == ["lasuite-docs-0a6fb2", "cryptpad-deadbe"] def test_reap_keeps_live_hex(): realms = ["master", "lasuite-docs-0a6fb2", "cryptpad-deadbe"] # cryptpad's stack is live -> its realm is kept; the orphaned one is reaped. assert sso.realms_to_reap(realms, {"deadbe"}) == ["lasuite-docs-0a6fb2"] def test_reap_keeps_all_when_all_live(): realms = ["lasuite-docs-0a6fb2", "cryptpad-deadbe"] assert sso.realms_to_reap(realms, {"0a6fb2", "deadbe"}) == [] def test_reap_only_matches_six_hex(): # 5 hex or 7 hex / non-hex suffixes must NOT be treated as per-run realms. realms = ["foo-0a6fb", "foo-0a6fb2x", "foo-zzzzzz", "foo-0a6fb2"] assert sso.realms_to_reap(realms, set()) == ["foo-0a6fb2"] def test_reap_handles_empty_and_none(): assert sso.realms_to_reap([], set()) == [] assert sso.realms_to_reap(None, None) == [] def test_delete_master_refused(): import pytest with pytest.raises(ValueError): sso.delete_keycloak_realm("warm-keycloak.ci.commoninternet.net", "master")