blob: a10075c23670344b622dbc08667743c60b9c4521 [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"bytes"
"fmt"
"reflect"
"testing"
"v.io/jiri"
"v.io/jiri/gerrit"
"v.io/jiri/jiritest"
"v.io/jiri/project"
"v.io/jiri/tool"
"v.io/x/devtools/tooldata"
)
func TestSendCLListsToPresubmitTest(t *testing.T) {
fake, cleanup := jiritest.NewFakeJiriRoot(t)
defer cleanup()
// Create a fake configuration file.
config := tooldata.NewConfig(
tooldata.ProjectTestsOpt(map[string][]string{
"release.go.core": []string{"go", "javascript"},
}),
tooldata.ProjectTestsOpt(map[string][]string{
"release.js.core": []string{"javascript"},
}),
)
if err := tooldata.SaveConfig(fake.X, config); err != nil {
t.Fatalf("%v", err)
}
clLists := []gerrit.CLList{
gerrit.CLList{
gerrit.GenCL(1000, 1, "release.js.core"),
},
gerrit.CLList{
gerrit.GenCLWithMoreData(2000, 1, "release.js.core", gerrit.PresubmitTestTypeNone, "vj@google.com"),
},
gerrit.CLList{
gerrit.GenCLWithMoreData(2010, 1, "release.js.core", gerrit.PresubmitTestTypeAll, "foo@bar.com"),
},
gerrit.CLList{
gerrit.GenMultiPartCL(1001, 1, "release.js.core", "t", 1, 2),
gerrit.GenMultiPartCL(1002, 1, "release.go.core", "t", 2, 2),
},
gerrit.CLList{
gerrit.GenMultiPartCL(1003, 1, "release.js.core", "t", 1, 3),
gerrit.GenMultiPartCL(1004, 1, "release.go.core", "t", 2, 3),
gerrit.GenMultiPartCLWithMoreData(1005, 1, "release.go.core", "t", 3, 3, "foo@bar.com"),
},
gerrit.CLList{
gerrit.GenCL(3000, 1, "non-existent-project"),
},
gerrit.CLList{
gerrit.GenMultiPartCL(1005, 1, "release.js.core", "t", 1, 2),
gerrit.GenMultiPartCL(1006, 1, "non-existent-project", "t", 2, 2),
},
}
sender := clsSender{
clLists: clLists,
projects: project.Projects{
project.ProjectKey("release.go.core"): project.Project{
Name: "release.go.core",
},
project.ProjectKey("release.js.core"): project.Project{
Name: "release.js.core",
},
},
// Mock out the removeOutdatedBuilds function.
removeOutdatedFn: func(jirix *jiri.X, cls clNumberToPatchsetMap) []error { return nil },
// Mock out the addPresubmitTestBuild function.
// It will return error for the first clList.
addPresubmitFn: func(jirix *jiri.X, cls gerrit.CLList, tests []string) error {
if reflect.DeepEqual(cls, clLists[0]) {
return fmt.Errorf("err")
} else {
return nil
}
},
// Mock out postMessage function.
postMessageFn: func(jirix *jiri.X, message string, refs []string, success bool) error { return nil },
}
var buf bytes.Buffer
f := false
fake.X.Context = tool.NewContext(tool.ContextOpts{
Stdout: &buf,
Stderr: &buf,
Verbose: &f,
})
if err := sender.sendCLListsToPresubmitTest(fake.X); err != nil {
t.Fatalf("want no error, got: %v", err)
}
// Check output and return value.
want := `[VANADIUM PRESUBMIT] FAIL: Add http://go/vcl/1000/1
[VANADIUM PRESUBMIT] addPresubmitTestBuild failed: err
[VANADIUM PRESUBMIT] SKIP: Add http://go/vcl/2000/1 (presubmit=none)
[VANADIUM PRESUBMIT] SKIP: Add http://go/vcl/2010/1 (non-google owner)
[VANADIUM PRESUBMIT] PASS: Add http://go/vcl/1001/1, http://go/vcl/1002/1
[VANADIUM PRESUBMIT] SKIP: Add http://go/vcl/1003/1, http://go/vcl/1004/1, http://go/vcl/1005/1 (non-google owner)
[VANADIUM PRESUBMIT] project="non-existent-project" (refs/changes/xx/3000/1) not found. Skipped.
[VANADIUM PRESUBMIT] SKIP: Empty CL set
[VANADIUM PRESUBMIT] project="non-existent-project" (refs/changes/xx/1006/1) not found. Skipped.
[VANADIUM PRESUBMIT] PASS: Add http://go/vcl/1005/1
`
if got := buf.String(); want != got {
t.Fatalf("GOT:\n%v\nWANT:\n%v", got, want)
}
if got, want := sender.clsSent, 3; got != want {
t.Fatalf("numSentCLs: got %d, want %d", got, want)
}
}
func TestGetTestsToRun(t *testing.T) {
fake, cleanup := jiritest.NewFakeJiriRoot(t)
defer cleanup()
// Create a fake configuration file.
config := tooldata.NewConfig(
tooldata.ProjectTestsOpt(map[string][]string{
"release.go.core": []string{"go", "javascript"},
}),
tooldata.TestGroupsOpt(map[string][]string{
"go": []string{"vanadium-go-build", "vanadium-go-test", "vanadium-go-race"},
}),
tooldata.TestPartsOpt(map[string][]string{
"vanadium-go-race": []string{"v.io/x/ref/services/device/...", "v.io/x/ref/runtime/..."},
}),
)
if err := tooldata.SaveConfig(fake.X, config); err != nil {
t.Fatalf("%v", err)
}
expected := []string{
"javascript",
"vanadium-go-build",
"vanadium-go-race-part0",
"vanadium-go-race-part1",
"vanadium-go-race-part2",
"vanadium-go-test",
}
sender := clsSender{}
got, err := sender.getTestsToRun(fake.X, []string{"release.go.core"})
if err != nil {
t.Fatalf("want no errors, got: %v", err)
}
if !reflect.DeepEqual(got, expected) {
t.Fatalf("want %v, got %v", expected, got)
}
}
func TestIsBuildOutdated(t *testing.T) {
type testCase struct {
refs string
cls clNumberToPatchsetMap
outdated bool
}
testCases := []testCase{
// Builds with a single ref.
testCase{
refs: "refs/changes/10/1000/2",
cls: clNumberToPatchsetMap{1000: 2},
outdated: true,
},
testCase{
refs: "refs/changes/10/1000/2",
cls: clNumberToPatchsetMap{1000: 1},
outdated: false,
},
// Builds with multiple refs.
//
// Overlapping cls.
testCase{
refs: "refs/changes/10/1001/2",
cls: clNumberToPatchsetMap{1001: 3, 2000: 2},
outdated: true,
},
// The other case with overlapping cl.
testCase{
refs: "refs/changes/10/1000/2:refs/changes/10/2000/2",
cls: clNumberToPatchsetMap{1001: 2, 2000: 2},
outdated: true,
},
// Both refs don't match.
testCase{
refs: "refs/changes/10/1000/2:refs/changes/10/2000/2",
cls: clNumberToPatchsetMap{1001: 2, 2000: 2},
outdated: true,
},
// Both patchsets in "cls" are smaller.
testCase{
refs: "refs/changes/10/1000/2:refs/changes/10/2000/2",
cls: clNumberToPatchsetMap{1000: 1, 2000: 1},
outdated: false,
},
// One of the patchsets in "cls" is larger than the one in "refs".
testCase{
refs: "refs/changes/10/1000/2:refs/changes/10/2000/2",
cls: clNumberToPatchsetMap{1000: 3, 2000: 2},
outdated: true,
},
// Both patchsets in "cls" are the same as the ones in "refs".
testCase{
refs: "refs/changes/10/1000/2:refs/changes/10/2000/2",
cls: clNumberToPatchsetMap{1000: 2, 2000: 2},
outdated: true,
},
}
for i, test := range testCases {
outdated, err := isBuildOutdated(test.refs, test.cls)
if err != nil {
t.Fatalf("want no errors, got: %v", err)
}
if expected, got := test.outdated, outdated; expected != got {
t.Fatalf("%d: want %v, got %v", i, expected, got)
}
}
}
func TestParseRefString(t *testing.T) {
type testCase struct {
ref string
expectErr bool
expectedCL int
expectedPatchSet int
}
testCases := []testCase{
// Normal case
testCase{
ref: "ref/changes/12/3412/2",
expectedCL: 3412,
expectedPatchSet: 2,
},
// Error cases
testCase{
ref: "ref/123",
expectErr: true,
},
testCase{
ref: "ref/changes/12/a/2",
expectErr: true,
},
testCase{
ref: "ref/changes/12/3412/a",
expectErr: true,
},
}
for _, test := range testCases {
cl, patchset, err := parseRefString(test.ref)
if test.expectErr {
if err == nil {
t.Fatalf("want errors, got: %v", err)
}
} else {
if err != nil {
t.Fatalf("want no errors, got: %v", err)
}
if cl != test.expectedCL {
t.Fatalf("want %v, got %v", test.expectedCL, cl)
}
if patchset != test.expectedPatchSet {
t.Fatalf("want %v, got %v", test.expectedPatchSet, patchset)
}
}
}
}