test(blob,manifest_consistency): sanity test on repair

This commit is contained in:
Edouard Vanbelle
2026-09-02 22:18:43 +02:00
parent 2a629c4e8b
commit 49001e9beb
2 changed files with 65 additions and 0 deletions
@@ -569,4 +569,40 @@ mod tests {
fn empty_registry_refuses_to_build_page_statement() {
let _ = chunk_page_sql(&BlobReferenceRegistry::new());
}
/// Golden test — the repair statement is assembled from the same
/// registry as `chunk_page_sql`, so pin it byte-for-byte too. If
/// the registry ever changes what it produces at
/// `RefLevel::Chunk`, BOTH this test and
/// `chunk_page_statement_is_stable` above break together — an
/// operator using `?repair=true` shouldn't see the detection
/// formula report drift the repair formula can't clear.
///
/// Ships the two-term formula (`storage.files` legacy-path count +
/// `storage.chunk_manifests` chunk-membership count) twice — once
/// in SET, once in the `<>` guard. Both must stay identical so the
/// guard is meaningful.
#[tokio::test]
async fn chunk_repair_statement_is_stable() {
let sql = chunk_repair_sql(&default_registry());
let expected = r#"UPDATE storage.blobs b
SET ref_count = ((SELECT COUNT(*) FROM storage.files cnt_f
WHERE cnt_f.blob_hash = b.hash
AND NOT EXISTS (
SELECT 1 FROM storage.chunk_manifests cnt_m
WHERE cnt_m.file_hash = cnt_f.blob_hash
))
+ (SELECT COUNT(*) FROM storage.chunk_manifests cnt_m
WHERE b.hash = ANY(cnt_m.chunk_hashes)))::bigint
WHERE b.hash = $1
AND b.ref_count <> ((SELECT COUNT(*) FROM storage.files cnt_f
WHERE cnt_f.blob_hash = b.hash
AND NOT EXISTS (
SELECT 1 FROM storage.chunk_manifests cnt_m
WHERE cnt_m.file_hash = cnt_f.blob_hash
))
+ (SELECT COUNT(*) FROM storage.chunk_manifests cnt_m
WHERE b.hash = ANY(cnt_m.chunk_hashes)))::bigint"#;
assert_eq!(sql, expected, "chunk repair statement changed:\n{sql}");
}
}
@@ -534,4 +534,33 @@ mod tests {
fn empty_registry_refuses_to_build_page_statement() {
let _ = manifest_page_sql(&BlobReferenceRegistry::new());
}
/// Golden test — the repair statement is assembled from the same
/// registry as `manifest_page_sql`, so pin it byte-for-byte too.
/// If the registry ever changes what it produces at
/// `RefLevel::Manifest`, BOTH this test and
/// `manifest_page_statement_is_stable` above break together — an
/// operator using `?repair=true` shouldn't see the detection
/// formula report drift the repair formula can't clear.
///
/// Ships the three-term formula (`storage.files` +
/// `storage.content_derived_blobs` + `storage.file_attached_blobs`)
/// twice — once in SET, once in the `<>` guard. Both must stay
/// identical so the guard is meaningful (else the UPDATE would fire
/// on drift the SET doesn't fix).
#[tokio::test]
async fn manifest_repair_statement_is_stable() {
let sql = manifest_repair_sql(&default_registry());
let expected = r#"UPDATE storage.chunk_manifests m
SET ref_count = ((SELECT COUNT(*) FROM storage.files cnt_f
WHERE cnt_f.blob_hash = m.file_hash)
+ (SELECT COUNT(*) FROM storage.content_derived_blobs cnt_d WHERE cnt_d.blob_hash = m.file_hash)
+ (SELECT COUNT(*) FROM storage.file_attached_blobs cnt_a WHERE cnt_a.blob_hash = m.file_hash))::bigint
WHERE m.file_hash = $1
AND m.ref_count <> ((SELECT COUNT(*) FROM storage.files cnt_f
WHERE cnt_f.blob_hash = m.file_hash)
+ (SELECT COUNT(*) FROM storage.content_derived_blobs cnt_d WHERE cnt_d.blob_hash = m.file_hash)
+ (SELECT COUNT(*) FROM storage.file_attached_blobs cnt_a WHERE cnt_a.blob_hash = m.file_hash))::bigint"#;
assert_eq!(sql, expected, "manifest repair statement changed:\n{sql}");
}
}