go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/resultdb/sink/validation_test.go (about)

     1  // Copyright 2020 The LUCI Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package sink
    16  
    17  import (
    18  	"strings"
    19  	"testing"
    20  
    21  	"google.golang.org/protobuf/types/known/structpb"
    22  
    23  	"go.chromium.org/luci/resultdb/pbutil"
    24  	pb "go.chromium.org/luci/resultdb/proto/v1"
    25  	sinkpb "go.chromium.org/luci/resultdb/sink/proto/v1"
    26  
    27  	. "github.com/smartystreets/goconvey/convey"
    28  	"go.chromium.org/luci/common/clock/testclock"
    29  	. "go.chromium.org/luci/common/testing/assertions"
    30  )
    31  
    32  func TestValidateTestResult(t *testing.T) {
    33  	t.Parallel()
    34  	Convey(`ValidateTestResult`, t, func() {
    35  		tr, cancel := validTestResult()
    36  		defer cancel()
    37  
    38  		Convey(`TestLocation`, func() {
    39  			tr.TestMetadata.Location.FileName = ""
    40  			err := validateTestResult(testclock.TestRecentTimeUTC, tr)
    41  			So(err, ShouldErrLike, "test_metadata: location: file_name: unspecified")
    42  		})
    43  
    44  		Convey(`TestMetadata`, func() {
    45  			tr.TestMetadata = &pb.TestMetadata{
    46  				Name: "name",
    47  				Location: &pb.TestLocation{
    48  					Repo:     "https://chromium.googlesource.com/chromium/src",
    49  					FileName: "//file",
    50  				},
    51  			}
    52  			err := validateTestResult(testclock.TestRecentTimeUTC, tr)
    53  			So(err, ShouldBeNil)
    54  		})
    55  
    56  		Convey(`Properties`, func() {
    57  			Convey(`Valid Properties`, func() {
    58  				tr.Properties = &structpb.Struct{
    59  					Fields: map[string]*structpb.Value{
    60  						"key_1": structpb.NewStringValue("value_1"),
    61  						"key_2": structpb.NewStructValue(&structpb.Struct{
    62  							Fields: map[string]*structpb.Value{
    63  								"child_key": structpb.NewNumberValue(1),
    64  							},
    65  						}),
    66  					},
    67  				}
    68  				err := validateTestResult(testclock.TestRecentTimeUTC, tr)
    69  				So(err, ShouldBeNil)
    70  			})
    71  
    72  			Convey(`Large Properties`, func() {
    73  				tr.Properties = &structpb.Struct{
    74  					Fields: map[string]*structpb.Value{
    75  						"key1": structpb.NewStringValue(strings.Repeat("1", pbutil.MaxSizeProperties)),
    76  					},
    77  				}
    78  				err := validateTestResult(testclock.TestRecentTimeUTC, tr)
    79  				So(err, ShouldErrLike, `properties: exceeds the maximum size of`, `bytes`)
    80  			})
    81  		})
    82  	})
    83  }
    84  
    85  func TestValidateArtifacts(t *testing.T) {
    86  	t.Parallel()
    87  	// valid artifacts
    88  	validArts := map[string]*sinkpb.Artifact{
    89  		"art1": {
    90  			Body:        &sinkpb.Artifact_FilePath{FilePath: "/tmp/foo"},
    91  			ContentType: "text/plain",
    92  		},
    93  		"art2": {
    94  			Body:        &sinkpb.Artifact_Contents{Contents: []byte("contents")},
    95  			ContentType: "text/plain",
    96  		},
    97  		"art3": {
    98  			Body:        &sinkpb.Artifact_GcsUri{GcsUri: "gs://bucket/bar"},
    99  			ContentType: "text/plain",
   100  		},
   101  	}
   102  	// invalid artifacts
   103  	invalidArts := map[string]*sinkpb.Artifact{
   104  		"art1": {ContentType: "text/plain"},
   105  	}
   106  
   107  	Convey("Succeeds", t, func() {
   108  		Convey("with no artifact", func() {
   109  			So(validateArtifacts(nil), ShouldBeNil)
   110  		})
   111  
   112  		Convey("with valid artifacts", func() {
   113  			So(validateArtifacts(validArts), ShouldBeNil)
   114  		})
   115  	})
   116  
   117  	Convey("Fails", t, func() {
   118  		expected := "body: one of file_path or contents or gcs_uri must be provided"
   119  
   120  		Convey("with invalid artifacts", func() {
   121  			So(validateArtifacts(invalidArts), ShouldErrLike, expected)
   122  		})
   123  
   124  		Convey("with a mix of valid and invalid artifacts", func() {
   125  			invalidArts["art2"] = validArts["art2"]
   126  			So(validateArtifacts(invalidArts), ShouldErrLike, expected)
   127  		})
   128  	})
   129  }