deb-bootc-image-builder/test/test_manifest.py

228 lines
8.1 KiB
Python

#!/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__])