mirror of https://github.com/portainer/portainer
158 lines
4.2 KiB
Go
158 lines
4.2 KiB
Go
package git
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/go-git/go-git/v5"
|
|
"github.com/go-git/go-git/v5/plumbing/object"
|
|
"github.com/pkg/errors"
|
|
"github.com/portainer/portainer/api/archive"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func setup(t *testing.T) string {
|
|
dir := t.TempDir()
|
|
bareRepoDir := filepath.Join(dir, "test-clone.git")
|
|
|
|
file, err := os.OpenFile("./testdata/test-clone-git-repo.tar.gz", os.O_RDONLY, 0755)
|
|
if err != nil {
|
|
t.Fatal(errors.Wrap(err, "failed to open an archive"))
|
|
}
|
|
|
|
err = archive.ExtractTarGz(file, dir)
|
|
if err != nil {
|
|
t.Fatal(errors.Wrapf(err, "failed to extract file from the archive to a folder %s", dir))
|
|
}
|
|
|
|
return bareRepoDir
|
|
}
|
|
|
|
func Test_ClonePublicRepository_Shallow(t *testing.T) {
|
|
service := Service{git: gitClient{preserveGitDirectory: true}} // no need for http client since the test access the repo via file system.
|
|
repositoryURL := setup(t)
|
|
referenceName := "refs/heads/main"
|
|
|
|
dir := t.TempDir()
|
|
t.Logf("Cloning into %s", dir)
|
|
err := service.CloneRepository(dir, repositoryURL, referenceName, "", "")
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, 1, getCommitHistoryLength(t, err, dir), "cloned repo has incorrect depth")
|
|
}
|
|
|
|
func Test_ClonePublicRepository_NoGitDirectory(t *testing.T) {
|
|
service := Service{git: gitClient{preserveGitDirectory: false}} // no need for http client since the test access the repo via file system.
|
|
repositoryURL := setup(t)
|
|
referenceName := "refs/heads/main"
|
|
|
|
dir := t.TempDir()
|
|
t.Logf("Cloning into %s", dir)
|
|
err := service.CloneRepository(dir, repositoryURL, referenceName, "", "")
|
|
assert.NoError(t, err)
|
|
assert.NoDirExists(t, filepath.Join(dir, ".git"))
|
|
}
|
|
|
|
func Test_cloneRepository(t *testing.T) {
|
|
service := Service{git: gitClient{preserveGitDirectory: true}} // no need for http client since the test access the repo via file system.
|
|
|
|
repositoryURL := setup(t)
|
|
referenceName := "refs/heads/main"
|
|
|
|
dir := t.TempDir()
|
|
t.Logf("Cloning into %s", dir)
|
|
|
|
err := service.cloneRepository(dir, cloneOptions{
|
|
repositoryUrl: repositoryURL,
|
|
referenceName: referenceName,
|
|
depth: 10,
|
|
})
|
|
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, 4, getCommitHistoryLength(t, err, dir), "cloned repo has incorrect depth")
|
|
}
|
|
|
|
func Test_latestCommitID(t *testing.T) {
|
|
service := Service{git: gitClient{preserveGitDirectory: true}} // no need for http client since the test access the repo via file system.
|
|
|
|
repositoryURL := setup(t)
|
|
referenceName := "refs/heads/main"
|
|
|
|
id, err := service.LatestCommitID(repositoryURL, referenceName, "", "")
|
|
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, "68dcaa7bd452494043c64252ab90db0f98ecf8d2", id)
|
|
}
|
|
|
|
func getCommitHistoryLength(t *testing.T, err error, dir string) int {
|
|
repo, err := git.PlainOpen(dir)
|
|
if err != nil {
|
|
t.Fatalf("can't open a git repo at %s with error %v", dir, err)
|
|
}
|
|
iter, err := repo.Log(&git.LogOptions{All: true})
|
|
if err != nil {
|
|
t.Fatalf("can't get a commit history iterator with error %v", err)
|
|
}
|
|
count := 0
|
|
err = iter.ForEach(func(_ *object.Commit) error {
|
|
count++
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("can't iterate over the commit history with error %v", err)
|
|
}
|
|
return count
|
|
}
|
|
|
|
type testDownloader struct {
|
|
called bool
|
|
}
|
|
|
|
func (t *testDownloader) download(_ context.Context, _ string, _ cloneOptions) error {
|
|
t.called = true
|
|
return nil
|
|
}
|
|
|
|
func (t *testDownloader) latestCommitID(_ context.Context, _ fetchOptions) (string, error) {
|
|
return "", nil
|
|
}
|
|
|
|
func Test_cloneRepository_azure(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
url string
|
|
called bool
|
|
}{
|
|
{
|
|
name: "Azure HTTP URL",
|
|
url: "https://Organisation@dev.azure.com/Organisation/Project/_git/Repository",
|
|
called: true,
|
|
},
|
|
{
|
|
name: "Azure SSH URL",
|
|
url: "git@ssh.dev.azure.com:v3/Organisation/Project/Repository",
|
|
called: true,
|
|
},
|
|
{
|
|
name: "Something else",
|
|
url: "https://example.com",
|
|
called: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
azure := &testDownloader{}
|
|
git := &testDownloader{}
|
|
|
|
s := &Service{azure: azure, git: git}
|
|
s.cloneRepository("", cloneOptions{repositoryUrl: tt.url, depth: 1})
|
|
|
|
// if azure API is called, git isn't and vice versa
|
|
assert.Equal(t, tt.called, azure.called)
|
|
assert.Equal(t, tt.called, !git.called)
|
|
})
|
|
}
|
|
}
|