repo_testing.go

  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}