caddy/middleware/git/git_test.go

252 lines
5.2 KiB
Go

package git
import (
"io/ioutil"
"log"
"testing"
"time"
"github.com/mholt/caddy/middleware/git/gittest"
)
// init sets the OS used to fakeOS.
func init() {
SetOS(gittest.FakeOS)
}
func check(t *testing.T, err error) {
if err != nil {
t.Errorf("Error not expected but found %v", err)
}
}
func TestInit(t *testing.T) {
err := Init()
check(t, err)
}
func TestHelpers(t *testing.T) {
f, err := writeScriptFile([]byte("script"))
check(t, err)
var b [6]byte
_, err = f.Read(b[:])
check(t, err)
if string(b[:]) != "script" {
t.Errorf("Expected script found %v", string(b[:]))
}
out, err := runCmdOutput(gitBinary, []string{"-version"}, "")
check(t, err)
if out != gittest.CmdOutput {
t.Errorf("Expected %v found %v", gittest.CmdOutput, out)
}
err = runCmd(gitBinary, []string{"-version"}, "")
check(t, err)
wScript := gitWrapperScript()
if string(wScript) != expectedWrapperScript {
t.Errorf("Expected %v found %v", expectedWrapperScript, string(wScript))
}
f, err = writeScriptFile(wScript)
check(t, err)
repo := &Repo{Host: "github.com", KeyPath: "~/.key"}
script := string(bashScript(f.Name(), repo, []string{"clone", "git@github.com/repo/user"}))
if script != expectedBashScript {
t.Errorf("Expected %v found %v", expectedBashScript, script)
}
}
func TestGit(t *testing.T) {
// prepare
repos := []*Repo{
nil,
&Repo{Path: "gitdir", URL: "success.git"},
}
for _, r := range repos {
repo := createRepo(r)
err := repo.Prepare()
check(t, err)
}
// pull with success
logFile := gittest.Open("file")
SetLogger(log.New(logFile, "", 0))
tests := []struct {
repo *Repo
output string
}{
{
&Repo{Path: "gitdir", URL: "git@github.com:user/repo.git", KeyPath: "~/.key", Then: "echo Hello"},
`git@github.com:user/repo.git pulled.
Command echo Hello successful.
`,
},
{
&Repo{Path: "gitdir", URL: "https://github.com/user/repo.git", Then: "echo Hello"},
`https://github.com/user/repo.git pulled.
Command echo Hello successful.
`,
},
{
&Repo{URL: "git@github.com:user/repo"},
`git@github.com:user/repo pulled.
`,
},
}
for i, test := range tests {
gittest.CmdOutput = test.repo.URL
test.repo = createRepo(test.repo)
err := test.repo.Prepare()
check(t, err)
err = test.repo.Pull()
check(t, err)
out, err := ioutil.ReadAll(logFile)
check(t, err)
if test.output != string(out) {
t.Errorf("Pull with Success %v: Expected %v found %v", i, test.output, string(out))
}
}
// pull with error
repos = []*Repo{
&Repo{Path: "gitdir", URL: "http://github.com:u/repo.git"},
&Repo{Path: "gitdir", URL: "https://github.com/user/repo.git", Then: "echo Hello"},
&Repo{Path: "gitdir"},
&Repo{Path: "gitdir", KeyPath: ".key"},
}
gittest.CmdOutput = "git@github.com:u1/repo.git"
for i, repo := range repos {
repo = createRepo(repo)
err := repo.Prepare()
if err == nil {
t.Errorf("Pull with Error %v: Error expected but not found %v", i, err)
continue
}
expected := "another git repo 'git@github.com:u1/repo.git' exists at gitdir"
if expected != err.Error() {
t.Errorf("Pull with Error %v: Expected %v found %v", i, expected, err.Error())
}
}
// timeout checks
timeoutTests := []struct {
repo *Repo
shouldPull bool
}{
{&Repo{Interval: time.Millisecond * 4900}, false},
{&Repo{Interval: time.Millisecond * 1}, false},
{&Repo{Interval: time.Second * 5}, true},
{&Repo{Interval: time.Second * 10}, true},
}
for i, r := range timeoutTests {
r.repo = createRepo(r.repo)
err := r.repo.Prepare()
check(t, err)
err = r.repo.Pull()
check(t, err)
before := r.repo.lastPull
gittest.Sleep(r.repo.Interval)
err = r.repo.Pull()
after := r.repo.lastPull
check(t, err)
expected := after.After(before)
if expected != r.shouldPull {
t.Errorf("Pull with Error %v: Expected %v found %v", i, expected, r.shouldPull)
}
}
}
func createRepo(r *Repo) *Repo {
repo := &Repo{
URL: "git@github.com/user/test",
Path: ".",
Host: "github.com",
Branch: "master",
Interval: time.Second * 60,
}
if r == nil {
return repo
}
if r.Branch != "" {
repo.Branch = r.Branch
}
if r.Host != "" {
repo.Branch = r.Branch
}
if r.Interval != 0 {
repo.Interval = r.Interval
}
if r.KeyPath != "" {
repo.KeyPath = r.KeyPath
}
if r.Path != "" {
repo.Path = r.Path
}
if r.Then != "" {
repo.Then = r.Then
}
if r.URL != "" {
repo.URL = r.URL
}
return repo
}
var expectedBashScript = `#!/bin/bash
mkdir -p ~/.ssh;
touch ~/.ssh/known_hosts;
ssh-keyscan -t rsa,dsa github.com 2>&1 | sort -u - ~/.ssh/known_hosts > ~/.ssh/tmp_hosts;
cat ~/.ssh/tmp_hosts >> ~/.ssh/known_hosts;
` + gittest.TempFileName + ` -i ~/.key clone git@github.com/repo/user;
`
var expectedWrapperScript = `#!/bin/bash
# The MIT License (MIT)
# Copyright (c) 2013 Alvin Abad
if [ $# -eq 0 ]; then
echo "Git wrapper script that can specify an ssh-key file
Usage:
git.sh -i ssh-key-file git-command
"
exit 1
fi
# remove temporary file on exit
trap 'rm -f /tmp/.git_ssh.$$' 0
if [ "$1" = "-i" ]; then
SSH_KEY=$2; shift; shift
echo "ssh -i $SSH_KEY \$@" > /tmp/.git_ssh.$$
chmod +x /tmp/.git_ssh.$$
export GIT_SSH=/tmp/.git_ssh.$$
fi
# in case the git command is repeated
[ "$1" = "git" ] && shift
# Run the git command
/usr/bin/git "$@"
`