86 lines
3.5 KiB
Python
86 lines
3.5 KiB
Python
import hashlib
|
|
import io
|
|
import json
|
|
import zipfile
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from app.registry_service import RegistryService, RegistryValidationError
|
|
|
|
|
|
def minimal_xlsx(marker: str = "v1") -> bytes:
|
|
buffer = io.BytesIO()
|
|
with zipfile.ZipFile(buffer, "w") as archive:
|
|
archive.writestr("[Content_Types].xml", "<Types/>")
|
|
archive.writestr("xl/workbook.xml", f"<workbook>{marker}</workbook>")
|
|
return buffer.getvalue()
|
|
|
|
|
|
def make_legacy_config(root: Path) -> None:
|
|
names = {
|
|
"Windows_Checklist.xlsx": "windows_config.json",
|
|
"CentOS_Checklist_NEW.xlsx": "centos_config_new.json",
|
|
"RHEL_Checklist_NEW.xlsx": "rhel_config_new.json",
|
|
"Ubuntu_Checklist_NEW.xlsx": "ubuntu_config_new.json",
|
|
"Oracle_Linux_Checklist.xlsx": "oracle_linux_config.json",
|
|
}
|
|
for checklist, rules in names.items():
|
|
(root / checklist).write_bytes(minimal_xlsx(checklist))
|
|
(root / rules).write_text('{"rules": []}', encoding="utf-8")
|
|
|
|
|
|
def test_seed_migrates_five_operating_system_profiles_and_aliases(tmp_path):
|
|
make_legacy_config(tmp_path)
|
|
service = RegistryService(tmp_path / "registry", legacy_config_root=tmp_path)
|
|
|
|
registry = service.seed_legacy_profiles()
|
|
|
|
assert len(registry["categories"]) == 1
|
|
assert len(registry["categories"][0]["components"]) == 5
|
|
assert service.resolve(os_type="redhat")["profile"]["id"] == "rhel-baseline"
|
|
resolved = service.resolve(os_type="windows")
|
|
assert resolved["version"]["active"] is True
|
|
assert Path(resolved["checklist_path"]).is_file()
|
|
|
|
|
|
def test_create_version_validates_payloads_and_records_sha256(tmp_path):
|
|
make_legacy_config(tmp_path)
|
|
service = RegistryService(tmp_path / "registry", legacy_config_root=tmp_path)
|
|
service.seed_legacy_profiles()
|
|
checklist = minimal_xlsx("v2")
|
|
rules = b'{"rules": [{"id": "A"}]}'
|
|
|
|
version = service.create_version("ubuntu-baseline", "2.0", checklist, rules)
|
|
|
|
assert version["checksums"]["checklist"] == hashlib.sha256(checklist).hexdigest()
|
|
assert json.loads(Path(service.root / version["artifacts"]["rules"]).read_text())["rules"][0]["id"] == "A"
|
|
with pytest.raises(RegistryValidationError):
|
|
service.create_version("ubuntu-baseline", "bad", b"not xlsx", rules)
|
|
|
|
|
|
def test_activation_and_rollback_are_versioned_and_persistent(tmp_path):
|
|
make_legacy_config(tmp_path)
|
|
service = RegistryService(tmp_path / "registry", legacy_config_root=tmp_path)
|
|
service.seed_legacy_profiles()
|
|
service.create_version("centos-baseline", "2.0", minimal_xlsx("v2"), b'{"rules": []}')
|
|
|
|
service.activate_version("centos-baseline", "2.0")
|
|
assert service.resolve(profile_id="centos-baseline")["version"]["version"] == "2.0"
|
|
service.rollback("centos-baseline")
|
|
assert service.resolve(profile_id="centos-baseline")["version"]["version"] == "legacy-1"
|
|
|
|
|
|
def test_rejects_bad_ids_duplicates_and_checksum_tampering(tmp_path):
|
|
make_legacy_config(tmp_path)
|
|
service = RegistryService(tmp_path / "registry", legacy_config_root=tmp_path)
|
|
service.seed_legacy_profiles()
|
|
with pytest.raises(RegistryValidationError):
|
|
service.create_category("../escape", "Escape")
|
|
with pytest.raises(RegistryValidationError):
|
|
service.create_component("operating-systems", "windows", "Duplicate")
|
|
resolved = service.resolve(os_type="ubuntu")
|
|
Path(resolved["checklist_path"]).write_bytes(b"tampered")
|
|
with pytest.raises(RegistryValidationError, match="checksum"):
|
|
service.resolve(os_type="ubuntu")
|