Clean up unittest attempt.
This commit is contained in:
@@ -1,213 +0,0 @@
|
||||
"""
|
||||
Test for building and validating the Apptainer container.
|
||||
"""
|
||||
|
||||
import unittest
|
||||
import subprocess
|
||||
import os
|
||||
import tempfile
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
class TestContainerBuild(unittest.TestCase):
|
||||
"""Test Apptainer container building and basic functionality."""
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
"""Set up test environment - run once for all tests."""
|
||||
cls.project_root = Path(__file__).parent.parent.absolute()
|
||||
cls.singularity_def = cls.project_root / "Singularity.def"
|
||||
cls.test_dir = Path(tempfile.mkdtemp())
|
||||
cls.container_path = cls.test_dir / "gallery_test.sif"
|
||||
|
||||
print(f"Project root: {cls.project_root}")
|
||||
print(f"Test directory: {cls.test_dir}")
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
"""Clean up test environment."""
|
||||
if cls.test_dir.exists():
|
||||
shutil.rmtree(cls.test_dir)
|
||||
|
||||
def test_01_singularity_def_exists(self):
|
||||
"""Test that Singularity.def file exists and is valid."""
|
||||
self.assertTrue(self.singularity_def.exists(),
|
||||
"Singularity.def file not found")
|
||||
|
||||
content = self.singularity_def.read_text()
|
||||
self.assertIn("Bootstrap:", content)
|
||||
self.assertIn("From:", content)
|
||||
self.assertIn("%post", content)
|
||||
self.assertIn("imagemagick", content.lower())
|
||||
self.assertIn("jinja2", content.lower())
|
||||
self.assertIn("pyyaml", content.lower())
|
||||
|
||||
def test_02_apptainer_available(self):
|
||||
"""Test that Apptainer/Singularity is available."""
|
||||
try:
|
||||
# Try apptainer first (newer)
|
||||
result = subprocess.run(['apptainer', '--version'],
|
||||
capture_output=True, text=True, timeout=10)
|
||||
if result.returncode == 0:
|
||||
self.container_cmd = 'apptainer'
|
||||
return
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
try:
|
||||
# Fall back to singularity
|
||||
result = subprocess.run(['singularity', '--version'],
|
||||
capture_output=True, text=True, timeout=10)
|
||||
if result.returncode == 0:
|
||||
self.container_cmd = 'singularity'
|
||||
return
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
self.fail("Neither 'apptainer' nor 'singularity' command found")
|
||||
|
||||
def test_03_build_container(self):
|
||||
"""Test building the container from Singularity.def."""
|
||||
# Ensure we have a container command from previous test
|
||||
if not hasattr(self, 'container_cmd'):
|
||||
self.test_02_apptainer_available()
|
||||
|
||||
print(f"Building container with {self.container_cmd}...")
|
||||
|
||||
# Build command
|
||||
build_cmd = [
|
||||
self.container_cmd, 'build',
|
||||
str(self.container_path),
|
||||
str(self.singularity_def)
|
||||
]
|
||||
|
||||
# Change to project directory for build context
|
||||
original_cwd = os.getcwd()
|
||||
try:
|
||||
os.chdir(self.project_root)
|
||||
|
||||
# Run build with extended timeout
|
||||
result = subprocess.run(
|
||||
build_cmd,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=300 # 5 minutes should be enough
|
||||
)
|
||||
|
||||
if result.returncode != 0:
|
||||
print("STDOUT:", result.stdout)
|
||||
print("STDERR:", result.stderr)
|
||||
self.fail(f"Container build failed with return code {result.returncode}")
|
||||
|
||||
# Verify container was created
|
||||
self.assertTrue(self.container_path.exists(),
|
||||
"Container file was not created")
|
||||
|
||||
# Check container size (should be > 100MB for a real container)
|
||||
size_mb = self.container_path.stat().st_size / (1024 * 1024)
|
||||
self.assertGreater(size_mb, 50,
|
||||
f"Container seems too small: {size_mb:.1f}MB")
|
||||
|
||||
print(f"✅ Container built successfully: {size_mb:.1f}MB")
|
||||
|
||||
finally:
|
||||
os.chdir(original_cwd)
|
||||
|
||||
def test_04_container_exec_python(self):
|
||||
"""Test that Python works inside the container."""
|
||||
if not self.container_path.exists():
|
||||
self.skipTest("Container not built")
|
||||
|
||||
cmd = [self.container_cmd, 'exec', str(self.container_path),
|
||||
'python3', '-c', 'import sys; print(f"Python {sys.version_info.major}.{sys.version_info.minor}")']
|
||||
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
|
||||
|
||||
self.assertEqual(result.returncode, 0,
|
||||
f"Python execution failed: {result.stderr}")
|
||||
self.assertIn("Python 3.", result.stdout)
|
||||
|
||||
def test_05_container_dependencies(self):
|
||||
"""Test that required dependencies are installed."""
|
||||
if not self.container_path.exists():
|
||||
self.skipTest("Container not built")
|
||||
|
||||
# Test Python dependencies
|
||||
python_test = """
|
||||
import sys
|
||||
try:
|
||||
import jinja2
|
||||
import yaml
|
||||
print("✅ Python dependencies OK")
|
||||
except ImportError as e:
|
||||
print(f"❌ Missing dependency: {e}")
|
||||
sys.exit(1)
|
||||
"""
|
||||
|
||||
cmd = [self.container_cmd, 'exec', str(self.container_path),
|
||||
'python3', '-c', python_test]
|
||||
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
|
||||
|
||||
self.assertEqual(result.returncode, 0,
|
||||
f"Dependency check failed: {result.stderr}")
|
||||
self.assertIn("Python dependencies OK", result.stdout)
|
||||
|
||||
# Test ImageMagick
|
||||
cmd = [self.container_cmd, 'exec', str(self.container_path),
|
||||
'convert', '-version']
|
||||
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
|
||||
|
||||
self.assertEqual(result.returncode, 0,
|
||||
f"ImageMagick not working: {result.stderr}")
|
||||
self.assertIn("ImageMagick", result.stdout)
|
||||
|
||||
def test_06_container_run_tests(self):
|
||||
"""Test running the container test suite."""
|
||||
if not self.container_path.exists():
|
||||
self.skipTest("Container not built")
|
||||
|
||||
# Run the container tests
|
||||
cmd = [self.container_cmd, 'exec', str(self.container_path),
|
||||
'python3', '/src/tests/test_container.py']
|
||||
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, timeout=120)
|
||||
|
||||
print("Container test output:")
|
||||
print(result.stdout)
|
||||
if result.stderr:
|
||||
print("Errors:")
|
||||
print(result.stderr)
|
||||
|
||||
self.assertEqual(result.returncode, 0,
|
||||
f"Container tests failed: {result.stderr}")
|
||||
self.assertIn("ALL TESTS PASSED", result.stdout)
|
||||
|
||||
|
||||
def run_build_tests():
|
||||
"""Run container build tests."""
|
||||
print("=" * 60)
|
||||
print("APPTAINER CONTAINER BUILD TESTS")
|
||||
print("=" * 60)
|
||||
|
||||
# Run tests in order
|
||||
suite = unittest.TestLoader().loadTestsFromTestCase(TestContainerBuild)
|
||||
runner = unittest.TextTestRunner(verbosity=2)
|
||||
result = runner.run(suite)
|
||||
|
||||
if result.wasSuccessful():
|
||||
print("\n✅ All container build tests passed!")
|
||||
else:
|
||||
print(f"\n❌ Container build tests failed!")
|
||||
print(f"Failures: {len(result.failures)}")
|
||||
print(f"Errors: {len(result.errors)}")
|
||||
|
||||
return 0 if result.wasSuccessful() else 1
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
exit_code = run_build_tests()
|
||||
sys.exit(exit_code)
|
||||
Reference in New Issue
Block a user