golang.org/x/build@v0.0.0-20240506185731-218518f32b70/maintner/gerrit_test.go (about) 1 // Copyright 2017 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package maintner 6 7 import ( 8 "bytes" 9 "testing" 10 "time" 11 ) 12 13 var statusTests = []struct { 14 msg string 15 want string 16 }{ 17 {`Create change 18 19 Uploaded patch set 1. 20 21 Patch-set: 1 (draft) 22 Change-id: I38a08cacc17bcd9587475495111fe98f10d6875c 23 Subject: test: test 24 Branch: refs/heads/master 25 Status: draft 26 Topic: 27 Commit: fee468c613a70d89f60fb5d683b0f796aabecaac`, "draft"}, 28 {`Update patch set 1 29 30 Change has been successfully cherry-picked as 117ac82c422a11e4dd5f4c14b50bafc1df840481 by Brad Fitzpatrick 31 32 Patch-set: 1 33 Status: merged 34 Submission-id: 16401-1446004855021-a20b3823`, "merged"}, 35 {`Create patch set 8 36 37 Uploaded patch set 8: Patch Set 7 was rebased. 38 39 Patch-set: 8 40 Subject: devapp: initial support for App Engine Flex 41 Commit: 17839a9f284b473986f235ad2757a2b445d05068 42 Tag: autogenerated:gerrit:newPatchSet 43 Groups: 17839a9f284b473986f235ad2757a2b445d05068`, ""}, 44 } 45 46 func TestGetGerritStatus(t *testing.T) { 47 for _, tt := range statusTests { 48 gc := &GitCommit{Msg: tt.msg} 49 got := getGerritStatus(gc) 50 if got != tt.want { 51 t.Errorf("getGerritStatus msg:\n%s\ngot %s, want %s", tt.msg, got, tt.want) 52 } 53 } 54 } 55 56 var normalizeTests = []struct { 57 in string 58 out string 59 }{ 60 {"foo", "foo"}, 61 {"http://foo", "foo"}, 62 {"upspin-review.googlesource.com", "upspin.googlesource.com"}, 63 {"go-review.googlesource.com", "go.googlesource.com"}, 64 } 65 66 func TestNormalizeServer(t *testing.T) { 67 for _, tt := range normalizeTests { 68 got := normalizeGerritServer(tt.in) 69 if got != tt.out { 70 t.Errorf("normalizeGerritServer(%q) = %q, want %q", tt.in, got, tt.out) 71 } 72 } 73 } 74 75 func TestGerritProject(t *testing.T) { 76 var c Corpus 77 c.EnableLeaderMode(new(dummyMutationLogger), "/fake/dir") 78 c.TrackGerrit("go.googlesource.com/build") 79 gp := c.Gerrit().Project("go-review.googlesource.com", "build") 80 if gp == nil { 81 t.Errorf("expected go-review.googlesource.com to return a project, got nil") 82 } 83 gp = c.Gerrit().Project("go-review.googlesource.com", "unknown") 84 if gp != nil { 85 t.Errorf("expected go-review.googlesource.com to return nil, got a project") 86 } 87 } 88 89 var messageTests = []struct { 90 in string 91 want string 92 wantNil bool 93 }{ 94 { 95 in: `Update patch set 1 96 97 Patch Set 1: Code-Review+2 98 99 Just to confirm, "go test" will consider an empty test file to be passing? 100 101 Patch-set: 1 102 Reviewer: Quentin Smith <13020@62eb7196-b449-3ce5-99f1-c037f21e1705> 103 Label: Code-Review=+2 104 `, 105 want: "Patch Set 1: Code-Review+2\n\nJust to confirm, \"go test\" will consider an empty test file to be passing?", 106 }, 107 { 108 in: `Create change 109 110 Uploaded patch set 1: Run-TryBot+1. 111 112 Patch-set: 1 113 Change-id: I1e0035ffba986c3551479d5742809e43da5e7c73 114 Subject: runtime: fall back to small mmaps if we fail to grow reservation 115 Branch: refs/heads/master 116 Status: new 117 Topic: 118 Commit: 8776f8d725c001456037e8888a72885d46cd6744 119 Tag: autogenerated:gerrit:newPatchSet 120 Groups: 8776f8d725c001456037e8888a72885d46cd6744 121 Reviewer: Keith Randall <5200@62eb7196-b449-3ce5-99f1-c037f21e1705> 122 Reviewer: Rick Hudson <5186@62eb7196-b449-3ce5-99f1-c037f21e1705> 123 Reviewer: Austin Clements <5167@62eb7196-b449-3ce5-99f1-c037f21e1705> 124 Label: Run-TryBot=+1 125 Private: false 126 Work-in-progress: false 127 `, 128 want: "Uploaded patch set 1: Run-TryBot+1.", 129 }, 130 { 131 in: `Uploaded patch set 1. 132 133 Patch-set: 1 134 `, 135 wantNil: true, 136 }, 137 { 138 in: `Create change 139 140 Uploaded patch set 1. 141 142 Patch-set: 1 143 Change-id: I3799148a111f1ab6bfee24c9e03e6ebbf9e9595b 144 Subject: net: make error messages consistent for invalid ports 145 Branch: refs/heads/master 146 Commit: 8a7de7048dc194d5e6f761add433b915beebb2e0 147 Groups: 8a7de7048dc194d5e6f761add433b915beebb2e0 148 `, 149 wantNil: true, 150 }, 151 { 152 in: `Create patch set 7 153 154 Uploaded patch set 7.: Commit message was updated 155 156 Patch-set: 7 157 Subject: cmd/vet: -lostcancel: check for discarded result of context.WithCancel 158 Commit: 5487cc78ea332c7b49d43ef5955211387aca73bb 159 Groups: 5487cc78ea332c7b49d43ef5955211387aca73bb 160 `, 161 wantNil: true, 162 }, 163 } 164 165 func TestGetGerritMessage(t *testing.T) { 166 var c Corpus 167 c.EnableLeaderMode(new(dummyMutationLogger), "/fake/dir") 168 c.TrackGerrit("go.googlesource.com/build") 169 gp := c.gerrit.projects["go.googlesource.com/build"] 170 for i, tt := range messageTests { 171 gc := &GitCommit{ 172 Msg: tt.in, 173 CommitTime: time.Now().UTC(), 174 } 175 msg := gp.getGerritMessage(gc) 176 if msg == nil != tt.wantNil { 177 if tt.wantNil { 178 t.Errorf("%d. getGerritMessage returned item; want nil", i) 179 } else { 180 t.Errorf("%d. getGerritMessage = nil; want a message", i) 181 } 182 continue 183 } 184 if msg == nil { 185 continue 186 } 187 // just checking these get copied through appropriately 188 if msg.Version != 1 { 189 t.Errorf("%d. getGerritMessage: want Version 1, got %d", i, msg.Version) 190 } 191 if msg.Date.IsZero() { 192 t.Errorf("%d. getGerritMessage: expected Date to be non-zero, got zero", i) 193 } 194 if msg.Message != tt.want { 195 t.Errorf("%d. getGerritMessage = %q; want %q", i, msg.Message, tt.want) 196 } 197 } 198 } 199 200 func TestOwnerID(t *testing.T) { 201 cl := &GerritCL{} 202 meta := newGerritMeta( 203 &GitCommit{ 204 Author: &GitPerson{ 205 Str: "Rick Sanchez <137@62eb7196-b449-3ce5-99f1-c037f21e1705>", 206 }, 207 }, 208 cl, 209 ) 210 cl.Meta = meta 211 cl.Metas = []*GerritMeta{meta} 212 cl.Commit = &GitCommit{} 213 214 testCases := []struct { 215 cl *GerritCL 216 OwnerID int 217 }{ 218 {&GerritCL{}, -1}, 219 {cl, 137}, 220 } 221 for _, tc := range testCases { 222 if got := tc.cl.OwnerID(); got != tc.OwnerID { 223 t.Errorf("cl.OwnerID() = %d; want %d", got, tc.OwnerID) 224 } 225 } 226 } 227 228 func TestSubject(t *testing.T) { 229 testcases := []struct{ msg, subject string }{ 230 {"maintner: slurp up all the things", "maintner: slurp up all the things"}, 231 {"cmd/go: build stuff\n\nand do other stuff, too.", "cmd/go: build stuff"}, 232 {"cmd/go: build lots\nof stuff\n\nand do other stuff, too.", "cmd/go: build lots of stuff"}, // Subject is separated from body by a blank line. 233 {"cmd/go: build lots\nof stuff", "cmd/go: build lots of stuff"}, 234 } 235 for _, tc := range testcases { 236 cl := &GerritCL{Commit: &GitCommit{Msg: tc.msg}} 237 if cl.Subject() != tc.subject { 238 t.Errorf("cl.Subject() = %q; want %q", cl.Subject(), tc.subject) 239 } 240 } 241 } 242 243 func TestChangeID(t *testing.T) { 244 testcases := []struct{ msg, changeID string }{ 245 {"maintner: slurp up all the things", ""}, 246 {"cmd/go: build stuff\n\nChange-Id: I7d3850e6774403c5d4ae15ca94c31c2f46f4ffa3", "I7d3850e6774403c5d4ae15ca94c31c2f46f4ffa3"}, 247 } 248 for _, tc := range testcases { 249 cl := &GerritCL{Commit: &GitCommit{Msg: tc.msg}} 250 if cl.ChangeID() != tc.changeID { 251 t.Errorf("cl.ChangeID() = %q; want %q", cl.ChangeID(), tc.changeID) 252 } 253 } 254 } 255 256 func TestLineValueOK(t *testing.T) { 257 tests := []struct { 258 all, prefix, want, wantRest string 259 wantOK bool 260 }{ 261 { 262 all: "foo: value ", 263 prefix: "foo:", 264 want: "value", 265 wantRest: "", 266 wantOK: true, 267 }, 268 { 269 all: "foo: value\n", 270 prefix: "foo:", 271 want: "value", 272 wantRest: "", 273 wantOK: true, 274 }, 275 { 276 all: "foo:\n", 277 prefix: "foo:", 278 want: "", 279 wantRest: "", 280 wantOK: true, 281 }, 282 { 283 all: "bar:\n", 284 prefix: "foo:", 285 want: "", 286 wantRest: "", 287 wantOK: false, 288 }, 289 { 290 all: "bar: other\nfoo: value\n", 291 prefix: "foo:", 292 want: "value", 293 wantRest: "", 294 wantOK: true, 295 }, 296 { 297 all: "notfoo: other\nfoo: value\n", 298 prefix: "foo:", 299 want: "value", 300 wantRest: "", 301 wantOK: true, 302 }, 303 { 304 all: "Foo: bar\nLabel: Vote=+1\nLabel: Vote=+2\n", 305 prefix: "Label: ", 306 want: "Vote=+1", 307 wantRest: "Label: Vote=+2\n", 308 wantOK: true, 309 }, 310 { 311 all: "Label: Vote=+2\n", 312 prefix: "Label: ", 313 want: "Vote=+2", 314 wantRest: "", 315 wantOK: true, 316 }, 317 } 318 for _, tt := range tests { 319 got, gotRest, gotOK := lineValueOK(tt.all, tt.prefix) 320 if got != tt.want { 321 t.Errorf("lineValueOK(%q, %q) returned value %q; want %q", tt.all, tt.prefix, got, tt.want) 322 } 323 if gotRest != tt.wantRest { 324 t.Errorf("lineValueOK(%q, %q) returned rest %q; want %q", tt.all, tt.prefix, gotRest, tt.wantRest) 325 } 326 if gotOK != tt.wantOK { 327 t.Errorf("lineValueOK(%q, %q) returned ok %v; want %v", tt.all, tt.prefix, gotOK, tt.wantOK) 328 } 329 } 330 } 331 332 func TestParseGerritLabelValue(t *testing.T) { 333 tests := []struct { 334 in string 335 wantLabel string 336 wantValue int8 337 wantWhose string 338 }{ 339 {"Run-TryBot=+1", "Run-TryBot", 1, ""}, 340 {"-Run-TryBot", "-Run-TryBot", 0, ""}, 341 {"-TryBot-Result Gobot Gobot <5976@62eb7196-b449-3ce5-99f1-c037f21e1705>", "-TryBot-Result", 0, "5976@62eb7196-b449-3ce5-99f1-c037f21e1705"}, 342 {"Run-TryBot=+1 Brad Fitzpatrick <5065@62eb7196-b449-3ce5-99f1-c037f21e1705>", "Run-TryBot", 1, "5065@62eb7196-b449-3ce5-99f1-c037f21e1705"}, 343 {"TryBot-Result=-1 Gobot Gobot <5976@62eb7196-b449-3ce5-99f1-c037f21e1705>", "TryBot-Result", -1, "5976@62eb7196-b449-3ce5-99f1-c037f21e1705"}, 344 } 345 for _, tt := range tests { 346 label, value, whose := parseGerritLabelValue(tt.in) 347 if label != tt.wantLabel || value != tt.wantValue || whose != tt.wantWhose { 348 t.Errorf("parseGerritLabelValue(%q) = %q, %v, %q; want %q, %v, %q", 349 tt.in, 350 label, value, whose, 351 tt.wantLabel, tt.wantValue, tt.wantWhose) 352 } 353 } 354 } 355 356 var hashtagTests = []struct { 357 commit string 358 wantAdd string 359 wantRemove string 360 }{ 361 { 362 commit: `Update patch set 1 363 364 Hashtag removed:foo 365 366 Patch-set: 1 367 Hashtags: 368 Tag: autogenerated:gerrit:setHashtag 369 `, 370 wantRemove: "foo", 371 }, 372 { 373 commit: `Update patch set 1 374 375 Hashtags removed: foo, bar 376 377 Patch-set: 1 378 Hashtags: 379 Tag: autogenerated:gerrit:setHashtag 380 `, 381 wantRemove: "foo, bar", 382 }, 383 { 384 commit: `Update patch set 1 385 386 Hashtag added: bar 387 388 Patch-set: 1 389 Hashtags: 390 Tag: autogenerated:gerrit:setHashtag 391 `, 392 wantAdd: "bar", 393 }, 394 { 395 commit: `Update patch set 1 396 397 Hashtags added: x,y 398 399 Patch-set: 1 400 Hashtags: 401 Tag: autogenerated:gerrit:setHashtag 402 `, 403 wantAdd: "x,y", 404 }, 405 // No tag: 406 { 407 commit: `Update patch set 1 408 409 Hashtags added: x,y 410 411 Patch-set: 1 412 Hashtags: 413 Tag: autogenerated:gerrit:otherTag 414 `, 415 }, 416 } 417 418 func TestParseHashtags(t *testing.T) { 419 for i, tt := range hashtagTests { 420 meta := newGerritMeta(&GitCommit{Msg: tt.commit}, nil) 421 added, removed, ok := meta.HashtagEdits() 422 if ok != (added != "" || removed != "") { 423 t.Errorf("%d. inconsistent return values: %q, %q, %v", i, added, removed, ok) 424 } 425 if string(added) != tt.wantAdd { 426 t.Errorf("%d. added = %q; want %q", i, added, tt.wantAdd) 427 } 428 if string(removed) != tt.wantRemove { 429 t.Errorf("%d. removed = %q; want %q", i, removed, tt.wantRemove) 430 } 431 432 // And an allocation test too: 433 allocs := testing.AllocsPerRun(100, func() { 434 _, _, _ = meta.HashtagEdits() 435 }) 436 if allocs > 0 { 437 t.Errorf("%d. allocs = %d; want 0", i, int(allocs)) 438 } 439 } 440 } 441 442 var addedSink, removedSink GerritHashtags 443 444 func BenchmarkParseHashtags(b *testing.B) { 445 b.ReportAllocs() 446 447 var metas []*GerritMeta 448 for _, tt := range hashtagTests { 449 metas = append(metas, &GerritMeta{Commit: &GitCommit{Msg: tt.commit}}) 450 } 451 452 for i := 0; i < b.N; i++ { 453 for _, meta := range metas { 454 addedSink, removedSink, _ = meta.HashtagEdits() 455 } 456 } 457 } 458 459 func TestGerritHashtagsContains(t *testing.T) { 460 tests := []struct { 461 set string 462 t string 463 want bool 464 }{ 465 {"", "", false}, 466 {"x", "", false}, 467 {"", "x", false}, 468 469 {"foo,bar", "foo", true}, 470 {"foo, bar", "foo", true}, 471 {" foo, bar", "foo", true}, 472 {" foo , bar", "foo", true}, 473 {" foo , bar ", "foo", true}, 474 475 {"foo,bar", "bar", true}, 476 {"foo, bar", "bar", true}, 477 {" foo, bar", "bar", true}, 478 {" foo , bar", "bar", true}, 479 {" foo , bar ", "bar", true}, 480 481 {"foo, bar", "fo", false}, 482 {"foo, bar", "foo, bar", false}, 483 {"foo, bar", "ba", false}, 484 } 485 for _, tt := range tests { 486 got := GerritHashtags(tt.set).Contains(tt.t) 487 if got != tt.want { 488 t.Errorf("GerritHashtags(%q).Contains(%q) = %v; want %v", tt.set, tt.t, got, tt.want) 489 } 490 } 491 } 492 493 func TestGerritHashtagsForeach(t *testing.T) { 494 tests := []struct { 495 set string 496 want string 497 }{ 498 {"", ""}, 499 500 {"foo", "foo."}, 501 {"foo ", "foo."}, 502 {" foo", "foo."}, 503 {"foo,bar", "foo.bar."}, 504 {" foo , bar ", "foo.bar."}, 505 } 506 for _, tt := range tests { 507 var buf bytes.Buffer 508 GerritHashtags(tt.set).Foreach(func(t string) { 509 buf.WriteString(t) 510 buf.WriteByte('.') 511 }) 512 got := buf.String() 513 if got != tt.want { 514 t.Errorf("For set %q, got %q; want %q", tt.set, got, tt.want) 515 } 516 } 517 } 518 519 func TestGerritHashtagsMatch(t *testing.T) { 520 tests := []struct { 521 set string 522 want bool // whether "foo" was found 523 wantCalls int 524 }{ 525 {"", false, 0}, 526 {"foo", true, 1}, 527 {"foo, foo", true, 1}, 528 {"bar, foo", true, 2}, 529 } 530 for _, tt := range tests { 531 calls := 0 532 got := GerritHashtags(tt.set).Match(func(t string) bool { 533 calls++ 534 return t == "foo" 535 }) 536 if got != tt.want { 537 t.Errorf("For set %q, Match = %v; want %v", tt.set, got, tt.want) 538 } 539 if calls != tt.wantCalls { 540 t.Errorf("For set %q, number of func calls = %v; want %v", tt.set, calls, tt.wantCalls) 541 } 542 } 543 } 544 545 func TestGerritHashtagsLen(t *testing.T) { 546 tests := []struct { 547 set string 548 want int 549 }{ 550 {"", 0}, 551 {"foo", 1}, 552 {"foo,bar", 2}, 553 {"foo, bar", 2}, 554 } 555 for _, tt := range tests { 556 got := GerritHashtags(tt.set).Len() 557 if got != tt.want { 558 t.Errorf("For set %q, Len = %v; want %v", tt.set, got, tt.want) 559 } 560 } 561 }