blob: 3275ffb6ff930cc5c31deabbd81194dd206b3f61 [file] [log] [blame]
package repo_manager
import (
"context"
"encoding/json"
"fmt"
"io/ioutil"
"os"
"path"
"strings"
"testing"
assert "github.com/stretchr/testify/require"
"go.skia.org/infra/autoroll/go/strategy"
"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"
gitiles_testutils "go.skia.org/infra/go/gitiles/testutils"
"go.skia.org/infra/go/mockhttpclient"
"go.skia.org/infra/go/recipe_cfg"
"go.skia.org/infra/go/testutils"
"go.skia.org/infra/go/vcsinfo"
)
const (
assetVersionBase = "7"
assetVersionPrev = "6"
assetVersionNext = "8"
assetName = "test_asset"
)
var (
assetVersionFile = fmt.Sprintf(ASSET_VERSION_TMPL, "test_asset")
)
func assetCfg() *AssetRepoManagerConfig {
return &AssetRepoManagerConfig{
DepotToolsRepoManagerConfig: DepotToolsRepoManagerConfig{
CommonRepoManagerConfig: CommonRepoManagerConfig{
ChildBranch: "master",
ChildPath: "unused/by/asset/repomanager",
ParentBranch: "master",
},
ParentRepo: "", // Filled in after GitInit().
},
Asset: assetName,
ChildRepo: "", // Filled in after GitInit().
}
}
func setupAsset(t *testing.T) (context.Context, RepoManager, *gitiles_testutils.MockRepo, *git_testutils.GitBuilder, *gitiles_testutils.MockRepo, *git_testutils.GitBuilder, *vcsinfo.LongCommit, func()) {
wd, err := ioutil.TempDir("", "")
assert.NoError(t, err)
cfg := assetCfg()
lastUpload := new(vcsinfo.LongCommit)
mockRun := &exec.CommandCollector{}
ctx := exec.NewContext(context.Background(), mockRun.Run)
mockRun.SetDelegateRun(func(cmd *exec.Command) error {
if cmd.Name == "git" && cmd.Args[0] == "cl" {
if cmd.Args[1] == "upload" {
d, err := git.GitDir(cmd.Dir).Details(ctx, "HEAD")
if err != nil {
return err
}
*lastUpload = *d
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)
})
// Create child and parent repos.
parent := git_testutils.GitInit(t, ctx)
parent.Add(ctx, assetVersionFile, assetVersionBase)
parent.Commit(ctx)
cfg.ParentRepo = parent.RepoUrl()
child := git_testutils.GitInit(t, ctx)
child.Add(ctx, assetVersionFile, assetVersionBase)
child.Commit(ctx)
cfg.ChildRepo = child.RepoUrl()
urlmock := mockhttpclient.NewURLMock()
mockParent := gitiles_testutils.NewMockRepo(t, parent.RepoUrl(), git.GitDir(parent.Dir()), urlmock)
mockChild := gitiles_testutils.NewMockRepo(t, child.RepoUrl(), git.GitDir(child.Dir()), urlmock)
gUrl := "https://fake-skia-review.googlesource.com"
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))
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))
g, err := gerrit.NewGerrit(gUrl, gitcookies, urlmock.Client())
assert.NoError(t, err)
// Initial update. Everything up-to-date.
mockParent.MockGetCommit(ctx, "master")
parentMaster, err := git.GitDir(parent.Dir()).RevParse(ctx, "HEAD")
assert.NoError(t, err)
mockParent.MockReadFile(ctx, assetVersionFile, parentMaster)
mockChild.MockGetCommit(ctx, "master")
childMaster, err := git.GitDir(child.Dir()).RevParse(ctx, "HEAD")
assert.NoError(t, err)
mockChild.MockReadFile(ctx, assetVersionFile, childMaster)
recipesCfg := path.Join(testutils.GetRepoRoot(t), recipe_cfg.RECIPE_CFG_PATH)
rm, err := NewAssetRepoManager(ctx, cfg, wd, g, recipesCfg, "fake.server.com", urlmock.Client(), gerritCR(t, g), false)
assert.NoError(t, err)
assert.NoError(t, SetStrategy(ctx, rm, strategy.ROLL_STRATEGY_BATCH))
assert.NoError(t, rm.Update(ctx))
cleanup := func() {
testutils.RemoveAll(t, wd)
parent.Cleanup()
}
return ctx, rm, mockParent, parent, mockChild, child, lastUpload, cleanup
}
func TestAssetRepoManager(t *testing.T) {
testutils.LargeTest(t)
ctx, rm, mockParent, parent, mockChild, child, lastUpload, cleanup := setupAsset(t)
defer cleanup()
assert.Equal(t, assetVersionBase, rm.LastRollRev())
assert.Equal(t, assetVersionBase, rm.NextRollRev())
rolledPast, err := rm.RolledPast(ctx, assetVersionPrev)
assert.NoError(t, err)
assert.True(t, rolledPast)
rolledPast, err = rm.RolledPast(ctx, assetVersionNext)
assert.NoError(t, err)
assert.False(t, rolledPast)
// There's a new version.
mockParent.MockGetCommit(ctx, "master")
parentMaster, err := git.GitDir(parent.Dir()).RevParse(ctx, "origin/master")
assert.NoError(t, err)
mockParent.MockReadFile(ctx, assetVersionFile, parentMaster)
child.Add(ctx, assetVersionFile, assetVersionNext)
childMaster := child.Commit(ctx)
mockChild.MockGetCommit(ctx, "master")
mockChild.MockReadFile(ctx, assetVersionFile, childMaster)
assert.NoError(t, rm.Update(ctx))
assert.Equal(t, assetVersionBase, rm.LastRollRev())
assert.Equal(t, assetVersionNext, rm.NextRollRev())
rolledPast, err = rm.RolledPast(ctx, assetVersionPrev)
assert.NoError(t, err)
assert.True(t, rolledPast)
rolledPast, err = rm.RolledPast(ctx, assetVersionBase)
assert.NoError(t, err)
assert.True(t, rolledPast)
rolledPast, err = rm.RolledPast(ctx, assetVersionNext)
assert.NoError(t, err)
assert.False(t, rolledPast)
assert.Equal(t, 1, rm.CommitsNotRolled())
// Upload a CL.
issue, err := rm.CreateNewRoll(ctx, rm.LastRollRev(), rm.NextRollRev(), emails, cqExtraTrybots, false)
assert.NoError(t, err)
assert.Equal(t, issueNum, issue)
from, to, err := autoroll.RollRev(ctx, lastUpload.Subject, nil)
assert.NoError(t, err)
assert.Equal(t, assetVersionBase, from)
assert.Equal(t, assetVersionNext, to)
}
func TestAssetConfigValidation(t *testing.T) {
testutils.SmallTest(t)
cfg := assetCfg()
cfg.ChildRepo = "dummy" // Not supplied above.
cfg.ParentRepo = "dummy" // Not supplied above.
assert.NoError(t, cfg.Validate())
cfg.Asset = ""
assert.EqualError(t, cfg.Validate(), "Asset is required.")
cfg.Asset = assetName
cfg.ChildRepo = ""
assert.EqualError(t, cfg.Validate(), "ChildRepo is required.")
}