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
473
test/testcases.py
Normal file
473
test/testcases.py
Normal file
|
|
@ -0,0 +1,473 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Test case definitions for deb-bootc-image-builder.
|
||||
|
||||
This module defines test cases and test data for various scenarios,
|
||||
including:
|
||||
- Basic functionality tests
|
||||
- Edge case tests
|
||||
- Error condition tests
|
||||
- Debian-specific test cases
|
||||
"""
|
||||
|
||||
import pytest
|
||||
import os
|
||||
import tempfile
|
||||
import shutil
|
||||
import json
|
||||
import yaml
|
||||
from typing import Dict, List, Any, Optional
|
||||
import logging
|
||||
|
||||
# Configure logging
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TestCaseDefinitions:
|
||||
"""Test case definitions for deb-bootc-image-builder."""
|
||||
|
||||
@staticmethod
|
||||
def get_basic_functionality_tests() -> List[Dict[str, Any]]:
|
||||
"""Get basic functionality test cases."""
|
||||
return [
|
||||
{
|
||||
"name": "basic_debian_image_build",
|
||||
"description": "Test basic Debian image building functionality",
|
||||
"container": "debian:trixie",
|
||||
"release": "trixie",
|
||||
"arch": "amd64",
|
||||
"image_type": "qcow2",
|
||||
"packages": ["linux-image-amd64", "systemd", "ostree"],
|
||||
"expected_result": "success"
|
||||
},
|
||||
{
|
||||
"name": "debian_with_custom_packages",
|
||||
"description": "Test Debian image building with custom packages",
|
||||
"container": "debian:bookworm",
|
||||
"release": "bookworm",
|
||||
"arch": "amd64",
|
||||
"image_type": "qcow2",
|
||||
"packages": [
|
||||
"linux-image-amd64",
|
||||
"systemd",
|
||||
"ostree",
|
||||
"grub-efi-amd64",
|
||||
"initramfs-tools",
|
||||
"sudo",
|
||||
"network-manager"
|
||||
],
|
||||
"expected_result": "success"
|
||||
},
|
||||
{
|
||||
"name": "debian_arm64_build",
|
||||
"description": "Test Debian ARM64 image building",
|
||||
"container": "debian:trixie",
|
||||
"release": "trixie",
|
||||
"arch": "arm64",
|
||||
"image_type": "qcow2",
|
||||
"packages": ["linux-image-arm64", "systemd", "ostree"],
|
||||
"expected_result": "success"
|
||||
}
|
||||
]
|
||||
|
||||
@staticmethod
|
||||
def get_edge_case_tests() -> List[Dict[str, Any]]:
|
||||
"""Get edge case test cases."""
|
||||
return [
|
||||
{
|
||||
"name": "empty_package_list",
|
||||
"description": "Test building with empty package list",
|
||||
"container": "debian:trixie",
|
||||
"release": "trixie",
|
||||
"arch": "amd64",
|
||||
"image_type": "qcow2",
|
||||
"packages": [],
|
||||
"expected_result": "error",
|
||||
"expected_error": "No packages specified"
|
||||
},
|
||||
{
|
||||
"name": "invalid_release",
|
||||
"description": "Test building with invalid Debian release",
|
||||
"container": "debian:trixie",
|
||||
"release": "invalid-release",
|
||||
"arch": "amd64",
|
||||
"image_type": "qcow2",
|
||||
"packages": ["linux-image-amd64"],
|
||||
"expected_result": "error",
|
||||
"expected_error": "Invalid Debian release"
|
||||
},
|
||||
{
|
||||
"name": "invalid_architecture",
|
||||
"description": "Test building with invalid architecture",
|
||||
"container": "debian:trixie",
|
||||
"release": "trixie",
|
||||
"arch": "invalid-arch",
|
||||
"image_type": "qcow2",
|
||||
"packages": ["linux-image-amd64"],
|
||||
"expected_result": "error",
|
||||
"expected_error": "Invalid architecture"
|
||||
},
|
||||
{
|
||||
"name": "very_long_package_list",
|
||||
"description": "Test building with very long package list",
|
||||
"container": "debian:trixie",
|
||||
"release": "trixie",
|
||||
"arch": "amd64",
|
||||
"image_type": "qcow2",
|
||||
"packages": [f"package-{i}" for i in range(1000)],
|
||||
"expected_result": "success"
|
||||
}
|
||||
]
|
||||
|
||||
@staticmethod
|
||||
def get_error_condition_tests() -> List[Dict[str, Any]]:
|
||||
"""Get error condition test cases."""
|
||||
return [
|
||||
{
|
||||
"name": "invalid_container_image",
|
||||
"description": "Test building with invalid container image",
|
||||
"container": "invalid:image",
|
||||
"release": "trixie",
|
||||
"arch": "amd64",
|
||||
"image_type": "qcow2",
|
||||
"packages": ["linux-image-amd64"],
|
||||
"expected_result": "error",
|
||||
"expected_error": "Invalid container image"
|
||||
},
|
||||
{
|
||||
"name": "network_failure",
|
||||
"description": "Test building with network failure simulation",
|
||||
"container": "debian:trixie",
|
||||
"release": "trixie",
|
||||
"arch": "amd64",
|
||||
"image_type": "qcow2",
|
||||
"packages": ["linux-image-amd64"],
|
||||
"expected_result": "error",
|
||||
"expected_error": "Network error",
|
||||
"simulate_network_failure": True
|
||||
},
|
||||
{
|
||||
"name": "disk_space_exhaustion",
|
||||
"description": "Test building with disk space exhaustion",
|
||||
"container": "debian:trixie",
|
||||
"release": "trixie",
|
||||
"arch": "amd64",
|
||||
"image_type": "qcow2",
|
||||
"packages": ["linux-image-amd64"],
|
||||
"expected_result": "error",
|
||||
"expected_error": "Disk space exhausted",
|
||||
"simulate_disk_full": True
|
||||
}
|
||||
]
|
||||
|
||||
@staticmethod
|
||||
def get_debian_specific_tests() -> List[Dict[str, Any]]:
|
||||
"""Get Debian-specific test cases."""
|
||||
return [
|
||||
{
|
||||
"name": "debian_trixie_minimal",
|
||||
"description": "Test Debian Trixie minimal image",
|
||||
"container": "debian:trixie",
|
||||
"release": "trixie",
|
||||
"arch": "amd64",
|
||||
"image_type": "qcow2",
|
||||
"packages": [
|
||||
"linux-image-amd64",
|
||||
"systemd",
|
||||
"ostree",
|
||||
"grub-efi-amd64",
|
||||
"initramfs-tools"
|
||||
],
|
||||
"debian_specific": {
|
||||
"initramfs_tools": True,
|
||||
"grub_efi": True,
|
||||
"ostree_integration": True
|
||||
},
|
||||
"expected_result": "success"
|
||||
},
|
||||
{
|
||||
"name": "debian_bookworm_desktop",
|
||||
"description": "Test Debian Bookworm desktop image",
|
||||
"container": "debian:bookworm",
|
||||
"release": "bookworm",
|
||||
"arch": "amd64",
|
||||
"image_type": "qcow2",
|
||||
"packages": [
|
||||
"linux-image-amd64",
|
||||
"systemd",
|
||||
"ostree",
|
||||
"grub-efi-amd64",
|
||||
"initramfs-tools",
|
||||
"task-desktop",
|
||||
"xorg",
|
||||
"lightdm"
|
||||
],
|
||||
"debian_specific": {
|
||||
"initramfs_tools": True,
|
||||
"grub_efi": True,
|
||||
"ostree_integration": True,
|
||||
"desktop_environment": True
|
||||
},
|
||||
"expected_result": "success"
|
||||
},
|
||||
{
|
||||
"name": "debian_bullseye_server",
|
||||
"description": "Test Debian Bullseye server image",
|
||||
"container": "debian:bullseye",
|
||||
"release": "bullseye",
|
||||
"arch": "amd64",
|
||||
"image_type": "qcow2",
|
||||
"packages": [
|
||||
"linux-image-amd64",
|
||||
"systemd",
|
||||
"ostree",
|
||||
"grub-efi-amd64",
|
||||
"initramfs-tools",
|
||||
"openssh-server",
|
||||
"nginx",
|
||||
"postgresql"
|
||||
],
|
||||
"debian_specific": {
|
||||
"initramfs_tools": True,
|
||||
"grub_efi": True,
|
||||
"ostree_integration": True,
|
||||
"server_services": True
|
||||
},
|
||||
"expected_result": "success"
|
||||
}
|
||||
]
|
||||
|
||||
@staticmethod
|
||||
def get_performance_tests() -> List[Dict[str, Any]]:
|
||||
"""Get performance test cases."""
|
||||
return [
|
||||
{
|
||||
"name": "small_image_build_time",
|
||||
"description": "Test build time for small image",
|
||||
"container": "debian:trixie",
|
||||
"release": "trixie",
|
||||
"arch": "amd64",
|
||||
"image_type": "qcow2",
|
||||
"packages": ["linux-image-amd64", "systemd"],
|
||||
"performance_requirements": {
|
||||
"max_build_time": 300, # 5 minutes
|
||||
"max_image_size": 1024 # 1GB
|
||||
},
|
||||
"expected_result": "success"
|
||||
},
|
||||
{
|
||||
"name": "large_image_build_time",
|
||||
"description": "Test build time for large image",
|
||||
"container": "debian:trixie",
|
||||
"release": "trixie",
|
||||
"arch": "amd64",
|
||||
"image_type": "qcow2",
|
||||
"packages": [f"package-{i}" for i in range(500)],
|
||||
"performance_requirements": {
|
||||
"max_build_time": 1800, # 30 minutes
|
||||
"max_image_size": 10240 # 10GB
|
||||
},
|
||||
"expected_result": "success"
|
||||
}
|
||||
]
|
||||
|
||||
@staticmethod
|
||||
def get_integration_tests() -> List[Dict[str, Any]]:
|
||||
"""Get integration test cases."""
|
||||
return [
|
||||
{
|
||||
"name": "full_pipeline_test",
|
||||
"description": "Test complete image building pipeline",
|
||||
"container": "debian:trixie",
|
||||
"release": "trixie",
|
||||
"arch": "amd64",
|
||||
"image_type": "qcow2",
|
||||
"packages": [
|
||||
"linux-image-amd64",
|
||||
"systemd",
|
||||
"ostree",
|
||||
"grub-efi-amd64",
|
||||
"initramfs-tools"
|
||||
],
|
||||
"pipeline_stages": [
|
||||
"filesystem_setup",
|
||||
"package_installation",
|
||||
"ostree_integration",
|
||||
"bootloader_configuration",
|
||||
"image_generation"
|
||||
],
|
||||
"expected_result": "success"
|
||||
},
|
||||
{
|
||||
"name": "cross_architecture_test",
|
||||
"description": "Test cross-architecture building",
|
||||
"container": "debian:trixie",
|
||||
"release": "trixie",
|
||||
"architectures": ["amd64", "arm64"],
|
||||
"image_type": "qcow2",
|
||||
"packages": ["linux-image-amd64", "systemd", "ostree"],
|
||||
"expected_result": "success"
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
class TestDataGenerator:
|
||||
"""Generate test data for various test scenarios."""
|
||||
|
||||
@staticmethod
|
||||
def generate_manifest(test_case: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""Generate a manifest from a test case."""
|
||||
manifest = {
|
||||
"pipeline": {
|
||||
"build": {
|
||||
"name": "org.osbuild.debian-filesystem",
|
||||
"options": {
|
||||
"rootfs_type": "ext4",
|
||||
"ostree_integration": True,
|
||||
"home_symlink": True
|
||||
}
|
||||
},
|
||||
"stages": [
|
||||
{
|
||||
"name": "org.osbuild.apt",
|
||||
"options": {
|
||||
"packages": test_case.get("packages", []),
|
||||
"release": test_case.get("release", "trixie"),
|
||||
"arch": test_case.get("arch", "amd64")
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
# Add Debian-specific stages if specified
|
||||
if test_case.get("debian_specific", {}).get("grub_efi"):
|
||||
manifest["pipeline"]["stages"].append({
|
||||
"name": "org.osbuild.debian-grub",
|
||||
"options": {
|
||||
"uefi": True,
|
||||
"secure_boot": False,
|
||||
"timeout": 5
|
||||
}
|
||||
})
|
||||
|
||||
if test_case.get("debian_specific", {}).get("initramfs_tools"):
|
||||
manifest["pipeline"]["stages"].append({
|
||||
"name": "org.osbuild.debian-kernel",
|
||||
"options": {
|
||||
"kernel_package": f"linux-image-{test_case.get('arch', 'amd64')}",
|
||||
"initramfs_tools": True,
|
||||
"ostree_integration": True
|
||||
}
|
||||
})
|
||||
|
||||
return manifest
|
||||
|
||||
@staticmethod
|
||||
def generate_test_environment(test_case: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""Generate test environment configuration."""
|
||||
return {
|
||||
"work_dir": "/tmp/test-env",
|
||||
"output_dir": "/tmp/test-output",
|
||||
"cache_dir": "/tmp/test-cache",
|
||||
"temp_dir": "/tmp/test-temp",
|
||||
"network_enabled": not test_case.get("simulate_network_failure", False),
|
||||
"disk_space_available": not test_case.get("simulate_disk_full", False)
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def generate_expected_output(test_case: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""Generate expected output for a test case."""
|
||||
expected_output = {
|
||||
"status": test_case.get("expected_result", "success"),
|
||||
"image_type": test_case.get("image_type", "qcow2"),
|
||||
"architecture": test_case.get("arch", "amd64"),
|
||||
"release": test_case.get("release", "trixie")
|
||||
}
|
||||
|
||||
if test_case.get("expected_result") == "success":
|
||||
expected_output["image_path"] = f"/tmp/test-output/debian-{test_case.get('release')}-{test_case.get('arch')}.{test_case.get('image_type')}"
|
||||
expected_output["build_log"] = "Build completed successfully"
|
||||
else:
|
||||
expected_output["error"] = test_case.get("expected_error", "Unknown error")
|
||||
expected_output["build_log"] = f"Build failed: {test_case.get('expected_error', 'Unknown error')}"
|
||||
|
||||
return expected_output
|
||||
|
||||
|
||||
def load_test_cases_from_file(file_path: str) -> List[Dict[str, Any]]:
|
||||
"""Load test cases from a file."""
|
||||
try:
|
||||
with open(file_path, 'r') as f:
|
||||
if file_path.endswith('.json'):
|
||||
return json.load(f)
|
||||
elif file_path.endswith('.yaml') or file_path.endswith('.yml'):
|
||||
return yaml.safe_load(f)
|
||||
else:
|
||||
raise ValueError(f"Unsupported file format: {file_path}")
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to load test cases from {file_path}: {e}")
|
||||
return []
|
||||
|
||||
|
||||
def save_test_cases_to_file(test_cases: List[Dict[str, Any]], file_path: str) -> bool:
|
||||
"""Save test cases to a file."""
|
||||
try:
|
||||
with open(file_path, 'w') as f:
|
||||
if file_path.endswith('.json'):
|
||||
json.dump(test_cases, f, indent=2)
|
||||
elif file_path.endswith('.yaml') or file_path.endswith('.yml'):
|
||||
yaml.dump(test_cases, f, default_flow_style=False)
|
||||
else:
|
||||
raise ValueError(f"Unsupported file format: {file_path}")
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to save test cases to {file_path}: {e}")
|
||||
return False
|
||||
|
||||
|
||||
def validate_test_case(test_case: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""Validate a test case definition."""
|
||||
validation_result = {
|
||||
"valid": True,
|
||||
"errors": [],
|
||||
"warnings": []
|
||||
}
|
||||
|
||||
# Check required fields
|
||||
required_fields = ["name", "description", "container", "release", "arch", "image_type", "packages"]
|
||||
for field in required_fields:
|
||||
if field not in test_case:
|
||||
validation_result["valid"] = False
|
||||
validation_result["errors"].append(f"Missing required field: {field}")
|
||||
|
||||
# Check field types
|
||||
if "packages" in test_case and not isinstance(test_case["packages"], list):
|
||||
validation_result["valid"] = False
|
||||
validation_result["errors"].append("Packages field must be a list")
|
||||
|
||||
if "arch" in test_case and test_case["arch"] not in ["amd64", "arm64", "i386"]:
|
||||
validation_result["warnings"].append(f"Unsupported architecture: {test_case['arch']}")
|
||||
|
||||
if "release" in test_case and test_case["release"] not in ["trixie", "bookworm", "bullseye"]:
|
||||
validation_result["warnings"].append(f"Unsupported Debian release: {test_case['release']}")
|
||||
|
||||
return validation_result
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Test the test case definitions
|
||||
test_cases = TestCaseDefinitions.get_basic_functionality_tests()
|
||||
print(f"Generated {len(test_cases)} basic functionality test cases")
|
||||
|
||||
for test_case in test_cases:
|
||||
manifest = TestDataGenerator.generate_manifest(test_case)
|
||||
print(f"Generated manifest for {test_case['name']}: {len(manifest['pipeline']['stages'])} stages")
|
||||
|
||||
validation = validate_test_case(test_case)
|
||||
print(f"Validation for {test_case['name']}: {'Valid' if validation['valid'] else 'Invalid'}")
|
||||
if validation['errors']:
|
||||
print(f" Errors: {validation['errors']}")
|
||||
if validation['warnings']:
|
||||
print(f" Warnings: {validation['warnings']}")
|
||||
Loading…
Add table
Add a link
Reference in a new issue