blob: e63e675265019cb1104b681fe7d4ac18fe9248db [file] [log] [blame]
// Copyright 2019 The Fuchsia 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 (
"context"
"errors"
"reflect"
"testing"
_struct "github.com/golang/protobuf/ptypes/struct"
buildbucketpb "go.chromium.org/luci/buildbucket/proto"
"google.golang.org/genproto/protobuf/field_mask"
"google.golang.org/grpc"
)
func TestGetStorageBucket(t *testing.T) {
tests := []struct {
// The name of this test case.
name string
// The ID of the build to query.
input string
// A mock RPC response from the BuildBucket service.
mock mockBuildsClient
// mock *buildbucketpb.Build
// The expected GetBuildRequest.
expectedRequest *buildbucketpb.GetBuildRequest
// The expected output Cloud Storage bucket.
expectedBucket string
// Whether to expect an error.
expectErr bool
}{
{
name: "should return the storage bucket read from a build's properties",
input: "123",
expectedBucket: "the_bucket",
expectedRequest: &buildbucketpb.GetBuildRequest{
Id: 123,
Fields: &field_mask.FieldMask{
Paths: []string{"output"},
},
},
mock: mockBuildsClient{
response: &buildbucketpb.Build{
Id: 123,
Output: &buildbucketpb.Build_Output{
Properties: &_struct.Struct{
Fields: map[string]*_struct.Value{
"artifact_gcs_bucket": {
Kind: &_struct.Value_StringValue{
StringValue: "the_bucket",
},
},
},
},
},
},
},
}, {
name: "should err if no build is returned",
input: "123",
expectErr: true,
expectedRequest: &buildbucketpb.GetBuildRequest{
Id: 123,
Fields: &field_mask.FieldMask{
Paths: []string{"output"},
},
},
mock: mockBuildsClient{
response: nil,
},
}, {
name: "should err if the RPC fails",
input: "123",
expectErr: true,
expectedRequest: &buildbucketpb.GetBuildRequest{
Id: 123,
Fields: &field_mask.FieldMask{
Paths: []string{"output"},
},
},
mock: mockBuildsClient{
shouldErr: true,
response: &buildbucketpb.Build{
Id: 123,
Output: &buildbucketpb.Build_Output{
Properties: &_struct.Struct{
Fields: map[string]*_struct.Value{},
},
},
},
},
}, {
name: "should err if no property describing the storage bucket is found",
input: "123",
expectErr: true,
expectedRequest: &buildbucketpb.GetBuildRequest{
Id: 123,
Fields: &field_mask.FieldMask{
Paths: []string{"output"},
},
},
mock: mockBuildsClient{
response: &buildbucketpb.Build{
Id: 123,
Output: &buildbucketpb.Build_Output{
Properties: &_struct.Struct{
Fields: map[string]*_struct.Value{},
},
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
bucket, err := getStorageBucket(context.Background(), &tt.mock, tt.input, false)
if err != nil != tt.expectErr {
if err == nil {
t.Error("wanted an error but got nil")
} else {
t.Errorf("unxpected error: %v", err)
}
}
compare := func(kind string, expected, actual interface{}) {
if !reflect.DeepEqual(expected, actual) {
t.Errorf("expected %s:\n%+v\nbut got:\n%+v", kind, expected, actual)
}
}
compare("SearchBuildsRequest", tt.expectedRequest, tt.mock.request)
compare("Storage bucket", tt.expectedBucket, bucket)
})
}
}
type mockBuildsClient struct {
shouldErr bool
response *buildbucketpb.Build
request *buildbucketpb.GetBuildRequest
}
func (mock *mockBuildsClient) GetBuild(ctx context.Context, req *buildbucketpb.GetBuildRequest, _ ...grpc.CallOption) (*buildbucketpb.Build, error) {
mock.request = req
if mock.shouldErr {
return nil, errors.New("no builds found")
}
return mock.response, nil
}