Add even more tests

This commit is contained in:
Kylian Schmidt
2025-09-09 14:00:37 +02:00
parent ded4eca0bf
commit 4352d26a7b
7 changed files with 812 additions and 5 deletions
+1
View File
@@ -3,3 +3,4 @@
*.sif
*.ipynb
backups
.pytest_cache
+180
View File
@@ -1,5 +1,6 @@
import zipfile
import datetime
from unittest.mock import patch
from utils import backup
@@ -32,3 +33,182 @@ def test_backup_creates_zip(tmp_path, monkeypatch):
# Cleanup: remove the backup file after test
backup_path.unlink()
def test_backup_with_subdirectories(tmp_path, monkeypatch):
# Setup fake web folder with subdirectories
web_folder = tmp_path / 'plots'
web_folder.mkdir()
(web_folder / 'file1.txt').write_text('content1')
subdir = web_folder / 'subdir'
subdir.mkdir()
(subdir / 'file2.txt').write_text('content2')
nested_subdir = subdir / 'nested'
nested_subdir.mkdir()
(nested_subdir / 'file3.txt').write_text('content3')
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)
# Call the backup function
backup.create_backup()
# Check that backup was created with all files
today = datetime.date.today().strftime('%Y%m%d')
backup_name = f'backup-{today}.zip'
backup_path = backup_folder / backup_name
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)
assert any('file3.txt' in n for n in names)
# Cleanup
backup_path.unlink()
def test_backup_existing_file(tmp_path, monkeypatch, capsys):
# Setup fake web folder
web_folder = tmp_path / 'plots'
web_folder.mkdir()
(web_folder / 'file1.txt').write_text('abc')
backup_folder = tmp_path / 'backups'
backup_folder.mkdir()
# Create existing backup file
today = datetime.date.today().strftime('%Y%m%d')
backup_name = f'backup-{today}.zip'
backup_path = backup_folder / backup_name
backup_path.write_text('existing backup')
# Patch the module variables
monkeypatch.setattr(backup, 'WEB_FOLDER', web_folder)
monkeypatch.setattr(backup, 'BACKUP_FOLDER', backup_folder)
# Call the backup function
backup.create_backup()
# Check that message about existing backup was printed
captured = capsys.readouterr()
assert f"Backup already exists: {backup_path}" in captured.out
# Cleanup
backup_path.unlink()
def test_backup_empty_folder(tmp_path, monkeypatch):
# Setup empty web folder
web_folder = tmp_path / 'plots'
web_folder.mkdir()
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)
# Call the backup function
backup.create_backup()
# Check that backup was created (empty)
today = datetime.date.today().strftime('%Y%m%d')
backup_name = f'backup-{today}.zip'
backup_path = backup_folder / backup_name
assert backup_path.exists()
with zipfile.ZipFile(backup_path, 'r') as z:
assert len(z.namelist()) == 0
# Cleanup
backup_path.unlink()
def test_backup_nonexistent_web_folder(tmp_path, monkeypatch):
# Setup nonexistent web folder
web_folder = tmp_path / 'nonexistent_plots'
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)
# Call the backup function
backup.create_backup()
# Check that backup was created (empty since source doesn't exist)
today = datetime.date.today().strftime('%Y%m%d')
backup_name = f'backup-{today}.zip'
backup_path = backup_folder / backup_name
assert backup_path.exists()
with zipfile.ZipFile(backup_path, 'r') as z:
assert len(z.namelist()) == 0
# Cleanup
backup_path.unlink()
@patch('datetime.date')
def test_backup_with_custom_date(mock_date, tmp_path, monkeypatch):
# Mock date to return a specific date
mock_date.today.return_value.strftime.return_value = "20230908"
# Setup fake web folder
web_folder = tmp_path / 'plots'
web_folder.mkdir()
(web_folder / 'file1.txt').write_text('test')
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)
# Call the backup function
backup.create_backup()
# Check that backup was created with custom date
backup_path = backup_folder / "backup-20230908.zip"
assert backup_path.exists()
# Cleanup
backup_path.unlink()
def test_backup_folder_creation(tmp_path, monkeypatch):
# Setup fake web folder
web_folder = tmp_path / 'plots'
web_folder.mkdir()
(web_folder / 'file1.txt').write_text('test')
# Don't create backup folder - let function create it
backup_folder = tmp_path / 'new_backups'
# Patch the module variables
monkeypatch.setattr(backup, 'WEB_FOLDER', web_folder)
monkeypatch.setattr(backup, 'BACKUP_FOLDER', backup_folder)
# Call the backup function
backup.create_backup()
# Check that backup folder was created
assert backup_folder.exists()
assert backup_folder.is_dir()
# Check that backup file was created
today = datetime.date.today().strftime('%Y%m%d')
backup_name = f'backup-{today}.zip'
backup_path = backup_folder / backup_name
assert backup_path.exists()
View File
+170
View File
@@ -1,3 +1,7 @@
from pathlib import Path
import tempfile
import pytest
import yaml
from utils import config
@@ -25,3 +29,169 @@ def test_metadata_config_defaults():
mc = config.MetadataConfig()
assert mc.cache_enabled is True
assert mc.inherit_from_parent is True
assert mc.supported_formats == ['.yaml', '.yml', '.json']
def test_metadata_config_custom():
mc = config.MetadataConfig(
cache_enabled=False,
inherit_from_parent=False,
supported_formats=['.yaml']
)
assert mc.cache_enabled is False
assert mc.inherit_from_parent is False
assert mc.supported_formats == ['.yaml']
def test_gallery_item():
item = config.GalleryItem(name="test", path=Path("/test/path"))
assert item.name == "test"
assert item.path == Path("/test/path")
def test_config_creation():
paths = config.PathConfig(work_dir="/work", web_folder="/web")
gallery = config.GalleryConfig(
plot_root="plots", png_dpi=300, backup_folder="backups")
ui = config.UIConfig(max_recent_plots=5, search_debounce_ms=100)
metadata = config.MetadataConfig()
cfg = config.Config(
paths=paths,
gallery=gallery,
ui=ui,
metadata=metadata
)
assert cfg.paths == paths
assert cfg.gallery == gallery
assert cfg.ui == ui
assert cfg.metadata == metadata
assert cfg.sources == []
def test_config_backward_compatibility_properties():
paths = config.PathConfig(work_dir="/work", web_folder="/web")
gallery = config.GalleryConfig(
plot_root="plots", png_dpi=300, backup_folder="backups")
ui = config.UIConfig(max_recent_plots=5, search_debounce_ms=100)
metadata = config.MetadataConfig()
cfg = config.Config(
paths=paths,
gallery=gallery,
ui=ui,
metadata=metadata
)
assert cfg.web_folder == "/web"
assert cfg.png_dpi == 300
assert cfg.plot_root == "plots"
assert cfg.backup_folder == "backups"
def test_config_from_yaml(tmp_path):
yaml_content = {
'paths': {
'work_dir': '/test/work',
'web_folder': '/test/web'
},
'gallery': {
'plot_root': 'test_plots',
'png_dpi': 200,
'backup_folder': 'test_backups'
},
'ui': {
'max_recent_plots': 15,
'search_debounce_ms': 300
},
'metadata': {
'cache_enabled': False,
'inherit_from_parent': False
},
'sources': [
{'name': 'source1', 'path': '/path1'},
{'name': 'source2', 'path': '/path2'}
]
}
yaml_file = tmp_path / 'test_config.yaml'
with yaml_file.open('w') as f:
yaml.dump(yaml_content, f)
cfg = config.Config.from_yaml(str(yaml_file))
assert cfg.paths.work_dir == '/test/work'
assert cfg.paths.web_folder == '/test/web'
assert cfg.gallery.plot_root == 'test_plots'
assert cfg.gallery.png_dpi == 200
assert cfg.ui.max_recent_plots == 15
assert cfg.metadata.cache_enabled is False
assert len(cfg.sources) == 2
assert cfg.sources[0].name == 'source1'
assert cfg.sources[0].path == Path('/path1')
def test_config_from_yaml_missing_file():
with pytest.raises(FileNotFoundError):
config.Config.from_yaml('/nonexistent/file.yaml')
def test_config_from_yaml_malformed():
with tempfile.NamedTemporaryFile(mode='w', suffix='.yaml',
delete=False) as f:
f.write('invalid: yaml: content: [')
f.flush()
with pytest.raises(yaml.YAMLError):
config.Config.from_yaml(f.name)
def test_config_to_yaml(tmp_path):
paths = config.PathConfig(work_dir="/work", web_folder="/web")
gallery = config.GalleryConfig(
plot_root="plots", png_dpi=300, backup_folder="backups")
ui = config.UIConfig(max_recent_plots=5, search_debounce_ms=100)
metadata = config.MetadataConfig()
sources = [config.GalleryItem(name="test", path=Path("/test"))]
cfg = config.Config(
paths=paths,
gallery=gallery,
ui=ui,
metadata=metadata,
sources=sources
)
yaml_file = tmp_path / 'output_config.yaml'
cfg.to_yaml(str(yaml_file))
assert yaml_file.exists()
# Load back and verify
with yaml_file.open('r') as f:
loaded_data = yaml.safe_load(f)
assert loaded_data['paths']['work_dir'] == "/work"
assert loaded_data['gallery']['png_dpi'] == 300
assert len(loaded_data['sources']) == 1
def test_config_from_yaml_partial_data(tmp_path):
# Test with minimal YAML data
yaml_content = {
'paths': {'work_dir': '/min', 'web_folder': '/min_web'},
'gallery': {'plot_root': 'min_plots', 'png_dpi': 100,
'backup_folder': 'min_backup'},
'ui': {'max_recent_plots': 3, 'search_debounce_ms': 50}
}
yaml_file = tmp_path / 'minimal_config.yaml'
with yaml_file.open('w') as f:
yaml.dump(yaml_content, f)
cfg = config.Config.from_yaml(str(yaml_file))
# Should use defaults for metadata and empty sources
assert cfg.metadata.cache_enabled is True # default
assert cfg.sources == [] # default empty list
+2 -2
View File
@@ -17,8 +17,8 @@ def test_python_version():
def test_required_modules():
"""Test that required Python modules are installed."""
try:
import jinja2 # type: ignore
import yaml # type: ignore
import jinja2 # noqa: F401
import yaml # noqa: F401
except ImportError as e:
pytest.fail(f"Required module not found: {e}")
+279
View File
@@ -0,0 +1,279 @@
from pathlib import Path
from unittest.mock import patch, MagicMock
from generate_gallery import (
convert_pdf_to_png,
needs_update,
build_gallery,
calculate_directory_stats,
format_file_size,
datetime_from_timestamp,
strftime_filter
)
from datetime import datetime
def test_format_file_size():
assert format_file_size(0) == "0 B"
assert format_file_size(1) == "1.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"
assert format_file_size(1099511627776) == "1.0 TB"
def test_format_file_size_edge_cases():
assert format_file_size(1023) == "1023.0 B"
assert format_file_size(1536) == "1.5 KB"
assert format_file_size(2621440) == "2.5 MB"
def test_needs_update_missing_target(tmp_path):
source = tmp_path / "source.txt"
target = tmp_path / "target.txt"
source.write_text("test content")
assert needs_update(source, target) is True
def test_needs_update_target_newer(tmp_path):
source = tmp_path / "source.txt"
target = tmp_path / "target.txt"
source.write_text("test")
target.write_text("test")
# Make target newer by modifying its timestamp
import time
time.sleep(0.1)
target.touch()
assert needs_update(source, target) is False
def test_needs_update_source_newer(tmp_path):
source = tmp_path / "source.txt"
target = tmp_path / "target.txt"
target.write_text("test")
import time
time.sleep(0.1)
source.write_text("test")
assert needs_update(source, target) is True
@patch('subprocess.run')
def test_convert_pdf_to_png_success(mock_run, tmp_path):
pdf_path = tmp_path / "test.pdf"
png_path = tmp_path / "test.png"
pdf_path.write_text("fake pdf")
mock_run.return_value = MagicMock(returncode=0)
convert_pdf_to_png(pdf_path)
mock_run.assert_called_once()
call_args = mock_run.call_args[0][0]
assert call_args[0] == "convert"
assert str(pdf_path) in call_args
assert str(png_path) in call_args
@patch('subprocess.run')
def test_convert_pdf_to_png_already_exists_newer(mock_run, tmp_path):
pdf_path = tmp_path / "test.pdf"
png_path = tmp_path / "test.png"
pdf_path.write_text("fake pdf")
png_path.write_text("fake png")
# Make PNG much newer than PDF
import time
time.sleep(0.1)
png_path.touch()
convert_pdf_to_png(pdf_path)
# Should not call subprocess since PNG is newer
mock_run.assert_not_called()
@patch('subprocess.run')
def test_convert_pdf_to_png_pdf_newer(mock_run, tmp_path):
pdf_path = tmp_path / "test.pdf"
png_path = tmp_path / "test.png"
png_path.write_text("fake png")
import time
time.sleep(0.1)
pdf_path.write_text("fake pdf")
mock_run.return_value = MagicMock(returncode=0)
convert_pdf_to_png(pdf_path)
# Should call subprocess since PDF is newer
mock_run.assert_called_once()
def test_calculate_directory_stats_empty(tmp_path):
stats = calculate_directory_stats(tmp_path)
assert stats["file_count"] == 0
assert stats["folder_count"] == 0
assert stats["total_size"] == 0
assert stats["pdf_size"] == 0
assert stats["png_size"] == 0
def test_calculate_directory_stats_with_files(tmp_path):
# Create test files
(tmp_path / "test.pdf").write_text("pdf content")
(tmp_path / "test.png").write_text("png content")
(tmp_path / "test.txt").write_text("txt content")
# Create subdirectory
subdir = tmp_path / "subdir"
subdir.mkdir()
(subdir / "nested.pdf").write_text("nested pdf")
stats = calculate_directory_stats(tmp_path)
assert stats["file_count"] == 4
assert stats["folder_count"] == 1
assert stats["total_size"] > 0
assert stats["pdf_size"] > 0
assert stats["png_size"] > 0
def test_calculate_directory_stats_nonexistent():
nonexistent = Path("/nonexistent/path")
stats = calculate_directory_stats(nonexistent)
assert stats["file_count"] == 0
assert stats["folder_count"] == 0
assert stats["total_size"] == 0
def test_datetime_from_timestamp():
timestamp = 1630000000 # Some Unix timestamp
dt = datetime_from_timestamp(timestamp)
assert isinstance(dt, datetime)
assert dt.timestamp() == timestamp
def test_strftime_filter():
dt = datetime(2023, 9, 8, 14, 30, 0)
formatted = strftime_filter(dt, "%Y-%m-%d %H:%M")
assert formatted == "2023-09-08 14:30"
@patch('generate_gallery.template')
@patch('generate_gallery.save_metadata_cache')
@patch('generate_gallery.resolve_metadata_for_plot')
@patch('generate_gallery.merge_metadata')
@patch('generate_gallery.load_folder_metadata')
@patch('generate_gallery.convert_pdf_to_png')
@patch('shutil.copy2')
def test_build_gallery_basic(
mock_copy,
mock_convert,
mock_load_folder,
mock_merge,
mock_resolve,
mock_save_cache,
mock_template,
tmp_path
):
source_dir = tmp_path / "source"
web_dir = tmp_path / "web"
source_dir.mkdir()
web_dir.mkdir()
# Create a test PDF
pdf_file = source_dir / "test.pdf"
pdf_file.write_text("fake pdf content")
# Create corresponding PNG
png_file = source_dir / "test.png"
png_file.write_text("fake png content")
# Mock returns
mock_load_folder.return_value = {"folder": "metadata"}
mock_merge.return_value = {"merged": "metadata"}
mock_resolve.return_value = {"plot": "metadata"}
mock_template.render.return_value = "<html>test</html>"
build_gallery(source_dir, web_dir)
# Verify mocks were called
mock_load_folder.assert_called_once_with(source_dir)
mock_convert.assert_called_once_with(pdf_file)
mock_copy.assert_called() # Should be called for PDF and PNG
mock_save_cache.assert_called_once()
# Check HTML file was created
html_file = web_dir / "index.html"
assert html_file.exists()
@patch('generate_gallery.template')
@patch('generate_gallery.save_metadata_cache')
@patch('generate_gallery.load_folder_metadata')
def test_build_gallery_with_subdirs(
mock_load_folder,
mock_save_cache,
mock_template,
tmp_path
):
source_dir = tmp_path / "source"
web_dir = tmp_path / "web"
source_dir.mkdir()
web_dir.mkdir()
# Create subdirectory
subdir = source_dir / "subdir"
subdir.mkdir()
mock_load_folder.return_value = {}
mock_template.render.return_value = "<html>test</html>"
build_gallery(source_dir, web_dir)
# Check subdirectory was created in web
web_subdir = web_dir / "subdir"
assert web_subdir.exists()
assert web_subdir.is_dir()
@patch('generate_gallery.needs_update')
@patch('shutil.copy2')
def test_build_gallery_skip_up_to_date(mock_copy, mock_needs_update, tmp_path):
source_dir = tmp_path / "source"
web_dir = tmp_path / "web"
source_dir.mkdir()
web_dir.mkdir()
# Create test files
pdf_file = source_dir / "test.pdf"
png_file = source_dir / "test.png"
pdf_file.write_text("pdf")
png_file.write_text("png")
# Create target files
web_pdf = web_dir / "test.pdf"
web_png = web_dir / "test.png"
web_pdf.write_text("pdf")
web_png.write_text("png")
# Mock needs_update to return False (up to date)
mock_needs_update.return_value = False
with patch('generate_gallery.template') as mock_template:
mock_template.render.return_value = "<html>test</html>"
build_gallery(source_dir, web_dir)
# copy2 should not be called since files are up to date
mock_copy.assert_not_called()
+177
View File
@@ -1,4 +1,5 @@
import json
import pytest
from utils import metadata
import yaml
@@ -23,3 +24,179 @@ def test_load_metadata_file_missing(tmp_path):
missing_path = tmp_path / 'nope.yaml'
result = metadata.load_metadata_file(missing_path)
assert result == {}
def test_load_metadata_file_yml_extension(tmp_path):
data = {'test': 'yml_format'}
yml_path = tmp_path / 'meta.yml'
yml_path.write_text(yaml.dump(data))
result = metadata.load_metadata_file(yml_path)
assert result == data
def test_load_metadata_file_unknown_format(tmp_path):
txt_path = tmp_path / 'meta.txt'
txt_path.write_text('some text')
result = metadata.load_metadata_file(txt_path)
assert result == {}
def test_load_metadata_file_malformed_yaml(tmp_path):
yaml_path = tmp_path / 'bad.yaml'
yaml_path.write_text('invalid: yaml: content: [')
with pytest.raises(yaml.YAMLError):
metadata.load_metadata_file(yaml_path)
def test_load_metadata_file_malformed_json(tmp_path):
json_path = tmp_path / 'bad.json'
json_path.write_text('{"invalid": json}')
with pytest.raises(json.JSONDecodeError):
metadata.load_metadata_file(json_path)
def test_load_folder_metadata_yaml(tmp_path):
data = {'folder': 'metadata'}
metadata_path = tmp_path / 'metadata.yaml'
metadata_path.write_text(yaml.dump(data))
result = metadata.load_folder_metadata(tmp_path)
assert result == data
def test_load_folder_metadata_yml(tmp_path):
data = {'folder': 'metadata_yml'}
metadata_path = tmp_path / 'metadata.yml'
metadata_path.write_text(yaml.dump(data))
result = metadata.load_folder_metadata(tmp_path)
assert result == data
def test_load_folder_metadata_json(tmp_path):
data = {'folder': 'metadata_json'}
metadata_path = tmp_path / 'metadata.json'
metadata_path.write_text(json.dumps(data))
result = metadata.load_folder_metadata(tmp_path)
assert result == data
def test_load_folder_metadata_missing(tmp_path):
result = metadata.load_folder_metadata(tmp_path)
assert result == {}
def test_get_metadata_file_path_existing_yaml(tmp_path):
metadata_path = tmp_path / 'metadata.yaml'
metadata_path.write_text('test: data')
result = metadata.get_metadata_file_path(tmp_path)
assert result == str(metadata_path)
def test_get_metadata_file_path_existing_yml(tmp_path):
metadata_path = tmp_path / 'metadata.yml'
metadata_path.write_text('test: data')
result = metadata.get_metadata_file_path(tmp_path)
assert result == str(metadata_path)
def test_get_metadata_file_path_existing_json(tmp_path):
metadata_path = tmp_path / 'metadata.json'
metadata_path.write_text('{"test": "data"}')
result = metadata.get_metadata_file_path(tmp_path)
assert result == str(metadata_path)
def test_get_metadata_file_path_none_existing(tmp_path):
result = metadata.get_metadata_file_path(tmp_path)
expected = str(tmp_path / 'metadata.yaml')
assert result == expected
def test_merge_metadata():
parent = {'project': 'Test', 'version': '1.0', 'author': 'Parent'}
child = {'experiment': 'A', 'version': '1.1'}
merged = metadata.merge_metadata(parent, child)
expected = {'project': 'Test', 'version': '1.1',
'author': 'Parent', 'experiment': 'A'}
assert merged == expected
def test_merge_metadata_empty_parent():
parent = {}
child = {'experiment': 'A', 'version': '1.1'}
merged = metadata.merge_metadata(parent, child)
assert merged == child
def test_merge_metadata_empty_child():
parent = {'project': 'Test', 'version': '1.0'}
child = {}
merged = metadata.merge_metadata(parent, child)
assert merged == parent
def test_resolve_metadata_for_plot_with_specific_yaml(tmp_path):
# Create plot-specific metadata file
plot_path = tmp_path / 'test_plot.pdf'
plot_metadata_path = tmp_path / 'test_plot.yaml'
plot_metadata = {'specific': 'plot_data', 'override': 'plot_value'}
plot_metadata_path.write_text(yaml.dump(plot_metadata))
inherited = {'general': 'data', 'override': 'inherited_value'}
result = metadata.resolve_metadata_for_plot(plot_path, inherited)
expected = {'general': 'data',
'override': 'plot_value', 'specific': 'plot_data'}
assert result == expected
def test_resolve_metadata_for_plot_with_specific_json(tmp_path):
plot_path = tmp_path / 'test_plot.pdf'
plot_metadata_path = tmp_path / 'test_plot.json'
plot_metadata = {'specific': 'plot_data_json'}
plot_metadata_path.write_text(json.dumps(plot_metadata))
inherited = {'general': 'data'}
result = metadata.resolve_metadata_for_plot(plot_path, inherited)
expected = {'general': 'data', 'specific': 'plot_data_json'}
assert result == expected
def test_resolve_metadata_for_plot_no_specific(tmp_path):
plot_path = tmp_path / 'test_plot.pdf'
inherited = {'general': 'data', 'inherited': 'value'}
result = metadata.resolve_metadata_for_plot(plot_path, inherited)
# Should return copy of inherited metadata
assert result == inherited
assert result is not inherited # Should be a copy
def test_save_metadata_cache(tmp_path):
cache_data = {
'plot1': {'title': 'Plot 1', 'author': 'Test'},
'plot2': {'title': 'Plot 2', 'experiment': 'B'}
}
metadata.save_metadata_cache(tmp_path, cache_data)
cache_file = tmp_path / 'meta_cache.json'
assert cache_file.exists()
with cache_file.open('r') as f:
loaded_data = json.load(f)
assert loaded_data == cache_data
def test_save_metadata_cache_empty(tmp_path):
cache_data = {}
metadata.save_metadata_cache(tmp_path, cache_data)
cache_file = tmp_path / 'meta_cache.json'
assert cache_file.exists()
with cache_file.open('r') as f:
loaded_data = json.load(f)
assert loaded_data == {}