summaryrefslogtreecommitdiffstats
path: root/packages/meshbay-node/tests/test_index_cache.py
blob: 24e2f768a441bd11f8ee47d392928b386e75d061 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
"""Tests for the (path, size, mtime) -> hash cache (indexer/cache.py)."""

import pytest

from meshbay_node.indexer.cache import IndexCache


@pytest.fixture
async def cache(tmp_path):
    c = IndexCache(db_path=tmp_path / "index_cache.db")
    await c.open()
    yield c
    await c.close()


@pytest.mark.asyncio
async def test_put_then_lookup_hits(cache):
    await cache.put("/lib/a.mkv", size=1000, mtime=111.0, hash="abc123",
                     type="video", added_at=42)

    hit = await cache.lookup("/lib/a.mkv", size=1000, mtime=111.0)

    assert hit is not None
    assert hit.hash == "abc123"
    assert hit.type == "video"
    assert hit.added_at == 42


@pytest.mark.asyncio
async def test_lookup_misses_on_unknown_path(cache):
    assert await cache.lookup("/lib/never-seen.mkv", size=1, mtime=1.0) is None


@pytest.mark.asyncio
async def test_lookup_misses_on_different_mtime(cache):
    await cache.put("/lib/a.mkv", size=1000, mtime=111.0, hash="abc123",
                     type="video", added_at=42)

    assert await cache.lookup("/lib/a.mkv", size=1000, mtime=222.0) is None


@pytest.mark.asyncio
async def test_lookup_misses_on_different_size(cache):
    await cache.put("/lib/a.mkv", size=1000, mtime=111.0, hash="abc123",
                     type="video", added_at=42)

    assert await cache.lookup("/lib/a.mkv", size=2000, mtime=111.0) is None


@pytest.mark.asyncio
async def test_put_overwrites_previous_row_for_same_path(cache):
    await cache.put("/lib/a.mkv", size=1000, mtime=111.0, hash="old",
                     type="video", added_at=1)
    await cache.put("/lib/a.mkv", size=2000, mtime=222.0, hash="new",
                     type="video", added_at=2)

    assert await cache.lookup("/lib/a.mkv", size=1000, mtime=111.0) is None
    hit = await cache.lookup("/lib/a.mkv", size=2000, mtime=222.0)
    assert hit.hash == "new"


@pytest.mark.asyncio
async def test_count_reflects_number_of_rows(cache):
    assert await cache.count() == 0

    await cache.put("/lib/a.mkv", size=1000, mtime=111.0, hash="a",
                     type="video", added_at=1)
    await cache.put("/lib/b.mkv", size=2000, mtime=222.0, hash="b",
                     type="video", added_at=2)

    assert await cache.count() == 2


@pytest.mark.asyncio
async def test_all_paths_returns_every_row(cache):
    await cache.put("/lib/a.mkv", size=1000, mtime=111.0, hash="a",
                     type="video", added_at=1)
    await cache.put("/lib/b.mkv", size=2000, mtime=222.0, hash="b",
                     type="video", added_at=2)

    assert set(await cache.all_paths()) == {"/lib/a.mkv", "/lib/b.mkv"}


@pytest.mark.asyncio
async def test_remove_many_drops_only_the_given_paths(cache):
    await cache.put("/lib/a.mkv", size=1000, mtime=111.0, hash="a",
                     type="video", added_at=1)
    await cache.put("/lib/b.mkv", size=2000, mtime=222.0, hash="b",
                     type="video", added_at=2)

    await cache.remove_many(["/lib/a.mkv"])

    assert await cache.lookup("/lib/a.mkv", size=1000, mtime=111.0) is None
    assert await cache.lookup("/lib/b.mkv", size=2000, mtime=222.0) is not None
    assert await cache.count() == 1


@pytest.mark.asyncio
async def test_remove_many_with_empty_list_is_a_no_op(cache):
    await cache.put("/lib/a.mkv", size=1000, mtime=111.0, hash="a",
                     type="video", added_at=1)

    await cache.remove_many([])

    assert await cache.count() == 1


@pytest.mark.asyncio
async def test_cache_survives_reopen(tmp_path):
    db_path = tmp_path / "index_cache.db"

    c1 = IndexCache(db_path=db_path)
    await c1.open()
    await c1.put("/lib/a.mkv", size=1000, mtime=111.0, hash="abc123",
                 type="video", added_at=42)
    await c1.close()

    c2 = IndexCache(db_path=db_path)
    await c2.open()
    hit = await c2.lookup("/lib/a.mkv", size=1000, mtime=111.0)
    await c2.close()

    assert hit is not None
    assert hit.hash == "abc123"