| // Copyright 2017 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package maintner |
| |
| import ( |
| "bytes" |
| "testing" |
| "time" |
| ) |
| |
| var statusTests = []struct { |
| msg string |
| want string |
| }{ |
| {`Create change |
| |
| Uploaded patch set 1. |
| |
| Patch-set: 1 (draft) |
| Change-id: I38a08cacc17bcd9587475495111fe98f10d6875c |
| Subject: test: test |
| Branch: refs/heads/master |
| Status: draft |
| Topic: |
| Commit: fee468c613a70d89f60fb5d683b0f796aabecaac`, "draft"}, |
| {`Update patch set 1 |
| |
| Change has been successfully cherry-picked as 117ac82c422a11e4dd5f4c14b50bafc1df840481 by Brad Fitzpatrick |
| |
| Patch-set: 1 |
| Status: merged |
| Submission-id: 16401-1446004855021-a20b3823`, "merged"}, |
| {`Create patch set 8 |
| |
| Uploaded patch set 8: Patch Set 7 was rebased. |
| |
| Patch-set: 8 |
| Subject: devapp: initial support for App Engine Flex |
| Commit: 17839a9f284b473986f235ad2757a2b445d05068 |
| Tag: autogenerated:gerrit:newPatchSet |
| Groups: 17839a9f284b473986f235ad2757a2b445d05068`, ""}, |
| } |
| |
| func TestGetGerritStatus(t *testing.T) { |
| for _, tt := range statusTests { |
| gc := &GitCommit{Msg: tt.msg} |
| got := getGerritStatus(gc) |
| if got != tt.want { |
| t.Errorf("getGerritStatus msg:\n%s\ngot %s, want %s", tt.msg, got, tt.want) |
| } |
| } |
| } |
| |
| var normalizeTests = []struct { |
| in string |
| out string |
| }{ |
| {"foo", "foo"}, |
| {"http://foo", "foo"}, |
| {"upspin-review.googlesource.com", "upspin.googlesource.com"}, |
| {"go-review.googlesource.com", "go.googlesource.com"}, |
| } |
| |
| func TestNormalizeServer(t *testing.T) { |
| for _, tt := range normalizeTests { |
| got := normalizeGerritServer(tt.in) |
| if got != tt.out { |
| t.Errorf("normalizeGerritServer(%q) = %q, want %q", tt.in, got, tt.out) |
| } |
| } |
| } |
| |
| func TestGerritProject(t *testing.T) { |
| var c Corpus |
| c.EnableLeaderMode(new(dummyMutationLogger), "/fake/dir") |
| c.TrackGerrit("go.googlesource.com/build") |
| gp := c.Gerrit().Project("go-review.googlesource.com", "build") |
| if gp == nil { |
| t.Errorf("expected go-review.googlesource.com to return a project, got nil") |
| } |
| gp = c.Gerrit().Project("go-review.googlesource.com", "unknown") |
| if gp != nil { |
| t.Errorf("expected go-review.googlesource.com to return nil, got a project") |
| } |
| } |
| |
| var messageTests = []struct { |
| in string |
| want string |
| wantNil bool |
| }{ |
| { |
| in: `Update patch set 1 |
| |
| Patch Set 1: Code-Review+2 |
| |
| Just to confirm, "go test" will consider an empty test file to be passing? |
| |
| Patch-set: 1 |
| Reviewer: Quentin Smith <13020@62eb7196-b449-3ce5-99f1-c037f21e1705> |
| Label: Code-Review=+2 |
| `, |
| want: "Patch Set 1: Code-Review+2\n\nJust to confirm, \"go test\" will consider an empty test file to be passing?", |
| }, |
| { |
| in: `Create change |
| |
| Uploaded patch set 1: Run-TryBot+1. |
| |
| Patch-set: 1 |
| Change-id: I1e0035ffba986c3551479d5742809e43da5e7c73 |
| Subject: runtime: fall back to small mmaps if we fail to grow reservation |
| Branch: refs/heads/master |
| Status: new |
| Topic: |
| Commit: 8776f8d725c001456037e8888a72885d46cd6744 |
| Tag: autogenerated:gerrit:newPatchSet |
| Groups: 8776f8d725c001456037e8888a72885d46cd6744 |
| Reviewer: Keith Randall <5200@62eb7196-b449-3ce5-99f1-c037f21e1705> |
| Reviewer: Rick Hudson <5186@62eb7196-b449-3ce5-99f1-c037f21e1705> |
| Reviewer: Austin Clements <5167@62eb7196-b449-3ce5-99f1-c037f21e1705> |
| Label: Run-TryBot=+1 |
| Private: false |
| Work-in-progress: false |
| `, |
| want: "Uploaded patch set 1: Run-TryBot+1.", |
| }, |
| { |
| in: `Uploaded patch set 1. |
| |
| Patch-set: 1 |
| `, |
| wantNil: true, |
| }, |
| { |
| in: `Create change |
| |
| Uploaded patch set 1. |
| |
| Patch-set: 1 |
| Change-id: I3799148a111f1ab6bfee24c9e03e6ebbf9e9595b |
| Subject: net: make error messages consistent for invalid ports |
| Branch: refs/heads/master |
| Commit: 8a7de7048dc194d5e6f761add433b915beebb2e0 |
| Groups: 8a7de7048dc194d5e6f761add433b915beebb2e0 |
| `, |
| wantNil: true, |
| }, |
| { |
| in: `Create patch set 7 |
| |
| Uploaded patch set 7.: Commit message was updated |
| |
| Patch-set: 7 |
| Subject: cmd/vet: -lostcancel: check for discarded result of context.WithCancel |
| Commit: 5487cc78ea332c7b49d43ef5955211387aca73bb |
| Groups: 5487cc78ea332c7b49d43ef5955211387aca73bb |
| `, |
| wantNil: true, |
| }, |
| } |
| |
| func TestGetGerritMessage(t *testing.T) { |
| var c Corpus |
| c.EnableLeaderMode(new(dummyMutationLogger), "/fake/dir") |
| c.TrackGerrit("go.googlesource.com/build") |
| gp := c.gerrit.projects["go.googlesource.com/build"] |
| for i, tt := range messageTests { |
| gc := &GitCommit{ |
| Msg: tt.in, |
| CommitTime: time.Now().UTC(), |
| } |
| msg := gp.getGerritMessage(gc) |
| if msg == nil != tt.wantNil { |
| if tt.wantNil { |
| t.Errorf("%d. getGerritMessage returned item; want nil", i) |
| } else { |
| t.Errorf("%d. getGerritMessage = nil; want a message", i) |
| } |
| continue |
| } |
| if msg == nil { |
| continue |
| } |
| // just checking these get copied through appropriately |
| if msg.Version != 1 { |
| t.Errorf("%d. getGerritMessage: want Version 1, got %d", i, msg.Version) |
| } |
| if msg.Date.IsZero() { |
| t.Errorf("%d. getGerritMessage: expected Date to be non-zero, got zero", i) |
| } |
| if msg.Message != tt.want { |
| t.Errorf("%d. getGerritMessage = %q; want %q", i, msg.Message, tt.want) |
| } |
| } |
| } |
| |
| func TestOwnerID(t *testing.T) { |
| cl := &GerritCL{} |
| meta := newGerritMeta( |
| &GitCommit{ |
| Author: &GitPerson{ |
| Str: "Rick Sanchez <137@62eb7196-b449-3ce5-99f1-c037f21e1705>", |
| }, |
| }, |
| cl, |
| ) |
| cl.Meta = meta |
| cl.Metas = []*GerritMeta{meta} |
| cl.Commit = &GitCommit{} |
| |
| testCases := []struct { |
| cl *GerritCL |
| OwnerID int |
| }{ |
| {&GerritCL{}, -1}, |
| {cl, 137}, |
| } |
| for _, tc := range testCases { |
| if got := tc.cl.OwnerID(); got != tc.OwnerID { |
| t.Errorf("cl.OwnerID() = %d; want %d", got, tc.OwnerID) |
| } |
| } |
| } |
| |
| func TestSubject(t *testing.T) { |
| testcases := []struct{ msg, subject string }{ |
| {"maintner: slurp up all the things", "maintner: slurp up all the things"}, |
| {"cmd/go: build stuff\n\nand do other stuff, too.", "cmd/go: build stuff"}, |
| {"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. |
| {"cmd/go: build lots\nof stuff", "cmd/go: build lots of stuff"}, |
| } |
| for _, tc := range testcases { |
| cl := &GerritCL{Commit: &GitCommit{Msg: tc.msg}} |
| if cl.Subject() != tc.subject { |
| t.Errorf("cl.Subject() = %q; want %q", cl.Subject(), tc.subject) |
| } |
| } |
| } |
| |
| func TestChangeID(t *testing.T) { |
| testcases := []struct{ msg, changeID string }{ |
| {"maintner: slurp up all the things", ""}, |
| {"cmd/go: build stuff\n\nChange-Id: I7d3850e6774403c5d4ae15ca94c31c2f46f4ffa3", "I7d3850e6774403c5d4ae15ca94c31c2f46f4ffa3"}, |
| } |
| for _, tc := range testcases { |
| cl := &GerritCL{Commit: &GitCommit{Msg: tc.msg}} |
| if cl.ChangeID() != tc.changeID { |
| t.Errorf("cl.ChangeID() = %q; want %q", cl.ChangeID(), tc.changeID) |
| } |
| } |
| } |
| |
| func TestLineValueOK(t *testing.T) { |
| tests := []struct { |
| all, prefix, want, wantRest string |
| wantOK bool |
| }{ |
| { |
| all: "foo: value ", |
| prefix: "foo:", |
| want: "value", |
| wantRest: "", |
| wantOK: true, |
| }, |
| { |
| all: "foo: value\n", |
| prefix: "foo:", |
| want: "value", |
| wantRest: "", |
| wantOK: true, |
| }, |
| { |
| all: "foo:\n", |
| prefix: "foo:", |
| want: "", |
| wantRest: "", |
| wantOK: true, |
| }, |
| { |
| all: "bar:\n", |
| prefix: "foo:", |
| want: "", |
| wantRest: "", |
| wantOK: false, |
| }, |
| { |
| all: "bar: other\nfoo: value\n", |
| prefix: "foo:", |
| want: "value", |
| wantRest: "", |
| wantOK: true, |
| }, |
| { |
| all: "notfoo: other\nfoo: value\n", |
| prefix: "foo:", |
| want: "value", |
| wantRest: "", |
| wantOK: true, |
| }, |
| { |
| all: "Foo: bar\nLabel: Vote=+1\nLabel: Vote=+2\n", |
| prefix: "Label: ", |
| want: "Vote=+1", |
| wantRest: "Label: Vote=+2\n", |
| wantOK: true, |
| }, |
| { |
| all: "Label: Vote=+2\n", |
| prefix: "Label: ", |
| want: "Vote=+2", |
| wantRest: "", |
| wantOK: true, |
| }, |
| } |
| for _, tt := range tests { |
| got, gotRest, gotOK := lineValueOK(tt.all, tt.prefix) |
| if got != tt.want { |
| t.Errorf("lineValueOK(%q, %q) returned value %q; want %q", tt.all, tt.prefix, got, tt.want) |
| } |
| if gotRest != tt.wantRest { |
| t.Errorf("lineValueOK(%q, %q) returned rest %q; want %q", tt.all, tt.prefix, gotRest, tt.wantRest) |
| } |
| if gotOK != tt.wantOK { |
| t.Errorf("lineValueOK(%q, %q) returned ok %v; want %v", tt.all, tt.prefix, gotOK, tt.wantOK) |
| } |
| } |
| } |
| |
| func TestParseGerritLabelValue(t *testing.T) { |
| tests := []struct { |
| in string |
| wantLabel string |
| wantValue int8 |
| wantWhose string |
| }{ |
| {"Run-TryBot=+1", "Run-TryBot", 1, ""}, |
| {"-Run-TryBot", "-Run-TryBot", 0, ""}, |
| {"-TryBot-Result Gobot Gobot <5976@62eb7196-b449-3ce5-99f1-c037f21e1705>", "-TryBot-Result", 0, "5976@62eb7196-b449-3ce5-99f1-c037f21e1705"}, |
| {"Run-TryBot=+1 Brad Fitzpatrick <5065@62eb7196-b449-3ce5-99f1-c037f21e1705>", "Run-TryBot", 1, "5065@62eb7196-b449-3ce5-99f1-c037f21e1705"}, |
| {"TryBot-Result=-1 Gobot Gobot <5976@62eb7196-b449-3ce5-99f1-c037f21e1705>", "TryBot-Result", -1, "5976@62eb7196-b449-3ce5-99f1-c037f21e1705"}, |
| } |
| for _, tt := range tests { |
| label, value, whose := parseGerritLabelValue(tt.in) |
| if label != tt.wantLabel || value != tt.wantValue || whose != tt.wantWhose { |
| t.Errorf("parseGerritLabelValue(%q) = %q, %v, %q; want %q, %v, %q", |
| tt.in, |
| label, value, whose, |
| tt.wantLabel, tt.wantValue, tt.wantWhose) |
| } |
| } |
| } |
| |
| var hashtagTests = []struct { |
| commit string |
| wantAdd string |
| wantRemove string |
| }{ |
| { |
| commit: `Update patch set 1 |
| |
| Hashtag removed:foo |
| |
| Patch-set: 1 |
| Hashtags: |
| Tag: autogenerated:gerrit:setHashtag |
| `, |
| wantRemove: "foo", |
| }, |
| { |
| commit: `Update patch set 1 |
| |
| Hashtags removed: foo, bar |
| |
| Patch-set: 1 |
| Hashtags: |
| Tag: autogenerated:gerrit:setHashtag |
| `, |
| wantRemove: "foo, bar", |
| }, |
| { |
| commit: `Update patch set 1 |
| |
| Hashtag added: bar |
| |
| Patch-set: 1 |
| Hashtags: |
| Tag: autogenerated:gerrit:setHashtag |
| `, |
| wantAdd: "bar", |
| }, |
| { |
| commit: `Update patch set 1 |
| |
| Hashtags added: x,y |
| |
| Patch-set: 1 |
| Hashtags: |
| Tag: autogenerated:gerrit:setHashtag |
| `, |
| wantAdd: "x,y", |
| }, |
| // No tag: |
| { |
| commit: `Update patch set 1 |
| |
| Hashtags added: x,y |
| |
| Patch-set: 1 |
| Hashtags: |
| Tag: autogenerated:gerrit:otherTag |
| `, |
| }, |
| } |
| |
| func TestParseHashtags(t *testing.T) { |
| for i, tt := range hashtagTests { |
| meta := newGerritMeta(&GitCommit{Msg: tt.commit}, nil) |
| added, removed, ok := meta.HashtagEdits() |
| if ok != (added != "" || removed != "") { |
| t.Errorf("%d. inconsistent return values: %q, %q, %v", i, added, removed, ok) |
| } |
| if string(added) != tt.wantAdd { |
| t.Errorf("%d. added = %q; want %q", i, added, tt.wantAdd) |
| } |
| if string(removed) != tt.wantRemove { |
| t.Errorf("%d. removed = %q; want %q", i, removed, tt.wantRemove) |
| } |
| |
| // And an allocation test too: |
| allocs := testing.AllocsPerRun(100, func() { |
| _, _, _ = meta.HashtagEdits() |
| }) |
| if allocs > 0 { |
| t.Errorf("%d. allocs = %d; want 0", i, int(allocs)) |
| } |
| } |
| } |
| |
| var addedSink, removedSink GerritHashtags |
| |
| func BenchmarkParseHashtags(b *testing.B) { |
| b.ReportAllocs() |
| |
| var metas []*GerritMeta |
| for _, tt := range hashtagTests { |
| metas = append(metas, &GerritMeta{Commit: &GitCommit{Msg: tt.commit}}) |
| } |
| |
| for i := 0; i < b.N; i++ { |
| for _, meta := range metas { |
| addedSink, removedSink, _ = meta.HashtagEdits() |
| } |
| } |
| } |
| |
| func TestGerritHashtagsContains(t *testing.T) { |
| tests := []struct { |
| set string |
| t string |
| want bool |
| }{ |
| {"", "", false}, |
| {"x", "", false}, |
| {"", "x", false}, |
| |
| {"foo,bar", "foo", true}, |
| {"foo, bar", "foo", true}, |
| {" foo, bar", "foo", true}, |
| {" foo , bar", "foo", true}, |
| {" foo , bar ", "foo", true}, |
| |
| {"foo,bar", "bar", true}, |
| {"foo, bar", "bar", true}, |
| {" foo, bar", "bar", true}, |
| {" foo , bar", "bar", true}, |
| {" foo , bar ", "bar", true}, |
| |
| {"foo, bar", "fo", false}, |
| {"foo, bar", "foo, bar", false}, |
| {"foo, bar", "ba", false}, |
| } |
| for _, tt := range tests { |
| got := GerritHashtags(tt.set).Contains(tt.t) |
| if got != tt.want { |
| t.Errorf("GerritHashtags(%q).Contains(%q) = %v; want %v", tt.set, tt.t, got, tt.want) |
| } |
| } |
| } |
| |
| func TestGerritHashtagsForeach(t *testing.T) { |
| tests := []struct { |
| set string |
| want string |
| }{ |
| {"", ""}, |
| |
| {"foo", "foo."}, |
| {"foo ", "foo."}, |
| {" foo", "foo."}, |
| {"foo,bar", "foo.bar."}, |
| {" foo , bar ", "foo.bar."}, |
| } |
| for _, tt := range tests { |
| var buf bytes.Buffer |
| GerritHashtags(tt.set).Foreach(func(t string) { |
| buf.WriteString(t) |
| buf.WriteByte('.') |
| }) |
| got := buf.String() |
| if got != tt.want { |
| t.Errorf("For set %q, got %q; want %q", tt.set, got, tt.want) |
| } |
| } |
| } |
| |
| func TestGerritHashtagsMatch(t *testing.T) { |
| tests := []struct { |
| set string |
| want bool // whether "foo" was found |
| wantCalls int |
| }{ |
| {"", false, 0}, |
| {"foo", true, 1}, |
| {"foo, foo", true, 1}, |
| {"bar, foo", true, 2}, |
| } |
| for _, tt := range tests { |
| calls := 0 |
| got := GerritHashtags(tt.set).Match(func(t string) bool { |
| calls++ |
| return t == "foo" |
| }) |
| if got != tt.want { |
| t.Errorf("For set %q, Match = %v; want %v", tt.set, got, tt.want) |
| } |
| if calls != tt.wantCalls { |
| t.Errorf("For set %q, number of func calls = %v; want %v", tt.set, calls, tt.wantCalls) |
| } |
| } |
| } |
| |
| func TestGerritHashtagsLen(t *testing.T) { |
| tests := []struct { |
| set string |
| want int |
| }{ |
| {"", 0}, |
| {"foo", 1}, |
| {"foo,bar", 2}, |
| {"foo, bar", 2}, |
| } |
| for _, tt := range tests { |
| got := GerritHashtags(tt.set).Len() |
| if got != tt.want { |
| t.Errorf("For set %q, Len = %v; want %v", tt.set, got, tt.want) |
| } |
| } |
| } |