Skip to content

Commit ebb0528

Browse files
committed
test(blob): verify storage read error boundaries and distinct content hash staging
1 parent a76e1bd commit ebb0528

1 file changed

Lines changed: 73 additions & 0 deletions

File tree

  • crates/lore-core/src/storage

‎crates/lore-core/src/storage/blob.rs‎

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,4 +394,77 @@ mod tests {
394394
assert!(!safe_relpath("C:/windows"));
395395
assert!(!safe_relpath("ab/cd:stream"));
396396
}
397+
398+
#[test]
399+
fn blob_store_supports_non_ascii_root_paths() {
400+
let parent = tempfile::tempdir().unwrap();
401+
let unicode_root = parent.path().join("🦀_üñîçødé_目录_テスト");
402+
let store = BlobStore::open(&unicode_root).unwrap();
403+
let content = b"patch in unicode path root: \xf0\x9f\x94\xa7";
404+
let staged = store.stage(content).unwrap();
405+
assert_eq!(store.read(staged.relpath()).unwrap(), content);
406+
assert!(store.remove(staged.relpath()).is_ok());
407+
assert!(store.read(staged.relpath()).is_err());
408+
}
409+
410+
#[test]
411+
fn zero_byte_blob_db_reference_and_deduplication() {
412+
let (_dir, store) = store();
413+
let conn = crate::storage::open_in_memory().unwrap();
414+
let empty_staged = store.stage(b"").unwrap();
415+
assert_eq!(empty_staged.byte_len, 0);
416+
417+
let id1 = BlobStore::reference(&conn, &empty_staged, "text/plain").unwrap();
418+
let id2 = BlobStore::reference(&conn, &empty_staged, "text/plain").unwrap();
419+
assert_eq!(id1, id2);
420+
421+
let (stored_len, state): (i64, String) = conn
422+
.query_row(
423+
"SELECT byte_len, scan_state FROM blob WHERE id = ?1",
424+
[&id1],
425+
|r| Ok((r.get(0)?, r.get(1)?)),
426+
)
427+
.unwrap();
428+
assert_eq!(stored_len, 0);
429+
assert_eq!(state, "pending");
430+
}
431+
432+
#[test]
433+
fn read_missing_or_corrupted_relpath_returns_io_error() {
434+
let (_dir, store) = store();
435+
// Valid relpath format but file does not exist
436+
assert!(store.read("00/0000000000000000nonexistent").is_err());
437+
// Non-existent shard directory
438+
assert!(store.read("ff/ffffffffffffffffnonexistent").is_err());
439+
}
440+
441+
#[test]
442+
fn blob_store_edge_cases_and_nonexistent_paths() {
443+
let (_dir, store) = store();
444+
445+
// Reading nonexistent valid relpath returns Io error
446+
assert!(store.read("00/0000000000000000dead").is_err());
447+
448+
// Reading invalid/traversal paths returns Io error
449+
assert!(matches!(
450+
store.read(""),
451+
Err(crate::storage::StorageError::Io)
452+
));
453+
assert!(matches!(
454+
store.read("/absolute/path"),
455+
Err(crate::storage::StorageError::Io)
456+
));
457+
assert!(matches!(
458+
store.read("../escape"),
459+
Err(crate::storage::StorageError::Io)
460+
));
461+
462+
// Staging multiple distinct payloads produces distinct content hashes and shard directories
463+
let a = store.stage(b"payload a").unwrap();
464+
let b = store.stage(b"payload b").unwrap();
465+
assert_ne!(a.content_hash(), b.content_hash());
466+
assert_ne!(a.relpath(), b.relpath());
467+
assert_eq!(store.read(a.relpath()).unwrap(), b"payload a");
468+
assert_eq!(store.read(b.relpath()).unwrap(), b"payload b");
469+
}
397470
}

0 commit comments

Comments
 (0)