sso.py: list_realms, delete_keycloak_realm (idempotent, refuses master), realms_to_reap (pure, concurrency-safe predicate), reap_orphaned_realms. The per-run realm is the isolation unit on a shared live-warm keycloak; orphans (crashed runs) reaped by hex not mapping to a live app stack. +8 unit tests (tests/unit/test_warm_realm.py); 43 unit pass on cc-ci. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
59 lines
2.0 KiB
Python
59 lines
2.0 KiB
Python
"""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 ("<parent>-<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")
|