This repository has been archived on 2026-10-08. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
recoll-modern/tests/indexing/test_map_export.py
T

67 lines
2.3 KiB
Python

import os
import struct
from pathlib import Path
import pytest
from recoll_modern.indexing.map_export import export_membership_map
class FakeRows:
def __init__(self, rows: dict[str, list[str]]) -> None:
self.rows = rows
def membership_map_rows(self) -> list[tuple[str, list[str]]]:
return list(self.rows.items())
def _decode(path: Path) -> dict[str, str]:
data = path.read_bytes()
assert data[:4] == b"RCM1"
offset = 4
result = {}
while offset < len(data):
path_length = struct.unpack_from(">I", data, offset)[0]
offset += 4
name = data[offset:offset + path_length].decode()
offset += path_length
value_length = struct.unpack_from(">I", data, offset)[0]
offset += 4
value = data[offset:offset + value_length].decode()
offset += value_length
result[name] = value
return result
def test_export_is_atomic_and_handles_newlines(tmp_path: Path) -> None:
destination = tmp_path / "membership.map"
export_membership_map(FakeRows({"/documents/odd\nname.pdf": ["c0000000001"]}), destination)
assert _decode(destination) == {"/documents/odd\nname.pdf": "c0000000001"}
assert list(tmp_path.glob("*.tmp")) == []
assert destination.stat().st_mode & 0o777 == 0o640
def test_export_sorts_paths_and_ids(tmp_path: Path) -> None:
destination = tmp_path / "membership.map"
export_membership_map(FakeRows({
"/documents/z": ["c0000000002", "c0000000001"],
"/documents/a": ["c0000000003"],
}), destination)
assert list(_decode(destination)) == ["/documents/a", "/documents/z"]
assert _decode(destination)["/documents/z"] == "c0000000001 c0000000002"
def test_failed_replace_preserves_old_map(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
destination = tmp_path / "membership.map"
export_membership_map(FakeRows({"/documents/old": ["c0000000001"]}), destination)
old = destination.read_bytes()
def fail_replace(source: str | Path, target: str | Path) -> None:
raise OSError("injected failure")
monkeypatch.setattr(os, "replace", fail_replace)
with pytest.raises(OSError, match="injected"):
export_membership_map(FakeRows({"/documents/new": ["c0000000002"]}), destination)
assert destination.read_bytes() == old
assert list(tmp_path.glob("*.tmp")) == []