STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
test_descriptions.py
Go to the documentation of this file.
1"""Unit tests for the shared per-run description store.
2
3Run: cd webviewer && .venv/bin/python -m pytest backend/test_descriptions.py -q
4"""
5
6import json
7
8import pytest
9
10from . import config, descriptions, export_cache, runs
11
12
13@pytest.fixture
14def elodin_dir(tmp_path, monkeypatch):
15 """A fake ELODIN_DIR with the store beside the runs, as in the real layout."""
16 monkeypatch.setattr(config, "ELODIN_DIR", tmp_path)
17 monkeypatch.setattr(config, "DESCRIPTIONS_PATH", tmp_path / "run_descriptions.json")
18 monkeypatch.setattr(export_cache, "is_cached", lambda run_id: False)
19 (tmp_path / "daq_20260811_120000").mkdir()
20 return tmp_path
21
22
23def test_set_get_and_clear(elodin_dir):
24 descriptions.set_text("daq_20260811_120000", "hotfire 3, ox lead 200 ms")
25 assert descriptions.get("daq_20260811_120000") == "hotfire 3, ox lead 200 ms"
26 # Empty text is how you remove a label, not how you store an empty one.
27 descriptions.set_text("daq_20260811_120000", "")
28 assert descriptions.get("daq_20260811_120000") == ""
29 assert "daq_20260811_120000" not in descriptions.all_texts()
30
31
33 stored = descriptions.set_text("daq_20260811_120000", " two\nlines and\t gaps ")
34 assert stored["text"] == "two lines and gaps"
35
36
38 stored = descriptions.set_text("daq_20260811_120000", "x" * 500)
39 assert len(stored["text"]) == descriptions.MAX_LEN
40
41
43 # No ownership by design — there is no login on this viewer.
44 descriptions.set_text("daq_20260811_120000", "first")
45 descriptions.set_text("daq_20260811_120000", "second")
46 assert descriptions.get("daq_20260811_120000") == "second"
47
48
50 # A discarded session removes its DB dir and config snapshot but knows nothing about
51 # this file, so entries for runs that no longer exist must not accumulate.
52 config.DESCRIPTIONS_PATH.write_text(
53 json.dumps({"version": 1, "runs": {"daq_20200101_000000": {"text": "gone"}}})
54 )
55 descriptions.set_text("daq_20260811_120000", "still here")
56 stored = json.loads(config.DESCRIPTIONS_PATH.read_text())["runs"]
57 assert set(stored) == {"daq_20260811_120000"}
58
59
61 config.DESCRIPTIONS_PATH.write_text("{ not json")
62 assert descriptions.all_texts() == {}
63 assert descriptions.get("daq_20260811_120000") == ""
64
65
67 descriptions.set_text("daq_20260811_120000", "a run")
68 leftovers = [p.name for p in elodin_dir.iterdir() if p.name.startswith(".descriptions-")]
69 assert leftovers == []
70
71
73 (elodin_dir / "daq_sim_20260827_204900").mkdir()
74 descriptions.set_text("daq_20260811_120000", "cold flow")
75 found = {r["id"]: r["description"] for r in runs.list_runs()}
76 assert found["daq_20260811_120000"] == "cold flow"
77 assert found["daq_sim_20260827_204900"] == "" # unlabelled runs still list
test_unreadable_store_degrades_to_no_descriptions(elodin_dir)
test_normalise_truncates_to_max_len(elodin_dir)
test_write_is_atomic_and_leaves_no_temp_files(elodin_dir)
test_listing_carries_descriptions(elodin_dir)
test_anyone_can_overwrite_anyone(elodin_dir)
test_orphans_are_pruned_on_write(elodin_dir)
elodin_dir(tmp_path, monkeypatch)
test_normalise_forces_one_line(elodin_dir)