blob: 1d749cab93d762c857355f47b458d5fa00ef1d74 [file] [log] [blame]
// Copyright 2021 The Chromium 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"
"context"
"errors"
"infra/chromium/bootstrapper/cipd"
fakecipd "infra/chromium/bootstrapper/fakes/cipd"
fakegitiles "infra/chromium/bootstrapper/fakes/gitiles"
"infra/chromium/bootstrapper/gitiles"
"io"
"io/ioutil"
"path/filepath"
"strings"
"testing"
. "github.com/smartystreets/goconvey/convey"
buildbucketpb "go.chromium.org/luci/buildbucket/proto"
. "go.chromium.org/luci/common/testing/assertions"
"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/proto"
)
func strPtr(s string) *string {
return &s
}
func createInput(buildJson string) io.Reader {
build := &buildbucketpb.Build{}
if err := protojson.Unmarshal([]byte(buildJson), build); err != nil {
panic(err)
}
buildProtoBytes, err := proto.Marshal(build)
if err != nil {
panic(err)
}
return bytes.NewReader(buildProtoBytes)
}
type reader struct {
readFn func([]byte) (int, error)
}
func (r reader) Read(p []byte) (n int, err error) {
return r.readFn(p)
}
func TestPerformBootstrap(t *testing.T) {
t.Parallel()
project := &fakegitiles.Project{
Refs: map[string]string{},
Files: map[fakegitiles.FileRevId]*string{},
}
pkg := &fakecipd.Package{
Refs: map[string]string{},
Instances: map[string]*fakecipd.PackageInstance{},
}
ctx := context.Background()
ctx = gitiles.UseGitilesClientFactory(ctx, fakegitiles.Factory(map[string]*fakegitiles.Host{
"fake-host": {
Projects: map[string]*fakegitiles.Project{
"fake-project": project,
},
},
}))
ctx = cipd.UseCipdClientFactory(ctx, fakecipd.Factory(map[string]*fakecipd.Package{
"fake-package": pkg,
}))
Convey("performBootstrap", t, func() {
cipdRoot := t.TempDir()
Convey("fails if reading input fails", func() {
input := reader{func(p []byte) (int, error) {
return 0, errors.New("test read failure")
}}
cmd, err := performBootstrap(ctx, input, cipdRoot, "")
So(err, ShouldNotBeNil)
So(cmd, ShouldBeNil)
})
Convey("fails if unmarshalling build fails", func() {
input := strings.NewReader("invalid-proto")
cmd, err := performBootstrap(ctx, input, cipdRoot, "")
So(err, ShouldNotBeNil)
So(cmd, ShouldBeNil)
})
Convey("fails if bootstrap fails", func() {
input := createInput(`{}`)
cmd, err := performBootstrap(ctx, input, cipdRoot, "")
So(err, ShouldNotBeNil)
So(cmd, ShouldBeNil)
})
Convey("succeeds for valid input", func() {
input := createInput(`{
"input": {
"properties": {
"$bootstrap": {
"top_level_project": {
"repo": {
"host": "fake-host",
"project": "fake-project"
},
"ref": "fake-ref"
},
"properties_file": "fake-properties-file",
"exe": {
"cipd_package": "fake-package",
"cipd_version": "fake-version",
"cmd": ["fake-exe"]
}
}
}
}
}`)
project.Refs["fake-ref"] = "fake-revision"
project.Files[fakegitiles.FileRevId{
Revision: "fake-revision",
Path: "fake-properties-file",
}] = strPtr(`{
"foo": "bar"
}`)
cmd, err := performBootstrap(ctx, input, cipdRoot, "fake-output-path")
So(err, ShouldBeNil)
So(cmd, ShouldNotBeNil)
So(cmd.Args, ShouldResemble, []string{
filepath.Join(cipdRoot, "fake-package", "fake-exe"),
"--output",
"fake-output-path",
})
contents, _ := ioutil.ReadAll(cmd.Stdin)
build := &buildbucketpb.Build{}
proto.Unmarshal(contents, build)
So(build, ShouldResembleProtoJSON, `{
"input": {
"properties": {
"$build/chromium_bootstrap": {
"commits": [
{
"host": "fake-host",
"project": "fake-project",
"ref": "fake-ref",
"id": "fake-revision"
}
]
},
"foo": "bar"
}
}
}`)
})
})
}