ref: df1f2fb3daa1acd25c88510f259d5535fb482126
dir: /object/store/packed/quarantine_test.go/
package packed_test
import (
"bytes"
"os"
"path/filepath"
"strings"
"testing"
"codeberg.org/lindenii/furgit/internal/testgit"
objectid "codeberg.org/lindenii/furgit/object/id"
objectstore "codeberg.org/lindenii/furgit/object/store"
"codeberg.org/lindenii/furgit/object/store/packed"
objecttype "codeberg.org/lindenii/furgit/object/type"
)
func fixturePath(t *testing.T, algo objectid.Algorithm, name string) string {
t.Helper()
return filepath.Join("internal", "ingest", "testdata", "fixtures", algo.String(), name)
}
func fixtureBytes(t *testing.T, algo objectid.Algorithm, name string) []byte {
t.Helper()
path := fixturePath(t, algo, name)
dir := filepath.Dir(path)
base := filepath.Base(path)
root, err := os.OpenRoot(dir)
if err != nil {
t.Fatalf("open fixture root %q: %v", dir, err)
}
defer func() {
err := root.Close()
if err != nil {
t.Fatalf("close fixture root %q: %v", dir, err)
}
}()
data, err := root.ReadFile(base)
if err != nil {
t.Fatalf("read fixture %q: %v", base, err)
}
return data
}
func fixtureMetadata(t *testing.T, algo objectid.Algorithm) map[string]string {
t.Helper()
data := fixtureBytes(t, algo, "METADATA.txt")
out := make(map[string]string)
for line := range strings.SplitSeq(strings.TrimSpace(string(data)), "\n") {
line = strings.TrimSpace(line)
if line == "" {
continue
}
key, value, ok := strings.Cut(line, "=")
if !ok {
t.Fatalf("invalid fixture metadata line %q", line)
}
out[strings.TrimSpace(key)] = strings.TrimSpace(value)
}
return out
}
func fixtureOID(t *testing.T, algo objectid.Algorithm, key string) objectid.ObjectID {
t.Helper()
meta := fixtureMetadata(t, algo)
hex, ok := meta[key]
if !ok {
t.Fatalf("missing fixture metadata key %q", key)
}
id, err := objectid.ParseHex(algo, hex)
if err != nil {
t.Fatalf("parse fixture metadata oid %q: %v", hex, err)
}
return id
}
func TestPackQuarantinePromotePublishesWrittenObjects(t *testing.T) {
t.Parallel()
testgit.ForEachAlgorithm(t, func(t *testing.T, algo objectid.Algorithm) { //nolint:thelper
head := fixtureOID(t, algo, "head")
packBytes := fixtureBytes(t, algo, "nonthin.pack")
repo := testgit.NewRepo(t, testgit.RepoOptions{ObjectFormat: algo, Bare: true})
packRoot := repo.OpenPackRoot(t)
store, err := packed.New(packRoot, algo, packed.Options{WriteRev: true})
if err != nil {
t.Fatalf("packed.New: %v", err)
}
defer func() {
err := store.Close()
if err != nil {
t.Fatalf("store.Close: %v", err)
}
}()
quarantiner, ok := any(store).(objectstore.PackQuarantiner)
if !ok {
t.Fatal("packed store does not implement PackQuarantiner")
}
quarantine, err := quarantiner.BeginPackQuarantine(objectstore.PackQuarantineOptions{})
if err != nil {
t.Fatalf("BeginPackQuarantine: %v", err)
}
err = quarantine.WritePack(bytes.NewReader(packBytes), objectstore.PackWriteOptions{RequireTrailingEOF: true})
if err != nil {
t.Fatalf("quarantine.WritePack: %v", err)
}
ty, _, err := quarantine.ReadHeader(head)
if err != nil {
t.Fatalf("quarantine.ReadHeader: %v", err)
}
if ty != objecttype.TypeCommit {
t.Fatalf("quarantine.ReadHeader type = %v, want commit", ty)
}
_, _, err = store.ReadHeader(head)
if err == nil {
t.Fatal("store.ReadHeader unexpectedly saw quarantined object before promote")
}
err = quarantine.Promote()
if err != nil {
t.Fatalf("quarantine.Promote: %v", err)
}
err = store.Refresh()
if err != nil {
t.Fatalf("store.Refresh: %v", err)
}
ty, _, err = store.ReadHeader(head)
if err != nil {
t.Fatalf("store.ReadHeader after promote: %v", err)
}
if ty != objecttype.TypeCommit {
t.Fatalf("store.ReadHeader type = %v, want commit", ty)
}
})
}
func TestPackQuarantineDiscardDropsWrittenObjects(t *testing.T) {
t.Parallel()
testgit.ForEachAlgorithm(t, func(t *testing.T, algo objectid.Algorithm) { //nolint:thelper
head := fixtureOID(t, algo, "head")
packBytes := fixtureBytes(t, algo, "nonthin.pack")
repo := testgit.NewRepo(t, testgit.RepoOptions{ObjectFormat: algo, Bare: true})
packRoot := repo.OpenPackRoot(t)
store, err := packed.New(packRoot, algo, packed.Options{WriteRev: true})
if err != nil {
t.Fatalf("packed.New: %v", err)
}
defer func() {
err := store.Close()
if err != nil {
t.Fatalf("store.Close: %v", err)
}
}()
quarantiner, ok := any(store).(objectstore.PackQuarantiner)
if !ok {
t.Fatalf("expected objectstore.PackQuarantiner")
}
quarantine, err := quarantiner.BeginPackQuarantine(objectstore.PackQuarantineOptions{})
if err != nil {
t.Fatalf("BeginPackQuarantine: %v", err)
}
err = quarantine.WritePack(bytes.NewReader(packBytes), objectstore.PackWriteOptions{RequireTrailingEOF: true})
if err != nil {
t.Fatalf("quarantine.WritePack: %v", err)
}
err = quarantine.Discard()
if err != nil {
t.Fatalf("quarantine.Discard: %v", err)
}
err = store.Refresh()
if err != nil {
t.Fatalf("store.Refresh: %v", err)
}
_, _, err = store.ReadHeader(head)
if err == nil {
t.Fatal("store.ReadHeader unexpectedly saw discarded object")
}
})
}