290 lines
11 KiB
Python
290 lines
11 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Test command line options for deb-bootc-image-builder.
|
|
|
|
This module tests command line argument parsing and validation,
|
|
including:
|
|
- Required arguments
|
|
- Optional arguments
|
|
- Argument validation
|
|
- Debian-specific options
|
|
"""
|
|
|
|
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 TestCommandLineOptions:
|
|
"""Test cases for command line options."""
|
|
|
|
def test_required_arguments(self, work_dir):
|
|
"""Test required command line arguments."""
|
|
# Test minimum required arguments
|
|
required_args = {
|
|
"container": "debian:trixie",
|
|
"output": work_dir
|
|
}
|
|
|
|
# Validate required arguments
|
|
for arg_name, arg_value in required_args.items():
|
|
assert arg_value is not None, f"Required argument {arg_name} is None"
|
|
if arg_name == "output":
|
|
assert os.path.exists(arg_value), f"Output directory {arg_value} does not exist"
|
|
|
|
def test_optional_arguments(self, work_dir):
|
|
"""Test optional command line arguments."""
|
|
# Test optional arguments with default values
|
|
optional_args = {
|
|
"release": "trixie",
|
|
"arch": "amd64",
|
|
"image_type": "qcow2",
|
|
"verbose": False,
|
|
"clean": False
|
|
}
|
|
|
|
# Validate optional arguments
|
|
for arg_name, arg_value in optional_args.items():
|
|
assert arg_name in optional_args, f"Optional argument {arg_name} not found"
|
|
assert arg_value is not None, f"Optional argument {arg_name} has no default value"
|
|
|
|
def test_debian_specific_options(self, work_dir):
|
|
"""Test Debian-specific command line options."""
|
|
# Test Debian-specific options
|
|
debian_options = {
|
|
"release": "trixie",
|
|
"arch": "amd64",
|
|
"package_manager": "apt",
|
|
"initramfs_tools": True,
|
|
"grub_efi": True
|
|
}
|
|
|
|
# Validate Debian-specific options
|
|
assert debian_options["release"] in ["trixie", "bookworm", "bullseye"], \
|
|
f"Invalid Debian release: {debian_options['release']}"
|
|
|
|
assert debian_options["arch"] in ["amd64", "arm64", "i386"], \
|
|
f"Invalid architecture: {debian_options['arch']}"
|
|
|
|
assert debian_options["package_manager"] == "apt", \
|
|
f"Invalid package manager: {debian_options['package_manager']}"
|
|
|
|
assert debian_options["initramfs_tools"] is True, \
|
|
"initramfs-tools should be enabled for Debian"
|
|
|
|
assert debian_options["grub_efi"] is True, \
|
|
"GRUB EFI should be enabled for Debian"
|
|
|
|
def test_argument_validation(self, work_dir):
|
|
"""Test argument validation logic."""
|
|
# Test valid arguments
|
|
valid_args = {
|
|
"container": "debian:trixie",
|
|
"output": work_dir,
|
|
"release": "trixie",
|
|
"arch": "amd64"
|
|
}
|
|
|
|
validation_result = self._validate_arguments(valid_args)
|
|
assert validation_result["valid"] is True, \
|
|
f"Valid arguments failed validation: {validation_result.get('error', 'Unknown error')}"
|
|
|
|
# Test invalid arguments
|
|
invalid_args = {
|
|
"container": "invalid:image",
|
|
"output": "/nonexistent/path",
|
|
"release": "invalid-release",
|
|
"arch": "invalid-arch"
|
|
}
|
|
|
|
validation_result = self._validate_arguments(invalid_args)
|
|
assert validation_result["valid"] is False, \
|
|
"Invalid arguments should fail validation"
|
|
|
|
def test_output_directory_handling(self, work_dir):
|
|
"""Test output directory handling."""
|
|
# Test existing directory
|
|
existing_dir = work_dir
|
|
result = self._handle_output_directory(existing_dir)
|
|
assert result["success"] is True, \
|
|
f"Existing directory handling failed: {result.get('error', 'Unknown error')}"
|
|
|
|
# Test non-existent directory creation
|
|
new_dir = os.path.join(work_dir, "new_output")
|
|
result = self._handle_output_directory(new_dir)
|
|
assert result["success"] is True, \
|
|
f"New directory creation failed: {result.get('error', 'Unknown error')}"
|
|
assert os.path.exists(new_dir), "New directory was not created"
|
|
|
|
# Test invalid directory path
|
|
invalid_dir = "/invalid/path/with/permissions/issue"
|
|
result = self._handle_output_directory(invalid_dir)
|
|
assert result["success"] is False, "Invalid directory should fail"
|
|
|
|
def test_container_image_validation(self, work_dir):
|
|
"""Test container image validation."""
|
|
# Test valid Debian image
|
|
valid_image = "debian:trixie"
|
|
result = self._validate_container_image(valid_image)
|
|
assert result["valid"] is True, \
|
|
f"Valid Debian image failed validation: {result.get('error', 'Unknown error')}"
|
|
|
|
# Test invalid image
|
|
invalid_image = "invalid:image"
|
|
result = self._validate_container_image(invalid_image)
|
|
assert result["valid"] is False, "Invalid image should fail validation"
|
|
|
|
# Test image with specific architecture
|
|
arch_image = "debian:trixie-amd64"
|
|
result = self._validate_container_image(arch_image)
|
|
assert result["valid"] is True, \
|
|
f"Architecture-specific image failed validation: {result.get('error', 'Unknown error')}"
|
|
|
|
def test_package_list_validation(self, work_dir):
|
|
"""Test package list validation."""
|
|
# Test valid Debian packages
|
|
valid_packages = [
|
|
"linux-image-amd64",
|
|
"systemd",
|
|
"ostree",
|
|
"grub-efi-amd64",
|
|
"initramfs-tools"
|
|
]
|
|
|
|
result = self._validate_package_list(valid_packages)
|
|
assert result["valid"] is True, \
|
|
f"Valid packages failed validation: {result.get('error', 'Unknown error')}"
|
|
|
|
# Test invalid packages
|
|
invalid_packages = [
|
|
"invalid-package",
|
|
"nonexistent-package"
|
|
]
|
|
|
|
result = self._validate_package_list(invalid_packages)
|
|
assert result["valid"] is False, "Invalid packages should fail validation"
|
|
|
|
def test_manifest_generation(self, work_dir):
|
|
"""Test manifest generation from command line options."""
|
|
# Test manifest generation
|
|
options = {
|
|
"container": "debian:trixie",
|
|
"release": "trixie",
|
|
"arch": "amd64",
|
|
"image_type": "qcow2",
|
|
"packages": ["linux-image-amd64", "systemd", "ostree"]
|
|
}
|
|
|
|
manifest = self._generate_manifest(options)
|
|
|
|
# Validate generated manifest
|
|
assert "pipeline" in manifest
|
|
assert "build" in manifest["pipeline"]
|
|
assert "stages" in manifest["pipeline"]
|
|
|
|
# Validate Debian-specific content
|
|
build_stage = manifest["pipeline"]["build"]
|
|
assert build_stage["name"] == "org.osbuild.debian-filesystem"
|
|
|
|
# Validate APT stage
|
|
apt_stage = next((s for s in manifest["pipeline"]["stages"]
|
|
if s["name"] == "org.osbuild.apt"), None)
|
|
assert apt_stage is not None
|
|
assert apt_stage["options"]["release"] == "trixie"
|
|
assert apt_stage["options"]["arch"] == "amd64"
|
|
|
|
def _validate_arguments(self, args):
|
|
"""Mock argument validation."""
|
|
# Check required arguments
|
|
if "container" not in args or not args["container"]:
|
|
return {"valid": False, "error": "Container image is required"}
|
|
|
|
if "output" not in args or not args["output"]:
|
|
return {"valid": False, "error": "Output directory is required"}
|
|
|
|
# Check Debian-specific validation
|
|
if "release" in args:
|
|
valid_releases = ["trixie", "bookworm", "bullseye"]
|
|
if args["release"] not in valid_releases:
|
|
return {"valid": False, "error": f"Invalid Debian release: {args['release']}"}
|
|
|
|
if "arch" in args:
|
|
valid_archs = ["amd64", "arm64", "i386"]
|
|
if args["arch"] not in valid_archs:
|
|
return {"valid": False, "error": f"Invalid architecture: {args['arch']}"}
|
|
|
|
return {"valid": True}
|
|
|
|
def _handle_output_directory(self, output_dir):
|
|
"""Mock output directory handling."""
|
|
try:
|
|
if not os.path.exists(output_dir):
|
|
os.makedirs(output_dir, exist_ok=True)
|
|
|
|
# Test if directory is writable
|
|
test_file = os.path.join(output_dir, "test_write")
|
|
with open(test_file, 'w') as f:
|
|
f.write("test")
|
|
os.remove(test_file)
|
|
|
|
return {"success": True}
|
|
except Exception as e:
|
|
return {"success": False, "error": str(e)}
|
|
|
|
def _validate_container_image(self, image):
|
|
"""Mock container image validation."""
|
|
# Check if it's a valid Debian image
|
|
if image.startswith("debian:"):
|
|
return {"valid": True, "type": "debian"}
|
|
else:
|
|
return {"valid": False, "error": "Not a valid Debian image"}
|
|
|
|
def _validate_package_list(self, packages):
|
|
"""Mock package list validation."""
|
|
# Check if packages look like valid Debian packages
|
|
valid_packages = [
|
|
"linux-image-amd64", "systemd", "ostree", "grub-efi-amd64",
|
|
"initramfs-tools", "util-linux", "parted", "e2fsprogs"
|
|
]
|
|
|
|
for pkg in packages:
|
|
if pkg not in valid_packages:
|
|
return {"valid": False, "error": f"Invalid package: {pkg}"}
|
|
|
|
return {"valid": True}
|
|
|
|
def _generate_manifest(self, options):
|
|
"""Mock manifest generation."""
|
|
return {
|
|
"pipeline": {
|
|
"build": {
|
|
"name": "org.osbuild.debian-filesystem",
|
|
"options": {
|
|
"rootfs_type": "ext4",
|
|
"ostree_integration": True
|
|
}
|
|
},
|
|
"stages": [
|
|
{
|
|
"name": "org.osbuild.apt",
|
|
"options": {
|
|
"packages": options.get("packages", []),
|
|
"release": options.get("release", "trixie"),
|
|
"arch": options.get("arch", "amd64")
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
|
|
|
|
if __name__ == "__main__":
|
|
pytest.main([__file__])
|