aboutsummaryrefslogtreecommitdiff
path: root/object/store/packed/refresh_test.go
blob: e54dc97dbeab381ed892e30f5a6e79d326a97663 (about) (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package packed_test

import (
	"errors"
	"os"
	"path/filepath"
	"testing"

	"lindenii.org/go/furgit/object/id"
	"lindenii.org/go/furgit/object/store"
	"lindenii.org/go/furgit/object/store/packed"
)

func TestRefreshIsExplicit(t *testing.T) {
	t.Parallel()

	for _, objectFormat := range id.SupportedObjectFormats() {
		t.Run(objectFormat.String(), func(t *testing.T) {
			t.Parallel()

			_, prefix, seeded := makeGitPack(t, objectFormat)
			oids := seeded.All()

			dir := t.TempDir()

			root, err := os.OpenRoot(dir)
			if err != nil {
				t.Fatalf("OpenRoot: %v", err)
			}

			t.Cleanup(func() { _ = root.Close() })

			packedStore, err := packed.New(root, objectFormat)
			if err != nil {
				t.Fatalf("New: %v", err)
			}

			t.Cleanup(func() { _ = packedStore.Close() })

			_, _, err = packedStore.ReadBytesContent(oids[0])
			if !errors.Is(err, store.ErrObjectNotFound) {
				t.Fatalf("empty store read error = %v, want ErrObjectNotFound", err)
			}

			t.Helper()

			base := filepath.Base(prefix)
			cp(t, prefix+".pack", filepath.Join(dir, base+".pack"))
			cp(t, prefix+".idx", filepath.Join(dir, base+".idx"))

			// New packs must stay invisible until an explicit Refresh.
			_, _, err = packedStore.ReadBytesContent(oids[0])
			if !errors.Is(err, store.ErrObjectNotFound) {
				t.Fatalf("pre-Refresh read error = %v, want ErrObjectNotFound", err)
			}

			err = packedStore.Refresh()
			if err != nil {
				t.Fatalf("Refresh: %v", err)
			}

			for _, oid := range oids {
				_, _, err := packedStore.ReadBytesContent(oid)
				if err != nil {
					t.Fatalf("post-Refresh ReadBytesContent(%s): %v", oid, err)
				}
			}
		})
	}
}

func TestRefreshRejectsIndexWithoutPack(t *testing.T) {
	t.Parallel()

	objectFormat := id.ObjectFormatSHA256

	_, prefix, _ := makeGitPack(t, objectFormat)

	dir := t.TempDir()
	cp(t, prefix+".idx", filepath.Join(dir, filepath.Base(prefix)+".idx"))

	root, err := os.OpenRoot(dir)
	if err != nil {
		t.Fatalf("OpenRoot: %v", err)
	}

	t.Cleanup(func() { _ = root.Close() })

	_, err = packed.New(root, objectFormat)
	if err == nil {
		t.Fatalf("New with orphan index: expected error")
	}
}

// cp copies one file from src to dst.
func cp(t *testing.T, src, dst string) {
	t.Helper()

	data, err := os.ReadFile(src) //nolint:gosec
	if err != nil {
		t.Fatalf("ReadFile: %v", err)
	}

	err = os.WriteFile(dst, data, 0o600) //#nosec G703
	if err != nil {
		t.Fatalf("WriteFile: %v", err)
	}
}