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 }