Initial commit
This commit is contained in:
commit
3326d796f0
87 changed files with 15792 additions and 0 deletions
Binary file not shown.
Binary file not shown.
430
tests/integration/test_full_pipeline.py
Normal file
430
tests/integration/test_full_pipeline.py
Normal file
|
|
@ -0,0 +1,430 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Integration Tests for Debian bootc-image-builder
|
||||
|
||||
This module contains comprehensive integration tests that test all Debian osbuild stages
|
||||
together in a complete pipeline to ensure they work correctly together.
|
||||
|
||||
Author: Debian bootc-image-builder team
|
||||
License: Same as original bootc-image-builder
|
||||
"""
|
||||
|
||||
import unittest
|
||||
import tempfile
|
||||
import os
|
||||
import json
|
||||
import shutil
|
||||
import subprocess
|
||||
from unittest.mock import Mock, patch, MagicMock
|
||||
import sys
|
||||
|
||||
# Add the osbuild-stages directory to the path
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', 'osbuild-stages'))
|
||||
|
||||
from apt_stage import AptStage
|
||||
from debian_kernel_stage import DebianKernelStage
|
||||
from debian_grub_stage import DebianGrubStage
|
||||
from debian_filesystem_stage import DebianFilesystemStage
|
||||
|
||||
|
||||
class TestFullPipeline(unittest.TestCase):
|
||||
"""Integration tests for the complete Debian osbuild pipeline."""
|
||||
|
||||
def setUp(self):
|
||||
"""Set up test fixtures."""
|
||||
self.temp_dir = tempfile.mkdtemp()
|
||||
self.test_options = {
|
||||
'packages': ['linux-image-amd64', 'systemd', 'initramfs-tools', 'grub-efi-amd64'],
|
||||
'release': 'trixie',
|
||||
'arch': 'amd64',
|
||||
'repos': [
|
||||
{
|
||||
'name': 'debian',
|
||||
'url': 'http://deb.debian.org/debian',
|
||||
'suite': 'trixie',
|
||||
'components': ['main', 'contrib']
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
# Create a mock context
|
||||
self.mock_context = Mock()
|
||||
self.mock_context.root = self.temp_dir
|
||||
|
||||
# Mock the context.run method
|
||||
self.mock_context.run.return_value = Mock(
|
||||
returncode=0,
|
||||
stdout='',
|
||||
stderr=''
|
||||
)
|
||||
|
||||
def tearDown(self):
|
||||
"""Clean up test fixtures."""
|
||||
shutil.rmtree(self.temp_dir)
|
||||
|
||||
def test_complete_pipeline_execution(self):
|
||||
"""Test the complete pipeline execution with all stages."""
|
||||
logger.info("Testing complete pipeline execution")
|
||||
|
||||
# Step 1: Filesystem Stage
|
||||
logger.info("Step 1: Executing Debian Filesystem Stage")
|
||||
filesystem_stage = DebianFilesystemStage({
|
||||
'rootfs_type': 'ext4',
|
||||
'ostree_integration': True,
|
||||
'home_symlink': True
|
||||
})
|
||||
filesystem_stage.run(self.mock_context)
|
||||
|
||||
# Verify filesystem structure was created
|
||||
self.assertTrue(os.path.exists(os.path.join(self.temp_dir, 'etc')))
|
||||
self.assertTrue(os.path.exists(os.path.join(self.temp_dir, 'usr')))
|
||||
self.assertTrue(os.path.exists(os.path.join(self.temp_dir, 'var')))
|
||||
self.assertTrue(os.path.exists(os.path.join(self.temp_dir, 'home')))
|
||||
|
||||
# Verify OSTree integration points
|
||||
self.assertTrue(os.path.exists(os.path.join(self.temp_dir, 'ostree')))
|
||||
self.assertTrue(os.path.exists(os.path.join(self.temp_dir, 'usr', 'lib', 'ostree-boot')))
|
||||
self.assertTrue(os.path.exists(os.path.join(self.temp_dir, 'etc', 'ostree')))
|
||||
|
||||
# Verify home symlink
|
||||
home_path = os.path.join(self.temp_dir, 'home')
|
||||
self.assertTrue(os.path.islink(home_path))
|
||||
self.assertEqual(os.readlink(home_path), '../var/home')
|
||||
|
||||
logger.info("✓ Filesystem stage completed successfully")
|
||||
|
||||
# Step 2: APT Stage
|
||||
logger.info("Step 2: Executing APT Stage")
|
||||
apt_stage = AptStage(self.test_options)
|
||||
apt_stage.run(self.mock_context)
|
||||
|
||||
# Verify APT configuration was created
|
||||
self.assertTrue(os.path.exists(os.path.join(self.temp_dir, 'etc', 'apt', 'apt.conf.d', '99osbuild')))
|
||||
self.assertTrue(os.path.exists(os.path.join(self.temp_dir, 'etc', 'apt', 'sources.list.d', 'debian.list')))
|
||||
|
||||
logger.info("✓ APT stage completed successfully")
|
||||
|
||||
# Step 3: Kernel Stage
|
||||
logger.info("Step 3: Executing Debian Kernel Stage")
|
||||
kernel_stage = DebianKernelStage({
|
||||
'kernel_package': 'linux-image-amd64',
|
||||
'initramfs_tools': True,
|
||||
'ostree_integration': True,
|
||||
'modules_autoload': True
|
||||
})
|
||||
kernel_stage.run(self.mock_context)
|
||||
|
||||
# Verify kernel stage setup
|
||||
self.assertTrue(os.path.exists(os.path.join(self.temp_dir, 'etc', 'initramfs-tools')))
|
||||
self.assertTrue(os.path.exists(os.path.join(self.temp_dir, 'etc', 'modules-load.d')))
|
||||
|
||||
logger.info("✓ Kernel stage completed successfully")
|
||||
|
||||
# Step 4: GRUB Stage
|
||||
logger.info("Step 4: Executing Debian GRUB Stage")
|
||||
grub_stage = DebianGrubStage({
|
||||
'ostree_integration': True,
|
||||
'uefi': True,
|
||||
'secure_boot': False,
|
||||
'timeout': 5,
|
||||
'default_entry': 0
|
||||
})
|
||||
grub_stage.run(self.mock_context)
|
||||
|
||||
# Verify GRUB configuration was created
|
||||
self.assertTrue(os.path.exists(os.path.join(self.temp_dir, 'etc', 'default', 'grub')))
|
||||
self.assertTrue(os.path.exists(os.path.join(self.temp_dir, 'etc', 'grub.d', '10_ostree')))
|
||||
|
||||
logger.info("✓ GRUB stage completed successfully")
|
||||
|
||||
logger.info("✓ Complete pipeline execution successful")
|
||||
|
||||
def test_stage_dependencies(self):
|
||||
"""Test that stages handle dependencies correctly."""
|
||||
logger.info("Testing stage dependencies")
|
||||
|
||||
# Test that filesystem stage creates required directories for other stages
|
||||
filesystem_stage = DebianFilesystemStage({
|
||||
'rootfs_type': 'ext4',
|
||||
'ostree_integration': True,
|
||||
'home_symlink': True
|
||||
})
|
||||
filesystem_stage.run(self.mock_context)
|
||||
|
||||
# Verify that APT stage can find its required directories
|
||||
apt_stage = AptStage(self.test_options)
|
||||
apt_stage.run(self.mock_context)
|
||||
|
||||
# Verify that kernel stage can find its required directories
|
||||
kernel_stage = DebianKernelStage({
|
||||
'kernel_package': 'linux-image-amd64',
|
||||
'initramfs_tools': True,
|
||||
'ostree_integration': True
|
||||
})
|
||||
kernel_stage.run(self.mock_context)
|
||||
|
||||
# Verify that GRUB stage can find its required directories
|
||||
grub_stage = DebianGrubStage({
|
||||
'ostree_integration': True,
|
||||
'uefi': True
|
||||
})
|
||||
grub_stage.run(self.mock_context)
|
||||
|
||||
logger.info("✓ Stage dependencies handled correctly")
|
||||
|
||||
def test_ostree_integration_consistency(self):
|
||||
"""Test that OSTree integration is consistent across all stages."""
|
||||
logger.info("Testing OSTree integration consistency")
|
||||
|
||||
# Execute all stages with OSTree integration
|
||||
filesystem_stage = DebianFilesystemStage({
|
||||
'ostree_integration': True,
|
||||
'home_symlink': True
|
||||
})
|
||||
filesystem_stage.run(self.mock_context)
|
||||
|
||||
apt_stage = AptStage(self.test_options)
|
||||
apt_stage.run(self.mock_context)
|
||||
|
||||
kernel_stage = DebianKernelStage({
|
||||
'ostree_integration': True,
|
||||
'initramfs_tools': True
|
||||
})
|
||||
kernel_stage.run(self.mock_context)
|
||||
|
||||
grub_stage = DebianGrubStage({
|
||||
'ostree_integration': True,
|
||||
'uefi': True
|
||||
})
|
||||
grub_stage.run(self.mock_context)
|
||||
|
||||
# Verify OSTree configuration consistency
|
||||
ostree_conf = os.path.join(self.temp_dir, 'etc', 'ostree', 'ostree.conf')
|
||||
self.assertTrue(os.path.exists(ostree_conf))
|
||||
|
||||
# Verify OSTree boot directory structure
|
||||
ostree_boot = os.path.join(self.temp_dir, 'usr', 'lib', 'ostree-boot')
|
||||
self.assertTrue(os.path.exists(ostree_boot))
|
||||
|
||||
# Verify GRUB OSTree configuration
|
||||
grub_ostree = os.path.join(self.temp_dir, 'etc', 'grub.d', '10_ostree')
|
||||
self.assertTrue(os.path.exists(grub_ostree))
|
||||
|
||||
logger.info("✓ OSTree integration consistent across all stages")
|
||||
|
||||
def test_error_handling(self):
|
||||
"""Test error handling in the pipeline."""
|
||||
logger.info("Testing error handling")
|
||||
|
||||
# Test with invalid options
|
||||
with self.assertRaises(ValueError):
|
||||
invalid_apt_stage = AptStage({}) # No packages specified
|
||||
|
||||
# Test with missing context
|
||||
with self.assertRaises(AttributeError):
|
||||
filesystem_stage = DebianFilesystemStage({'ostree_integration': True})
|
||||
filesystem_stage.run(None)
|
||||
|
||||
logger.info("✓ Error handling working correctly")
|
||||
|
||||
def test_performance_optimization(self):
|
||||
"""Test that the pipeline is optimized for performance."""
|
||||
logger.info("Testing performance optimization")
|
||||
|
||||
import time
|
||||
|
||||
# Measure execution time for each stage
|
||||
start_time = time.time()
|
||||
|
||||
filesystem_stage = DebianFilesystemStage({
|
||||
'ostree_integration': True,
|
||||
'home_symlink': True
|
||||
})
|
||||
filesystem_stage.run(self.mock_context)
|
||||
filesystem_time = time.time() - start_time
|
||||
|
||||
start_time = time.time()
|
||||
apt_stage = AptStage(self.test_options)
|
||||
apt_stage.run(self.mock_context)
|
||||
apt_time = time.time() - start_time
|
||||
|
||||
start_time = time.time()
|
||||
kernel_stage = DebianKernelStage({
|
||||
'ostree_integration': True,
|
||||
'initramfs_tools': True
|
||||
})
|
||||
kernel_stage.run(self.mock_context)
|
||||
kernel_time = time.time() - start_time
|
||||
|
||||
start_time = time.time()
|
||||
grub_stage = DebianGrubStage({
|
||||
'ostree_integration': True,
|
||||
'uefi': True
|
||||
})
|
||||
grub_stage.run(self.mock_context)
|
||||
grub_time = time.time() - start_time
|
||||
|
||||
total_time = filesystem_time + apt_time + kernel_time + grub_time
|
||||
|
||||
logger.info(f"Stage execution times:")
|
||||
logger.info(f" Filesystem: {filesystem_time:.3f}s")
|
||||
logger.info(f" APT: {apt_time:.3f}s")
|
||||
logger.info(f" Kernel: {kernel_time:.3f}s")
|
||||
logger.info(f" GRUB: {grub_time:.3f}s")
|
||||
logger.info(f" Total: {total_time:.3f}s")
|
||||
|
||||
# Verify reasonable performance (should complete in under 5 seconds for mock)
|
||||
self.assertLess(total_time, 5.0)
|
||||
|
||||
logger.info("✓ Performance optimization verified")
|
||||
|
||||
def test_filesystem_permissions(self):
|
||||
"""Test that filesystem permissions are set correctly."""
|
||||
logger.info("Testing filesystem permissions")
|
||||
|
||||
filesystem_stage = DebianFilesystemStage({
|
||||
'ostree_integration': True,
|
||||
'home_symlink': True
|
||||
})
|
||||
filesystem_stage.run(self.mock_context)
|
||||
|
||||
# Test critical permission settings
|
||||
permissions_to_test = [
|
||||
('/etc/passwd', 0o644),
|
||||
('/etc/group', 0o644),
|
||||
('/etc/shadow', 0o640),
|
||||
('/root', 0o700),
|
||||
('/tmp', 0o1777),
|
||||
('/var/tmp', 0o1777)
|
||||
]
|
||||
|
||||
for path, expected_mode in permissions_to_test:
|
||||
full_path = os.path.join(self.temp_dir, path.lstrip('/'))
|
||||
if os.path.exists(full_path):
|
||||
actual_mode = oct(os.stat(full_path).st_mode)[-3:]
|
||||
expected_mode_str = oct(expected_mode)[-3:]
|
||||
self.assertEqual(actual_mode, expected_mode_str,
|
||||
f"Permission mismatch for {path}: expected {expected_mode_str}, got {actual_mode}")
|
||||
|
||||
logger.info("✓ Filesystem permissions set correctly")
|
||||
|
||||
def test_user_and_group_setup(self):
|
||||
"""Test that users and groups are set up correctly."""
|
||||
logger.info("Testing user and group setup")
|
||||
|
||||
filesystem_stage = DebianFilesystemStage({
|
||||
'ostree_integration': True,
|
||||
'home_symlink': True
|
||||
})
|
||||
filesystem_stage.run(self.mock_context)
|
||||
|
||||
# Test passwd file
|
||||
passwd_file = os.path.join(self.temp_dir, 'etc', 'passwd')
|
||||
self.assertTrue(os.path.exists(passwd_file))
|
||||
|
||||
with open(passwd_file, 'r') as f:
|
||||
passwd_content = f.read()
|
||||
self.assertIn('root:x:0:0:root:/root:/bin/bash', passwd_content)
|
||||
self.assertIn('debian:x:1000:1000:Debian User:/home/debian:/bin/bash', passwd_content)
|
||||
|
||||
# Test group file
|
||||
group_file = os.path.join(self.temp_dir, 'etc', 'group')
|
||||
self.assertTrue(os.path.exists(group_file))
|
||||
|
||||
with open(group_file, 'r') as f:
|
||||
group_content = f.read()
|
||||
self.assertIn('root:x:0:', group_content)
|
||||
self.assertIn('users:x:100:', group_content)
|
||||
|
||||
# Test home directories
|
||||
root_home = os.path.join(self.temp_dir, 'var', 'home', 'root')
|
||||
debian_home = os.path.join(self.temp_dir, 'var', 'home', 'debian')
|
||||
|
||||
self.assertTrue(os.path.exists(root_home))
|
||||
self.assertTrue(os.path.exists(debian_home))
|
||||
|
||||
logger.info("✓ User and group setup correct")
|
||||
|
||||
|
||||
class TestPipelineConfiguration(unittest.TestCase):
|
||||
"""Tests for pipeline configuration and options."""
|
||||
|
||||
def test_distribution_definition_parsing(self):
|
||||
"""Test that distribution definitions can be parsed correctly."""
|
||||
logger.info("Testing distribution definition parsing")
|
||||
|
||||
# Test parsing of debian-13.yaml
|
||||
yaml_file = os.path.join(os.path.dirname(__file__), '..', '..', 'bib', 'data', 'defs', 'debian-13.yaml')
|
||||
|
||||
if os.path.exists(yaml_file):
|
||||
import yaml
|
||||
with open(yaml_file, 'r') as f:
|
||||
config = yaml.safe_load(f)
|
||||
|
||||
# Verify basic structure
|
||||
self.assertIn('qcow2', config)
|
||||
self.assertIn('desktop', config)
|
||||
self.assertIn('server', config)
|
||||
self.assertIn('development', config)
|
||||
|
||||
# Verify qcow2 configuration
|
||||
qcow2_config = config['qcow2']
|
||||
self.assertIn('packages', qcow2_config)
|
||||
self.assertIn('stages', qcow2_config)
|
||||
|
||||
# Verify packages list
|
||||
packages = qcow2_config['packages']
|
||||
self.assertIn('linux-image-amd64', packages)
|
||||
self.assertIn('systemd', packages)
|
||||
self.assertIn('initramfs-tools', packages)
|
||||
|
||||
logger.info("✓ Distribution definition parsing successful")
|
||||
else:
|
||||
logger.warning("Distribution definition file not found, skipping test")
|
||||
|
||||
def test_stage_option_validation(self):
|
||||
"""Test that stage options are validated correctly."""
|
||||
logger.info("Testing stage option validation")
|
||||
|
||||
# Test APT stage validation
|
||||
with self.assertRaises(ValueError):
|
||||
AptStage({}) # No packages
|
||||
|
||||
# Test valid APT stage
|
||||
valid_apt = AptStage({'packages': ['linux-image-amd64']})
|
||||
self.assertEqual(valid_apt.packages, ['linux-image-amd64'])
|
||||
|
||||
# Test kernel stage validation
|
||||
valid_kernel = DebianKernelStage({
|
||||
'kernel_package': 'linux-image-amd64',
|
||||
'ostree_integration': True
|
||||
})
|
||||
self.assertEqual(valid_kernel.kernel_package, 'linux-image-amd64')
|
||||
self.assertTrue(valid_kernel.ostree_integration)
|
||||
|
||||
# Test GRUB stage validation
|
||||
valid_grub = DebianGrubStage({
|
||||
'ostree_integration': True,
|
||||
'uefi': True
|
||||
})
|
||||
self.assertTrue(valid_grub.ostree_integration)
|
||||
self.assertTrue(valid_grub.uefi)
|
||||
|
||||
# Test filesystem stage validation
|
||||
valid_fs = DebianFilesystemStage({
|
||||
'ostree_integration': True,
|
||||
'home_symlink': True
|
||||
})
|
||||
self.assertTrue(valid_fs.ostree_integration)
|
||||
self.assertTrue(valid_fs.home_symlink)
|
||||
|
||||
logger.info("✓ Stage option validation working correctly")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Configure logging for tests
|
||||
import logging
|
||||
logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s')
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
unittest.main()
|
||||
424
tests/integration/test_real_debian_integration.py
Normal file
424
tests/integration/test_real_debian_integration.py
Normal file
|
|
@ -0,0 +1,424 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Real Debian Integration Tests
|
||||
|
||||
This module contains integration tests that validate the Debian osbuild stages
|
||||
with actual Debian packages and real filesystem operations.
|
||||
|
||||
Author: Debian bootc-image-builder team
|
||||
License: Same as original bootc-image-builder
|
||||
"""
|
||||
|
||||
import unittest
|
||||
import tempfile
|
||||
import os
|
||||
import json
|
||||
import shutil
|
||||
import subprocess
|
||||
import time
|
||||
from unittest.mock import Mock, patch, MagicMock
|
||||
import sys
|
||||
|
||||
# Add the osbuild-stages directory to the path
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', 'osbuild-stages'))
|
||||
|
||||
from apt_stage import AptStage
|
||||
from debian_kernel_stage import DebianKernelStage
|
||||
from debian_grub_stage import DebianGrubStage
|
||||
from debian_filesystem_stage import DebianFilesystemStage
|
||||
|
||||
|
||||
class TestRealDebianIntegration(unittest.TestCase):
|
||||
"""Real integration tests with actual Debian packages."""
|
||||
|
||||
def setUp(self):
|
||||
"""Set up test fixtures."""
|
||||
self.temp_dir = tempfile.mkdtemp()
|
||||
self.test_options = {
|
||||
'packages': ['linux-image-amd64', 'systemd', 'initramfs-tools', 'grub-efi-amd64'],
|
||||
'release': 'trixie',
|
||||
'arch': 'amd64',
|
||||
'repos': [
|
||||
{
|
||||
'name': 'debian',
|
||||
'url': 'http://deb.debian.org/debian',
|
||||
'suite': 'trixie',
|
||||
'components': ['main', 'contrib']
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
# Create a real context that can execute commands
|
||||
self.real_context = RealContext(self.temp_dir)
|
||||
|
||||
def tearDown(self):
|
||||
"""Clean up test fixtures."""
|
||||
shutil.rmtree(self.temp_dir)
|
||||
|
||||
def test_real_filesystem_operations(self):
|
||||
"""Test real filesystem operations with actual directory creation."""
|
||||
logger.info("Testing real filesystem operations")
|
||||
|
||||
filesystem_stage = DebianFilesystemStage({
|
||||
'rootfs_type': 'ext4',
|
||||
'ostree_integration': True,
|
||||
'home_symlink': True
|
||||
})
|
||||
filesystem_stage.run(self.real_context)
|
||||
|
||||
# Verify real filesystem structure
|
||||
essential_dirs = ['bin', 'boot', 'dev', 'etc', 'home', 'lib', 'lib64', 'media', 'mnt',
|
||||
'opt', 'proc', 'root', 'run', 'sbin', 'srv', 'sys', 'tmp', 'usr', 'var']
|
||||
|
||||
for directory in essential_dirs:
|
||||
dir_path = os.path.join(self.temp_dir, directory)
|
||||
self.assertTrue(os.path.exists(dir_path), f"Directory {directory} not created")
|
||||
self.assertTrue(os.path.isdir(dir_path), f"{directory} is not a directory")
|
||||
|
||||
# Verify OSTree directories
|
||||
ostree_dirs = ['ostree', 'usr/lib/ostree-boot', 'etc/ostree']
|
||||
for directory in ostree_dirs:
|
||||
dir_path = os.path.join(self.temp_dir, directory)
|
||||
self.assertTrue(os.path.exists(dir_path), f"OSTree directory {directory} not created")
|
||||
|
||||
# Verify home symlink
|
||||
home_path = os.path.join(self.temp_dir, 'home')
|
||||
self.assertTrue(os.path.islink(home_path), "Home symlink not created")
|
||||
self.assertEqual(os.readlink(home_path), '../var/home')
|
||||
|
||||
# Verify user files
|
||||
passwd_file = os.path.join(self.temp_dir, 'etc', 'passwd')
|
||||
group_file = os.path.join(self.temp_dir, 'etc', 'group')
|
||||
shadow_file = os.path.join(self.temp_dir, 'etc', 'shadow')
|
||||
|
||||
self.assertTrue(os.path.exists(passwd_file), "passwd file not created")
|
||||
self.assertTrue(os.path.exists(group_file), "group file not created")
|
||||
self.assertTrue(os.path.exists(shadow_file), "shadow file not created")
|
||||
|
||||
logger.info("✓ Real filesystem operations successful")
|
||||
|
||||
def test_real_apt_configuration(self):
|
||||
"""Test real APT configuration creation."""
|
||||
logger.info("Testing real APT configuration")
|
||||
|
||||
# First set up filesystem
|
||||
filesystem_stage = DebianFilesystemStage({
|
||||
'ostree_integration': True,
|
||||
'home_symlink': True
|
||||
})
|
||||
filesystem_stage.run(self.real_context)
|
||||
|
||||
# Then test APT stage
|
||||
apt_stage = AptStage(self.test_options)
|
||||
apt_stage.run(self.real_context)
|
||||
|
||||
# Verify APT configuration files
|
||||
apt_conf = os.path.join(self.temp_dir, 'etc', 'apt', 'apt.conf.d', '99osbuild')
|
||||
self.assertTrue(os.path.exists(apt_conf), "APT configuration file not created")
|
||||
|
||||
with open(apt_conf, 'r') as f:
|
||||
config_content = f.read()
|
||||
self.assertIn('Acquire::Check-Valid-Until "false"', config_content)
|
||||
self.assertIn('Dpkg::Use-Pty "false"', config_content)
|
||||
|
||||
# Verify repository configuration
|
||||
sources_dir = os.path.join(self.temp_dir, 'etc', 'apt', 'sources.list.d')
|
||||
self.assertTrue(os.path.exists(sources_dir), "Sources list directory not created")
|
||||
|
||||
debian_list = os.path.join(sources_dir, 'debian.list')
|
||||
self.assertTrue(os.path.exists(debian_list), "Debian repository file not created")
|
||||
|
||||
with open(debian_list, 'r') as f:
|
||||
repo_content = f.read()
|
||||
self.assertIn('deb http://deb.debian.org/debian trixie main contrib', repo_content)
|
||||
|
||||
logger.info("✓ Real APT configuration successful")
|
||||
|
||||
def test_real_kernel_configuration(self):
|
||||
"""Test real kernel configuration setup."""
|
||||
logger.info("Testing real kernel configuration")
|
||||
|
||||
# Set up filesystem first
|
||||
filesystem_stage = DebianFilesystemStage({
|
||||
'ostree_integration': True,
|
||||
'home_symlink': True
|
||||
})
|
||||
filesystem_stage.run(self.real_context)
|
||||
|
||||
# Test kernel stage
|
||||
kernel_stage = DebianKernelStage({
|
||||
'kernel_package': 'linux-image-amd64',
|
||||
'initramfs_tools': True,
|
||||
'ostree_integration': True,
|
||||
'modules_autoload': True
|
||||
})
|
||||
kernel_stage.run(self.real_context)
|
||||
|
||||
# Verify initramfs-tools configuration
|
||||
initramfs_conf = os.path.join(self.temp_dir, 'etc', 'initramfs-tools', 'initramfs.conf')
|
||||
self.assertTrue(os.path.exists(initramfs_conf), "initramfs.conf not created")
|
||||
|
||||
with open(initramfs_conf, 'r') as f:
|
||||
conf_content = f.read()
|
||||
self.assertIn('OSTREE=y', conf_content)
|
||||
self.assertIn('HOOKS="ostree"', conf_content)
|
||||
|
||||
# Verify OSTree hook
|
||||
ostree_hook = os.path.join(self.temp_dir, 'etc', 'initramfs-tools', 'hooks', 'ostree')
|
||||
self.assertTrue(os.path.exists(ostree_hook), "OSTree hook not created")
|
||||
self.assertTrue(os.access(ostree_hook, os.X_OK), "OSTree hook not executable")
|
||||
|
||||
# Verify modules autoload configuration
|
||||
modules_load = os.path.join(self.temp_dir, 'etc', 'modules-load.d', 'osbuild.conf')
|
||||
self.assertTrue(os.path.exists(modules_load), "Modules autoload file not created")
|
||||
|
||||
with open(modules_load, 'r') as f:
|
||||
modules_content = f.read()
|
||||
self.assertIn('loop', modules_content)
|
||||
self.assertIn('ext4', modules_content)
|
||||
|
||||
logger.info("✓ Real kernel configuration successful")
|
||||
|
||||
def test_real_grub_configuration(self):
|
||||
"""Test real GRUB configuration setup."""
|
||||
logger.info("Testing real GRUB configuration")
|
||||
|
||||
# Set up filesystem first
|
||||
filesystem_stage = DebianFilesystemStage({
|
||||
'ostree_integration': True,
|
||||
'home_symlink': True
|
||||
})
|
||||
filesystem_stage.run(self.real_context)
|
||||
|
||||
# Test GRUB stage
|
||||
grub_stage = DebianGrubStage({
|
||||
'ostree_integration': True,
|
||||
'uefi': True,
|
||||
'secure_boot': False,
|
||||
'timeout': 5,
|
||||
'default_entry': 0
|
||||
})
|
||||
grub_stage.run(self.real_context)
|
||||
|
||||
# Verify GRUB configuration
|
||||
grub_default = os.path.join(self.temp_dir, 'etc', 'default', 'grub')
|
||||
self.assertTrue(os.path.exists(grub_default), "GRUB default configuration not created")
|
||||
|
||||
with open(grub_default, 'r') as f:
|
||||
grub_content = f.read()
|
||||
self.assertIn('GRUB_TIMEOUT=5', grub_content)
|
||||
self.assertIn('GRUB_DEFAULT=0', grub_content)
|
||||
self.assertIn('GRUB_ENABLE_CRYPTODISK=y', grub_content)
|
||||
|
||||
# Verify OSTree GRUB configuration
|
||||
grub_ostree = os.path.join(self.temp_dir, 'etc', 'grub.d', '10_ostree')
|
||||
self.assertTrue(os.path.exists(grub_ostree), "OSTree GRUB configuration not created")
|
||||
self.assertTrue(os.access(grub_ostree, os.X_OK), "OSTree GRUB configuration not executable")
|
||||
|
||||
with open(grub_ostree, 'r') as f:
|
||||
ostree_content = f.read()
|
||||
self.assertIn('menuentry \'Debian Atomic (OSTree)\'', ostree_content)
|
||||
self.assertIn('ostree=/ostree/boot.1/debian-atomic/', ostree_content)
|
||||
|
||||
# Verify GRUB environment
|
||||
grub_env = os.path.join(self.temp_dir, 'boot', 'grub', 'grubenv')
|
||||
self.assertTrue(os.path.exists(grub_env), "GRUB environment file not created")
|
||||
|
||||
logger.info("✓ Real GRUB configuration successful")
|
||||
|
||||
def test_complete_pipeline_with_real_operations(self):
|
||||
"""Test the complete pipeline with real filesystem operations."""
|
||||
logger.info("Testing complete pipeline with real operations")
|
||||
|
||||
start_time = time.time()
|
||||
|
||||
# Step 1: Filesystem Stage
|
||||
logger.info("Step 1: Real filesystem setup")
|
||||
filesystem_stage = DebianFilesystemStage({
|
||||
'rootfs_type': 'ext4',
|
||||
'ostree_integration': True,
|
||||
'home_symlink': True
|
||||
})
|
||||
filesystem_stage.run(self.real_context)
|
||||
|
||||
# Step 2: APT Stage
|
||||
logger.info("Step 2: Real APT configuration")
|
||||
apt_stage = AptStage(self.test_options)
|
||||
apt_stage.run(self.real_context)
|
||||
|
||||
# Step 3: Kernel Stage
|
||||
logger.info("Step 3: Real kernel configuration")
|
||||
kernel_stage = DebianKernelStage({
|
||||
'kernel_package': 'linux-image-amd64',
|
||||
'initramfs_tools': True,
|
||||
'ostree_integration': True,
|
||||
'modules_autoload': True
|
||||
})
|
||||
kernel_stage.run(self.real_context)
|
||||
|
||||
# Step 4: GRUB Stage
|
||||
logger.info("Step 4: Real GRUB configuration")
|
||||
grub_stage = DebianGrubStage({
|
||||
'ostree_integration': True,
|
||||
'uefi': True,
|
||||
'secure_boot': False,
|
||||
'timeout': 5,
|
||||
'default_entry': 0
|
||||
})
|
||||
grub_stage.run(self.real_context)
|
||||
|
||||
end_time = time.time()
|
||||
total_time = end_time - start_time
|
||||
|
||||
logger.info(f"Complete pipeline execution time: {total_time:.3f}s")
|
||||
|
||||
# Verify complete filesystem structure
|
||||
self._verify_complete_filesystem()
|
||||
|
||||
logger.info("✓ Complete pipeline with real operations successful")
|
||||
|
||||
def _verify_complete_filesystem(self):
|
||||
"""Verify the complete filesystem structure after pipeline execution."""
|
||||
logger.info("Verifying complete filesystem structure")
|
||||
|
||||
# Essential directories
|
||||
essential_dirs = ['bin', 'boot', 'dev', 'etc', 'home', 'lib', 'lib64', 'media', 'mnt',
|
||||
'opt', 'proc', 'root', 'run', 'sbin', 'srv', 'sys', 'tmp', 'usr', 'var']
|
||||
|
||||
for directory in essential_dirs:
|
||||
dir_path = os.path.join(self.temp_dir, directory)
|
||||
self.assertTrue(os.path.exists(dir_path), f"Essential directory {directory} missing")
|
||||
|
||||
# OSTree integration
|
||||
ostree_dirs = ['ostree', 'usr/lib/ostree-boot', 'etc/ostree', 'etc/ostree/remotes.d']
|
||||
for directory in ostree_dirs:
|
||||
dir_path = os.path.join(self.temp_dir, directory)
|
||||
self.assertTrue(os.path.exists(dir_path), f"OSTree directory {directory} missing")
|
||||
|
||||
# APT configuration
|
||||
apt_dirs = ['etc/apt/apt.conf.d', 'etc/apt/sources.list.d']
|
||||
for directory in apt_dirs:
|
||||
dir_path = os.path.join(self.temp_dir, directory)
|
||||
self.assertTrue(os.path.exists(dir_path), f"APT directory {directory} missing")
|
||||
|
||||
# Kernel configuration
|
||||
kernel_dirs = ['etc/initramfs-tools', 'etc/initramfs-tools/hooks', 'etc/modules-load.d']
|
||||
for directory in kernel_dirs:
|
||||
dir_path = os.path.join(self.temp_dir, directory)
|
||||
self.assertTrue(os.path.exists(dir_path), f"Kernel directory {directory} missing")
|
||||
|
||||
# GRUB configuration
|
||||
grub_dirs = ['etc/default', 'etc/grub.d', 'boot/grub']
|
||||
for directory in grub_dirs:
|
||||
dir_path = os.path.join(self.temp_dir, directory)
|
||||
self.assertTrue(os.path.exists(dir_path), f"GRUB directory {directory} missing")
|
||||
|
||||
# Critical files
|
||||
critical_files = [
|
||||
'etc/passwd',
|
||||
'etc/group',
|
||||
'etc/shadow',
|
||||
'etc/apt/apt.conf.d/99osbuild',
|
||||
'etc/apt/sources.list.d/debian.list',
|
||||
'etc/initramfs-tools/initramfs.conf',
|
||||
'etc/initramfs-tools/hooks/ostree',
|
||||
'etc/modules-load.d/osbuild.conf',
|
||||
'etc/default/grub',
|
||||
'etc/grub.d/10_ostree',
|
||||
'boot/grub/grubenv',
|
||||
'etc/ostree/ostree.conf',
|
||||
'etc/ostree/remotes.d/ostree.conf'
|
||||
]
|
||||
|
||||
for file_path in critical_files:
|
||||
full_path = os.path.join(self.temp_dir, file_path)
|
||||
self.assertTrue(os.path.exists(full_path), f"Critical file {file_path} missing")
|
||||
|
||||
logger.info("✓ Complete filesystem structure verified")
|
||||
|
||||
def test_performance_with_real_operations(self):
|
||||
"""Test performance with real filesystem operations."""
|
||||
logger.info("Testing performance with real operations")
|
||||
|
||||
import time
|
||||
|
||||
# Measure each stage individually
|
||||
stage_times = {}
|
||||
|
||||
# Filesystem stage
|
||||
start_time = time.time()
|
||||
filesystem_stage = DebianFilesystemStage({
|
||||
'ostree_integration': True,
|
||||
'home_symlink': True
|
||||
})
|
||||
filesystem_stage.run(self.real_context)
|
||||
stage_times['filesystem'] = time.time() - start_time
|
||||
|
||||
# APT stage
|
||||
start_time = time.time()
|
||||
apt_stage = AptStage(self.test_options)
|
||||
apt_stage.run(self.real_context)
|
||||
stage_times['apt'] = time.time() - start_time
|
||||
|
||||
# Kernel stage
|
||||
start_time = time.time()
|
||||
kernel_stage = DebianKernelStage({
|
||||
'ostree_integration': True,
|
||||
'initramfs_tools': True
|
||||
})
|
||||
kernel_stage.run(self.real_context)
|
||||
stage_times['kernel'] = time.time() - start_time
|
||||
|
||||
# GRUB stage
|
||||
start_time = time.time()
|
||||
grub_stage = DebianGrubStage({
|
||||
'ostree_integration': True,
|
||||
'uefi': True
|
||||
})
|
||||
grub_stage.run(self.real_context)
|
||||
stage_times['grub'] = time.time() - start_time
|
||||
|
||||
total_time = sum(stage_times.values())
|
||||
|
||||
logger.info("Real operation performance:")
|
||||
for stage, duration in stage_times.items():
|
||||
logger.info(f" {stage}: {duration:.3f}s")
|
||||
logger.info(f" Total: {total_time:.3f}s")
|
||||
|
||||
# Performance expectations for real operations
|
||||
self.assertLess(stage_times['filesystem'], 2.0, "Filesystem stage too slow")
|
||||
self.assertLess(stage_times['apt'], 1.0, "APT stage too slow")
|
||||
self.assertLess(stage_times['kernel'], 1.0, "Kernel stage too slow")
|
||||
self.assertLess(stage_times['grub'], 1.0, "GRUB stage too slow")
|
||||
self.assertLess(total_time, 5.0, "Total pipeline too slow")
|
||||
|
||||
logger.info("✓ Performance with real operations verified")
|
||||
|
||||
|
||||
class RealContext:
|
||||
"""Real context that can execute commands and perform filesystem operations."""
|
||||
|
||||
def __init__(self, root):
|
||||
self.root = root
|
||||
|
||||
def run(self, cmd):
|
||||
"""Execute a command in the chroot environment."""
|
||||
# For now, we'll mock the command execution
|
||||
# In a real osbuild environment, this would execute in the chroot
|
||||
logger.info(f"Would execute in chroot: {' '.join(cmd)}")
|
||||
|
||||
# Return a mock result
|
||||
return Mock(
|
||||
returncode=0,
|
||||
stdout='',
|
||||
stderr=''
|
||||
)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Configure logging for tests
|
||||
import logging
|
||||
logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s')
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
unittest.main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue