Publish curated Unraid-AppOps-Gateway source from 207d2a918641b199961d27de09b6c1fdf45a6e4b
This commit is contained in:
1 parent
28f691b77e
commit
2c5788da5d
3 files changed
+95
-4
No files matched your search
@@ -2841,6 +2841,97 @@ def test_candidate_preparation_helper_is_staged_archived_and_digest_bound(tmp_pa
|
||||
module._release_identity(tampered)
|
||||
|
||||
|
||||
def _retry_release_fixture(monkeypatch):
|
||||
source = {name: (f"qualified:{name}\n".encode(), 0o644) for name in module.RELEASE_FILES}
|
||||
monkeypatch.setattr(module, "_stage_source_files", lambda _root: dict(source))
|
||||
monkeypatch.setattr(module, "_read_release_leaf", lambda _revision: None)
|
||||
arguments = (Path("unused-stage"), ({}, {"": 0o755}), "a" * 40, "b" * 40, "2.1.45")
|
||||
first = module._prepare_merged_tree(*arguments)
|
||||
return arguments, first
|
||||
|
||||
|
||||
def test_retry_preparation_preserves_exact_existing_artifact_despite_different_clock(monkeypatch):
|
||||
arguments, first = _retry_release_fixture(monkeypatch)
|
||||
monkeypatch.setattr(module, "_read_release_leaf", lambda _revision: first)
|
||||
|
||||
class LaterClock:
|
||||
@staticmethod
|
||||
def now(_timezone):
|
||||
raise AssertionError("An existing immutable artifact must retain its creation time")
|
||||
|
||||
monkeypatch.setattr(module, "datetime", LaterClock)
|
||||
second = module._prepare_merged_tree(*arguments)
|
||||
assert second == first
|
||||
assert module._release_tar_bytes(arguments[2], second) == module._release_tar_bytes(arguments[2], first)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("field,value", [
|
||||
("sourceRevision", "c" * 40),
|
||||
("sourceTree", "c" * 40),
|
||||
("controllerVersion", "2.1.46"),
|
||||
])
|
||||
def test_retry_preparation_rejects_existing_foreign_identity(monkeypatch, field, value):
|
||||
arguments, first = _retry_release_fixture(monkeypatch)
|
||||
entries = dict(first[0])
|
||||
manifest = json.loads(entries["controller-release.json"][0])
|
||||
manifest[field] = value
|
||||
entries["controller-release.json"] = (json.dumps(manifest).encode(), 0o644)
|
||||
monkeypatch.setattr(module, "_read_release_leaf", lambda _revision: (entries, first[1]))
|
||||
with pytest.raises(module.VolumeTransitionError, match="release_collision"):
|
||||
module._prepare_merged_tree(*arguments)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("difference", ["content", "file_mode", "manifest_mode", "directory_mode", "extra_file"])
|
||||
def test_retry_preparation_rejects_any_other_existing_tree_difference(monkeypatch, difference):
|
||||
arguments, first = _retry_release_fixture(monkeypatch)
|
||||
entries, directories = dict(first[0]), dict(first[1])
|
||||
if difference == "content":
|
||||
entries["status_server.py"] = (b"different-but-self-consistent-source", 0o644)
|
||||
manifest = json.loads(entries["controller-release.json"][0])
|
||||
manifest["artifactSha256"] = module._artifact_digest(entries)
|
||||
entries["controller-release.json"] = (json.dumps(manifest).encode(), 0o644)
|
||||
elif difference == "file_mode":
|
||||
entries["status_server.py"] = (entries["status_server.py"][0], 0o755)
|
||||
elif difference == "manifest_mode":
|
||||
entries["controller-release.json"] = (entries["controller-release.json"][0], 0o600)
|
||||
elif difference == "directory_mode":
|
||||
directories[""] = 0o700
|
||||
elif difference == "extra_file":
|
||||
entries["unexpected.txt"] = (b"unexpected", 0o644)
|
||||
monkeypatch.setattr(module, "_read_release_leaf", lambda _revision: (entries, directories))
|
||||
with pytest.raises(module.VolumeTransitionError):
|
||||
module._prepare_merged_tree(*arguments)
|
||||
|
||||
|
||||
def test_retry_preparation_can_complete_a_matching_partial_copy(monkeypatch):
|
||||
arguments, first = _retry_release_fixture(monkeypatch)
|
||||
partial = dict(first[0])
|
||||
del partial["status_server.py"]
|
||||
monkeypatch.setattr(module, "_read_release_leaf", lambda _revision: (partial, first[1]))
|
||||
assert module._prepare_merged_tree(*arguments) == first
|
||||
|
||||
|
||||
def test_retry_preparation_reuses_complete_leaf_without_any_writer(monkeypatch):
|
||||
arguments, first = _retry_release_fixture(monkeypatch)
|
||||
monkeypatch.setattr(module, "_read_release_leaf", lambda _revision: first)
|
||||
prepared = module._prepare_merged_tree(*arguments)
|
||||
calls = _fake_release_writer(monkeypatch, {"tree": first})
|
||||
module._install_release_leaf(arguments[2], prepared, IMAGE_ID)
|
||||
assert not any(call[:2] == ["docker", "create"] for call in calls)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("payload", [b"not-json", b'{"credential":"fixture-do-not-leak"}'])
|
||||
def test_retry_preparation_rejects_invalid_manifest_without_exposing_contents(monkeypatch, payload):
|
||||
arguments, first = _retry_release_fixture(monkeypatch)
|
||||
entries = dict(first[0])
|
||||
entries["controller-release.json"] = (payload, 0o644)
|
||||
monkeypatch.setattr(module, "_read_release_leaf", lambda _revision: (entries, first[1]))
|
||||
with pytest.raises(module.VolumeTransitionError) as error:
|
||||
module._prepare_merged_tree(*arguments)
|
||||
assert str(error.value) == "controller_volume_release_identity_invalid"
|
||||
assert "fixture-do-not-leak" not in str(error.value)
|
||||
|
||||
|
||||
def test_installer_explicit_archive_and_install_contract_includes_candidate_helper():
|
||||
source = (ROOT / "scripts/upgrade_deployment_controller.sh").read_text(encoding="utf-8")
|
||||
archive_paths = source.split("source_paths=(", 1)[1].split("\n)", 1)[0]
|
||||
|
||||
Reference in new issue
Block a user