diff options
| author | 2026-01-29 14:38:18 +0100 | |
|---|---|---|
| committer | 2026-01-29 14:51:10 +0100 | |
| commit | 33de7fd28ce870d0b98016fcb42aa9ae5c0ca78a (patch) | |
| tree | 06e2ef213cb07396bf59e979096df910ed477ede /packed_read_test.go | |
| parent | pack: Harden pack writing test with 1000 1kb files (diff) | |
| signature | No signature | |
packed: More uniform file naming scheme
Diffstat (limited to 'packed_read_test.go')
| -rw-r--r-- | packed_read_test.go | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/packed_read_test.go b/packed_read_test.go new file mode 100644 index 00000000..184a4e5c --- /dev/null +++ b/packed_read_test.go @@ -0,0 +1,149 @@ +package furgit + +import ( + "bytes" + "fmt" + "os" + "path/filepath" + "strings" + "testing" +) + +func TestPackfileRead(t *testing.T) { + repoPath, cleanup := setupTestRepo(t) + defer cleanup() + + gitCmd(t, repoPath, "config", "gc.auto", "0") + + workDir, cleanupWork := setupWorkDir(t) + defer cleanupWork() + + err := os.WriteFile(filepath.Join(workDir, "file1.txt"), []byte("content1"), 0o644) + if err != nil { + t.Fatalf("failed to write file1.txt: %v", err) + } + err = os.WriteFile(filepath.Join(workDir, "file2.txt"), []byte("content2"), 0o644) + if err != nil { + t.Fatalf("failed to write file2.txt: %v", err) + } + + gitCmd(t, repoPath, "--work-tree="+workDir, "add", ".") + gitCmd(t, repoPath, "--work-tree="+workDir, "commit", "-m", "Test commit") + commitHash := gitCmd(t, repoPath, "rev-parse", "HEAD") + + gitCmd(t, repoPath, "repack", "-a", "-d") + + repo, err := OpenRepository(repoPath) + if err != nil { + t.Fatalf("OpenRepository failed: %v", err) + } + defer func() { _ = repo.Close() }() + + hashObj, _ := repo.ParseHash(commitHash) + obj, err := repo.ReadObject(hashObj) + if err != nil { + t.Fatalf("ReadObject from pack failed: %v", err) + } + + commit, ok := obj.(*StoredCommit) + if !ok { + t.Fatalf("expected *StoredCommit, got %T", obj) + } + + treeObj, err := repo.ReadObject(commit.Tree) + if err != nil { + t.Fatalf("ReadObject tree failed: %v", err) + } + + tree, ok := treeObj.(*StoredTree) + if !ok { + t.Fatalf("expected *StoredTree, got %T", treeObj) + } + + if len(tree.Entries) != 2 { + t.Errorf("tree entries: got %d, want 2", len(tree.Entries)) + } + + gitLsTree := gitCmd(t, repoPath, "ls-tree", commit.Tree.String()) + for _, entry := range tree.Entries { + if !strings.Contains(gitLsTree, string(entry.Name)) { + t.Errorf("git ls-tree doesn't contain %s", entry.Name) + } + } +} + +func TestPackfileLarge(t *testing.T) { + if testing.Short() { + t.Skip("skipping large packfile test in short mode") + } + + repoPath, cleanup := setupTestRepo(t) + defer cleanup() + + gitCmd(t, repoPath, "config", "gc.auto", "0") + + workDir, cleanupWork := setupWorkDir(t) + defer cleanupWork() + + numFiles := 1000 + for i := 0; i < numFiles; i++ { + filename := filepath.Join(workDir, fmt.Sprintf("file%04d.txt", i)) + content := fmt.Sprintf("Content for file %d\n", i) + err := os.WriteFile(filename, []byte(content), 0o644) + if err != nil { + t.Fatalf("failed to write %s: %v", filename, err) + } + } + + gitCmd(t, repoPath, "--work-tree="+workDir, "add", ".") + gitCmd(t, repoPath, "--work-tree="+workDir, "commit", "-m", "Large commit") + commitHash := gitCmd(t, repoPath, "rev-parse", "HEAD") + + gitCmd(t, repoPath, "repack", "-a", "-d") + + repo, err := OpenRepository(repoPath) + if err != nil { + t.Fatalf("OpenRepository failed: %v", err) + } + defer func() { _ = repo.Close() }() + + hashObj, _ := repo.ParseHash(commitHash) + obj, _ := repo.ReadObject(hashObj) + commit := obj.(*StoredCommit) + + treeObj, _ := repo.ReadObject(commit.Tree) + tree := treeObj.(*StoredTree) + + if len(tree.Entries) != numFiles { + t.Errorf("tree entries: got %d, want %d", len(tree.Entries), numFiles) + } + + gitCount := gitCmd(t, repoPath, "ls-tree", commit.Tree.String()) + gitLines := strings.Count(gitCount, "\n") + 1 + if len(tree.Entries) != gitLines { + t.Errorf("furgit found %d entries, git found %d", len(tree.Entries), gitLines) + } + + for i := 0; i < 10; i++ { + idx := i * (numFiles / 10) + expectedName := fmt.Sprintf("file%04d.txt", idx) + entry := tree.Entry([]byte(expectedName)) + if entry == nil { + t.Errorf("expected to find entry %s", expectedName) + continue + } + + blobObj, _ := repo.ReadObject(entry.ID) + blob := blobObj.(*StoredBlob) + + expectedContent := fmt.Sprintf("Content for file %d\n", idx) + if string(blob.Data) != expectedContent { + t.Errorf("blob %s: got %q, want %q", expectedName, blob.Data, expectedContent) + } + + gitData := gitCatFile(t, repoPath, "blob", entry.ID.String()) + if !bytes.Equal(blob.Data, gitData) { + t.Errorf("blob %s: furgit data doesn't match git data", expectedName) + } + } +} |
