diff options
| author | 2026-02-21 05:35:12 +0800 | |
|---|---|---|
| committer | 2026-02-21 11:15:18 +0800 | |
| commit | ae879b8cf5a87199802a33d6b15c76afafa8002b (patch) | |
| tree | a93e9486a9610b78823e157c68b75e0724366217 /objectstore/packed/read_test.go | |
| parent | cache/lru: Add basic LRU (diff) | |
| signature | No signature | |
objectstore/packed: Add initial pack reading support
Diffstat (limited to 'objectstore/packed/read_test.go')
| -rw-r--r-- | objectstore/packed/read_test.go | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/objectstore/packed/read_test.go b/objectstore/packed/read_test.go new file mode 100644 index 00000000..9244d573 --- /dev/null +++ b/objectstore/packed/read_test.go @@ -0,0 +1,149 @@ +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) { + testgit.ForEachAlgorithm(t, func(t *testing.T, algo objectid.Algorithm) { + testRepo, ids := createPackedFixtureRepo(t, algo) + store := openPackedStore(t, testRepo.Dir(), algo) + + for _, id := range ids { + id := id + 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) { + testgit.ForEachAlgorithm(t, func(t *testing.T, algo objectid.Algorithm) { + 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) { + 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) { + testRepo := testgit.NewBareRepo(t, objectid.AlgorithmSHA1) + 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) + } +} |
