go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/analysis/pbutil/resultdb_test.go (about)

     1  // Copyright 2022 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 pbutil
    16  
    17  import (
    18  	"encoding/hex"
    19  	"testing"
    20  
    21  	rdbpb "go.chromium.org/luci/resultdb/proto/v1"
    22  
    23  	pb "go.chromium.org/luci/analysis/proto/v1"
    24  
    25  	. "github.com/smartystreets/goconvey/convey"
    26  	. "go.chromium.org/luci/common/testing/assertions"
    27  )
    28  
    29  func TestResultDB(t *testing.T) {
    30  	Convey("FailureReasonFromResultDB", t, func() {
    31  		rdbFailureReason := &rdbpb.FailureReason{
    32  			PrimaryErrorMessage: "Some error message.",
    33  		}
    34  		fr := FailureReasonFromResultDB(rdbFailureReason)
    35  		So(fr, ShouldResembleProto, &pb.FailureReason{
    36  			PrimaryErrorMessage: "Some error message.",
    37  		})
    38  	})
    39  	Convey("SkipReasonFromResultDB", t, func() {
    40  		// Confirm LUCI Analysis handles every skip reason defined by ResultDB.
    41  		// This test is designed to break if ResultDB extends the set of
    42  		// allowed values, without a corresponding update to LUCI Analysis.
    43  		for _, v := range rdbpb.SkipReason_value {
    44  			rdbReason := rdbpb.SkipReason(v)
    45  
    46  			reason := SkipReasonFromResultDB(rdbReason)
    47  			if rdbReason == rdbpb.SkipReason_SKIP_REASON_UNSPECIFIED {
    48  				So(reason, ShouldEqual, pb.TestVerdictStatus_TEST_VERDICT_STATUS_UNSPECIFIED)
    49  				continue
    50  			}
    51  			So(reason, ShouldNotEqual, pb.TestVerdictStatus_TEST_VERDICT_STATUS_UNSPECIFIED)
    52  		}
    53  
    54  	})
    55  	Convey("TestMetadataFromResultDB", t, func() {
    56  		rdbTestMetadata := &rdbpb.TestMetadata{
    57  			Name: "name",
    58  			Location: &rdbpb.TestLocation{
    59  				Repo:     "repo",
    60  				FileName: "fileName",
    61  				Line:     123,
    62  			},
    63  		}
    64  		tmd := TestMetadataFromResultDB(rdbTestMetadata)
    65  		So(tmd, ShouldResembleProto, &pb.TestMetadata{
    66  			Name: "name",
    67  			Location: &pb.TestLocation{
    68  				Repo:     "repo",
    69  				FileName: "fileName",
    70  				Line:     123,
    71  			}})
    72  	})
    73  	Convey("TestResultStatusFromResultDB", t, func() {
    74  		// Confirm LUCI Analysis handles every test status defined by ResultDB.
    75  		// This test is designed to break if ResultDB extends the set of
    76  		// allowed values, without a corresponding update to LUCI Analysis.
    77  		for _, v := range rdbpb.TestStatus_value {
    78  			rdbStatus := rdbpb.TestStatus(v)
    79  			if rdbStatus == rdbpb.TestStatus_STATUS_UNSPECIFIED {
    80  				continue
    81  			}
    82  
    83  			status := TestResultStatusFromResultDB(rdbStatus)
    84  			So(status, ShouldNotEqual, pb.TestResultStatus_TEST_RESULT_STATUS_UNSPECIFIED)
    85  		}
    86  	})
    87  	Convey("TestVerdictStatusFromResultDB", t, func() {
    88  		// Confirm LUCI Analysis handles every test variant status defined by ResultDB.
    89  		// This test is designed to break if ResultDB extends the set of
    90  		// allowed values, without a corresponding update to LUCI Analysis.
    91  		for _, v := range rdbpb.TestVariantStatus_value {
    92  			rdbStatus := rdbpb.TestVariantStatus(v)
    93  			if rdbStatus == rdbpb.TestVariantStatus_TEST_VARIANT_STATUS_UNSPECIFIED ||
    94  				rdbStatus == rdbpb.TestVariantStatus_UNEXPECTED_MASK {
    95  				continue
    96  			}
    97  
    98  			status := TestVerdictStatusFromResultDB(rdbStatus)
    99  			So(status, ShouldNotEqual, pb.TestVerdictStatus_TEST_VERDICT_STATUS_UNSPECIFIED)
   100  		}
   101  	})
   102  	Convey("ExonerationReasonFromResultDB", t, func() {
   103  		// Confirm LUCI Analysis handles every exoneration reason defined by
   104  		// ResultDB.
   105  		// This test is designed to break if ResultDB extends the set of
   106  		// allowed values, without a corresponding update to LUCI Analysis.
   107  		for _, v := range rdbpb.ExonerationReason_value {
   108  			rdbReason := rdbpb.ExonerationReason(v)
   109  			if rdbReason == rdbpb.ExonerationReason_EXONERATION_REASON_UNSPECIFIED {
   110  				continue
   111  			}
   112  
   113  			reason := ExonerationReasonFromResultDB(rdbReason)
   114  			So(reason, ShouldNotEqual, pb.ExonerationReason_EXONERATION_REASON_UNSPECIFIED)
   115  		}
   116  	})
   117  	Convey("BugComponent from ResultDB Metadata", t, func() {
   118  		Convey("using issuetracker bug component", func() {
   119  			resultDbTmd := &rdbpb.TestMetadata{
   120  				BugComponent: &rdbpb.BugComponent{
   121  					System: &rdbpb.BugComponent_IssueTracker{
   122  						IssueTracker: &rdbpb.IssueTrackerComponent{
   123  							ComponentId: 12345,
   124  						},
   125  					},
   126  				},
   127  			}
   128  			converted := TestMetadataFromResultDB(resultDbTmd)
   129  
   130  			So(converted.BugComponent.System.(*pb.BugComponent_IssueTracker).IssueTracker.ComponentId, ShouldEqual, 12345)
   131  		})
   132  		Convey("using monorail bug component", func() {
   133  			resultDbTmd := &rdbpb.TestMetadata{
   134  				BugComponent: &rdbpb.BugComponent{
   135  					System: &rdbpb.BugComponent_Monorail{
   136  						Monorail: &rdbpb.MonorailComponent{
   137  							Project: "chrome",
   138  							Value:   "Blink>Data",
   139  						},
   140  					},
   141  				},
   142  			}
   143  			converted := TestMetadataFromResultDB(resultDbTmd)
   144  
   145  			So(converted.BugComponent.System.(*pb.BugComponent_Monorail).Monorail.Project, ShouldEqual, "chrome")
   146  			So(converted.BugComponent.System.(*pb.BugComponent_Monorail).Monorail.Value, ShouldEqual, "Blink>Data")
   147  		})
   148  	})
   149  	Convey("Sources to/from ResultDB", t, func() {
   150  		rdbSources := &rdbpb.Sources{
   151  			GitilesCommit: &rdbpb.GitilesCommit{
   152  				Host:       "project.googlesource.com",
   153  				Project:    "myproject/src",
   154  				Ref:        "refs/heads/main",
   155  				CommitHash: "abcdefabcd1234567890abcdefabcd1234567890",
   156  				Position:   16801,
   157  			},
   158  			Changelists: []*rdbpb.GerritChange{
   159  				{
   160  					Host:     "project-review.googlesource.com",
   161  					Project:  "myproject/src2",
   162  					Change:   9991,
   163  					Patchset: 82,
   164  				},
   165  			},
   166  			IsDirty: true,
   167  		}
   168  		analysisSources := &pb.Sources{
   169  			GitilesCommit: &pb.GitilesCommit{
   170  				Host:       "project.googlesource.com",
   171  				Project:    "myproject/src",
   172  				Ref:        "refs/heads/main",
   173  				CommitHash: "abcdefabcd1234567890abcdefabcd1234567890",
   174  				Position:   16801,
   175  			},
   176  			Changelists: []*pb.GerritChange{
   177  				{
   178  					Host:     "project-review.googlesource.com",
   179  					Project:  "myproject/src2",
   180  					Change:   9991,
   181  					Patchset: 82,
   182  				},
   183  			},
   184  			IsDirty: true,
   185  		}
   186  		So(SourcesFromResultDB(rdbSources), ShouldResembleProto, analysisSources)
   187  		So(SourcesToResultDB(analysisSources), ShouldResembleProto, rdbSources)
   188  	})
   189  	Convey("SourceRef to resultdb", t, func() {
   190  		sourceRef := &pb.SourceRef{
   191  			System: &pb.SourceRef_Gitiles{
   192  				Gitiles: &pb.GitilesRef{
   193  					Host:    "host",
   194  					Project: "proj",
   195  					Ref:     "ref",
   196  				},
   197  			},
   198  		}
   199  		sourceRef1 := SourceRefToResultDB(sourceRef)
   200  		So(sourceRef1, ShouldResembleProto, &rdbpb.SourceRef{
   201  			System: &rdbpb.SourceRef_Gitiles{
   202  				Gitiles: &rdbpb.GitilesRef{
   203  					Host:    "host",
   204  					Project: "proj",
   205  					Ref:     "ref",
   206  				},
   207  			},
   208  		})
   209  	})
   210  	Convey("RefFromSources", t, func() {
   211  		sources := &pb.Sources{
   212  			GitilesCommit: &pb.GitilesCommit{
   213  				Host:       "project.googlesource.com",
   214  				Project:    "myproject/src",
   215  				Ref:        "refs/heads/main",
   216  				CommitHash: "abcdefabcd1234567890abcdefabcd1234567890",
   217  				Position:   16801,
   218  			},
   219  		}
   220  		ref := SourceRefFromSources(sources)
   221  		So(ref, ShouldResembleProto, &pb.SourceRef{
   222  			System: &pb.SourceRef_Gitiles{
   223  				Gitiles: &pb.GitilesRef{
   224  					Host:    "project.googlesource.com",
   225  					Project: "myproject/src",
   226  					Ref:     "refs/heads/main",
   227  				},
   228  			},
   229  		})
   230  	})
   231  	Convey("RefHash", t, func() {
   232  		ref := &pb.SourceRef{
   233  			System: &pb.SourceRef_Gitiles{
   234  				Gitiles: &pb.GitilesRef{
   235  					Host:    "project.googlesource.com",
   236  					Project: "myproject/src",
   237  					Ref:     "refs/heads/main",
   238  				},
   239  			},
   240  		}
   241  		hash := SourceRefHash(ref)
   242  		So(hex.EncodeToString(hash), ShouldEqual, `5d47c679cf080cb5`)
   243  	})
   244  }