Artifact f07f96ce9c5affdf2994d8911b4e833c9706fe329c6958562b4345477f23bb2b:
- File
internal/content/cone_reference_budget_test.go
— part of check-in
[2f0f64f464]
at
2026-10-21 11:26:47
on branch feat/submanifest-reader
— fix(content): charge the sparse card budget only to decks
Preparation counted newlines in every artifact against the 1M card budget, so a repository holding one large multi-line text file was refused far below its byte limits. Only an artifact with a verified Z card can parse as a deck, so only those are charged cards and parsed; the byte budgets still bound all content. (user: [email protected], size: 6469) [annotate] [blame] [check-ins using]
package content import ( "bytes" "context" "encoding/binary" "fmt" "testing" "time" "github.com/danmestas/go-libfossil/db" "github.com/danmestas/go-libfossil/internal/deck" "github.com/danmestas/go-libfossil/internal/delta" "github.com/danmestas/go-libfossil/internal/blob" ) func TestConeReferenceBudgetVerifiedDelta(t *testing.T) { d := setupTestDB(t) base := bytes.Repeat([]byte("0123456789abcdefghijklmnopqrstuv"), 2048) target := append([]byte(nil), base...) target[len(target)/2] = 'X' baseRID, _, err := blob.Store(d, base) if err != nil { t.Fatal(err) } targetRID, uuid, err := blob.Store(d, target) if err != nil { t.Fatal(err) } if err := d.WithTx(func(tx *db.Tx) error { saved, err := Deltify(tx, targetRID, baseRID) if err == nil && saved == 0 { t.Fatal("fixture did not store a delta") } return err }); err != nil { t.Fatal(err) } budget := ReferenceBudget{Artifacts: 10, StoredBytes: 1 << 20, InflatedBytes: 1 << 20, ExpandedBytes: 1 << 20, Cards: 100} facts, work, err := LoadConeReferenceFactsBounded(context.Background(), d, budget) if err != nil || facts == nil { t.Fatal(err) } if facts.held[uuid] != targetRID || work.ExpandBytes != int64(len(target)) { t.Fatalf("valid delta not hash-verified within budget: %+v", work) } } func TestConeReferenceBudgetRejectsLyingInflationPrefix(t *testing.T) { d := setupTestDB(t) rid, _, err := blob.Store(d, bytes.Repeat([]byte{'x'}, 1<<20)) if err != nil { t.Fatal(err) } var packed []byte if err := d.QueryRow("SELECT content FROM blob WHERE rid=?", rid).Scan(&packed); err != nil { t.Fatal(err) } binary.BigEndian.PutUint32(packed[:4], 1) if _, err := d.Exec("UPDATE blob SET content=?,size=1 WHERE rid=?", packed, rid); err != nil { t.Fatal(err) } budget := ReferenceBudget{Artifacts: 10, StoredBytes: 4096, InflatedBytes: 1024, ExpandedBytes: 1024, Cards: 10} _, work, err := LoadConeReferenceFactsBounded(context.Background(), d, budget) if err == nil || work.InflateBytes != 1 || work.ExpandBytes != 0 || work.Visits != 0 { t.Fatalf("lying prefix must not allocate actual expansion: work=%+v err=%v", work, err) } } func TestConeReferenceBudgetBeforeDeltaAllocation(t *testing.T) { d := setupTestDB(t) base := []byte("base content") baseRID, _, err := blob.Store(d, base) if err != nil { t.Fatal(err) } payload, err := delta.Create(base, bytes.Repeat([]byte{'x'}, 4096)) if err != nil { t.Fatal(err) } rid, _, err := blob.Store(d, payload) if err != nil { t.Fatal(err) } if _, err := d.Exec("INSERT INTO delta(rid,srcid) VALUES(?,?)", rid, baseRID); err != nil { t.Fatal(err) } if _, err := d.Exec("UPDATE blob SET size=1 WHERE rid=?", rid); err != nil { t.Fatal(err) } budget := ReferenceBudget{Artifacts: 10, StoredBytes: 4096, InflatedBytes: 4096, ExpandedBytes: 1024, Cards: 10} _, work, err := LoadConeReferenceFactsBounded(context.Background(), d, budget) if err == nil || work.ExpandBytes != 0 { t.Fatalf("delta allocated before output bound: work=%+v err=%v", work, err) } } // SQLite permits TEXT in a BLOB-affinity column. length(TEXT) stops at NUL; // reject that storage class before either prefix or payload reads. func TestConeReferenceBudgetCountsStoredBytesNotText(t *testing.T) { d := setupTestDB(t) rid, _, err := blob.Store(d, []byte("original")) if err != nil { t.Fatal(err) } packed := append([]byte{1, 1, 1, 1, 0x78, 0x9c, 0}, bytes.Repeat([]byte{'x'}, 1<<20)...) if _, err := d.Exec("UPDATE blob SET content=CAST(? AS TEXT),size=1 WHERE rid=?", packed, rid); err != nil { t.Fatal(err) } budget := ReferenceBudget{Artifacts: 10, StoredBytes: 4096, InflatedBytes: 32 << 20, ExpandedBytes: 4096, Cards: 10} _, work, err := LoadConeReferenceFactsBounded(context.Background(), d, budget) if err == nil || work.PrefixReads != 0 || work.PayloadReads != 0 || work.InflateBytes != 0 { t.Fatalf("TEXT bypassed byte preflight: work=%+v err=%v", work, err) } } func TestConeReferenceBudgetBeforeExpansion(t *testing.T) { d := setupTestDB(t) if _, _, err := blob.Store(d, []byte("bounded raw facts")); err != nil { t.Fatal(err) } budget := ReferenceBudget{Artifacts: 10, StoredBytes: 1, InflatedBytes: 1024, ExpandedBytes: 1024, Cards: 10} _, work, err := LoadConeReferenceFactsBounded(context.Background(), d, budget) if err == nil || work.PrefixReads != 0 || work.PayloadReads != 0 || work.InflateBytes != 0 || work.Visits != 0 { t.Fatalf("preflight must reject before content read/allocation: work=%+v err=%v", work, err) } budget.StoredBytes = 1024 facts, work, err := LoadConeReferenceFactsBounded(context.Background(), d, budget) if err != nil || facts == nil || work.PayloadReads != 1 || work.Visits != 1 { t.Fatalf("valid bounded preparation: work=%+v err=%v", work, err) } } // Ordinary file content is never parsed as a deck, so its lines are not // charged to the card budget; the byte budgets still bound it. func TestConeReferenceBudgetCardsChargeOnlyDecks(t *testing.T) { d := setupTestDB(t) text := bytes.Repeat([]byte("x\n"), 2<<20) rid, uuid, err := blob.Store(d, text) if err != nil { t.Fatal(err) } budget := ReferenceBudget{Artifacts: 1 << 18, StoredBytes: 64 << 20, InflatedBytes: 128 << 20, ExpandedBytes: 128 << 20, Cards: 1 << 20} facts, _, err := LoadConeReferenceFactsBounded(context.Background(), d, budget) if err != nil { t.Fatalf("multi-line file refused by the card budget: %v", err) } if facts.held[uuid] != rid { t.Fatal("multi-line file not held") } } func TestConeReferenceBudgetCardsRefuseLargeDeck(t *testing.T) { d := setupTestDB(t) files := make([]deck.FileCard, 0, 11) for i := 0; i < 11; i++ { files = append(files, deck.FileCard{Name: fmt.Sprintf("src/%02d", i), UUID: "da39a3ee5e6b4b0d3255bfef95601890afd80709"}) } data, err := (&deck.Deck{C: "cards", D: time.Unix(0, 0).UTC(), U: deck.User("u"), F: files}).Marshal() if err != nil { t.Fatal(err) } if _, _, err := blob.Store(d, data); err != nil { t.Fatal(err) } budget := ReferenceBudget{Artifacts: 10, StoredBytes: 1 << 20, InflatedBytes: 1 << 20, ExpandedBytes: 1 << 20, Cards: 10} if _, _, err := LoadConeReferenceFactsBounded(context.Background(), d, budget); err == nil { t.Fatal("deck over the card budget prepared") } budget.Cards = 20 if _, _, err := LoadConeReferenceFactsBounded(context.Background(), d, budget); err != nil { t.Fatalf("deck within the card budget refused: %v", err) } }