99 lines
3.3 KiB
Python
99 lines
3.3 KiB
Python
"""Test notebooks that require Docker environments (py312, neo4j, benchmark).
|
|
|
|
Same as test_chapter_notebooks.py but IGNORES skip flags from overrides.yaml.
|
|
These notebooks are skipped in uv-native runs (missing modules like signatory,
|
|
gensim, esig, tfcausalimpact, or Neo4j) but CAN run inside their respective
|
|
Docker images.
|
|
|
|
The skip flag stays in overrides.yaml so the uv-native runner still skips them.
|
|
This file runs them in Docker where the dependencies are available.
|
|
|
|
Usage:
|
|
# Py312 notebooks (signatory, gensim, esig, pfhedge, tfcausalimpact, torch CUDA bug)
|
|
python -m pytest tests/test_docker_notebooks.py -v -k "03_sigcwgan or ..."
|
|
|
|
# Neo4j notebooks
|
|
python -m pytest tests/test_docker_notebooks.py -v -k "08_8k_event_extraction or ..."
|
|
|
|
# Benchmark notebooks
|
|
python -m pytest tests/test_docker_notebooks.py -v -k "18_storage_benchmark_database or ..."
|
|
"""
|
|
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from tests.pm_helpers import (
|
|
collect_chapter_notebooks,
|
|
current_test_tier,
|
|
get_overrides,
|
|
get_tier,
|
|
run_notebook,
|
|
)
|
|
|
|
REPO_ROOT = Path(__file__).parent.parent
|
|
|
|
# Collect all chapter teaching notebooks (Ch01-Ch26) + data layer
|
|
CHAPTER_RANGE = range(1, 27)
|
|
CHAPTER_NOTEBOOKS = collect_chapter_notebooks(REPO_ROOT, CHAPTER_RANGE)
|
|
for notebook in sorted(REPO_ROOT.glob("data/**/dataset_card.py")):
|
|
CHAPTER_NOTEBOOKS.append(notebook)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"notebook_path",
|
|
CHAPTER_NOTEBOOKS,
|
|
ids=lambda p: p.relative_to(REPO_ROOT).as_posix().replace("/", "::"),
|
|
)
|
|
def test_docker_notebook(notebook_path, populated_data_dir, seeded_output_dir):
|
|
"""Execute a notebook via Papermill, ignoring skip flags.
|
|
|
|
Identical to test_chapter_notebook() but does NOT honor the 'skip' key
|
|
in overrides.yaml. This allows Docker-based CI jobs to run notebooks
|
|
that are skipped in the uv-native environment due to missing modules.
|
|
|
|
GPU skips are still honored (Docker CI runners have no GPU).
|
|
"""
|
|
rel_path = notebook_path.relative_to(REPO_ROOT).with_suffix("")
|
|
overrides = get_overrides(str(rel_path))
|
|
|
|
# Tier routing still applies — Docker tests are normally per_commit, but
|
|
# this honors the same env-driven gating used by the uv-native runners.
|
|
nb_tier = get_tier(overrides)
|
|
run_tier = current_test_tier()
|
|
if nb_tier != run_tier:
|
|
pytest.skip(f"Tier {nb_tier} — current run tier is {run_tier}")
|
|
|
|
# NOTE: We intentionally do NOT check overrides.get("skip") here.
|
|
# That's the whole point of this file — Docker provides the missing deps.
|
|
|
|
# GPU requirement still applies (CI runners have no GPU)
|
|
if overrides.get("gpu"):
|
|
try:
|
|
import torch
|
|
|
|
if not torch.cuda.is_available():
|
|
pytest.skip("GPU required but not available")
|
|
except ImportError:
|
|
pytest.skip("GPU required but torch not installed")
|
|
|
|
timeout = overrides.get("timeout", 300)
|
|
parameters = overrides.get("parameters", {})
|
|
|
|
result = run_notebook(
|
|
py_path=notebook_path,
|
|
parameters=parameters,
|
|
timeout=timeout,
|
|
output_dir=seeded_output_dir,
|
|
data_dir=populated_data_dir,
|
|
)
|
|
|
|
if result["status"] == "error":
|
|
pytest.fail(
|
|
f"\n{'=' * 70}\n"
|
|
f"Notebook failed: {rel_path}\n"
|
|
f"{'=' * 70}\n"
|
|
f"Error: {result['error']}\n"
|
|
f"{'=' * 70}\n"
|
|
)
|