go.fuchsia.dev/infra@v0.0.0-20240507153436-9b593402251b/cmd/artifacts/common_test.go (about) 1 // Copyright 2019 The Fuchsia Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 package main 5 6 import ( 7 "context" 8 "errors" 9 "reflect" 10 "testing" 11 12 buildbucketpb "go.chromium.org/luci/buildbucket/proto" 13 "google.golang.org/genproto/protobuf/field_mask" 14 "google.golang.org/grpc" 15 "google.golang.org/protobuf/types/known/structpb" 16 ) 17 18 func TestGetStorageBucket(t *testing.T) { 19 tests := []struct { 20 // The name of this test case. 21 name string 22 23 // The ID of the build to query. 24 input string 25 26 // A mock RPC response from the BuildBucket service. 27 mock mockBuildsClient 28 // mock *buildbucketpb.Build 29 30 // The expected GetBuildRequest. 31 expectedRequest *buildbucketpb.GetBuildRequest 32 33 // The expected output Cloud Storage bucket. 34 expectedBucket string 35 36 // Whether to expect an error. 37 expectErr bool 38 }{ 39 { 40 name: "should return the storage bucket read from a build's properties", 41 input: "123", 42 expectedBucket: "the_bucket", 43 expectedRequest: &buildbucketpb.GetBuildRequest{ 44 Id: 123, 45 Fields: &field_mask.FieldMask{ 46 Paths: []string{"output"}, 47 }, 48 }, 49 mock: mockBuildsClient{ 50 response: &buildbucketpb.Build{ 51 Id: 123, 52 Output: &buildbucketpb.Build_Output{ 53 Properties: &structpb.Struct{ 54 Fields: map[string]*structpb.Value{ 55 "artifact_gcs_bucket": { 56 Kind: &structpb.Value_StringValue{ 57 StringValue: "the_bucket", 58 }, 59 }, 60 }, 61 }, 62 }, 63 }, 64 }, 65 }, { 66 name: "should return default bucket if no build is returned", 67 input: "123", 68 expectedBucket: defaultStorageBucket, 69 expectedRequest: &buildbucketpb.GetBuildRequest{ 70 Id: 123, 71 Fields: &field_mask.FieldMask{ 72 Paths: []string{"output"}, 73 }, 74 }, 75 mock: mockBuildsClient{ 76 response: nil, 77 }, 78 }, { 79 name: "should return default bucket if the RPC fails", 80 input: "123", 81 expectedBucket: defaultStorageBucket, 82 expectedRequest: &buildbucketpb.GetBuildRequest{ 83 Id: 123, 84 Fields: &field_mask.FieldMask{ 85 Paths: []string{"output"}, 86 }, 87 }, 88 mock: mockBuildsClient{ 89 shouldErr: true, 90 response: &buildbucketpb.Build{ 91 Id: 123, 92 Output: &buildbucketpb.Build_Output{ 93 Properties: &structpb.Struct{ 94 Fields: map[string]*structpb.Value{}, 95 }, 96 }, 97 }, 98 }, 99 }, { 100 name: "should err if no property describing the storage bucket is found", 101 input: "123", 102 expectErr: true, 103 expectedRequest: &buildbucketpb.GetBuildRequest{ 104 Id: 123, 105 Fields: &field_mask.FieldMask{ 106 Paths: []string{"output"}, 107 }, 108 }, 109 mock: mockBuildsClient{ 110 response: &buildbucketpb.Build{ 111 Id: 123, 112 Output: &buildbucketpb.Build_Output{ 113 Properties: &structpb.Struct{ 114 Fields: map[string]*structpb.Value{}, 115 }, 116 }, 117 }, 118 }, 119 }, 120 } 121 122 for _, tt := range tests { 123 t.Run(tt.name, func(t *testing.T) { 124 bucket, err := getStorageBucket(context.Background(), &tt.mock, tt.input) 125 if err != nil != tt.expectErr { 126 if err == nil { 127 t.Error("wanted an error but got nil") 128 } else { 129 t.Errorf("unexpected error: %s", err) 130 } 131 } 132 133 compare := func(kind string, expected, actual any) { 134 if !reflect.DeepEqual(expected, actual) { 135 t.Errorf("expected %s:\n%+v\nbut got:\n%+v", kind, expected, actual) 136 } 137 } 138 139 compare("SearchBuildsRequest", tt.expectedRequest, tt.mock.request) 140 compare("Storage bucket", tt.expectedBucket, bucket) 141 }) 142 } 143 } 144 145 type mockBuildsClient struct { 146 shouldErr bool 147 response *buildbucketpb.Build 148 request *buildbucketpb.GetBuildRequest 149 } 150 151 func (mock *mockBuildsClient) GetBuild(ctx context.Context, req *buildbucketpb.GetBuildRequest, _ ...grpc.CallOption) (*buildbucketpb.Build, error) { 152 mock.request = req 153 if mock.shouldErr { 154 return nil, errors.New("no builds found") 155 } 156 157 return mock.response, nil 158 }