test_wire_snapshot_delta.py
python
sha256:a34090cc4a394a78bd72cbbe34b08cc59525141e19135b6c0ab154f10611b9ef
debug(push/stream): instrument O-frame decode path with INF…
Sonnet 4.6
patch
121 days ago
| 1 | """TDD — snapshot delta reconstruction on the server side. |
| 2 | |
| 3 | Tests that wire_push_stream correctly: |
| 4 | A. Accepts C frames with snapshot_deltas and reconstructs full snapshots |
| 5 | B. Rejects a delta whose base_id is not in the stream cache |
| 6 | C. Delta + full snapshot in same C frame both stored correctly |
| 7 | D. Chain of deltas reconstructs all snapshots correctly |
| 8 | E. WireSnapshotDelta model rejects invalid snapshot_id / base_id |
| 9 | F. reconstruct_snapshot_delta returns correct WireSnapshot |
| 10 | G. reconstruct_snapshot_delta raises WireFrameError for missing base |
| 11 | """ |
| 12 | from __future__ import annotations |
| 13 | |
| 14 | import msgpack |
| 15 | |
| 16 | from muse.core.types import blob_id, fake_id, long_id |
| 17 | from musehub.types.json_types import StrDict |
| 18 | import pytest |
| 19 | |
| 20 | _SNAP_A = fake_id("snap-a") |
| 21 | _SNAP_B = fake_id("snap-b") |
| 22 | _SNAP_C = fake_id("snap-c") |
| 23 | _SNAP_0 = fake_id("snap-0") |
| 24 | _OBJ_F = fake_id("obj-f") |
| 25 | _OBJ_9 = fake_id("obj-9") |
| 26 | |
| 27 | |
| 28 | # --------------------------------------------------------------------------- |
| 29 | # Helpers |
| 30 | # --------------------------------------------------------------------------- |
| 31 | |
| 32 | def _sha256_manifest(manifest: StrDict) -> str: |
| 33 | raw = msgpack.packb(sorted(manifest.items()), use_bin_type=True) |
| 34 | return blob_id(raw) |
| 35 | |
| 36 | |
| 37 | def _make_manifest(n: int) -> StrDict: |
| 38 | return {f"src/file_{i}.py": fake_id(f"file-{i}") for i in range(n)} |
| 39 | |
| 40 | |
| 41 | def _snap_id(manifest: StrDict) -> str: |
| 42 | return _sha256_manifest(manifest) |
| 43 | |
| 44 | |
| 45 | # --------------------------------------------------------------------------- |
| 46 | # E. WireSnapshotDelta model validation |
| 47 | # --------------------------------------------------------------------------- |
| 48 | |
| 49 | def test_wire_snapshot_delta_valid() -> None: |
| 50 | from musehub.models.wire import WireSnapshotDelta |
| 51 | delta = WireSnapshotDelta( |
| 52 | snapshot_id=_SNAP_A, |
| 53 | base_id=_SNAP_B, |
| 54 | added={"src/foo.py": long_id("c" * 64)}, |
| 55 | removed=["src/old.py"], |
| 56 | directories=[], |
| 57 | created_at="2026-04-23T00:00:00+00:00", |
| 58 | ) |
| 59 | assert delta.snapshot_id == _SNAP_A |
| 60 | assert delta.base_id == _SNAP_B |
| 61 | |
| 62 | |
| 63 | def test_wire_snapshot_delta_invalid_snapshot_id() -> None: |
| 64 | from musehub.models.wire import WireSnapshotDelta |
| 65 | import pydantic |
| 66 | with pytest.raises(pydantic.ValidationError): |
| 67 | WireSnapshotDelta( |
| 68 | snapshot_id="not-a-valid-id", |
| 69 | base_id=_SNAP_B, |
| 70 | ) |
| 71 | |
| 72 | |
| 73 | def test_wire_snapshot_delta_invalid_base_id() -> None: |
| 74 | from musehub.models.wire import WireSnapshotDelta |
| 75 | import pydantic |
| 76 | with pytest.raises(pydantic.ValidationError): |
| 77 | WireSnapshotDelta( |
| 78 | snapshot_id=_SNAP_A, |
| 79 | base_id="bare-hex-no-prefix", |
| 80 | ) |
| 81 | |
| 82 | |
| 83 | # --------------------------------------------------------------------------- |
| 84 | # F. reconstruct_snapshot_delta returns correct WireSnapshot |
| 85 | # --------------------------------------------------------------------------- |
| 86 | |
| 87 | def test_reconstruct_snapshot_delta_basic() -> None: |
| 88 | from musehub.services.musehub_wire import reconstruct_snapshot_delta |
| 89 | from musehub.models.wire import WireSnapshotDelta |
| 90 | |
| 91 | base_manifest = _make_manifest(50) |
| 92 | base_id = _SNAP_B |
| 93 | |
| 94 | new_manifest = dict(base_manifest) |
| 95 | new_manifest["src/file_5.py"] = _OBJ_F |
| 96 | del new_manifest["src/file_10.py"] |
| 97 | snap_id = _SNAP_A |
| 98 | |
| 99 | delta = WireSnapshotDelta( |
| 100 | snapshot_id=snap_id, |
| 101 | base_id=base_id, |
| 102 | added={"src/file_5.py": _OBJ_F}, |
| 103 | removed=["src/file_10.py"], |
| 104 | directories=[], |
| 105 | created_at="2026-04-23T00:00:00+00:00", |
| 106 | ) |
| 107 | |
| 108 | cache = {base_id: base_manifest} |
| 109 | result = reconstruct_snapshot_delta(delta, cache) |
| 110 | |
| 111 | assert result.snapshot_id == snap_id |
| 112 | assert result.manifest["src/file_5.py"] == _OBJ_F |
| 113 | assert "src/file_10.py" not in result.manifest |
| 114 | assert len(result.manifest) == len(base_manifest) - 1 # file_10 removed, file_5 modified (same count) |
| 115 | |
| 116 | |
| 117 | def test_reconstruct_snapshot_delta_add_only() -> None: |
| 118 | from musehub.services.musehub_wire import reconstruct_snapshot_delta |
| 119 | from musehub.models.wire import WireSnapshotDelta |
| 120 | |
| 121 | base_manifest = _make_manifest(10) |
| 122 | base_id = _SNAP_B |
| 123 | snap_id = _SNAP_A |
| 124 | |
| 125 | new_file = "src/brand_new.py" |
| 126 | new_hash = _OBJ_9 |
| 127 | |
| 128 | delta = WireSnapshotDelta( |
| 129 | snapshot_id=snap_id, |
| 130 | base_id=base_id, |
| 131 | added={new_file: new_hash}, |
| 132 | removed=[], |
| 133 | directories=[], |
| 134 | created_at="", |
| 135 | ) |
| 136 | |
| 137 | cache = {base_id: base_manifest} |
| 138 | result = reconstruct_snapshot_delta(delta, cache) |
| 139 | assert result.manifest[new_file] == new_hash |
| 140 | assert len(result.manifest) == len(base_manifest) + 1 |
| 141 | |
| 142 | |
| 143 | # --------------------------------------------------------------------------- |
| 144 | # G. reconstruct_snapshot_delta raises WireFrameError for missing base |
| 145 | # --------------------------------------------------------------------------- |
| 146 | |
| 147 | def test_reconstruct_snapshot_delta_missing_base_raises() -> None: |
| 148 | from musehub.services.musehub_wire import reconstruct_snapshot_delta |
| 149 | from musehub.models.wire import WireSnapshotDelta |
| 150 | from muse.core.mpack import WireFrameError |
| 151 | |
| 152 | delta = WireSnapshotDelta( |
| 153 | snapshot_id=_SNAP_A, |
| 154 | base_id=_SNAP_B, |
| 155 | added={}, |
| 156 | removed=[], |
| 157 | directories=[], |
| 158 | created_at="", |
| 159 | ) |
| 160 | |
| 161 | with pytest.raises(WireFrameError, match="base snapshot"): |
| 162 | reconstruct_snapshot_delta(delta, manifest_cache={}) |
| 163 | |
| 164 | |
| 165 | # --------------------------------------------------------------------------- |
| 166 | # A. Chain reconstruction — multiple deltas in sequence |
| 167 | # --------------------------------------------------------------------------- |
| 168 | |
| 169 | def test_delta_chain_reconstruction() -> None: |
| 170 | """Build a 5-snapshot delta chain manually and verify each reconstructs.""" |
| 171 | from musehub.services.musehub_wire import reconstruct_snapshot_delta |
| 172 | from musehub.models.wire import WireSnapshotDelta |
| 173 | |
| 174 | base_manifest = _make_manifest(100) |
| 175 | base_id = _SNAP_0 |
| 176 | |
| 177 | cache: dict[str, dict] = {base_id: base_manifest} |
| 178 | expected_manifests: dict[str, dict] = {} |
| 179 | |
| 180 | prev_id = base_id |
| 181 | prev_manifest = base_manifest |
| 182 | |
| 183 | for i in range(5): |
| 184 | new_manifest = dict(prev_manifest) |
| 185 | changed_path = f"src/file_{i * 10}.py" |
| 186 | new_hash = long_id("c" * 63 + str(i)) |
| 187 | new_manifest[changed_path] = new_hash |
| 188 | snap_id = long_id("d" * 63 + str(i)) |
| 189 | |
| 190 | delta = WireSnapshotDelta( |
| 191 | snapshot_id=snap_id, |
| 192 | base_id=prev_id, |
| 193 | added={changed_path: new_hash}, |
| 194 | removed=[], |
| 195 | directories=[], |
| 196 | created_at="", |
| 197 | ) |
| 198 | result = reconstruct_snapshot_delta(delta, cache) |
| 199 | cache[snap_id] = dict(result.manifest) |
| 200 | expected_manifests[snap_id] = new_manifest |
| 201 | |
| 202 | prev_id = snap_id |
| 203 | prev_manifest = new_manifest |
| 204 | |
| 205 | for snap_id, expected in expected_manifests.items(): |
| 206 | assert cache[snap_id] == expected, f"Mismatch at {snap_id[:16]}" |
| 207 | |
| 208 | |
| 209 | # --------------------------------------------------------------------------- |
| 210 | # B. Empty delta (no-op commit) reconstructs to identical manifest |
| 211 | # --------------------------------------------------------------------------- |
| 212 | |
| 213 | def test_empty_delta_is_identity() -> None: |
| 214 | from musehub.services.musehub_wire import reconstruct_snapshot_delta |
| 215 | from musehub.models.wire import WireSnapshotDelta |
| 216 | |
| 217 | base_manifest = _make_manifest(20) |
| 218 | base_id = _SNAP_B |
| 219 | snap_id = _SNAP_A |
| 220 | |
| 221 | delta = WireSnapshotDelta( |
| 222 | snapshot_id=snap_id, |
| 223 | base_id=base_id, |
| 224 | added={}, |
| 225 | removed=[], |
| 226 | directories=[], |
| 227 | created_at="", |
| 228 | ) |
| 229 | |
| 230 | cache = {base_id: base_manifest} |
| 231 | result = reconstruct_snapshot_delta(delta, cache) |
| 232 | assert result.manifest == base_manifest |
File History
1 commit
sha256:a34090cc4a394a78bd72cbbe34b08cc59525141e19135b6c0ab154f10611b9ef
debug(push/stream): instrument O-frame decode path with INF…
Sonnet 4.6
patch
121 days ago