| 274 | |
| 275 | #[test] |
| 276 | fn truncated_file_stops_at_committed_prefix() { |
| 277 | let dir = tempfile::tempdir().unwrap(); |
| 278 | let path = dir.path().join("truncated.wal"); |
| 279 | |
| 280 | // Write records. |
| 281 | { |
| 282 | let mut writer = WalWriter::open_without_direct_io(&path).unwrap(); |
| 283 | writer |
| 284 | .append(RecordType::Put as u32, 1, 0, 0, b"good-record") |
| 285 | .unwrap(); |
| 286 | writer.sync().unwrap(); |
| 287 | } |
| 288 | |
| 289 | // Append garbage (simulating a torn write). |
| 290 | { |
| 291 | use std::io::Write; |
| 292 | let mut file = std::fs::OpenOptions::new() |
| 293 | .append(true) |
| 294 | .open(&path) |
| 295 | .unwrap(); |
| 296 | file.write_all(b"GARBAGE_PARTIAL_RECORD").unwrap(); |
| 297 | } |
| 298 | |
| 299 | // Reader should return only the valid record. |
| 300 | let reader = WalReader::open(&path).unwrap(); |
| 301 | let records: Vec<_> = reader.records().collect::<Result<_>>().unwrap(); |
| 302 | assert_eq!(records.len(), 1); |
| 303 | assert_eq!(records[0].payload, b"good-record"); |
| 304 | } |
| 305 | |
| 306 | #[test] |
| 307 | fn skip_many_unknown_optional_records_is_iterative() { |