302 lines
10 KiB
Python
302 lines
10 KiB
Python
#!/usr/bin/python3
|
|
"""
|
|
Test OSTree Composition for Debian Atomic
|
|
|
|
This script tests the OSTree composition functionality to ensure
|
|
Debian packages can be properly converted to atomic commits.
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
import subprocess
|
|
import tempfile
|
|
import json
|
|
import shutil
|
|
|
|
|
|
def test_ostree_availability():
|
|
"""Test if ostree is available and working"""
|
|
print("Testing OSTree availability...")
|
|
|
|
try:
|
|
result = subprocess.run(["ostree", "--version"],
|
|
capture_output=True, text=True, check=True)
|
|
print(f"✅ ostree is available: {result.stdout.strip()}")
|
|
return True
|
|
except subprocess.CalledProcessError as e:
|
|
print(f"❌ ostree command failed: {e}")
|
|
return False
|
|
except FileNotFoundError:
|
|
print("❌ ostree not found in PATH")
|
|
return False
|
|
|
|
|
|
def test_ostree_repo_creation():
|
|
"""Test OSTree repository creation"""
|
|
print("Testing OSTree repository creation...")
|
|
|
|
with tempfile.TemporaryDirectory() as temp_dir:
|
|
repo_path = os.path.join(temp_dir, "test-repo")
|
|
|
|
try:
|
|
# Create repository
|
|
result = subprocess.run(["ostree", "init", "--repo", repo_path],
|
|
capture_output=True, text=True, check=True)
|
|
print(f"✅ Repository created at {repo_path}")
|
|
|
|
# Check repository structure
|
|
if os.path.exists(os.path.join(repo_path, "config")):
|
|
print("✅ Repository config exists")
|
|
else:
|
|
print("❌ Repository config missing")
|
|
return False
|
|
|
|
return True
|
|
|
|
except subprocess.CalledProcessError as e:
|
|
print(f"❌ Repository creation failed: {e}")
|
|
print(f"stderr: {e.stderr}")
|
|
return False
|
|
|
|
|
|
def test_ostree_commit_creation():
|
|
"""Test OSTree commit creation from filesystem"""
|
|
print("Testing OSTree commit creation...")
|
|
|
|
with tempfile.TemporaryDirectory() as temp_dir:
|
|
repo_path = os.path.join(temp_dir, "test-repo")
|
|
tree_path = os.path.join(temp_dir, "test-tree")
|
|
|
|
try:
|
|
# Create repository
|
|
subprocess.run(["ostree", "init", "--repo", repo_path], check=True)
|
|
|
|
# Create test filesystem tree
|
|
os.makedirs(tree_path, exist_ok=True)
|
|
os.makedirs(os.path.join(tree_path, "etc"), exist_ok=True)
|
|
os.makedirs(os.path.join(tree_path, "usr"), exist_ok=True)
|
|
|
|
# Create test files
|
|
with open(os.path.join(tree_path, "etc", "test.conf"), "w") as f:
|
|
f.write("# Test configuration\n")
|
|
|
|
with open(os.path.join(tree_path, "usr", "test.txt"), "w") as f:
|
|
f.write("Test content\n")
|
|
|
|
# Create commit
|
|
cmd = [
|
|
"ostree", "commit",
|
|
"--repo", repo_path,
|
|
"--branch", "test/debian",
|
|
"--subject", "Test Debian commit",
|
|
tree_path
|
|
]
|
|
|
|
result = subprocess.run(cmd, capture_output=True, text=True, check=True)
|
|
commit_hash = result.stdout.strip()
|
|
|
|
print(f"✅ Commit created: {commit_hash}")
|
|
|
|
# Verify commit exists
|
|
result = subprocess.run(["ostree", "show", "--repo", repo_path, commit_hash],
|
|
capture_output=True, text=True, check=True)
|
|
print("✅ Commit verification successful")
|
|
|
|
return True
|
|
|
|
except subprocess.CalledProcessError as e:
|
|
print(f"❌ Commit creation failed: {e}")
|
|
print(f"stderr: {e.stderr}")
|
|
return False
|
|
|
|
|
|
def test_debian_ostree_stage():
|
|
"""Test the Debian OSTree stage functionality"""
|
|
print("Testing Debian OSTree stage...")
|
|
|
|
# Check if stage file exists
|
|
stage_file = "stages/org.osbuild.ostree.commit.py"
|
|
if not os.path.exists(stage_file):
|
|
print(f"❌ Stage file not found: {stage_file}")
|
|
return False
|
|
|
|
print(f"✅ Stage file exists: {stage_file}")
|
|
|
|
# Check if metadata file exists
|
|
meta_file = "stages/org.osbuild.ostree.commit.meta.json"
|
|
if not os.path.exists(meta_file):
|
|
print(f"❌ Metadata file not found: {meta_file}")
|
|
return False
|
|
|
|
print(f"✅ Metadata file exists: {meta_file}")
|
|
|
|
# Validate metadata JSON
|
|
try:
|
|
with open(meta_file, 'r') as f:
|
|
metadata = json.load(f)
|
|
|
|
required_fields = ["name", "version", "description", "options"]
|
|
for field in required_fields:
|
|
if field not in metadata:
|
|
print(f"❌ Missing required field: {field}")
|
|
return False
|
|
|
|
print("✅ Metadata validation passed")
|
|
return True
|
|
|
|
except json.JSONDecodeError as e:
|
|
print(f"❌ Invalid JSON in metadata: {e}")
|
|
return False
|
|
except Exception as e:
|
|
print(f"❌ Metadata validation failed: {e}")
|
|
return False
|
|
|
|
|
|
def test_ostree_deploy_stage():
|
|
"""Test the OSTree deploy stage"""
|
|
print("Testing OSTree deploy stage...")
|
|
|
|
# Check if stage file exists
|
|
stage_file = "stages/org.osbuild.ostree.deploy.py"
|
|
if not os.path.exists(stage_file):
|
|
print(f"❌ Deploy stage file not found: {stage_file}")
|
|
return False
|
|
|
|
print(f"✅ Deploy stage file exists: {stage_file}")
|
|
|
|
# Check if metadata file exists
|
|
meta_file = "stages/org.osbuild.ostree.deploy.meta.json"
|
|
if not os.path.exists(meta_file):
|
|
print(f"❌ Deploy metadata file not found: {meta_file}")
|
|
return False
|
|
|
|
print(f"✅ Deploy metadata file exists: {meta_file}")
|
|
|
|
return True
|
|
|
|
|
|
def test_ostree_workflow():
|
|
"""Test complete OSTree workflow"""
|
|
print("Testing complete OSTree workflow...")
|
|
|
|
with tempfile.TemporaryDirectory() as temp_dir:
|
|
repo_path = os.path.join(temp_dir, "workflow-repo")
|
|
tree_path = os.path.join(temp_dir, "workflow-tree")
|
|
deploy_path = os.path.join(temp_dir, "workflow-deploy")
|
|
|
|
try:
|
|
# 1. Create repository
|
|
subprocess.run(["ostree", "init", "--repo", repo_path], check=True)
|
|
print("✅ Step 1: Repository created")
|
|
|
|
# 2. Create test filesystem
|
|
os.makedirs(tree_path, exist_ok=True)
|
|
os.makedirs(os.path.join(tree_path, "etc"), exist_ok=True)
|
|
os.makedirs(os.path.join(tree_path, "usr", "bin"), exist_ok=True)
|
|
|
|
# Create test files
|
|
with open(os.path.join(tree_path, "etc", "debian-version"), "w") as f:
|
|
f.write("12.0\n")
|
|
|
|
with open(os.path.join(tree_path, "usr", "bin", "test-app"), "w") as f:
|
|
f.write("#!/bin/bash\necho 'Debian Atomic Test'\n")
|
|
|
|
os.chmod(os.path.join(tree_path, "usr", "bin", "test-app"), 0o755)
|
|
print("✅ Step 2: Test filesystem created")
|
|
|
|
# 3. Create commit
|
|
cmd = [
|
|
"ostree", "commit",
|
|
"--repo", repo_path,
|
|
"--branch", "debian/atomic/test",
|
|
"--subject", "Debian Atomic Test Commit",
|
|
tree_path
|
|
]
|
|
|
|
result = subprocess.run(cmd, capture_output=True, text=True, check=True)
|
|
commit_hash = result.stdout.strip()
|
|
print(f"✅ Step 3: Commit created: {commit_hash}")
|
|
|
|
# 4. Deploy commit
|
|
os.makedirs(deploy_path, exist_ok=True)
|
|
|
|
deploy_cmd = [
|
|
"ostree", "admin", "init-fs", "--modern", deploy_path
|
|
]
|
|
subprocess.run(deploy_cmd, check=True)
|
|
print("✅ Step 4: Deployment filesystem initialized")
|
|
|
|
# 5. Pull and deploy
|
|
pull_cmd = [
|
|
"ostree", "pull-local", repo_path, "debian/atomic/test",
|
|
"--repo", os.path.join(deploy_path, "ostree/repo")
|
|
]
|
|
subprocess.run(pull_cmd, check=True)
|
|
print("✅ Step 5: Commit pulled to deployment repo")
|
|
|
|
# 6. Initialize OS
|
|
os_init_cmd = [
|
|
"ostree", "admin", "os-init", "debian-atomic", deploy_path
|
|
]
|
|
subprocess.run(os_init_cmd, check=True)
|
|
print("✅ Step 6: OS initialized")
|
|
|
|
# 7. Deploy
|
|
deploy_cmd = [
|
|
"ostree", "admin", "deploy", "debian/atomic/test",
|
|
"--sysroot", deploy_path,
|
|
"--os", "debian-atomic"
|
|
]
|
|
subprocess.run(deploy_cmd, check=True)
|
|
print("✅ Step 7: Deployment completed")
|
|
|
|
# Verify deployment
|
|
stateroot = os.path.join(deploy_path, "ostree/deploy/debian-atomic")
|
|
if os.path.exists(stateroot):
|
|
print("✅ Step 8: Deployment verification successful")
|
|
return True
|
|
else:
|
|
print("❌ Step 8: Deployment verification failed")
|
|
return False
|
|
|
|
except subprocess.CalledProcessError as e:
|
|
print(f"❌ Workflow failed at step: {e}")
|
|
return False
|
|
|
|
|
|
def main():
|
|
"""Run all OSTree composition tests"""
|
|
print("OSTree Composition Tests for Debian Atomic")
|
|
print("=" * 50)
|
|
|
|
tests = [
|
|
("OSTree Availability", test_ostree_availability),
|
|
("Repository Creation", test_ostree_repo_creation),
|
|
("Commit Creation", test_ostree_commit_creation),
|
|
("Debian OSTree Stage", test_debian_ostree_stage),
|
|
("OSTree Deploy Stage", test_ostree_deploy_stage),
|
|
("Complete Workflow", test_ostree_workflow),
|
|
]
|
|
|
|
passed = 0
|
|
total = len(tests)
|
|
|
|
for test_name, test_func in tests:
|
|
print(f"\nRunning {test_name}...")
|
|
if test_func():
|
|
passed += 1
|
|
print()
|
|
|
|
print("=" * 50)
|
|
print(f"Test Results: {passed}/{total} passed")
|
|
|
|
if passed == total:
|
|
print("🎉 All OSTree composition tests passed!")
|
|
return 0
|
|
else:
|
|
print("❌ Some tests failed")
|
|
return 1
|
|
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(main())
|