debian-forge/debian-forge-tests/test-composer-build-management.py
robojerk 502e1469ae
Some checks failed
Checks / Spelling (push) Has been cancelled
Checks / Python Linters (push) Has been cancelled
Checks / Shell Linters (push) Has been cancelled
Checks / 📦 Packit config lint (push) Has been cancelled
Checks / 🔍 Check for valid snapshot urls (push) Has been cancelled
Checks / 🔍 Check JSON files for formatting consistency (push) Has been cancelled
Generate / Documentation (push) Has been cancelled
Generate / Test Data (push) Has been cancelled
Tests / Unittest (push) Has been cancelled
Tests / Assembler test (legacy) (push) Has been cancelled
Tests / Smoke run: unittest as normal user on default runner (push) Has been cancelled
Move composer scripts to root directory and add comprehensive Debian Atomic support
2025-08-23 08:02:45 -07:00

376 lines
12 KiB
Python

#!/usr/bin/env python3
"""
Test Composer Build Management for Debian Forge
This script tests the composer build management components including
status monitoring and build history.
"""
import json
import os
import sys
import tempfile
import time
from pathlib import Path
from datetime import datetime
# Add current directory to Python path
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
def test_status_monitor_import():
"""Test importing the status monitor"""
print("Testing status monitor import...")
try:
from composer_status_monitor import StatusMonitor, StatusNotifier, ConsoleStatusDisplay, BuildProgress, BuildStatus
print(" ✅ Status monitor imported successfully")
return True
except ImportError as e:
print(f" ❌ Failed to import status monitor: {e}")
return False
def test_build_history_import():
"""Test importing the build history"""
print("\nTesting build history import...")
try:
from composer_build_history import BuildHistoryDB, BuildHistoryManager, BuildRecord
print(" ✅ Build history imported successfully")
return True
except ImportError as e:
print(f" ❌ Failed to import build history: {e}")
return False
def test_build_progress_dataclass():
"""Test BuildProgress dataclass"""
print("\nTesting BuildProgress dataclass...")
try:
from composer_status_monitor import BuildProgress
progress = BuildProgress(
stage="debootstrap",
progress=0.5,
message="Installing base system",
timestamp=datetime.now()
)
if progress.stage != "debootstrap":
print(" ❌ Stage field not set correctly")
return False
if progress.progress != 0.5:
print(" ❌ Progress field not set correctly")
return False
print(" ✅ BuildProgress dataclass works correctly")
return True
except Exception as e:
print(f" ❌ BuildProgress test failed: {e}")
return False
def test_build_status_dataclass():
"""Test BuildStatus dataclass"""
print("\nTesting BuildStatus dataclass...")
try:
from composer_status_monitor import BuildStatus, BuildProgress
progress_list = [
BuildProgress("debootstrap", 0.5, "Installing base system", datetime.now())
]
status = BuildStatus(
build_id="test-123",
status="RUNNING",
created_at=datetime.now(),
updated_at=datetime.now(),
blueprint="debian-atomic-base",
target="qcow2",
architecture="amd64",
progress=progress_list,
logs=["Build started", "Debootstrap in progress"]
)
if status.build_id != "test-123":
print(" ❌ Build ID field not set correctly")
return False
if len(status.progress) != 1:
print(" ❌ Progress list not set correctly")
return False
print(" ✅ BuildStatus dataclass works correctly")
return True
except Exception as e:
print(f" ❌ BuildStatus test failed: {e}")
return False
def test_build_record_dataclass():
"""Test BuildRecord dataclass"""
print("\nTesting BuildRecord dataclass...")
try:
from composer_build_history import BuildRecord
record = BuildRecord(
build_id="test-123",
blueprint="debian-atomic-base",
target="qcow2",
architecture="amd64",
status="FINISHED",
created_at=datetime.now(),
completed_at=datetime.now(),
duration=120.5,
metadata={"priority": "normal"},
logs=["Build completed successfully"],
artifacts=["debian-atomic-base.qcow2"],
error_message=None
)
if record.build_id != "test-123":
print(" ❌ Build ID field not set correctly")
return False
if record.duration != 120.5:
print(" ❌ Duration field not set correctly")
return False
print(" ✅ BuildRecord dataclass works correctly")
return True
except Exception as e:
print(f" ❌ BuildRecord test failed: {e}")
return False
def test_build_history_database():
"""Test build history database operations"""
print("\nTesting build history database...")
try:
from composer_build_history import BuildHistoryDB, BuildRecord
# Create temporary database
with tempfile.NamedTemporaryFile(suffix='.db', delete=False) as f:
db_path = f.name
try:
db = BuildHistoryDB(db_path)
# Test adding a build record
record = BuildRecord(
build_id="test-db-123",
blueprint="debian-atomic-base",
target="qcow2",
architecture="amd64",
status="RUNNING",
created_at=datetime.now(),
completed_at=None,
duration=None,
metadata={},
logs=[],
artifacts=[],
error_message=None
)
if not db.add_build(record):
print(" ❌ Failed to add build record")
return False
# Test retrieving the build record
retrieved = db.get_build("test-db-123")
if not retrieved:
print(" ❌ Failed to retrieve build record")
return False
if retrieved.build_id != "test-db-123":
print(" ❌ Retrieved build ID doesn't match")
return False
# Test updating build status
if not db.update_build_status("test-db-123", status="FINISHED", duration=60.0):
print(" ❌ Failed to update build status")
return False
# Test statistics
stats = db.get_build_statistics()
if stats['total_builds'] != 1:
print(" ❌ Statistics not working correctly")
return False
print(" ✅ Build history database works correctly")
return True
finally:
# Clean up
os.unlink(db_path)
except Exception as e:
print(f" ❌ Build history database test failed: {e}")
return False
def test_build_history_manager():
"""Test build history manager"""
print("\nTesting build history manager...")
try:
from composer_build_history import BuildHistoryManager
# Create temporary database
with tempfile.NamedTemporaryFile(suffix='.db', delete=False) as f:
db_path = f.name
try:
manager = BuildHistoryManager(db_path)
# Test starting a build
if not manager.start_build("test-manager-123", "debian-atomic-base", "qcow2", "amd64"):
print(" ❌ Failed to start build")
return False
# Test updating build progress
if not manager.update_build_progress("test-manager-123", "RUNNING", logs=["Build in progress"]):
print(" ❌ Failed to update build progress")
return False
# Test completing a build
if not manager.update_build_progress("test-manager-123", "FINISHED", artifacts=["image.qcow2"]):
print(" ❌ Failed to complete build")
return False
# Test getting build summary
summary = manager.get_build_summary()
if summary['total_builds'] != 1:
print(" ❌ Build summary not working correctly")
return False
print(" ✅ Build history manager works correctly")
return True
finally:
# Clean up
os.unlink(db_path)
except Exception as e:
print(f" ❌ Build history manager test failed: {e}")
return False
def test_status_notifier():
"""Test status notifier"""
print("\nTesting status notifier...")
try:
from composer_status_monitor import StatusNotifier
notifier = StatusNotifier()
# Test notification
notifier.notify("build_completed", "Build test-123 completed successfully")
# Test notification history
history = notifier.get_notification_history()
if len(history) != 1:
print(" ❌ Notification history not working correctly")
return False
if history[0]['type'] != "build_completed":
print(" ❌ Notification type not set correctly")
return False
print(" ✅ Status notifier works correctly")
return True
except Exception as e:
print(f" ❌ Status notifier test failed: {e}")
return False
def test_console_status_display():
"""Test console status display"""
print("\nTesting console status display...")
try:
from composer_status_monitor import ConsoleStatusDisplay, BuildStatus, BuildProgress
display = ConsoleStatusDisplay()
# Create test build status
progress_list = [
BuildProgress("debootstrap", 0.75, "Installing packages", datetime.now())
]
status = BuildStatus(
build_id="test-display-123",
status="RUNNING",
created_at=datetime.now(),
updated_at=datetime.now(),
blueprint="debian-atomic-base",
target="qcow2",
architecture="amd64",
progress=progress_list,
logs=["Build started", "Debootstrap in progress"],
metadata=None
)
# Test display (this should not fail)
display.display_build_status(status)
print(" ✅ Console status display works correctly")
return True
except Exception as e:
print(f" ❌ Console status display test failed: {e}")
return False
def main():
"""Main test function"""
print("Composer Build Management Test for Debian Forge")
print("=" * 60)
tests = [
("Status Monitor Import", test_status_monitor_import),
("Build History Import", test_build_history_import),
("BuildProgress Dataclass", test_build_progress_dataclass),
("BuildStatus Dataclass", test_build_status_dataclass),
("BuildRecord Dataclass", test_build_record_dataclass),
("Build History Database", test_build_history_database),
("Build History Manager", test_build_history_manager),
("Status Notifier", test_status_notifier),
("Console Status Display", test_console_status_display)
]
results = []
for test_name, test_func in tests:
try:
result = test_func()
results.append((test_name, result))
except Exception as e:
print(f"{test_name} test failed with exception: {e}")
results.append((test_name, False))
# Summary
print("\n" + "=" * 60)
print("TEST SUMMARY")
print("=" * 60)
passed = 0
total = len(results)
for test_name, result in results:
status = "✅ PASS" if result else "❌ FAIL"
print(f"{test_name}: {status}")
if result:
passed += 1
print(f"\nOverall: {passed}/{total} tests passed")
if passed == total:
print("🎉 All tests passed! Composer build management is ready.")
return 0
else:
print("⚠️ Some tests failed. Please review the issues above.")
return 1
if __name__ == '__main__':
sys.exit(main())