| 185 | |
| 186 | #[test] |
| 187 | fn snapshot_with_data_roundtrip() { |
| 188 | let snap = CoreSnapshot { |
| 189 | watermark: 42, |
| 190 | sparse_documents: vec![ |
| 191 | KvPair { |
| 192 | key: "users:u1".into(), |
| 193 | value: b"alice".to_vec(), |
| 194 | }, |
| 195 | KvPair { |
| 196 | key: "users:u2".into(), |
| 197 | value: b"bob".to_vec(), |
| 198 | }, |
| 199 | ], |
| 200 | sparse_indexes: vec![KvPair { |
| 201 | key: "users:name:alice:u1".into(), |
| 202 | value: vec![], |
| 203 | }], |
| 204 | edges: vec![TenantKvPair { |
| 205 | tenant_id: 1, |
| 206 | key: "u1\0knows\0u2".into(), |
| 207 | value: b"{}".to_vec(), |
| 208 | }], |
| 209 | hnsw_indexes: vec![HnswSnapshot { |
| 210 | tenant_id: 1, |
| 211 | collection: "embeddings".into(), |
| 212 | checkpoint_bytes: vec![0xDE, 0xAD, 0xBE, 0xEF], |
| 213 | }], |
| 214 | crdt_snapshots: vec![CrdtSnapshot { |
| 215 | tenant_id: 1, |
| 216 | peer_id: 100, |
| 217 | snapshot_bytes: vec![0xAB, 0xCD], |
| 218 | }], |
| 219 | }; |
| 220 | |
| 221 | let bytes = snap.to_bytes().unwrap(); |
| 222 | let decoded = CoreSnapshot::from_bytes(&bytes).unwrap(); |
| 223 | |
| 224 | assert_eq!(decoded.watermark, 42); |
| 225 | assert_eq!(decoded.sparse_documents.len(), 2); |
| 226 | assert_eq!(decoded.sparse_documents[0].key, "users:u1"); |
| 227 | assert_eq!(decoded.edges.len(), 1); |
| 228 | assert_eq!(decoded.hnsw_indexes.len(), 1); |
| 229 | assert_eq!(decoded.hnsw_indexes[0].collection, "embeddings"); |
| 230 | assert_eq!(decoded.hnsw_indexes[0].tenant_id, 1); |
| 231 | assert_eq!(decoded.crdt_snapshots.len(), 1); |
| 232 | assert!(decoded.approx_size() > 0); |
| 233 | } |
| 234 | |
| 235 | #[test] |
| 236 | fn hnsw_snapshot_checkpoint_bytes_roundtrip() { |