ref: c9eefd50557a5436da84e0a38ee96c812d453336
dir: /objectstore/packed/read_test.go/
package packed_test
import (
"bytes"
"errors"
"os"
"strings"
"testing"
"codeberg.org/lindenii/furgit/internal/testgit"
"codeberg.org/lindenii/furgit/objectid"
"codeberg.org/lindenii/furgit/objectstore"
"codeberg.org/lindenii/furgit/objectstore/packed"
)
func TestPackedStoreReadAgainstGit(t *testing.T) {
t.Parallel()
testgit.ForEachAlgorithm(t, func(t *testing.T, algo objectid.Algorithm) { //nolint:thelper
testRepo, ids := createPackedFixtureRepo(t, algo)
store := openPackedStore(t, testRepo.Dir(), algo)
for _, id := range ids {
t.Run(id.String(), func(t *testing.T) {
wantType, wantBody, wantRaw := expectedRawObject(t, testRepo, id)
gotHeaderType, gotHeaderSize, err := store.ReadHeader(id)
if err != nil {
t.Fatalf("ReadHeader: %v", err)
}
if gotHeaderType != wantType {
t.Fatalf("ReadHeader type = %v, want %v", gotHeaderType, wantType)
}
if gotHeaderSize != int64(len(wantBody)) {
t.Fatalf("ReadHeader size = %d, want %d", gotHeaderSize, len(wantBody))
}
gotRaw, err := store.ReadBytesFull(id)
if err != nil {
t.Fatalf("ReadBytesFull: %v", err)
}
if !bytes.Equal(gotRaw, wantRaw) {
t.Fatalf("ReadBytesFull mismatch")
}
gotType, gotBody, err := store.ReadBytesContent(id)
if err != nil {
t.Fatalf("ReadBytesContent: %v", err)
}
if gotType != wantType {
t.Fatalf("ReadBytesContent type = %v, want %v", gotType, wantType)
}
if !bytes.Equal(gotBody, wantBody) {
t.Fatalf("ReadBytesContent mismatch")
}
fullReader, err := store.ReadReaderFull(id)
if err != nil {
t.Fatalf("ReadReaderFull: %v", err)
}
if got := mustReadAllAndClose(t, fullReader); !bytes.Equal(got, wantRaw) {
t.Fatalf("ReadReaderFull mismatch")
}
contentType, contentSize, contentReader, err := store.ReadReaderContent(id)
if err != nil {
t.Fatalf("ReadReaderContent: %v", err)
}
if contentType != wantType {
t.Fatalf("ReadReaderContent type = %v, want %v", contentType, wantType)
}
if contentSize != int64(len(wantBody)) {
t.Fatalf("ReadReaderContent size = %d, want %d", contentSize, len(wantBody))
}
if got := mustReadAllAndClose(t, contentReader); !bytes.Equal(got, wantBody) {
t.Fatalf("ReadReaderContent mismatch")
}
})
}
})
}
func TestPackedStoreErrors(t *testing.T) {
t.Parallel()
testgit.ForEachAlgorithm(t, func(t *testing.T, algo objectid.Algorithm) { //nolint:thelper
testRepo, _ := createPackedFixtureRepo(t, algo)
store := openPackedStore(t, testRepo.Dir(), algo)
notFoundID, err := objectid.ParseHex(algo, strings.Repeat("0", algo.HexLen()))
if err != nil {
t.Fatalf("ParseHex(notFound): %v", err)
}
if _, err := store.ReadBytesFull(notFoundID); !errors.Is(err, objectstore.ErrObjectNotFound) {
t.Fatalf("ReadBytesFull not-found error = %v", err)
}
if _, _, err := store.ReadBytesContent(notFoundID); !errors.Is(err, objectstore.ErrObjectNotFound) {
t.Fatalf("ReadBytesContent not-found error = %v", err)
}
if _, err := store.ReadReaderFull(notFoundID); !errors.Is(err, objectstore.ErrObjectNotFound) {
t.Fatalf("ReadReaderFull not-found error = %v", err)
}
if _, _, _, err := store.ReadReaderContent(notFoundID); !errors.Is(err, objectstore.ErrObjectNotFound) {
t.Fatalf("ReadReaderContent not-found error = %v", err)
}
if _, _, err := store.ReadHeader(notFoundID); !errors.Is(err, objectstore.ErrObjectNotFound) {
t.Fatalf("ReadHeader not-found error = %v", err)
}
var otherAlgo objectid.Algorithm
for _, candidate := range objectid.SupportedAlgorithms() {
if candidate != algo {
otherAlgo = candidate
break
}
}
if otherAlgo != objectid.AlgorithmUnknown {
mismatchID, err := objectid.ParseHex(otherAlgo, strings.Repeat("0", otherAlgo.HexLen()))
if err != nil {
t.Fatalf("ParseHex(mismatch): %v", err)
}
if _, err := store.ReadBytesFull(mismatchID); err == nil || !strings.Contains(err.Error(), "algorithm mismatch") {
t.Fatalf("ReadBytesFull algorithm-mismatch error = %v", err)
}
}
})
}
func TestPackedStoreNewValidation(t *testing.T) {
t.Parallel()
testRepo, _ := createPackedFixtureRepo(t, objectid.AlgorithmSHA1)
store := openPackedStore(t, testRepo.Dir(), objectid.AlgorithmSHA1)
if err := store.Close(); err != nil {
t.Fatalf("Close: %v", err)
}
if err := store.Close(); err != nil {
t.Fatalf("Close second: %v", err)
}
}
func TestPackedStoreInvalidAlgorithm(t *testing.T) {
t.Parallel()
testRepo := testgit.NewRepo(t, testgit.RepoOptions{ObjectFormat: objectid.AlgorithmSHA1, Bare: true})
root, err := os.OpenRoot(testRepo.Dir())
if err != nil {
t.Fatalf("OpenRoot(%q): %v", testRepo.Dir(), err)
}
t.Cleanup(func() { _ = root.Close() })
if _, err := packed.New(root, objectid.AlgorithmUnknown); !errors.Is(err, objectid.ErrInvalidAlgorithm) {
t.Fatalf("packed.New invalid algorithm error = %v", err)
}
}