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