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
376 lines
12 KiB
Python
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())
|