Files
vaultik/internal/vaultik/verify_manifest_test.go
T
clawbot 86361c8b50
check / check (pull_request) Successful in 1m20s
check / check (push) Successful in 2m42s
Fail closed on unreadable manifests instead of losing blobs (closes #157)
Prune learned which blobs are in use by reading every snapshot's manifest, but merely logged and skipped one it could not download or decode. Blobs referenced only by that snapshot then looked unreferenced and were deleted, with a zero exit -- and snapshot create --prune runs this unattended. collectReferencedBlobs now errors, naming the remote key, so prune deletes nothing and exits non-zero.

Manifest generation likewise skipped a blob whose lookup failed or was missing, yielding a manifest short of what the snapshot needs; it now fails. Deep verify only warned when the manifest omitted a database blob; it now fails on any divergence. Docs corrected.

Model: opus-4-8
2026-09-22 11:45:30 +02:00

62 lines
1.9 KiB
Go

package vaultik //nolint:testpackage // calls unexported verifyManifestAgainstDatabase
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"sneak.berlin/go/vaultik/internal/log"
"sneak.berlin/go/vaultik/internal/snapshot"
)
// Blob hashes shared by the manifest-verification tests below.
const (
manifestTestBlobA = "blob-a"
manifestTestBlobB = "blob-b"
)
// TestVerifyManifestAgainstDatabase_MissingBlobFails is the regression
// guard for issue #157: deep verify must fail when the manifest omits a
// blob the database records. The divergence used to be logged as a
// warning while verification still returned ok, so an incomplete
// manifest — the exact defect that lets prune later delete a needed blob
// — passed unnoticed.
func TestVerifyManifestAgainstDatabase_MissingBlobFails(t *testing.T) {
log.Initialize(log.Config{})
t.Parallel()
v := &Vaultik{}
dbBlobs := []snapshot.BlobInfo{
{Hash: manifestTestBlobA, CompressedSize: 10},
{Hash: manifestTestBlobB, CompressedSize: 20},
}
manifest := &snapshot.Manifest{
Blobs: []snapshot.BlobInfo{
{Hash: manifestTestBlobA, CompressedSize: 10},
},
}
err := v.verifyManifestAgainstDatabase(manifest, dbBlobs)
require.Error(t, err, "verify must fail when the manifest omits a database blob")
assert.Contains(t, err.Error(), manifestTestBlobB)
}
// TestVerifyManifestAgainstDatabase_MatchingSetsPass keeps the other half
// honest: identical blob sets still verify, so the check above cannot be
// satisfied by failing everything.
func TestVerifyManifestAgainstDatabase_MatchingSetsPass(t *testing.T) {
log.Initialize(log.Config{})
t.Parallel()
v := &Vaultik{}
blobs := []snapshot.BlobInfo{
{Hash: manifestTestBlobA, CompressedSize: 10},
{Hash: manifestTestBlobB, CompressedSize: 20},
}
manifest := &snapshot.Manifest{Blobs: blobs}
require.NoError(t, v.verifyManifestAgainstDatabase(manifest, blobs))
}