1package repository
2
3import (
4 "log"
5 "math/rand"
6 "os"
7 "strings"
8 "testing"
9
10 "github.com/stretchr/testify/assert"
11 "github.com/stretchr/testify/require"
12
13 "github.com/MichaelMure/git-bug/util/git"
14)
15
16func CleanupTestRepos(repos ...Repo) {
17 var firstErr error
18 for _, repo := range repos {
19 path := repo.GetPath()
20 if strings.HasSuffix(path, "/.git") {
21 // for a normal repository (not --bare), we want to remove everything
22 // including the parent directory where files are checked out
23 path = strings.TrimSuffix(path, "/.git")
24
25 // Testing non-bare repo should also check path is
26 // only .git (i.e. ./.git), but doing so, we should
27 // try to remove the current directory and hav some
28 // trouble. In the present case, this case should not
29 // occur.
30 // TODO consider warning or error when path == ".git"
31 }
32 // fmt.Println("Cleaning repo:", path)
33 err := os.RemoveAll(path)
34 if err != nil {
35 log.Println(err)
36 if firstErr == nil {
37 firstErr = err
38 }
39 }
40 }
41
42 if firstErr != nil {
43 log.Fatal(firstErr)
44 }
45}
46
47type RepoCreator func(bare bool) TestedRepo
48type RepoCleaner func(repos ...Repo)
49
50// Test suite for a Repo implementation
51func RepoTest(t *testing.T, creator RepoCreator, cleaner RepoCleaner) {
52 t.Run("Blob-Tree-Commit-Ref", func(t *testing.T) {
53 repo := creator(false)
54 defer cleaner(repo)
55
56 // Blob
57
58 data := randomData()
59
60 blobHash1, err := repo.StoreData(data)
61 require.NoError(t, err)
62 assert.True(t, blobHash1.IsValid())
63
64 blob1Read, err := repo.ReadData(blobHash1)
65 require.NoError(t, err)
66 assert.Equal(t, data, blob1Read)
67
68 // Tree
69
70 blobHash2, err := repo.StoreData(randomData())
71 require.NoError(t, err)
72 blobHash3, err := repo.StoreData(randomData())
73 require.NoError(t, err)
74
75 tree1 := []TreeEntry{
76 {
77 ObjectType: Blob,
78 Hash: blobHash1,
79 Name: "blob1",
80 },
81 {
82 ObjectType: Blob,
83 Hash: blobHash2,
84 Name: "blob2",
85 },
86 }
87
88 treeHash1, err := repo.StoreTree(tree1)
89 require.NoError(t, err)
90 assert.True(t, treeHash1.IsValid())
91
92 tree1Read, err := repo.ReadTree(treeHash1)
93 require.NoError(t, err)
94 assert.ElementsMatch(t, tree1, tree1Read)
95
96 tree2 := []TreeEntry{
97 {
98 ObjectType: Tree,
99 Hash: treeHash1,
100 Name: "tree1",
101 },
102 {
103 ObjectType: Blob,
104 Hash: blobHash3,
105 Name: "blob3",
106 },
107 }
108
109 treeHash2, err := repo.StoreTree(tree2)
110 require.NoError(t, err)
111 assert.True(t, treeHash2.IsValid())
112
113 tree2Read, err := repo.ReadTree(treeHash2)
114 require.NoError(t, err)
115 assert.ElementsMatch(t, tree2, tree2Read)
116
117 // Commit
118
119 commit1, err := repo.StoreCommit(treeHash1)
120 require.NoError(t, err)
121 assert.True(t, commit1.IsValid())
122
123 treeHash1Read, err := repo.GetTreeHash(commit1)
124 require.NoError(t, err)
125 assert.Equal(t, treeHash1, treeHash1Read)
126
127 commit2, err := repo.StoreCommitWithParent(treeHash2, commit1)
128 require.NoError(t, err)
129 assert.True(t, commit2.IsValid())
130
131 treeHash2Read, err := repo.GetTreeHash(commit2)
132 require.NoError(t, err)
133 assert.Equal(t, treeHash2, treeHash2Read)
134
135 // Ref
136
137 exist1, err := repo.RefExist("refs/bugs/ref1")
138 require.NoError(t, err)
139 assert.False(t, exist1)
140
141 err = repo.UpdateRef("refs/bugs/ref1", commit2)
142 require.NoError(t, err)
143
144 exist1, err = repo.RefExist("refs/bugs/ref1")
145 require.NoError(t, err)
146 assert.True(t, exist1)
147
148 ls, err := repo.ListRefs("refs/bugs")
149 require.NoError(t, err)
150 assert.Equal(t, []string{"refs/bugs/ref1"}, ls)
151
152 err = repo.CopyRef("refs/bugs/ref1", "refs/bugs/ref2")
153 require.NoError(t, err)
154
155 ls, err = repo.ListRefs("refs/bugs")
156 require.NoError(t, err)
157 assert.Equal(t, []string{"refs/bugs/ref1", "refs/bugs/ref2"}, ls)
158
159 commits, err := repo.ListCommits("refs/bugs/ref2")
160 require.NoError(t, err)
161 assert.Equal(t, []git.Hash{commit1, commit2}, commits)
162
163 // Graph
164
165 commit3, err := repo.StoreCommitWithParent(treeHash1, commit1)
166 require.NoError(t, err)
167
168 ancestorHash, err := repo.FindCommonAncestor(commit2, commit3)
169 require.NoError(t, err)
170 assert.Equal(t, commit1, ancestorHash)
171 })
172
173 t.Run("Local config", func(t *testing.T) {
174 repo := creator(false)
175 defer cleaner(repo)
176
177 testConfig(t, repo.LocalConfig())
178 })
179}
180
181func randomData() []byte {
182 var letterRunes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
183 b := make([]byte, 32)
184 for i := range b {
185 b[i] = letterRunes[rand.Intn(len(letterRunes))]
186 }
187 return b
188}