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

245 lines
8.6 KiB
Python

#!/usr/bin/env python3
"""
Test ISO image building functionality for deb-bootc-image-builder.
This module tests the ISO image building pipeline, including:
- ISO manifest validation
- ISO creation process
- Debian-specific ISO features
"""
import pytest
import os
import tempfile
import shutil
import json
from unittest.mock import Mock, patch
import logging
# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
class TestISOBuilding:
"""Test cases for ISO image building functionality."""
def test_iso_manifest_validation(self, work_dir):
"""Test ISO manifest validation for Debian images."""
# Create a test ISO manifest
manifest = {
"pipeline": {
"build": {
"name": "org.osbuild.debian-filesystem",
"options": {
"rootfs_type": "ext4",
"ostree_integration": True
}
},
"stages": [
{
"name": "org.osbuild.apt",
"options": {
"packages": ["linux-image-amd64", "systemd"],
"release": "trixie",
"arch": "amd64"
}
},
{
"name": "org.osbuild.debian-grub",
"options": {
"uefi": True,
"secure_boot": False
}
},
{
"name": "org.osbuild.debian-kernel",
"options": {
"kernel_package": "linux-image-amd64",
"initramfs_tools": True
}
}
]
}
}
# Validate manifest structure
assert "pipeline" in manifest
assert "build" in manifest["pipeline"]
assert "stages" in manifest["pipeline"]
# Validate Debian-specific options
build_stage = manifest["pipeline"]["build"]
assert build_stage["name"] == "org.osbuild.debian-filesystem"
assert build_stage["options"]["ostree_integration"] is True
# Validate stages
stages = manifest["pipeline"]["stages"]
assert len(stages) >= 3
# 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 apt_stage["options"]["release"] == "trixie"
def test_debian_iso_package_installation(self, work_dir):
"""Test Debian package installation for ISO builds."""
# Mock package installation
with patch('subprocess.run') as mock_run:
mock_run.return_value.returncode = 0
# Test package installation
packages = ["linux-image-amd64", "systemd", "ostree", "grub-efi-amd64"]
result = self._install_iso_packages(packages, work_dir)
assert result is True
mock_run.assert_called()
def test_iso_filesystem_creation(self, work_dir):
"""Test ISO filesystem creation."""
# Test filesystem structure
fs_structure = self._create_iso_filesystem(work_dir)
expected_dirs = ["/etc", "/var", "/home", "/boot", "/usr", "/media"]
for expected_dir in expected_dirs:
full_path = os.path.join(work_dir, expected_dir.lstrip("/"))
assert os.path.exists(full_path), f"Directory {expected_dir} not created"
# Test ISO-specific directories
iso_dirs = ["/media/cdrom", "/media/usb"]
for iso_dir in iso_dirs:
full_path = os.path.join(work_dir, iso_dir.lstrip("/"))
assert os.path.exists(full_path), f"ISO directory {iso_dir} not created"
def test_iso_bootloader_configuration(self, work_dir):
"""Test ISO bootloader configuration."""
# Test GRUB configuration for ISO
grub_config = self._configure_iso_grub(work_dir)
assert "GRUB_DEFAULT" in grub_config
assert "GRUB_TIMEOUT" in grub_config
assert "GRUB_CMDLINE_LINUX" in grub_config
# Test ISO-specific boot options
assert "cdrom" in grub_config["GRUB_CMDLINE_LINUX"]
assert "iso-scan" in grub_config["GRUB_CMDLINE_LINUX"]
def test_iso_ostree_integration(self, work_dir):
"""Test OSTree integration for ISO builds."""
# Test OSTree configuration
ostree_config = self._setup_iso_ostree(work_dir)
assert ostree_config["mode"] == "bare-user-only"
assert ostree_config["repo"] == "/var/lib/ostree/repo"
# Test ISO-specific OSTree paths
iso_repo_path = os.path.join(work_dir, "media", "cdrom", "ostree")
assert os.path.exists(iso_repo_path), "ISO OSTree repository not created"
def test_iso_creation_process(self, work_dir):
"""Test the complete ISO creation process."""
# Test ISO build pipeline
iso_result = self._create_iso_image(work_dir)
assert iso_result["status"] == "success"
assert "iso_path" in iso_result
assert os.path.exists(iso_result["iso_path"])
# Test ISO properties
iso_props = self._get_iso_properties(iso_result["iso_path"])
assert iso_props["format"] == "iso9660"
assert iso_props["size"] > 0
def _install_iso_packages(self, packages, work_dir):
"""Mock ISO package installation."""
logger.info(f"Installing ISO packages: {packages}")
return True
def _create_iso_filesystem(self, work_dir):
"""Create ISO filesystem structure."""
dirs = [
"etc", "var", "home", "boot", "usr", "media",
"media/cdrom", "media/usb", "usr/bin", "usr/lib", "usr/sbin"
]
for dir_path in dirs:
full_path = os.path.join(work_dir, dir_path)
os.makedirs(full_path, exist_ok=True)
# Create /home -> /var/home symlink
var_home = os.path.join(work_dir, "var", "home")
os.makedirs(var_home, exist_ok=True)
home_link = os.path.join(work_dir, "home")
if os.path.exists(home_link):
os.remove(home_link)
os.symlink(var_home, home_link)
return {"status": "created", "directories": dirs}
def _configure_iso_grub(self, work_dir):
"""Configure GRUB for ISO boot."""
grub_config = {
"GRUB_DEFAULT": "0",
"GRUB_TIMEOUT": "5",
"GRUB_CMDLINE_LINUX": "console=ttyS0,115200n8 console=tty0 cdrom iso-scan"
}
# Write GRUB configuration
grub_dir = os.path.join(work_dir, "etc", "default")
os.makedirs(grub_dir, exist_ok=True)
grub_file = os.path.join(grub_dir, "grub")
with open(grub_file, 'w') as f:
for key, value in grub_config.items():
f.write(f'{key}="{value}"\n')
return grub_config
def _setup_iso_ostree(self, work_dir):
"""Set up OSTree for ISO builds."""
ostree_dir = os.path.join(work_dir, "var", "lib", "ostree", "repo")
os.makedirs(ostree_dir, exist_ok=True)
# Create ISO-specific OSTree repository
iso_ostree_dir = os.path.join(work_dir, "media", "cdrom", "ostree")
os.makedirs(iso_ostree_dir, exist_ok=True)
config = {
"mode": "bare-user-only",
"repo": "/var/lib/ostree/repo"
}
# Write OSTree configuration
config_file = os.path.join(work_dir, "etc", "ostree", "ostree.conf")
os.makedirs(os.path.dirname(config_file), exist_ok=True)
with open(config_file, 'w') as f:
f.write("[core]\n")
f.write(f"mode={config['mode']}\n")
f.write(f"repo={config['repo']}\n")
return config
def _create_iso_image(self, work_dir):
"""Mock ISO image creation."""
# Create a dummy ISO file
iso_path = os.path.join(work_dir, "debian-trixie.iso")
with open(iso_path, 'wb') as f:
f.write(b"ISO9660 dummy content")
return {
"status": "success",
"iso_path": iso_path,
"size": os.path.getsize(iso_path)
}
def _get_iso_properties(self, iso_path):
"""Get ISO image properties."""
return {
"format": "iso9660",
"size": os.path.getsize(iso_path),
"path": iso_path
}
if __name__ == "__main__":
pytest.main([__file__])