Publish curated Unraid-AppOps-Gateway source from 84f2a9958b2bdf1c1c13553925026d75f32703c3
This commit is contained in:
1 parent
8dd4b40252
commit
5d598db0df
14 files changed
+2765
-46
No files matched your search
@@ -0,0 +1,167 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from types import SimpleNamespace
|
||||
|
||||
import pytest
|
||||
from test_deploy_broker import deploy_module as _deploy_fixture
|
||||
from test_hub_component_transport import controller as _controller_fixture
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def deploy_module():
|
||||
return _deploy_fixture.__wrapped__()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def controller(monkeypatch):
|
||||
return _controller_fixture.__wrapped__(monkeypatch)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("mode", ["deploy", "rollback"])
|
||||
def test_original_git_objects_are_bound_before_identity_reads(deploy_module, monkeypatch, mode):
|
||||
monkeypatch.delenv("APPOPS_REGISTERED_LEGACY_REQUEST_ID", raising=False)
|
||||
monkeypatch.delenv("GIT_NO_REPLACE_OBJECTS", raising=False)
|
||||
assert deploy_module.bind_registered_legacy_request({}, mode) == ""
|
||||
assert deploy_module.os.environ["GIT_NO_REPLACE_OBJECTS"] == "1"
|
||||
|
||||
|
||||
def test_known_registered_restore_keeps_verified_revision_and_fresh_runtime_ids(deploy_module):
|
||||
prior_revision = "a" * 40
|
||||
restored_artifacts = {
|
||||
"containers": {
|
||||
"quiz-monitor-quiz-server-1": {
|
||||
"container_id": "b" * 64,
|
||||
"image_id": "sha256:" + "c" * 64,
|
||||
}
|
||||
},
|
||||
"registered_legacy": {"requestId": "restored-request", "revision": prior_revision},
|
||||
}
|
||||
restored_receipt = {"revision": prior_revision, "containers": restored_artifacts["containers"]}
|
||||
project = {
|
||||
"_registered_legacy_restored": True,
|
||||
"_registered_legacy_restored_revision": prior_revision,
|
||||
"_registered_legacy_restored_artifacts": restored_artifacts,
|
||||
"_registered_legacy_restored_receipt": restored_receipt,
|
||||
}
|
||||
result = deploy_module.resolve_failed_live_state(
|
||||
{"live_revision": prior_revision, "live_status": "healthy"},
|
||||
{"revision": prior_revision, "legacy_provenance": False, "registered_legacy": {}},
|
||||
project,
|
||||
production_started=True,
|
||||
failure_stage="verification",
|
||||
restore_error=None,
|
||||
)
|
||||
|
||||
assert result["live_revision"] == prior_revision
|
||||
assert result["live_status"] == "healthy"
|
||||
assert result["live_legacy_provenance"] is False
|
||||
assert result["live_artifacts"] == restored_artifacts
|
||||
assert result["live_receipt"] == restored_receipt
|
||||
|
||||
|
||||
def test_failed_known_registered_restore_keeps_provenance_unknown(deploy_module):
|
||||
prior_revision = "a" * 40
|
||||
result = deploy_module.resolve_failed_live_state(
|
||||
{"live_revision": prior_revision, "live_status": "healthy"},
|
||||
{"revision": prior_revision, "legacy_provenance": False, "registered_legacy": {}},
|
||||
{},
|
||||
production_started=True,
|
||||
failure_stage="verification",
|
||||
restore_error=RuntimeError("restore failed"),
|
||||
)
|
||||
|
||||
assert result["live_status"] == "unknown"
|
||||
assert result["live_artifacts"] == {}
|
||||
assert result["live_receipt"] == {}
|
||||
|
||||
|
||||
def test_known_restore_source_callback_precedes_verification_and_state_binding(
|
||||
deploy_module, monkeypatch
|
||||
):
|
||||
previous_revision = "a" * 40
|
||||
failed_revision = "d" * 40
|
||||
image_ids = {"quiz-monitor-quiz-server-1": "sha256:" + "c" * 64}
|
||||
restored_receipt = {"revision": previous_revision, "build": {"revision": previous_revision}}
|
||||
artifacts = {"containers": {}, "registered_legacy": {"revision": previous_revision}}
|
||||
events = []
|
||||
project = {}
|
||||
|
||||
def core_restore(_repository, _project, _snapshot, _failed, **kwargs):
|
||||
events.append("signed-preimage-verified")
|
||||
restore_source = kwargs.get("restore_source")
|
||||
assert callable(restore_source), "known restore requires a source callback after signed validation"
|
||||
restore_source(previous_revision)
|
||||
events.append("restored-runtime-signed")
|
||||
return {"revision": previous_revision, "artifacts": artifacts,
|
||||
"imageIDs": image_ids, "liveReceipt": restored_receipt}
|
||||
|
||||
def source_restore(_project, _repository, revision):
|
||||
assert revision == previous_revision
|
||||
events.append("prior-source-restored")
|
||||
|
||||
def verify(_project, metadata, *, expected_image_ids):
|
||||
assert metadata["revision"] == previous_revision
|
||||
assert expected_image_ids == image_ids
|
||||
events.append("health-and-provenance-verified")
|
||||
return restored_receipt
|
||||
|
||||
monkeypatch.setattr(deploy_module, "read_state", lambda _project: {})
|
||||
monkeypatch.setattr(deploy_module, "_registered_legacy_receipt_key", lambda: b"k" * 32)
|
||||
monkeypatch.setattr(deploy_module, "_load_registered_legacy_adoption", lambda: SimpleNamespace(
|
||||
restore_deployment_snapshot=core_restore
|
||||
))
|
||||
monkeypatch.setattr(deploy_module, "restore_live_source", source_restore)
|
||||
monkeypatch.setattr(deploy_module, "validate_recorded_receipt", lambda *_args: restored_receipt["build"])
|
||||
monkeypatch.setattr(deploy_module, "verify_deployment", verify)
|
||||
|
||||
deploy_module.restore_compose_snapshot(
|
||||
project,
|
||||
{"revision": previous_revision, "legacy_provenance": False, "registered_legacy": {}},
|
||||
"jens/quiz-monitor", failed_revision,
|
||||
)
|
||||
|
||||
assert events == ["signed-preimage-verified", "prior-source-restored",
|
||||
"restored-runtime-signed", "health-and-provenance-verified"]
|
||||
assert project["_registered_legacy_restored"] is True
|
||||
assert project["_registered_legacy_restored_revision"] == previous_revision
|
||||
assert project["_registered_legacy_restored_receipt"] == restored_receipt
|
||||
|
||||
|
||||
@pytest.mark.parametrize("receipt_matches", [True, False])
|
||||
def test_typed_rollback_worker_supplies_fixed_source_and_provenance_verifiers(
|
||||
controller, monkeypatch, receipt_matches
|
||||
):
|
||||
import sys
|
||||
|
||||
module, projects = controller
|
||||
repository = "jens/quiz-monitor"
|
||||
previous_revision = "a" * 40
|
||||
receipt = {"revision": previous_revision, "build": {"revision": previous_revision}}
|
||||
project = {"slug": "quiz-monitor", "source_dir": "/fixed/source"}
|
||||
projects[repository] = project
|
||||
calls = []
|
||||
|
||||
def rollback(_payload, **kwargs):
|
||||
kwargs["restore_source"](previous_revision)
|
||||
kwargs["verify_restored"]({"revision": previous_revision, "liveReceipt": receipt,
|
||||
"imageIDs": {"quiz": "immutable-image"}})
|
||||
calls.append("state-cas")
|
||||
|
||||
monkeypatch.setitem(sys.modules, "registered_legacy_adoption", SimpleNamespace(
|
||||
rollback=rollback, read_registered_state=lambda *_a: ({}, None),
|
||||
RegisteredLegacyAdoptionError=ValueError,
|
||||
record_worker_failure=lambda *_a, **_k: calls.append("failed"),
|
||||
))
|
||||
monkeypatch.setitem(sys.modules, "deploy", SimpleNamespace(
|
||||
restore_live_source=lambda selected, repo, revision: calls.append(
|
||||
("source", selected, repo, revision)),
|
||||
validate_recorded_receipt=lambda selected, raw, repo, revision: receipt["build"],
|
||||
verify_deployment=lambda selected, build, **kwargs: calls.append("verified") or (
|
||||
receipt if receipt_matches else {**receipt, "revision": "f" * 40}
|
||||
),
|
||||
))
|
||||
module._run_registered_legacy_rollback({
|
||||
"repository": repository, "requestId": "11111111-1111-4111-8111-111111111111",
|
||||
}, b"k" * 32)
|
||||
assert calls == [("source", project, repository, previous_revision), "verified",
|
||||
"state-cas" if receipt_matches else "failed"]
|
||||
Reference in new issue
Block a user