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