274 lines
9.2 KiB
Python
274 lines
9.2 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Test the test utilities for deb-bootc-image-builder.
|
|
|
|
This module tests the test utility functions and classes,
|
|
including:
|
|
- Test data generation
|
|
- Mock objects
|
|
- Helper functions
|
|
- Debian-specific utilities
|
|
"""
|
|
|
|
import pytest
|
|
import os
|
|
import tempfile
|
|
import shutil
|
|
import json
|
|
import time
|
|
from unittest.mock import Mock, patch
|
|
import logging
|
|
|
|
# Configure logging
|
|
logging.basicConfig(level=logging.INFO)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class TestTestUtilities:
|
|
"""Test cases for test utility functions and classes."""
|
|
|
|
def test_test_data_generator(self, work_dir):
|
|
"""Test the TestDataGenerator class."""
|
|
from testutil import TestDataGenerator
|
|
|
|
# Test Debian package list generation
|
|
packages = TestDataGenerator.create_debian_package_list()
|
|
assert isinstance(packages, list)
|
|
assert len(packages) > 0
|
|
|
|
# Check for essential Debian packages
|
|
essential_packages = ["linux-image-amd64", "systemd", "ostree"]
|
|
for pkg in essential_packages:
|
|
assert pkg in packages, f"Essential package {pkg} missing"
|
|
|
|
# Test repository configuration
|
|
repo_config = TestDataGenerator.create_debian_repository_config()
|
|
assert "release" in repo_config
|
|
assert "arch" in repo_config
|
|
assert "repos" in repo_config
|
|
assert repo_config["release"] == "trixie"
|
|
assert repo_config["arch"] == "amd64"
|
|
|
|
# Test OSTree configuration
|
|
ostree_config = TestDataGenerator.create_ostree_config()
|
|
assert "mode" in ostree_config
|
|
assert "repo" in ostree_config
|
|
assert ostree_config["mode"] == "bare-user-only"
|
|
|
|
# Test GRUB configuration
|
|
grub_config = TestDataGenerator.create_grub_config()
|
|
assert "uefi" in grub_config
|
|
assert "timeout" in grub_config
|
|
assert grub_config["uefi"] is True
|
|
|
|
def test_mock_container_image(self, work_dir):
|
|
"""Test the MockContainerImage class."""
|
|
from testutil import MockContainerImage
|
|
|
|
# Test default labels
|
|
image = MockContainerImage()
|
|
labels = image.get_labels()
|
|
|
|
assert "com.debian.bootc" in labels
|
|
assert "ostree.bootable" in labels
|
|
assert labels["com.debian.bootc"] == "true"
|
|
assert labels["ostree.bootable"] == "true"
|
|
|
|
# Test custom labels
|
|
custom_labels = {
|
|
"com.debian.bootc": "true",
|
|
"version": "2.0",
|
|
"custom.label": "value"
|
|
}
|
|
image = MockContainerImage(custom_labels)
|
|
|
|
assert image.get_labels() == custom_labels
|
|
assert image.get_ref() == "debian:trixie"
|
|
assert image.get_arch() == "amd64"
|
|
assert image.get_os() == "linux"
|
|
|
|
def test_mock_ostree_repo(self, work_dir):
|
|
"""Test the MockOSTreeRepo class."""
|
|
from testutil import MockOSTreeRepo
|
|
|
|
# Test repository creation
|
|
repo = MockOSTreeRepo("/tmp/test-repo")
|
|
|
|
assert repo.path == "/tmp/test-repo"
|
|
assert len(repo.list_refs()) > 0
|
|
assert "debian/trixie/amd64" in repo.list_refs()
|
|
|
|
# Test deployment info
|
|
deployment_info = repo.get_deployment_info("debian/trixie/amd64")
|
|
assert deployment_info is not None
|
|
assert deployment_info["ref"] == "debian/trixie/amd64"
|
|
assert deployment_info["osname"] == "debian"
|
|
assert deployment_info["bootable"] is True
|
|
|
|
# Test non-existent deployment
|
|
non_existent = repo.get_deployment_info("non-existent")
|
|
assert non_existent is None
|
|
|
|
def test_test_environment(self, work_dir):
|
|
"""Test the TestEnvironment class."""
|
|
from testutil import TestEnvironment
|
|
|
|
# Create test environment
|
|
env = TestEnvironment(work_dir)
|
|
|
|
# Test setup
|
|
env.setup()
|
|
|
|
# Check that directories were created
|
|
expected_dirs = ["etc", "var", "home", "boot", "usr", "var/lib", "var/lib/ostree", "var/home"]
|
|
for expected_dir in expected_dirs:
|
|
full_path = os.path.join(work_dir, expected_dir)
|
|
assert os.path.exists(full_path), f"Directory {expected_dir} not created"
|
|
|
|
# Check /home symlink
|
|
home_link = os.path.join(work_dir, "home")
|
|
var_home = os.path.join(work_dir, "var", "home")
|
|
assert os.path.islink(home_link), "/home symlink not created"
|
|
assert os.path.realpath(home_link) == var_home
|
|
|
|
# Test file creation
|
|
test_file = env.create_test_file("test.txt", "test content")
|
|
assert os.path.exists(test_file)
|
|
|
|
with open(test_file, 'r') as f:
|
|
content = f.read()
|
|
assert content == "test content"
|
|
|
|
# Test directory creation
|
|
test_dir = env.create_test_directory("test_dir")
|
|
assert os.path.exists(test_dir)
|
|
assert os.path.isdir(test_dir)
|
|
|
|
# Test teardown
|
|
env.teardown()
|
|
# Note: teardown only changes directory, doesn't remove files
|
|
|
|
def test_utility_functions(self, work_dir):
|
|
"""Test utility functions."""
|
|
from testutil import (
|
|
create_temp_manifest,
|
|
cleanup_temp_files,
|
|
assert_filesystem_structure,
|
|
assert_file_contents,
|
|
create_mock_context
|
|
)
|
|
|
|
# Test manifest creation
|
|
manifest_data = {
|
|
"pipeline": {
|
|
"build": {"name": "test"},
|
|
"stages": []
|
|
}
|
|
}
|
|
|
|
manifest_file = create_temp_manifest(manifest_data)
|
|
assert os.path.exists(manifest_file)
|
|
|
|
# Test manifest loading
|
|
with open(manifest_file, 'r') as f:
|
|
loaded_data = json.load(f)
|
|
assert loaded_data == manifest_data
|
|
|
|
# Test cleanup
|
|
cleanup_temp_files(manifest_file)
|
|
assert not os.path.exists(manifest_file)
|
|
|
|
# Test filesystem structure assertion
|
|
test_dir = os.path.join(work_dir, "test_structure")
|
|
os.makedirs(test_dir, exist_ok=True)
|
|
os.makedirs(os.path.join(test_dir, "etc"), exist_ok=True)
|
|
os.makedirs(os.path.join(test_dir, "var"), exist_ok=True)
|
|
|
|
assert_filesystem_structure(test_dir, ["/etc", "/var"])
|
|
|
|
# Test file contents assertion
|
|
test_file = os.path.join(test_dir, "test.txt")
|
|
with open(test_file, 'w') as f:
|
|
f.write("test content")
|
|
|
|
assert_file_contents(test_file, "test content")
|
|
|
|
# Test mock context creation
|
|
context = create_mock_context()
|
|
assert context.root == "/tmp/mock-root"
|
|
assert hasattr(context, 'run')
|
|
|
|
# Test mock context run method
|
|
result = context.run("test command")
|
|
assert result.returncode == 0
|
|
assert result.stdout == b"mock output"
|
|
|
|
def test_debian_specific_utilities(self, work_dir):
|
|
"""Test Debian-specific utility functions."""
|
|
from testutil import TestDataGenerator
|
|
|
|
# Test Debian filesystem configuration
|
|
fs_config = TestDataGenerator.create_filesystem_config()
|
|
|
|
assert "rootfs_type" in fs_config
|
|
assert "ostree_integration" in fs_config
|
|
assert "home_symlink" in fs_config
|
|
assert "users" in fs_config
|
|
assert "permissions" in fs_config
|
|
|
|
assert fs_config["rootfs_type"] == "ext4"
|
|
assert fs_config["ostree_integration"] is True
|
|
assert fs_config["home_symlink"] is True
|
|
|
|
# Test user configuration
|
|
users = fs_config["users"]
|
|
assert len(users) > 0
|
|
assert "name" in users[0]
|
|
assert "password" in users[0]
|
|
assert "groups" in users[0]
|
|
|
|
# Test permission configuration
|
|
permissions = fs_config["permissions"]
|
|
assert "/etc/ostree" in permissions
|
|
assert "/var/lib/ostree" in permissions
|
|
assert permissions["/etc/ostree"] == "755"
|
|
|
|
def test_error_handling(self, work_dir):
|
|
"""Test error handling in utility functions."""
|
|
from testutil import cleanup_temp_files, assert_file_contents
|
|
|
|
# Test cleanup with non-existent file
|
|
cleanup_temp_files("/non/existent/file")
|
|
# Should not raise an exception
|
|
|
|
# Test file contents assertion with non-existent file
|
|
with pytest.raises(AssertionError):
|
|
assert_file_contents("/non/existent/file", "content")
|
|
|
|
def test_performance_utilities(self, work_dir):
|
|
"""Test performance-related utilities."""
|
|
from testutil import create_mock_context
|
|
|
|
# Test multiple context creation
|
|
start_time = time.time()
|
|
contexts = []
|
|
|
|
for i in range(100):
|
|
context = create_mock_context()
|
|
contexts.append(context)
|
|
|
|
end_time = time.time()
|
|
creation_time = end_time - start_time
|
|
|
|
# Should be reasonably fast
|
|
assert creation_time < 1.0, f"Context creation took too long: {creation_time}s"
|
|
assert len(contexts) == 100
|
|
|
|
# Test context functionality
|
|
for context in contexts:
|
|
result = context.run("test")
|
|
assert result.returncode == 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
pytest.main([__file__])
|