Source code for id3c.tests.test_check_ad_files_symlink

"""Tests for ``id3c.plans.flyscan_3idc._check_ad_files_symlink``.

Verifies:
- existing image-files symlink (symlink OR plain dir) is silently
  accepted;
- a missing symlink emits a WARNING containing the suggested
  ``ln -s`` command and the verification steps;
- the warning fires once per (master_dir, target) combination;
- a custom read_path_template is reflected in the suggested target;
- when read_path_template is missing the helper uses a placeholder
  the operator must fill in;
- the helper never creates or modifies the link.
"""

from types import SimpleNamespace

import pytest

from id3c.plans import flyscan_3idc as plan_mod
from id3c.plans.flyscan_3idc import _check_ad_files_symlink


def _make_det(
    read_path_template="/net/s3data/export/sector3/s3ida/XRD/", name="eiger2"
):
    """Duck-typed det with ``.name`` and hdf1.read_path_template."""
    hdf1 = SimpleNamespace()
    if read_path_template is not None:
        hdf1.read_path_template = read_path_template
    return SimpleNamespace(name=name, hdf1=hdf1)


@pytest.fixture(autouse=True)
def _clear_warned_set():
    """Reset the once-per-session warned-set between tests."""
    plan_mod._AD_FILES_WARNED.clear()
    yield
    plan_mod._AD_FILES_WARNED.clear()






[docs] def test_existing_ad_files_directory_is_accepted_silently(tmp_path, caplog): """A plain directory named {det.name}_files (no symlink) is accepted.""" (tmp_path / "eiger2_files").mkdir() det = _make_det() with caplog.at_level("WARNING", logger="id3c.plans.flyscan_3idc"): ok = _check_ad_files_symlink(det, master_dir=str(tmp_path)) assert ok is True
[docs] def test_missing_ad_files_emits_warning_with_ln_s_command(tmp_path, caplog): """Missing ad_files emits a WARNING with the ln -s recipe. Verifies the warning includes the suggested command, the verification step, and the audience-appropriate explanation. """ det = _make_det(read_path_template="/mnt/data/XRD/") with caplog.at_level("WARNING", logger="id3c.plans.flyscan_3idc"): ok = _check_ad_files_symlink(det, master_dir=str(tmp_path)) assert ok is False msgs = [rec.message for rec in caplog.records if rec.levelname == "WARNING"] assert msgs, "warning was not emitted" msg = msgs[0] # Substantive content the operator needs: assert "missing" in msg assert "ln -s /mnt/data/XRD eiger2_files" in msg assert "ls -l eiger2_files" in msg assert str(tmp_path) in msg # Helper does NOT actually create the link. assert not (tmp_path / "eiger2_files").exists()
[docs] def test_warning_fires_only_once_per_master_dir_target_combination(tmp_path, caplog): """Second call with the same (master_dir, target) is silent.""" det = _make_det(read_path_template="/mnt/data/XRD/") with caplog.at_level("WARNING", logger="id3c.plans.flyscan_3idc"): _check_ad_files_symlink(det, master_dir=str(tmp_path)) warnings_after_first = [r for r in caplog.records if r.levelname == "WARNING"] _check_ad_files_symlink(det, master_dir=str(tmp_path)) warnings_after_second = [r for r in caplog.records if r.levelname == "WARNING"] assert len(warnings_after_first) == 1 assert ( len(warnings_after_second) == 1 ), "warning should not fire twice for the same (master_dir, target)"
[docs] def test_warning_fires_again_when_master_dir_changes(tmp_path, caplog): """A different master_dir legitimately warns again.""" other = tmp_path / "other_session" other.mkdir() det = _make_det(read_path_template="/mnt/data/XRD/") with caplog.at_level("WARNING", logger="id3c.plans.flyscan_3idc"): _check_ad_files_symlink(det, master_dir=str(tmp_path)) _check_ad_files_symlink(det, master_dir=str(other)) warnings = [r for r in caplog.records if r.levelname == "WARNING"] assert len(warnings) == 2
[docs] def test_missing_read_path_template_uses_placeholder(tmp_path, caplog): """Missing read_path_template yields a placeholder target. The operator must fill it in; we explicitly do NOT guess `/`. """ det = _make_det(read_path_template=None) with caplog.at_level("WARNING", logger="id3c.plans.flyscan_3idc"): _check_ad_files_symlink(det, master_dir=str(tmp_path)) msg = next(r.message for r in caplog.records if r.levelname == "WARNING") assert "the directory on this workstation" in msg assert "where the area-detector files are mounted" in msg # And the placeholder is not literally `/`. assert "ln -s / eiger2_files" not in msg