|
3 | 3 |
|
4 | 4 | from __future__ import annotations |
5 | 5 |
|
| 6 | +import json |
| 7 | + |
6 | 8 | import numpy as np |
7 | 9 | import pytest |
8 | 10 |
|
|
11 | 13 | BruteForceIndex, |
12 | 14 | HashingEmbedder, |
13 | 15 | MemoryStore, |
| 16 | + UsearchIndex, |
14 | 17 | ) |
15 | 18 |
|
16 | 19 |
|
@@ -116,6 +119,38 @@ def test_save_and_load(tmp_path): |
116 | 119 | assert hits[0].metadata == {"k": 1} |
117 | 120 |
|
118 | 121 |
|
| 122 | +def test_snapshot_records_resolved_backend_not_auto(tmp_path): |
| 123 | + # backend="auto" must persist the concrete backend it resolved to, never "auto", |
| 124 | + # so load() rebuilds the right index type. |
| 125 | + store = make_store(backend="auto") |
| 126 | + store.save(tmp_path / "snap") |
| 127 | + with open(tmp_path / "snap" / "meta.json") as f: |
| 128 | + meta = json.load(f) |
| 129 | + assert meta["backend"] in ("bruteforce", "usearch") |
| 130 | + assert meta["backend"] != "auto" |
| 131 | + |
| 132 | + |
| 133 | +def test_usearch_auto_save_load_roundtrip(tmp_path): |
| 134 | + # Regression: backend="auto" + large expected_size selects UsearchIndex; the |
| 135 | + # snapshot must reload as UsearchIndex rather than crashing in BruteForceIndex.load. |
| 136 | + pytest.importorskip("usearch") |
| 137 | + emb = HashingEmbedder(dims=64) |
| 138 | + store = MemoryStore(embedder=emb, backend="auto", expected_size=200_000) |
| 139 | + assert isinstance(store._collection, UsearchIndex) |
| 140 | + |
| 141 | + store.upsert("name", "user is Ada") # fact -> brute force |
| 142 | + for i in range(20): |
| 143 | + store.add(f"memory number {i} about topic {i % 5}") |
| 144 | + store.save(tmp_path / "snap") |
| 145 | + |
| 146 | + loaded = MemoryStore.load(tmp_path / "snap", embedder=HashingEmbedder(dims=64)) |
| 147 | + assert isinstance(loaded._collection, UsearchIndex) |
| 148 | + assert len(loaded) == 21 |
| 149 | + assert loaded.all(namespace=FACTS_NAMESPACE)[0].text == "user is Ada" |
| 150 | + hits = loaded.search("memory number 7 about topic 2", limit=1) |
| 151 | + assert hits and "number 7" in hits[0].text |
| 152 | + |
| 153 | + |
119 | 154 | def test_dimension_mismatch_rejected(): |
120 | 155 | store = make_store() # dims=64 |
121 | 156 | with pytest.raises(ValueError): |
|
0 commit comments