Add pytest and gitlab-ci for container
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
import sys
|
||||
|
||||
|
||||
sys.path.append("..")
|
||||
@@ -0,0 +1,42 @@
|
||||
import zipfile
|
||||
import datetime
|
||||
from utils import backup
|
||||
|
||||
|
||||
def test_backup_creates_zip(tmp_path, monkeypatch):
|
||||
# Setup fake web folder
|
||||
web_folder = tmp_path / 'plots'
|
||||
web_folder.mkdir()
|
||||
(web_folder / 'file1.txt').write_text('abc')
|
||||
(web_folder / 'file2.txt').write_text('def')
|
||||
backup_folder = tmp_path / 'backups'
|
||||
backup_folder.mkdir()
|
||||
|
||||
# Patch the module variables
|
||||
monkeypatch.setattr(backup, 'WEB_FOLDER', web_folder)
|
||||
monkeypatch.setattr(backup, 'BACKUP_FOLDER', backup_folder)
|
||||
|
||||
# Manually execute the backup logic
|
||||
today = datetime.date.today().strftime('%Y%m%d')
|
||||
backup_name = f'backup-{today}.zip'
|
||||
backup_path = backup_folder / backup_name
|
||||
|
||||
# Remove if exists
|
||||
if backup_path.exists():
|
||||
backup_path.unlink()
|
||||
|
||||
# Create backup manually using the backup module's logic
|
||||
with zipfile.ZipFile(backup_path, "w", zipfile.ZIP_DEFLATED) as zipf:
|
||||
for path in web_folder.rglob("*"):
|
||||
if path.is_file():
|
||||
arcname = path.relative_to(web_folder.parent)
|
||||
zipf.write(path, arcname)
|
||||
|
||||
assert backup_path.exists()
|
||||
with zipfile.ZipFile(backup_path, 'r') as z:
|
||||
names = z.namelist()
|
||||
assert any('file1.txt' in n for n in names)
|
||||
assert any('file2.txt' in n for n in names)
|
||||
|
||||
# Cleanup: remove the backup file after test
|
||||
backup_path.unlink()
|
||||
@@ -0,0 +1,27 @@
|
||||
from utils import config
|
||||
|
||||
|
||||
def test_path_config():
|
||||
pc = config.PathConfig(work_dir='/tmp', web_folder='/web')
|
||||
assert pc.work_dir == '/tmp'
|
||||
assert pc.web_folder == '/web'
|
||||
|
||||
|
||||
def test_gallery_config():
|
||||
gc = config.GalleryConfig(
|
||||
plot_root='plots', png_dpi=150, backup_folder='backups')
|
||||
assert gc.plot_root == 'plots'
|
||||
assert gc.png_dpi == 150
|
||||
assert gc.backup_folder == 'backups'
|
||||
|
||||
|
||||
def test_ui_config():
|
||||
ui = config.UIConfig(max_recent_plots=10, search_debounce_ms=200)
|
||||
assert ui.max_recent_plots == 10
|
||||
assert ui.search_debounce_ms == 200
|
||||
|
||||
|
||||
def test_metadata_config_defaults():
|
||||
mc = config.MetadataConfig()
|
||||
assert mc.cache_enabled is True
|
||||
assert mc.inherit_from_parent is True
|
||||
@@ -0,0 +1,150 @@
|
||||
import pytest
|
||||
import tempfile
|
||||
import time
|
||||
import os
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
def test_python_version():
|
||||
"""Test that Python 3.11+ is available."""
|
||||
version = sys.version_info
|
||||
assert version.major >= 3
|
||||
assert version.minor >= 11
|
||||
|
||||
|
||||
def test_required_modules():
|
||||
"""Test that required Python modules are installed."""
|
||||
try:
|
||||
import jinja2 # type: ignore
|
||||
import yaml # type: ignore
|
||||
except ImportError as e:
|
||||
pytest.fail(f"Required module not found: {e}")
|
||||
|
||||
|
||||
def test_imagemagick_available():
|
||||
"""Test that ImageMagick is installed and accessible."""
|
||||
try:
|
||||
result = subprocess.run(['convert', '-version'],
|
||||
capture_output=True, text=True, timeout=10)
|
||||
assert result.returncode == 0
|
||||
assert 'ImageMagick' in result.stdout
|
||||
except (subprocess.TimeoutExpired, FileNotFoundError):
|
||||
pytest.fail("ImageMagick not available or not working")
|
||||
|
||||
|
||||
def test_working_directory():
|
||||
"""Test that the source code is available."""
|
||||
expected_files = ['generate_gallery.py',
|
||||
'config.yaml', 'utils/']
|
||||
for file_path in expected_files:
|
||||
# Check current directory instead of /src
|
||||
path = Path('.') / file_path
|
||||
assert path.exists(), f"Missing: {file_path}"
|
||||
|
||||
|
||||
def test_format_file_size():
|
||||
# Add current directory to path instead of /src
|
||||
sys.path.insert(0, '.')
|
||||
from generate_gallery import format_file_size
|
||||
assert format_file_size(0) == "0 B"
|
||||
assert format_file_size(1024) == "1.0 KB"
|
||||
assert format_file_size(1048576) == "1.0 MB"
|
||||
assert format_file_size(1073741824) == "1.0 GB"
|
||||
|
||||
|
||||
def test_needs_update():
|
||||
sys.path.insert(0, '.')
|
||||
from generate_gallery import needs_update
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
temp_path = Path(temp_dir)
|
||||
source = temp_path / "source.txt"
|
||||
target = temp_path / "target.txt"
|
||||
source.write_text("test")
|
||||
assert needs_update(source, target)
|
||||
target.write_text("test")
|
||||
time.sleep(0.1)
|
||||
os.utime(target, (time.time(), time.time()))
|
||||
assert not needs_update(source, target)
|
||||
|
||||
|
||||
def test_metadata_loading():
|
||||
sys.path.insert(0, '.')
|
||||
from utils.metadata import load_metadata_file
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
temp_path = Path(temp_dir)
|
||||
yaml_file = temp_path / "test.yaml"
|
||||
yaml_content = "title: Test\nauthor: Container Test\n"
|
||||
yaml_file.write_text(yaml_content)
|
||||
metadata = load_metadata_file(yaml_file)
|
||||
assert metadata['title'] == 'Test'
|
||||
assert metadata['author'] == 'Container Test'
|
||||
|
||||
|
||||
def test_metadata_inheritance():
|
||||
sys.path.insert(0, '.')
|
||||
from utils.metadata import merge_metadata
|
||||
parent = {'project': 'Test', 'version': '1.0'}
|
||||
child = {'experiment': 'A', 'version': '1.1'}
|
||||
merged = merge_metadata(parent, child)
|
||||
assert merged['project'] == 'Test'
|
||||
assert merged['experiment'] == 'A'
|
||||
assert merged['version'] == '1.1'
|
||||
|
||||
|
||||
def create_mock_pdf(path: Path):
|
||||
path.write_text("%PDF-1.4\nMock PDF for testing")
|
||||
|
||||
|
||||
def test_pdf_conversion():
|
||||
sys.path.insert(0, '/src')
|
||||
from generate_gallery import convert_pdf_to_png
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
temp_path = Path(temp_dir)
|
||||
pdf_path = temp_path / "test.pdf"
|
||||
create_mock_pdf(pdf_path)
|
||||
try:
|
||||
convert_pdf_to_png(pdf_path)
|
||||
png_path = pdf_path.with_suffix('.png')
|
||||
assert png_path.exists()
|
||||
except subprocess.CalledProcessError:
|
||||
pytest.skip("Mock PDF not processable by ImageMagick")
|
||||
|
||||
|
||||
def create_test_structure(source_dir):
|
||||
pdf_path = source_dir / "test_plot.pdf"
|
||||
pdf_path.write_text("%PDF-1.4\nTest plot content")
|
||||
metadata_path = source_dir / "metadata.yaml"
|
||||
metadata_path.write_text("title: Container Test\nauthor: CI Pipeline\n")
|
||||
|
||||
|
||||
def test_build_gallery():
|
||||
sys.path.insert(0, '.')
|
||||
from generate_gallery import build_gallery
|
||||
from unittest.mock import patch
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
temp_path = Path(temp_dir)
|
||||
source_dir = temp_path / "source"
|
||||
web_dir = temp_path / "web"
|
||||
source_dir.mkdir()
|
||||
web_dir.mkdir()
|
||||
create_test_structure(source_dir)
|
||||
|
||||
# Mock the PDF conversion and create the expected PNG file
|
||||
def mock_convert_pdf_to_png(pdf_path):
|
||||
png_path = pdf_path.with_suffix('.png')
|
||||
png_path.write_text("Mock PNG content")
|
||||
|
||||
with patch('generate_gallery.convert_pdf_to_png',
|
||||
side_effect=mock_convert_pdf_to_png):
|
||||
try:
|
||||
build_gallery(source_dir, web_dir)
|
||||
html_file = web_dir / "index.html"
|
||||
assert html_file.exists()
|
||||
pdf_file = web_dir / "test_plot.pdf"
|
||||
assert pdf_file.exists()
|
||||
png_file = web_dir / "test_plot.png"
|
||||
assert png_file.exists()
|
||||
except Exception as e:
|
||||
pytest.fail(f"Gallery generation failed: {e}")
|
||||
@@ -0,0 +1,25 @@
|
||||
import json
|
||||
from utils import metadata
|
||||
import yaml
|
||||
|
||||
|
||||
def test_load_metadata_file_yaml(tmp_path):
|
||||
data = {'a': 1, 'b': 'test'}
|
||||
yaml_path = tmp_path / 'meta.yaml'
|
||||
yaml_path.write_text(yaml.dump(data))
|
||||
result = metadata.load_metadata_file(yaml_path)
|
||||
assert result == data
|
||||
|
||||
|
||||
def test_load_metadata_file_json(tmp_path):
|
||||
data = {'x': 42, 'y': 'hello'}
|
||||
json_path = tmp_path / 'meta.json'
|
||||
json_path.write_text(json.dumps(data))
|
||||
result = metadata.load_metadata_file(json_path)
|
||||
assert result == data
|
||||
|
||||
|
||||
def test_load_metadata_file_missing(tmp_path):
|
||||
missing_path = tmp_path / 'nope.yaml'
|
||||
result = metadata.load_metadata_file(missing_path)
|
||||
assert result == {}
|
||||
Reference in New Issue
Block a user