Add missing files and complete Debian fork setup - Add missing test files and directories - Add missing configuration files - Complete Debian-specific adaptations - Replace Red Hat/Fedora tooling with Debian equivalents - Add comprehensive test suite for Debian bootc-image-builder
This commit is contained in:
parent
3326d796f0
commit
59ffbbc4d0
41 changed files with 10856 additions and 8 deletions
251
test/test_build_cross.py
Normal file
251
test/test_build_cross.py
Normal file
|
|
@ -0,0 +1,251 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Test cross-architecture building for deb-bootc-image-builder.
|
||||
|
||||
This module tests cross-architecture image building, including:
|
||||
- Cross-arch manifest validation
|
||||
- Multi-architecture package handling
|
||||
- Cross-arch image generation
|
||||
"""
|
||||
|
||||
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 TestCrossArchitectureBuilding:
|
||||
"""Test cases for cross-architecture building functionality."""
|
||||
|
||||
def test_cross_arch_manifest_validation(self, work_dir):
|
||||
"""Test cross-architecture manifest validation."""
|
||||
# Create a test cross-arch 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"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"target_architectures": ["amd64", "arm64"]
|
||||
}
|
||||
|
||||
# Validate manifest structure
|
||||
assert "pipeline" in manifest
|
||||
assert "target_architectures" in manifest
|
||||
|
||||
# Validate target architectures
|
||||
target_archs = manifest["target_architectures"]
|
||||
assert "amd64" in target_archs
|
||||
assert "arm64" in target_archs
|
||||
assert len(target_archs) == 2
|
||||
|
||||
def test_multi_arch_package_handling(self, work_dir):
|
||||
"""Test multi-architecture package handling."""
|
||||
# Test package lists for different architectures
|
||||
amd64_packages = ["linux-image-amd64", "grub-efi-amd64"]
|
||||
arm64_packages = ["linux-image-arm64", "grub-efi-arm64"]
|
||||
|
||||
# Validate package architecture specificity
|
||||
for pkg in amd64_packages:
|
||||
assert "amd64" in pkg, f"Package {pkg} should be amd64 specific"
|
||||
|
||||
for pkg in arm64_packages:
|
||||
assert "arm64" in pkg, f"Package {pkg} should be arm64 specific"
|
||||
|
||||
# Test package installation for different architectures
|
||||
amd64_result = self._install_arch_packages(amd64_packages, "amd64", work_dir)
|
||||
arm64_result = self._install_arch_packages(arm64_packages, "arm64", work_dir)
|
||||
|
||||
assert amd64_result is True
|
||||
assert arm64_result is True
|
||||
|
||||
def test_cross_arch_filesystem_creation(self, work_dir):
|
||||
"""Test cross-architecture filesystem creation."""
|
||||
# Test filesystem structure for different architectures
|
||||
for arch in ["amd64", "arm64"]:
|
||||
fs_structure = self._create_arch_filesystem(work_dir, arch)
|
||||
|
||||
expected_dirs = ["/etc", "/var", "/home", "/boot", "/usr"]
|
||||
for expected_dir in expected_dirs:
|
||||
full_path = os.path.join(work_dir, arch, expected_dir.lstrip("/"))
|
||||
assert os.path.exists(full_path), f"Directory {expected_dir} not created for {arch}"
|
||||
|
||||
# Test architecture-specific paths
|
||||
arch_specific_path = os.path.join(work_dir, arch, "usr", "lib", arch)
|
||||
assert os.path.exists(arch_specific_path), f"Architecture-specific path not created for {arch}"
|
||||
|
||||
def test_cross_arch_bootloader_configuration(self, work_dir):
|
||||
"""Test cross-architecture bootloader configuration."""
|
||||
# Test GRUB configuration for different architectures
|
||||
for arch in ["amd64", "arm64"]:
|
||||
grub_config = self._configure_arch_grub(work_dir, arch)
|
||||
|
||||
assert "GRUB_DEFAULT" in grub_config
|
||||
assert "GRUB_TIMEOUT" in grub_config
|
||||
assert "GRUB_CMDLINE_LINUX" in grub_config
|
||||
|
||||
# Test architecture-specific boot options
|
||||
if arch == "amd64":
|
||||
assert "efi" in grub_config["GRUB_CMDLINE_LINUX"]
|
||||
elif arch == "arm64":
|
||||
assert "arm64" in grub_config["GRUB_CMDLINE_LINUX"]
|
||||
|
||||
def test_cross_arch_image_generation(self, work_dir):
|
||||
"""Test cross-architecture image generation."""
|
||||
# Test image generation for different architectures
|
||||
for arch in ["amd64", "arm64"]:
|
||||
image_result = self._generate_arch_image(work_dir, arch)
|
||||
|
||||
assert image_result["status"] == "success"
|
||||
assert image_result["architecture"] == arch
|
||||
assert "image_path" in image_result
|
||||
assert os.path.exists(image_result["image_path"])
|
||||
|
||||
# Test image properties
|
||||
image_props = self._get_image_properties(image_result["image_path"])
|
||||
assert image_props["architecture"] == arch
|
||||
assert image_props["size"] > 0
|
||||
|
||||
def test_cross_arch_dependency_resolution(self, work_dir):
|
||||
"""Test cross-architecture dependency resolution."""
|
||||
# Test dependency resolution for different architectures
|
||||
for arch in ["amd64", "arm64"]:
|
||||
deps = self._resolve_arch_dependencies(arch, work_dir)
|
||||
|
||||
assert "packages" in deps
|
||||
assert "repositories" in deps
|
||||
|
||||
# Validate architecture-specific dependencies
|
||||
packages = deps["packages"]
|
||||
for pkg in packages:
|
||||
if arch in pkg:
|
||||
assert pkg.endswith(arch), f"Package {pkg} should end with {arch}"
|
||||
|
||||
def _install_arch_packages(self, packages, arch, work_dir):
|
||||
"""Mock architecture-specific package installation."""
|
||||
logger.info(f"Installing {arch} packages: {packages}")
|
||||
return True
|
||||
|
||||
def _create_arch_filesystem(self, work_dir, arch):
|
||||
"""Create architecture-specific filesystem structure."""
|
||||
arch_dir = os.path.join(work_dir, arch)
|
||||
dirs = [
|
||||
"etc", "var", "home", "boot", "usr",
|
||||
"usr/bin", "usr/lib", "usr/sbin",
|
||||
f"usr/lib/{arch}"
|
||||
]
|
||||
|
||||
for dir_path in dirs:
|
||||
full_path = os.path.join(arch_dir, dir_path)
|
||||
os.makedirs(full_path, exist_ok=True)
|
||||
|
||||
# Create /home -> /var/home symlink
|
||||
var_home = os.path.join(arch_dir, "var", "home")
|
||||
os.makedirs(var_home, exist_ok=True)
|
||||
home_link = os.path.join(arch_dir, "home")
|
||||
if os.path.exists(home_link):
|
||||
os.remove(home_link)
|
||||
os.symlink(var_home, home_link)
|
||||
|
||||
return {"status": "created", "architecture": arch, "directories": dirs}
|
||||
|
||||
def _configure_arch_grub(self, work_dir, arch):
|
||||
"""Configure GRUB for specific architecture."""
|
||||
arch_dir = os.path.join(work_dir, arch)
|
||||
|
||||
if arch == "amd64":
|
||||
grub_config = {
|
||||
"GRUB_DEFAULT": "0",
|
||||
"GRUB_TIMEOUT": "5",
|
||||
"GRUB_CMDLINE_LINUX": "console=ttyS0,115200n8 console=tty0 efi"
|
||||
}
|
||||
elif arch == "arm64":
|
||||
grub_config = {
|
||||
"GRUB_DEFAULT": "0",
|
||||
"GRUB_TIMEOUT": "5",
|
||||
"GRUB_CMDLINE_LINUX": "console=ttyAMA0,115200 console=tty0 arm64"
|
||||
}
|
||||
else:
|
||||
grub_config = {
|
||||
"GRUB_DEFAULT": "0",
|
||||
"GRUB_TIMEOUT": "5",
|
||||
"GRUB_CMDLINE_LINUX": "console=tty0"
|
||||
}
|
||||
|
||||
# Write GRUB configuration
|
||||
grub_dir = os.path.join(arch_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 _generate_arch_image(self, work_dir, arch):
|
||||
"""Mock architecture-specific image generation."""
|
||||
arch_dir = os.path.join(work_dir, arch)
|
||||
image_path = os.path.join(arch_dir, f"debian-trixie-{arch}.img")
|
||||
|
||||
# Create a dummy image file
|
||||
with open(image_path, 'wb') as f:
|
||||
f.write(f"Debian {arch} image content".encode())
|
||||
|
||||
return {
|
||||
"status": "success",
|
||||
"architecture": arch,
|
||||
"image_path": image_path,
|
||||
"size": os.path.getsize(image_path)
|
||||
}
|
||||
|
||||
def _get_image_properties(self, image_path):
|
||||
"""Get image properties."""
|
||||
return {
|
||||
"architecture": image_path.split("-")[-1].replace(".img", ""),
|
||||
"size": os.path.getsize(image_path),
|
||||
"path": image_path
|
||||
}
|
||||
|
||||
def _resolve_arch_dependencies(self, arch, work_dir):
|
||||
"""Mock architecture-specific dependency resolution."""
|
||||
if arch == "amd64":
|
||||
packages = ["linux-image-amd64", "grub-efi-amd64", "initramfs-tools"]
|
||||
repositories = ["debian", "debian-security"]
|
||||
elif arch == "arm64":
|
||||
packages = ["linux-image-arm64", "grub-efi-arm64", "initramfs-tools"]
|
||||
repositories = ["debian", "debian-security"]
|
||||
else:
|
||||
packages = ["linux-image-generic", "grub-efi", "initramfs-tools"]
|
||||
repositories = ["debian", "debian-security"]
|
||||
|
||||
return {
|
||||
"packages": packages,
|
||||
"repositories": repositories,
|
||||
"architecture": arch
|
||||
}
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
pytest.main([__file__])
|
||||
Loading…
Add table
Add a link
Reference in a new issue