sigs.k8s.io/prow@v0.0.0-20240503223140-c5e374dc7eb1/pkg/commentpruner/commentpruner_test.go (about) 1 /* 2 Copyright 2017 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package commentpruner 18 19 import ( 20 "reflect" 21 "sort" 22 "testing" 23 24 "github.com/sirupsen/logrus" 25 26 "sigs.k8s.io/prow/pkg/github" 27 ) 28 29 type fakeGHClient struct { 30 comments []github.IssueComment 31 deletedComments []int 32 listCallCount int 33 } 34 35 func (*fakeGHClient) BotUserChecker() (func(candidate string) bool, error) { 36 return func(candidate string) bool { 37 return candidate == "k8s-ci-robot" 38 }, nil 39 } 40 41 func (f *fakeGHClient) ListIssueComments(_, _ string, _ int) ([]github.IssueComment, error) { 42 f.listCallCount++ 43 return f.comments, nil 44 } 45 46 func (f *fakeGHClient) DeleteComment(_, _ string, ID int) error { 47 f.deletedComments = append(f.deletedComments, ID) 48 return nil 49 } 50 51 func newFakeGHClient(commentsToLogins map[int]string) *fakeGHClient { 52 comments := make([]github.IssueComment, 0, len(commentsToLogins)) 53 for num, login := range commentsToLogins { 54 comments = append(comments, github.IssueComment{ID: num, User: github.User{Login: login}}) 55 } 56 return &fakeGHClient{ 57 comments: comments, 58 deletedComments: []int{}, 59 } 60 } 61 62 func testPruneFunc(errorComments *[]int, toPrunes, toErrs []int) func(github.IssueComment) bool { 63 return func(ic github.IssueComment) bool { 64 for _, toErr := range toErrs { 65 if ic.ID == toErr { 66 *errorComments = append(*errorComments, ic.ID) 67 break 68 } 69 } 70 for _, toPrune := range toPrunes { 71 if ic.ID == toPrune { 72 return true 73 } 74 } 75 return false 76 } 77 } 78 79 func TestPruneComments(t *testing.T) { 80 botLogin := "k8s-ci-robot" 81 humanLogin := "cjwagner" 82 83 var errs *[]int 84 tcs := []struct { 85 name string 86 comments map[int]string 87 callers []func(github.IssueComment) bool 88 expectedDeleted []int 89 }{ 90 { 91 name: "One caller, multiple deletions.", 92 comments: map[int]string{1: botLogin, 2: botLogin, 3: botLogin}, 93 callers: []func(github.IssueComment) bool{testPruneFunc(errs, []int{1, 2}, nil)}, 94 expectedDeleted: []int{1, 2}, 95 }, 96 { 97 name: "One caller, no deletions.", 98 comments: map[int]string{3: botLogin}, 99 callers: []func(github.IssueComment) bool{testPruneFunc(errs, []int{1, 2}, nil)}, 100 expectedDeleted: []int{}, 101 }, 102 { 103 name: "Two callers.", 104 comments: map[int]string{1: botLogin, 2: botLogin, 3: botLogin, 4: botLogin, 5: botLogin}, 105 callers: []func(github.IssueComment) bool{ 106 testPruneFunc(errs, []int{1, 2}, nil), 107 testPruneFunc(errs, []int{4}, []int{1, 2}), 108 }, 109 expectedDeleted: []int{1, 2, 4}, 110 }, 111 { 112 name: "Three callers. Some Human messages", 113 comments: map[int]string{1: humanLogin, 2: botLogin, 3: botLogin, 4: botLogin, 5: botLogin, 6: humanLogin, 7: botLogin}, 114 callers: []func(github.IssueComment) bool{ 115 testPruneFunc(errs, []int{2, 3}, []int{1, 6}), 116 testPruneFunc(errs, []int{5}, []int{1, 2, 3, 6}), 117 testPruneFunc(errs, []int{4}, []int{1, 2, 3, 5, 6}), 118 }, 119 expectedDeleted: []int{2, 3, 4, 5}, 120 }, 121 } 122 123 /* 124 Ensure the following: 125 When multiple callers ask for comment deletion from the same client... 126 - They should not see comments deleted by previous caller. 127 - Comments should be listed only once. 128 - All comments that are stale should be deleted. 129 */ 130 for _, tc := range tcs { 131 errs = &[]int{} 132 fgc := newFakeGHClient(tc.comments) 133 client := NewEventClient(fgc, logrus.WithField("client", "commentpruner"), "org", "repo", 1) 134 for _, call := range tc.callers { 135 client.PruneComments(call) 136 } 137 138 if fgc.listCallCount != 1 { 139 t.Errorf("[%s]: Expected comments to be fetched exactly once, instead got %d.", tc.name, fgc.listCallCount) 140 } 141 if len(*errs) > 0 { 142 t.Errorf("[%s]: The following comments should not have been seen be subsequent callers: %v.", tc.name, *errs) 143 } 144 sort.Ints(tc.expectedDeleted) 145 sort.Ints(fgc.deletedComments) 146 if !reflect.DeepEqual(tc.expectedDeleted, fgc.deletedComments) { 147 t.Errorf("[%s]: Expected the comments %#v to be deleted, but %#v were deleted instead.", tc.name, tc.expectedDeleted, fgc.deletedComments) 148 } 149 } 150 }