blob: 12c467ca18c8227b95448ee29e13d5964a7d216b [file] [log] [blame]
// Copyright 2022 The LUCI Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main
import (
"context"
"flag"
"os/exec"
"path/filepath"
"testing"
"go.chromium.org/luci/buildbucket"
bbpb "go.chromium.org/luci/buildbucket/proto"
"go.chromium.org/luci/buildbucket/protoutil"
"go.chromium.org/luci/common/errors"
"go.chromium.org/luci/common/logging/memlogger"
"go.chromium.org/luci/gae/impl/memory"
"go.chromium.org/luci/lucictx"
"go.chromium.org/luci/luciexe"
. "github.com/smartystreets/goconvey/convey"
. "go.chromium.org/luci/common/testing/assertions"
)
func TestReadyToFinalize(t *testing.T) {
ctx := memory.Use(context.Background())
ctx = memlogger.Use(ctx)
outputFlag := luciexe.AddOutputFlagToSet(&flag.FlagSet{})
finalBuild := &bbpb.Build{}
Convey("Ready to finalize: success", t, func() {
isReady := readyToFinalize(ctx, finalBuild, nil, nil, outputFlag)
So(isReady, ShouldEqual, true)
})
Convey("Not ready to finalize: fatal error not nil", t, func() {
isReady := readyToFinalize(ctx, finalBuild, errors.New("Fatal Error Happened"), nil, outputFlag)
So(isReady, ShouldEqual, false)
})
}
func TestBackFillTaskInfo(t *testing.T) {
t.Parallel()
Convey("backFillTaskInfo", t, func() {
ctx := lucictx.SetSwarming(context.Background(), &lucictx.Swarming{
Task: &lucictx.Task{
BotDimensions: []string{
"cpu:x86",
"cpu:x86-64",
"id:bot_id",
"gcp:google.com:chromecompute",
},
},
})
Convey("swarming", func() {
build := &bbpb.Build{
Infra: &bbpb.BuildInfra{
Swarming: &bbpb.BuildInfra_Swarming{},
},
}
input := clientInput{input: &bbpb.BBAgentArgs{Build: build}}
So(backFillTaskInfo(ctx, input), ShouldEqual, 0)
So(build.Infra.Swarming.BotDimensions, ShouldResembleProto, []*bbpb.StringPair{
{
Key: "cpu",
Value: "x86",
},
{
Key: "cpu",
Value: "x86-64",
},
{
Key: "id",
Value: "bot_id",
},
{
Key: "gcp",
Value: "google.com:chromecompute",
},
})
})
Convey("backend", func() {
build := &bbpb.Build{
Infra: &bbpb.BuildInfra{
Backend: &bbpb.BuildInfra_Backend{},
},
}
input := clientInput{input: &bbpb.BBAgentArgs{Build: build}}
Convey("fail", func() {
So(backFillTaskInfo(ctx, input), ShouldEqual, 1)
})
Convey("pass", func() {
build.Infra.Backend.Task = &bbpb.Task{
Id: &bbpb.TaskID{
Id: "id",
Target: "swarming://target",
},
}
So(backFillTaskInfo(ctx, input), ShouldEqual, 0)
actual, err := protoutil.BotDimensionsFromBackend(build)
So(err, ShouldBeNil)
So(actual, ShouldResembleProto, []*bbpb.StringPair{
{
Key: "cpu",
Value: "x86",
},
{
Key: "cpu",
Value: "x86-64",
},
{
Key: "gcp",
Value: "google.com:chromecompute",
},
{
Key: "id",
Value: "bot_id",
},
})
})
})
})
}
func TestDownloadInputs(t *testing.T) {
resultsFilePath = filepath.Join(t.TempDir(), "cipd_ensure_results.json")
build := &bbpb.Build{
Id: 123,
Infra: &bbpb.BuildInfra{
Buildbucket: &bbpb.BuildInfra_Buildbucket{
Agent: &bbpb.BuildInfra_Buildbucket_Agent{
Input: &bbpb.BuildInfra_Buildbucket_Agent_Input{
CipdSource: map[string]*bbpb.InputDataRef{
"cipddir": {
DataType: &bbpb.InputDataRef_Cipd{
Cipd: &bbpb.InputDataRef_CIPD{
Server: "chrome-infra-packages.appspot.com",
Specs: []*bbpb.InputDataRef_CIPD_PkgSpec{
{
Package: "infra/tools/cipd/${platform}",
Version: "latest",
},
},
},
},
},
},
Data: map[string]*bbpb.InputDataRef{
"path_a": {
DataType: &bbpb.InputDataRef_Cipd{
Cipd: &bbpb.InputDataRef_CIPD{
Specs: []*bbpb.InputDataRef_CIPD_PkgSpec{{Package: "pkg_a", Version: "latest"}},
},
},
OnPath: []string{"path_a/bin", "path_a"},
},
},
},
Output: &bbpb.BuildInfra_Buildbucket_Agent_Output{},
},
},
},
Input: &bbpb.Build_Input{
Experiments: []string{"luci.buildbucket.agent.cipd_installation"},
},
CancelTime: nil,
}
Convey("downloadCipdPackages", t, func(c C) {
Convey("success", func() {
testCase = "success"
ctx := memory.Use(context.Background())
ctx = memlogger.Use(ctx)
execCommandContext = fakeExecCommand
defer func() { execCommandContext = exec.CommandContext }()
tempDir := t.TempDir()
bbclient := &testBBClient{}
input := &bbpb.BBAgentArgs{Build: build}
rc := downloadInputs(ctx, tempDir, "cache", clientInput{bbclient, input})
So(rc, ShouldEqual, 0)
So(len(bbclient.requests), ShouldEqual, 2)
So(bbclient.requests[0].Build.Infra.Buildbucket.Agent.Output.Status, ShouldEqual, bbpb.Status_STARTED)
So(bbclient.requests[1].Build.Infra.Buildbucket.Agent.Output.Status, ShouldEqual, bbpb.Status_SUCCESS)
})
})
}
func TestStartBuild(t *testing.T) {
Convey("startBuild", t, func() {
ctx := context.Background()
Convey("pass", func() {
bbclient := &testBBClient{}
res, err := startBuild(ctx, bbclient, 87654321, "pass")
So(err, ShouldBeNil)
So(res, ShouldNotBeNil)
})
Convey("duplicate", func() {
bbclient := &testBBClient{}
res, err := startBuild(ctx, bbclient, 87654321, "duplicate")
So(res, ShouldBeNil)
So(buildbucket.DuplicateTask.In(err), ShouldBeTrue)
})
})
}
func TestChooseCacheDir(t *testing.T) {
input := &bbpb.BBAgentArgs{
Build: &bbpb.Build{},
CacheDir: "inputCacheDir",
}
Convey("use input.CacheDir no backend", t, func() {
cacheDir := chooseCacheDir(input, "")
So(cacheDir, ShouldEqual, "inputCacheDir")
})
Convey("use input.CacheDir backend exists", t, func() {
input.Build.Infra = &bbpb.BuildInfra{
Backend: &bbpb.BuildInfra_Backend{},
}
cacheDir := chooseCacheDir(input, "")
So(cacheDir, ShouldEqual, "inputCacheDir")
})
Convey("use cache-base flag backend exists", t, func() {
input.Build.Infra = &bbpb.BuildInfra{
Backend: &bbpb.BuildInfra_Backend{},
}
cacheDir := chooseCacheDir(input, "cache")
So(cacheDir, ShouldEqual, "cache")
})
}