blob: b6c5a9361713f01fe886ff7bbb6c075d30aa3e18 [file] [log] [blame]
package repo_manager
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"path"
"strings"
"testing"
assert "github.com/stretchr/testify/require"
"go.skia.org/infra/go/autoroll"
"go.skia.org/infra/go/exec"
"go.skia.org/infra/go/gerrit"
"go.skia.org/infra/go/git"
git_testutils "go.skia.org/infra/go/git/testutils"
"go.skia.org/infra/go/mockhttpclient"
"go.skia.org/infra/go/testutils"
)
const (
childPath = "path/to/child"
cqExtraTrybots = ""
depotTools = ""
issueNum = int64(12345)
mockServer = "https://skia-review.googlesource.com"
mockUser = "user@chromium.org"
numChildCommits = 10
)
var (
emails = []string{"reviewer@chromium.org"}
)
func setup(t *testing.T) (string, *git_testutils.GitBuilder, []string, *git_testutils.GitBuilder, func()) {
wd, err := ioutil.TempDir("", "")
assert.NoError(t, err)
// Create child and parent repos.
child := git_testutils.GitInit(t)
f := "somefile.txt"
childCommits := make([]string, 0, 10)
for i := 0; i < numChildCommits; i++ {
childCommits = append(childCommits, child.CommitGen(f))
}
parent := git_testutils.GitInit(t)
parent.Add("DEPS", fmt.Sprintf(`deps = {
"%s": "%s@%s",
}`, childPath, child.RepoUrl(), childCommits[0]))
parent.Commit()
mockRun := exec.CommandCollector{}
mockRun.SetDelegateRun(func(cmd *exec.Command) error {
if cmd.Name == "git" && cmd.Args[0] == "cl" {
if cmd.Args[1] == "upload" {
return nil
} else if cmd.Args[1] == "issue" {
json := testutils.MarshalJSON(t, &issueJson{
Issue: issueNum,
IssueUrl: "???",
})
f := strings.Split(cmd.Args[2], "=")[1]
testutils.WriteFile(t, f, json)
return nil
}
}
return exec.DefaultRun(cmd)
})
exec.SetRunForTesting(mockRun.Run)
cleanup := func() {
exec.SetRunForTesting(exec.DefaultRun)
testutils.RemoveAll(t, wd)
child.Cleanup()
parent.Cleanup()
}
return wd, child, childCommits, parent, cleanup
}
func setupFakeGerrit(t *testing.T, wd string) *gerrit.Gerrit {
gUrl := "https://fake-skia-review.googlesource.com"
urlMock := mockhttpclient.NewURLMock()
serialized, err := json.Marshal(&gerrit.AccountDetails{
AccountId: 101,
Name: mockUser,
Email: mockUser,
UserName: mockUser,
})
assert.NoError(t, err)
serialized = append([]byte("abcd\n"), serialized...)
urlMock.MockOnce(gUrl+"/a/accounts/self/detail", mockhttpclient.MockGetDialogue(serialized))
gitcookies := path.Join(wd, "gitcookies_fake")
assert.NoError(t, ioutil.WriteFile(gitcookies, []byte(".googlesource.com\tTRUE\t/\tTRUE\t123\to\tgit-user.google.com=abc123"), os.ModePerm))
g, err := gerrit.NewGerrit(gUrl, gitcookies, urlMock.Client())
assert.NoError(t, err)
return g
}
// TestRepoManager tests all aspects of the DEPSRepoManager except for CreateNewRoll.
func TestDEPSRepoManager(t *testing.T) {
testutils.LargeTest(t)
wd, child, childCommits, parent, cleanup := setup(t)
defer cleanup()
g := setupFakeGerrit(t, wd)
s, err := GetNextRollStrategy(ROLL_STRATEGY_BATCH, "master", "")
assert.NoError(t, err)
rm, err := NewDEPSRepoManager(wd, parent.RepoUrl(), "master", childPath, "master", depotTools, g, s, nil)
assert.NoError(t, err)
assert.Equal(t, childCommits[0], rm.LastRollRev())
assert.Equal(t, childCommits[len(childCommits)-1], rm.NextRollRev())
// Test FullChildHash.
for _, c := range childCommits {
h, err := rm.FullChildHash(c[:12])
assert.NoError(t, err)
assert.Equal(t, c, h)
}
// Test update.
lastCommit := child.CommitGen("abc.txt")
assert.NoError(t, rm.Update())
assert.Equal(t, lastCommit, rm.NextRollRev())
// RolledPast.
rp, err := rm.RolledPast(childCommits[0])
assert.NoError(t, err)
assert.True(t, rp)
for _, c := range childCommits[1:] {
rp, err := rm.RolledPast(c)
assert.NoError(t, err)
assert.False(t, rp)
}
// User, name only.
assert.Equal(t, mockUser, rm.User())
}
func testCreateNewDEPSRoll(t *testing.T, strategy string, expectIdx int) {
testutils.LargeTest(t)
wd, child, childCommits, parent, cleanup := setup(t)
defer cleanup()
s, err := GetNextRollStrategy(strategy, "master", "")
assert.NoError(t, err)
g := setupFakeGerrit(t, wd)
rm, err := NewDEPSRepoManager(wd, parent.RepoUrl(), "master", childPath, "master", depotTools, g, s, nil)
assert.NoError(t, err)
// Create a roll, assert that it's at tip of tree.
issue, err := rm.CreateNewRoll(rm.LastRollRev(), rm.NextRollRev(), emails, cqExtraTrybots, false)
assert.NoError(t, err)
assert.Equal(t, issueNum, issue)
msg, err := ioutil.ReadFile(path.Join(rm.(*depsRepoManager).parentDir, ".git", "COMMIT_EDITMSG"))
assert.NoError(t, err)
from, to, err := autoroll.RollRev(strings.Split(string(msg), "\n")[0], func(h string) (string, error) {
return git.GitDir(child.Dir()).RevParse(h)
})
assert.NoError(t, err)
assert.Equal(t, childCommits[0], from)
assert.Equal(t, childCommits[expectIdx], to)
}
// TestDEPSRepoManagerBatch tests the batch roll strategy.
func TestDEPSRepoManagerBatch(t *testing.T) {
testCreateNewDEPSRoll(t, ROLL_STRATEGY_BATCH, numChildCommits-1)
}
// TestDEPSRepoManagerSingle tests the single-commit roll strategy.
func TestDEPSRepoManagerSingle(t *testing.T) {
testCreateNewDEPSRoll(t, ROLL_STRATEGY_SINGLE, 1)
}
// Verify that we ran the PreUploadSteps.
func TestRanPreUploadStepsDeps(t *testing.T) {
testutils.LargeTest(t)
wd, _, _, parent, cleanup := setup(t)
defer cleanup()
s, err := GetNextRollStrategy(ROLL_STRATEGY_BATCH, "master", "")
assert.NoError(t, err)
g := setupFakeGerrit(t, wd)
rm, err := NewDEPSRepoManager(wd, parent.RepoUrl(), "master", childPath, "master", depotTools, g, s, nil)
assert.NoError(t, err)
ran := false
rm.(*depsRepoManager).preUploadSteps = []PreUploadStep{
func(string) error {
ran = true
return nil
},
}
// Create a roll, assert that we ran the PreUploadSteps.
_, err = rm.CreateNewRoll(rm.LastRollRev(), rm.NextRollRev(), emails, cqExtraTrybots, false)
assert.NoError(t, err)
assert.True(t, ran)
}