go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/resultdb/pbutil/invocation_test.go (about) 1 // Copyright 2019 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 "testing" 19 20 pb "go.chromium.org/luci/resultdb/proto/v1" 21 22 . "github.com/smartystreets/goconvey/convey" 23 . "go.chromium.org/luci/common/testing/assertions" 24 ) 25 26 func TestInvocationName(t *testing.T) { 27 t.Parallel() 28 Convey("ParseInvocationName", t, func() { 29 Convey("Parse", func() { 30 id, err := ParseInvocationName("invocations/a") 31 So(err, ShouldBeNil) 32 So(id, ShouldEqual, "a") 33 }) 34 35 Convey("Invalid", func() { 36 _, err := ParseInvocationName("invocations/-") 37 So(err, ShouldErrLike, `does not match`) 38 }) 39 40 Convey("Format", func() { 41 So(InvocationName("a"), ShouldEqual, "invocations/a") 42 }) 43 44 }) 45 } 46 47 func TestInvocationUtils(t *testing.T) { 48 t.Parallel() 49 Convey(`Normalization normalizes tags`, t, func() { 50 inv := &pb.Invocation{ 51 Tags: StringPairs( 52 "k2", "v21", 53 "k2", "v20", 54 "k3", "v30", 55 "k1", "v1", 56 "k3", "v31", 57 ), 58 } 59 60 NormalizeInvocation(inv) 61 62 So(inv.Tags, ShouldResembleProto, StringPairs( 63 "k1", "v1", 64 "k2", "v20", 65 "k2", "v21", 66 "k3", "v30", 67 "k3", "v31", 68 )) 69 }) 70 Convey(`Normalization normalizes gerrit changelists`, t, func() { 71 inv := &pb.Invocation{ 72 SourceSpec: &pb.SourceSpec{ 73 Sources: &pb.Sources{ 74 Changelists: []*pb.GerritChange{ 75 { 76 Host: "chromium-review.googlesource.com", 77 Project: "chromium/src", 78 Change: 111, 79 Patchset: 1, 80 }, 81 { 82 Host: "a-review.googlesource.com", 83 Project: "chromium/src", 84 Change: 444, 85 Patchset: 1, 86 }, 87 { 88 Host: "a-review.googlesource.com", 89 Project: "aaa", 90 Change: 555, 91 Patchset: 1, 92 }, 93 { 94 Host: "chromium-review.googlesource.com", 95 Project: "chromium/src", 96 Change: 333, 97 Patchset: 1, 98 }, 99 { 100 Host: "chromium-review.googlesource.com", 101 Project: "chromium/src", 102 Change: 222, 103 Patchset: 1, 104 }, 105 }, 106 }, 107 }, 108 } 109 110 NormalizeInvocation(inv) 111 112 So(inv.SourceSpec.Sources.Changelists, ShouldResembleProto, []*pb.GerritChange{ 113 { 114 Host: "a-review.googlesource.com", 115 Project: "aaa", 116 Change: 555, 117 Patchset: 1, 118 }, 119 { 120 Host: "a-review.googlesource.com", 121 Project: "chromium/src", 122 Change: 444, 123 Patchset: 1, 124 }, 125 { 126 Host: "chromium-review.googlesource.com", 127 Project: "chromium/src", 128 Change: 111, 129 Patchset: 1, 130 }, 131 { 132 Host: "chromium-review.googlesource.com", 133 Project: "chromium/src", 134 Change: 222, 135 Patchset: 1, 136 }, 137 { 138 Host: "chromium-review.googlesource.com", 139 Project: "chromium/src", 140 Change: 333, 141 Patchset: 1, 142 }, 143 }) 144 }) 145 } 146 147 func TestValidateInvocation(t *testing.T) { 148 t.Parallel() 149 Convey(`ValidateSources`, t, func() { 150 sources := &pb.Sources{ 151 GitilesCommit: &pb.GitilesCommit{ 152 Host: "chromium.googlesource.com", 153 Project: "chromium/src", 154 Ref: "refs/heads/branch", 155 CommitHash: "123456789012345678901234567890abcdefabcd", 156 Position: 1, 157 }, 158 Changelists: []*pb.GerritChange{ 159 { 160 Host: "chromium-review.googlesource.com", 161 Project: "infra/luci-go", 162 Change: 12345, 163 Patchset: 321, 164 }, 165 }, 166 IsDirty: true, 167 } 168 Convey(`Valid with sources`, func() { 169 So(ValidateSources(sources), ShouldBeNil) 170 }) 171 Convey(`Nil`, func() { 172 So(ValidateSources(nil), ShouldErrLike, `unspecified`) 173 }) 174 Convey(`Gitiles commit`, func() { 175 Convey(`Missing`, func() { 176 sources.GitilesCommit = nil 177 So(ValidateSources(sources), ShouldErrLike, `gitiles_commit: unspecified`) 178 }) 179 Convey(`Invalid`, func() { 180 // protocol prefix should not be included. 181 sources.GitilesCommit.Host = "https://service" 182 So(ValidateSources(sources), ShouldErrLike, `gitiles_commit: host: does not match`) 183 }) 184 }) 185 Convey(`Changelists`, func() { 186 Convey(`Zero length`, func() { 187 sources.Changelists = nil 188 So(ValidateSources(sources), ShouldBeNil) 189 }) 190 Convey(`Invalid`, func() { 191 sources.Changelists[0].Change = -1 192 So(ValidateSources(sources), ShouldErrLike, `changelists[0]: change: cannot be negative`) 193 }) 194 Convey(`Too many`, func() { 195 sources.Changelists = nil 196 for i := 0; i < 11; i++ { 197 sources.Changelists = append(sources.Changelists, 198 &pb.GerritChange{ 199 Host: "chromium-review.googlesource.com", 200 Project: "infra/luci-go", 201 Change: int64(i + 1), 202 Patchset: 321, 203 }, 204 ) 205 } 206 So(ValidateSources(sources), ShouldErrLike, `changelists: exceeds maximum of 10 changelists`) 207 }) 208 Convey(`Duplicates`, func() { 209 sources.Changelists = nil 210 for i := 0; i < 2; i++ { 211 sources.Changelists = append(sources.Changelists, 212 &pb.GerritChange{ 213 Host: "chromium-review.googlesource.com", 214 Project: "infra/luci-go", 215 Change: 12345, 216 Patchset: int64(i + 1), 217 }, 218 ) 219 } 220 So(ValidateSources(sources), ShouldErrLike, `changelists[1]: duplicate change modulo patchset number; same change at changelists[0]`) 221 }) 222 }) 223 }) 224 Convey(`ValidateSourceSpec`, t, func() { 225 sourceSpec := &pb.SourceSpec{ 226 Sources: &pb.Sources{ 227 GitilesCommit: &pb.GitilesCommit{ 228 Host: "chromium.googlesource.com", 229 Project: "chromium/src", 230 Ref: "refs/heads/branch", 231 CommitHash: "123456789012345678901234567890abcdefabcd", 232 Position: 1, 233 }, 234 }, 235 Inherit: false, 236 } 237 Convey(`Valid`, func() { 238 Convey(`Sources only`, func() { 239 So(ValidateSourceSpec(sourceSpec), ShouldBeNil) 240 }) 241 Convey(`Empty`, func() { 242 sourceSpec.Sources = nil 243 So(ValidateSourceSpec(sourceSpec), ShouldBeNil) 244 }) 245 Convey(`Inherit only`, func() { 246 sourceSpec.Sources = nil 247 sourceSpec.Inherit = true 248 So(ValidateSourceSpec(sourceSpec), ShouldBeNil) 249 }) 250 Convey(`Nil`, func() { 251 So(ValidateSourceSpec(nil), ShouldBeNil) 252 }) 253 }) 254 Convey(`Cannot specify inherit concurrently with sources`, func() { 255 So(sourceSpec.Sources, ShouldNotBeNil) 256 sourceSpec.Inherit = true 257 So(ValidateSourceSpec(sourceSpec), ShouldErrLike, `only one of inherit and sources may be set`) 258 }) 259 Convey(`Invalid Sources`, func() { 260 sourceSpec.Sources.GitilesCommit.Host = "b@d" 261 So(ValidateSourceSpec(sourceSpec), ShouldErrLike, `sources: gitiles_commit: host: does not match`) 262 }) 263 }) 264 }