refactor(level): four essential rungs only — integration & recipe-local are optional
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
Per operator: the level ladder is now the FOUR essential rungs every recipe is held to — install, upgrade (essential), backup/restore, functional (top = L4). Integration (SSO/OIDC) and recipe-local are OPTIONAL capabilities: they no longer appear as level rungs or skip rows and never cap the level. SSO is still enforced for the run VERDICT (unchanged in run_recipe_ci.py); it just doesn't affect the level. derive_rungs simplified accordingly (drops declared/deps/sso/repo-local inputs). custom-html-tiny's EXPECTED_NA is back to just backup_restore. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -105,83 +105,31 @@ def _results(**kw):
|
||||
return base
|
||||
|
||||
|
||||
def test_derive_rungs_full_stateful_sso():
|
||||
rungs = R.derive_rungs(
|
||||
_results(),
|
||||
backup_capable=True,
|
||||
declared=["keycloak"],
|
||||
deps_ready=True,
|
||||
sso_unverified=False,
|
||||
has_custom=True,
|
||||
has_repo_local=False,
|
||||
repo_local_passed=False,
|
||||
)
|
||||
def test_derive_rungs_full_climb_four_essential():
|
||||
rungs = R.derive_rungs(_results(), backup_capable=True, has_custom=True)
|
||||
# only the four essential rungs — integration/recipe-local are optional, not produced here.
|
||||
assert rungs == {
|
||||
"install": "pass",
|
||||
"upgrade": "pass",
|
||||
"backup_restore": "pass",
|
||||
"functional": "pass",
|
||||
"integration": "pass",
|
||||
"recipe_local": "na",
|
||||
}
|
||||
|
||||
|
||||
def test_derive_rungs_no_sso_surface_is_integration_na():
|
||||
rungs = R.derive_rungs(
|
||||
_results(),
|
||||
backup_capable=True,
|
||||
declared=[],
|
||||
deps_ready=True,
|
||||
sso_unverified=False,
|
||||
has_custom=True,
|
||||
has_repo_local=False,
|
||||
repo_local_passed=False,
|
||||
)
|
||||
assert rungs["integration"] == "na"
|
||||
assert rungs["functional"] == "pass"
|
||||
|
||||
|
||||
def test_derive_rungs_stateless_backup_na():
|
||||
def test_derive_rungs_stateless_backup_and_functional_na():
|
||||
rungs = R.derive_rungs(
|
||||
_results(backup="skip", restore="skip", custom="skip"),
|
||||
backup_capable=False,
|
||||
declared=[],
|
||||
deps_ready=True,
|
||||
sso_unverified=False,
|
||||
has_custom=False,
|
||||
has_repo_local=False,
|
||||
repo_local_passed=False,
|
||||
)
|
||||
assert rungs["backup_restore"] == "na"
|
||||
assert rungs["functional"] == "na"
|
||||
assert "integration" not in rungs and "recipe_local" not in rungs
|
||||
|
||||
|
||||
def test_derive_rungs_sso_unverified_is_integration_fail():
|
||||
rungs = R.derive_rungs(
|
||||
_results(),
|
||||
backup_capable=True,
|
||||
declared=["keycloak"],
|
||||
deps_ready=False,
|
||||
sso_unverified=True,
|
||||
has_custom=True,
|
||||
has_repo_local=False,
|
||||
repo_local_passed=False,
|
||||
)
|
||||
assert rungs["integration"] == "fail"
|
||||
|
||||
|
||||
def test_derive_rungs_repo_local_pass():
|
||||
rungs = R.derive_rungs(
|
||||
_results(),
|
||||
backup_capable=True,
|
||||
declared=[],
|
||||
deps_ready=True,
|
||||
sso_unverified=False,
|
||||
has_custom=True,
|
||||
has_repo_local=True,
|
||||
repo_local_passed=True,
|
||||
)
|
||||
assert rungs["recipe_local"] == "pass"
|
||||
def test_derive_rungs_functional_fail():
|
||||
rungs = R.derive_rungs(_results(custom="fail"), backup_capable=True, has_custom=True)
|
||||
assert rungs["functional"] == "fail"
|
||||
|
||||
|
||||
# ---- build_results: end-to-end incl level + flags ----
|
||||
@ -212,16 +160,13 @@ def test_build_results_level_and_flags(tmp_path):
|
||||
records=recs,
|
||||
results=_results(),
|
||||
backup_capable=True,
|
||||
declared=[],
|
||||
deps_ready=True,
|
||||
sso_unverified=False,
|
||||
clean_teardown=True,
|
||||
no_secret_leak=True,
|
||||
finished_ts=1234.0,
|
||||
)
|
||||
# stateful, functional pass, no SSO surface, no repo-local → caps at L4
|
||||
# all four essential rungs pass → full climb to L4 (the top), no cap
|
||||
assert data["level"] == 4
|
||||
assert "L5" in data["level_cap_reason"]
|
||||
assert data["level_cap_reason"] == ""
|
||||
assert data["recipe"] == "hedgedoc"
|
||||
assert data["ref"] == "deadbeefcafe"
|
||||
assert data["flags"] == {"clean_teardown": True, "no_secret_leak": True}
|
||||
@ -246,9 +191,6 @@ def test_build_results_capped_at_L1_on_upgrade_fail(tmp_path):
|
||||
records=recs,
|
||||
results=_results(upgrade="fail"),
|
||||
backup_capable=True,
|
||||
declared=[],
|
||||
deps_ready=True,
|
||||
sso_unverified=False,
|
||||
clean_teardown=True,
|
||||
no_secret_leak=True,
|
||||
finished_ts=0.0,
|
||||
@ -266,8 +208,6 @@ def _rungs(**kw):
|
||||
"upgrade": "pass",
|
||||
"backup_restore": "pass",
|
||||
"functional": "pass",
|
||||
"integration": "na",
|
||||
"recipe_local": "na",
|
||||
}
|
||||
base.update(kw)
|
||||
return base
|
||||
@ -276,16 +216,16 @@ def _rungs(**kw):
|
||||
def test_skips_intentional_vs_unintentional():
|
||||
rungs = _rungs(backup_restore="na", functional="na")
|
||||
sk = R.skips(rungs, {"backup_restore": "stateless static server"})
|
||||
# backup_restore is declared (intentional, with reason); everything else skipped is unintentional.
|
||||
# backup_restore is declared (intentional, with reason); functional skipped but not declared.
|
||||
assert sk["intentional"] == {"backup_restore": "stateless static server"}
|
||||
assert sk["unintentional"] == ["functional", "integration", "recipe_local"]
|
||||
assert sk["unintentional"] == ["functional"]
|
||||
|
||||
|
||||
def test_skips_none_declared_all_unintentional():
|
||||
rungs = _rungs(backup_restore="na")
|
||||
sk = R.skips(rungs, None)
|
||||
assert sk["intentional"] == {}
|
||||
assert sk["unintentional"] == ["backup_restore", "integration", "recipe_local"]
|
||||
assert sk["unintentional"] == ["backup_restore"]
|
||||
|
||||
|
||||
def test_skips_declaration_only_counts_when_actually_skipped():
|
||||
@ -323,17 +263,10 @@ def test_build_results_threads_expected_na(tmp_path):
|
||||
records=recs,
|
||||
results=_results(backup="skip", restore="skip"), # custom=pass (default) → functional pass
|
||||
backup_capable=False, # no backupbot label → backup_restore skipped (N/A)
|
||||
declared=[],
|
||||
deps_ready=True,
|
||||
sso_unverified=False,
|
||||
clean_teardown=True,
|
||||
no_secret_leak=True,
|
||||
finished_ts=0.0,
|
||||
expected_na={
|
||||
"backup_restore": "stateless static file server",
|
||||
"integration": "no SSO surface",
|
||||
"recipe_local": "no upstream tests/",
|
||||
},
|
||||
expected_na={"backup_restore": "stateless static file server"},
|
||||
)
|
||||
# backup_restore skip still caps at L2 (never inflates) — even though functional passes above it,
|
||||
# the skip caps the climb — but it's the declared (intentional) rung that capped.
|
||||
@ -342,7 +275,7 @@ def test_build_results_threads_expected_na(tmp_path):
|
||||
assert data["level_cap_rung"] == "backup_restore"
|
||||
assert data["rungs"]["functional"] == "pass"
|
||||
assert data["skips"]["intentional"]["backup_restore"] == "stateless static file server"
|
||||
assert data["skips"]["unintentional"] == [] # every skip accounted for → fully clean
|
||||
assert data["skips"]["unintentional"] == [] # backup_restore declared; functional passed → clean
|
||||
|
||||
|
||||
def test_write_results_roundtrip(tmp_path):
|
||||
|
||||
Reference in New Issue
Block a user