diff options
Diffstat (limited to 'packages/meshbay-node/tests/test_index_progress.py')
| -rw-r--r-- | packages/meshbay-node/tests/test_index_progress.py | 57 |
1 files changed, 48 insertions, 9 deletions
diff --git a/packages/meshbay-node/tests/test_index_progress.py b/packages/meshbay-node/tests/test_index_progress.py index ecdc223..2fa8a5c 100644 --- a/packages/meshbay-node/tests/test_index_progress.py +++ b/packages/meshbay-node/tests/test_index_progress.py @@ -14,7 +14,7 @@ from fastapi.testclient import TestClient from meshbay_node.config import Config, HubConfig, KeystoreConfig, NodeConfig from meshbay_node.daemon import NodeDaemon from meshbay_node.indexer.group_index import GroupIndex -from meshbay_node.indexer.indexer import IndexProgress +from meshbay_node.indexer.indexer import NO_ANSWER, IndexProgress, UnreadFile from meshbay_node.transport.webrtc_server import WebRTCPeerSession from meshbay_node.ui.app import create_ui_app @@ -64,19 +64,30 @@ def _ui_client(state: dict) -> TestClient: "indexes": {}, **state})) +def _indexer(progress: IndexProgress, *, unread=(), stalled=None, slow=None) -> MagicMock: + """What the routes read off an indexer, with nothing wrong unless said.""" + indexer = MagicMock() + indexer.progress = progress + indexer.unread = {u.path: u for u in unread} + indexer.unread_count.return_value = len(indexer.unread) + indexer.stalled = dict(stalled or {}) + indexer.disk_wait.return_value = slow + return indexer + + def test_index_status_route_idle_for_unknown_group(): client = _ui_client({"indexers": {}}) resp = client.get("/api/groups/unknown-group/index-status") assert resp.status_code == 200 assert resp.json() == {"scanning": False, "scanned_bytes": 0, - "total_bytes": 0, "current_dir": ""} + "total_bytes": 0, "current_dir": "", + "unread": [], "unread_total": 0, "stalled": []} def test_index_status_route_reflects_indexer_progress(): - fake_indexer = MagicMock() - fake_indexer.progress = IndexProgress( + fake_indexer = _indexer(IndexProgress( scanning=True, scanned_bytes=1_000_000, total_bytes=4_000_000_000, - current_dir="2024") + current_dir="2024")) client = _ui_client({"indexers": {"g" * 32: fake_indexer}}) resp = client.get(f"/api/groups/{'g' * 32}/index-status") @@ -84,20 +95,47 @@ def test_index_status_route_reflects_indexer_progress(): assert resp.json() == { "scanning": True, "scanned_bytes": 1_000_000, "total_bytes": 4_000_000_000, "current_dir": "2024", + "unread": [], "unread_total": 0, "stalled": [], } +def test_the_operator_is_shown_what_a_scan_could_not_read_and_where_it_stopped(): + """On the node's own machine only: these are paths. A scan that sat still + used to say nothing about the file it sat on, and a file it gave up on was + one line in a log the operator does not read.""" + silent = UnreadFile(path="/srv/music/a/one.flac", root="music", reason=NO_ANSWER, + size=1, mtime=1.0) + refused = UnreadFile(path="/srv/music/b/two.flac", root="music", + reason="Permission denied", size=1, mtime=1.0) + indexer = _indexer(IndexProgress(), unread=[silent, refused], + stalled={"music": "/srv/music/a/three.flac"}, + slow=("/srv/music/a/four.flac", 23.7)) + config = MagicMock() + config.groups = [] + client = _ui_client({"config": config, "indexers": {"g" * 32: indexer}}) + + one = client.get(f"/api/groups/{'g' * 32}/index-status").json() + assert one["unread"] == [ + {"root": "music", "path": "/srv/music/a/one.flac", "reason": "no_answer"}, + {"root": "music", "path": "/srv/music/b/two.flac", "reason": "Permission denied"}] + assert one["unread_total"] == 2 + assert one["stalled"] == [{"root": "music", "path": "/srv/music/a/three.flac"}] + + (band,) = client.get("/api/index-status").json()["groups"] + assert (band["slow_path"], band["slow_secs"]) == ("/srv/music/a/four.flac", 23) + assert (band["unread"], band["stalled"]) == (2, ["music"]) + + # ── /api/index-status (loopback, every group) ─────────────────────────────── def test_every_group_is_described_including_one_still_being_attached(): """The band reads one route for the whole node. A group in its initial scan is in state["indexers"] and not yet in groups_ctx, and must be there.""" - busy, idle = MagicMock(), MagicMock() - busy.progress = IndexProgress( + busy = _indexer(IndexProgress( scanning=True, scanned_bytes=10, total_bytes=40, current_dir="2024", root="results", root_pos=1, kind="scan", files_done=1, files_total=4, - queued=["archive"]) - idle.progress = IndexProgress() + queued=["archive"])) + idle = _indexer(IndexProgress()) config = MagicMock() named = MagicMock() named.id, named.name = "a" * 32, "outputs" @@ -112,6 +150,7 @@ def test_every_group_is_described_including_one_still_being_attached(): "kind": "scan", "root": "results", "current_dir": "2024", "scanned_bytes": 10, "total_bytes": 40, "files_done": 1, "files_total": 4, "queued": ["archive"], + "slow_path": "", "slow_secs": 0, "unread": 0, "stalled": [], } assert groups["b" * 32]["group_name"] == "b" * 8 assert groups["b" * 32]["scanning"] is False |