Files
ss-tools/scripts/tests/test_bundle_metadata_binding.py

117 lines
5.1 KiB
Python

# #region Test.Tooling.DockerBundle.Metadata [C:3] [TYPE Module] [SEMANTICS bundle,metadata,release]
# @TEST_INVARIANT The actual producer binds both generated deployment files before publishing manifestv2; any mismatch refuses before Docker.
import hashlib
import json
from pathlib import Path
import shlex
import subprocess
from unittest.mock import patch
import pytest
from test_import_docker_bundle import archive_bytes, importer
ROOT = Path(__file__).resolve().parents[2]
# #region Test.Tooling.DockerBundle.Metadata.Generator [C:3] [TYPE Function]
def generate(root, tag):
archive_dir = root / "inert-exports"
archive_dir.mkdir(exist_ok=True)
target = root / "bundle"
identity = None
for role in importer.ROLES:
archive, identity = archive_bytes(f"superset-tools-{role}:{tag}", modern=True)
(archive_dir / f"superset-tools-{role}.{tag}.tar.xz").write_bytes(archive)
text = (ROOT / "build.sh").read_text()
actual = text[text.index("generate_deploy_compose() {"):text.index("bundle_light() {")]
prefix = f"""
set -euo pipefail
umask 077
DIST_ROOT={shlex.quote(str(target))}
SCRIPT_DIR={shlex.quote(str(ROOT))}
FIXTURE_EXPORTS={shlex.quote(str(archive_dir))}
FIXTURE_ID={shlex.quote(identity)}
build_backend(){{ return 0; }}
build_frontend(){{ return 0; }}
ensure_image_present(){{ return 0; }}
run_bundle_smoke(){{ return 0; }}
docker(){{ [ "$1" = tag ] || return 99; }}
get_image_id(){{ printf '%s' "$FIXTURE_ID"; }}
get_repo_digest(){{ printf 'unavailable'; }}
export_image(){{ cp "$FIXTURE_EXPORTS/${{1%%:*}}.${{1#*:}}.tar.xz" "$2"; }}
"""
result = subprocess.run(["/usr/bin/bash", "-c", prefix + actual + "\nbundle_release " + shlex.quote(tag)],
stdin=subprocess.DEVNULL, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=False)
assert result.returncode == 0, result.stderr.decode()
return target
# #endregion Test.Tooling.DockerBundle.Metadata.Generator
# #region Test.Tooling.DockerBundle.Metadata.BeforeDocker [C:3] [TYPE Function]
def without_docker(directory, name, tag):
actual = subprocess.Popen
def boundary(argv, **kwargs):
assert argv[0] != "docker", "metadata refusal must precede even read-only Docker inspection"
return actual(argv, **kwargs)
with patch.object(importer.subprocess, "Popen", side_effect=boundary):
return importer.execute(directory, name, tag, verify_only=False)
# #endregion Test.Tooling.DockerBundle.Metadata.BeforeDocker
# #region Test.Tooling.DockerBundle.Metadata.Cases [C:3] [TYPE Function]
def test_actual_bundle_generator_publishes_v2_after_both_metadata_files(tmp_path):
root = generate(tmp_path, "fresh")
value = json.loads((root / "manifest.fresh.json").read_text())
assert value["manifest_version"] == 2
assert value["compose_sha256"] == hashlib.sha256((root / value["compose_file"]).read_bytes()).hexdigest()
assert value["env_template_sha256"] == hashlib.sha256((root / value["env_template"]).read_bytes()).hexdigest()
rc, result = importer.execute(root, "manifest.fresh.json", "fresh", True)
assert rc == 0, result
assert result["status"] == "verified"
def test_second_release_shared_compose_refuses_old_manifest_before_docker(tmp_path):
root = generate(tmp_path, "old")
before = (root / "manifest.old.json").read_bytes()
generate(tmp_path, "new")
assert (root / "manifest.old.json").read_bytes() == before
assert "superset-tools-backend:new" in (root / "docker-compose.enterprise-clean.yml").read_text()
rc, result = without_docker(root, "manifest.old.json", "old")
assert rc == 2
assert result["code"] == "deployment_metadata_checksum_conflict"
assert result["attempted_roles"] == result["loaded_roles"] == []
def test_env_template_tamper_refuses_before_docker(tmp_path):
root = generate(tmp_path, "fresh")
with (root / ".env.example").open("a") as output:
output.write("\n# Modified template\n")
rc, result = without_docker(root, "manifest.fresh.json", "fresh")
assert rc == 2
assert result["code"] == "deployment_metadata_checksum_conflict"
assert not result["partial_load_possible"]
def test_unbound_v1_has_no_fallback(tmp_path):
root = generate(tmp_path, "fresh")
path = root / "manifest.fresh.json"
value = json.loads(path.read_text())
value["manifest_version"] = 1
value.pop("compose_sha256", None)
value.pop("env_template_sha256", None)
path.write_text(json.dumps(value))
rc, result = without_docker(root, path.name, "fresh")
assert rc == 2
assert result["code"] == "unsupported_bundle_manifest"
@pytest.mark.parametrize("name", ["docker-compose.enterprise-clean.yml", ".env.example"])
def test_metadata_symlink_refuses_before_docker(tmp_path, name):
root = generate(tmp_path, "fresh")
original = root / (name + ".original")
(root / name).rename(original)
(root / name).symlink_to(original)
rc, result = without_docker(root, "manifest.fresh.json", "fresh")
assert rc == 2
assert result["loaded_roles"] == []
# #endregion Test.Tooling.DockerBundle.Metadata.Cases
# #endregion Test.Tooling.DockerBundle.Metadata