#!/usr/bin/env python3 """ Test manifest validation and processing for deb-bootc-image-builder. This module tests manifest handling, including: - Manifest structure validation - Stage configuration validation - Debian-specific manifest processing """ import pytest import os import tempfile import shutil import json import yaml from unittest.mock import Mock, patch import logging # Configure logging logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) class TestManifestValidation: """Test cases for manifest validation.""" def test_debian_manifest_structure(self, work_dir): """Test Debian manifest structure validation.""" manifest = self._create_debian_manifest() # Validate top-level structure assert "pipeline" in manifest assert "build" in manifest["pipeline"] assert "stages" in manifest["pipeline"] # Validate build stage build_stage = manifest["pipeline"]["build"] assert build_stage["name"] == "org.osbuild.debian-filesystem" assert "options" in build_stage # Validate stages stages = manifest["pipeline"]["stages"] assert len(stages) > 0 # Validate APT stage apt_stage = next((s for s in stages if s["name"] == "org.osbuild.apt"), None) assert apt_stage is not None assert "options" in apt_stage assert "packages" in apt_stage["options"] def test_debian_package_validation(self, work_dir): """Test Debian package validation in manifests.""" manifest = self._create_debian_manifest() # Extract packages from APT stage apt_stage = next((s for s in manifest["pipeline"]["stages"] if s["name"] == "org.osbuild.apt"), None) packages = apt_stage["options"]["packages"] # Validate essential Debian packages essential_packages = [ "linux-image-amd64", "systemd", "ostree" ] for pkg in essential_packages: assert pkg in packages, f"Essential package {pkg} missing" # Validate package format for pkg in packages: assert isinstance(pkg, str), f"Package {pkg} is not a string" assert len(pkg) > 0, f"Empty package name found" def test_debian_repository_configuration(self, work_dir): """Test Debian repository configuration in manifests.""" manifest = self._create_debian_manifest() # Validate repository configuration apt_stage = next((s for s in manifest["pipeline"]["stages"] if s["name"] == "org.osbuild.apt"), None) options = apt_stage["options"] assert "release" in options assert "arch" in options # Validate Debian release assert options["release"] == "trixie" assert options["arch"] == "amd64" def test_ostree_integration_configuration(self, work_dir): """Test OSTree integration configuration.""" manifest = self._create_debian_manifest() # Validate OSTree integration in filesystem stage fs_stage = manifest["pipeline"]["build"] options = fs_stage["options"] assert "ostree_integration" in options assert options["ostree_integration"] is True # Validate home symlink configuration assert "home_symlink" in options assert options["home_symlink"] is True def test_manifest_serialization(self, work_dir): """Test manifest serialization to YAML and JSON.""" manifest = self._create_debian_manifest() # Test YAML serialization yaml_content = yaml.dump(manifest, default_flow_style=False) assert "org.osbuild.debian-filesystem" in yaml_content assert "org.osbuild.apt" in yaml_content # Test JSON serialization json_content = json.dumps(manifest, indent=2) assert "org.osbuild.debian-filesystem" in json_content assert "org.osbuild.apt" in json_content # Test round-trip serialization yaml_parsed = yaml.safe_load(yaml_content) assert yaml_parsed == manifest json_parsed = json.loads(json_content) assert json_parsed == manifest def test_manifest_validation_errors(self, work_dir): """Test manifest validation error handling.""" # Test missing pipeline invalid_manifest = {"stages": []} with pytest.raises(KeyError): _ = invalid_manifest["pipeline"] # Test missing build stage invalid_manifest = {"pipeline": {"stages": []}} with pytest.raises(KeyError): _ = invalid_manifest["pipeline"]["build"] # Test missing stages invalid_manifest = {"pipeline": {"build": {"name": "test"}}} with pytest.raises(KeyError): _ = invalid_manifest["pipeline"]["stages"] def test_debian_specific_manifest_features(self, work_dir): """Test Debian-specific manifest features.""" manifest = self._create_debian_manifest() # Test GRUB stage configuration grub_stage = next((s for s in manifest["pipeline"]["stages"] if s["name"] == "org.osbuild.debian-grub"), None) if grub_stage: options = grub_stage["options"] assert "uefi" in options assert "secure_boot" in options assert "timeout" in options # Test kernel stage configuration kernel_stage = next((s for s in manifest["pipeline"]["stages"] if s["name"] == "org.osbuild.debian-kernel"), None) if kernel_stage: options = kernel_stage["options"] assert "kernel_package" in options assert "initramfs_tools" in options def _create_debian_manifest(self): """Create a sample Debian manifest for testing.""" return { "pipeline": { "build": { "name": "org.osbuild.debian-filesystem", "options": { "rootfs_type": "ext4", "ostree_integration": True, "home_symlink": True } }, "stages": [ { "name": "org.osbuild.apt", "options": { "packages": [ "linux-image-amd64", "linux-headers-amd64", "systemd", "systemd-sysv", "dbus", "ostree", "grub-efi-amd64", "initramfs-tools", "util-linux", "parted", "e2fsprogs", "dosfstools", "efibootmgr", "sudo", "network-manager" ], "release": "trixie", "arch": "amd64" } }, { "name": "org.osbuild.debian-grub", "options": { "uefi": True, "secure_boot": False, "timeout": 5, "default_entry": 0 } }, { "name": "org.osbuild.debian-kernel", "options": { "kernel_package": "linux-image-amd64", "initramfs_tools": True, "ostree_integration": True } } ] } } if __name__ == "__main__": pytest.main([__file__])