github.com/yrj2011/jx-test-infra@v0.0.0-20190529031832-7a2065ee98eb/prow/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  	"k8s.io/test-infra/prow/github"
    27  )
    28  
    29  type fakeGHClient struct {
    30  	comments        []github.IssueComment
    31  	deletedComments []int
    32  	listCallCount   int
    33  }
    34  
    35  func (f *fakeGHClient) BotName() (string, error) {
    36  	return "k8s-ci-robot", nil
    37  }
    38  
    39  func (f *fakeGHClient) ListIssueComments(_, _ string, _ int) ([]github.IssueComment, error) {
    40  	f.listCallCount++
    41  	return f.comments, nil
    42  }
    43  
    44  func (f *fakeGHClient) DeleteComment(_, _ string, ID int) error {
    45  	f.deletedComments = append(f.deletedComments, ID)
    46  	return nil
    47  }
    48  
    49  func newFakeGHClient(commentsToLogins map[int]string) *fakeGHClient {
    50  	comments := make([]github.IssueComment, 0, len(commentsToLogins))
    51  	for num, login := range commentsToLogins {
    52  		comments = append(comments, github.IssueComment{ID: num, User: github.User{Login: login}})
    53  	}
    54  	return &fakeGHClient{
    55  		comments:        comments,
    56  		deletedComments: []int{},
    57  	}
    58  }
    59  
    60  func testPruneFunc(errorComments *[]int, toPrunes, toErrs []int) func(github.IssueComment) bool {
    61  	return func(ic github.IssueComment) bool {
    62  		for _, toErr := range toErrs {
    63  			if ic.ID == toErr {
    64  				*errorComments = append(*errorComments, ic.ID)
    65  				break
    66  			}
    67  		}
    68  		for _, toPrune := range toPrunes {
    69  			if ic.ID == toPrune {
    70  				return true
    71  			}
    72  		}
    73  		return false
    74  	}
    75  }
    76  
    77  func TestPruneComments(t *testing.T) {
    78  	botLogin := "k8s-ci-robot"
    79  	humanLogin := "cjwagner"
    80  
    81  	var errs *[]int
    82  	tcs := []struct {
    83  		name            string
    84  		comments        map[int]string
    85  		callers         []func(github.IssueComment) bool
    86  		expectedDeleted []int
    87  	}{
    88  		{
    89  			name:            "One caller, multiple deletions.",
    90  			comments:        map[int]string{1: botLogin, 2: botLogin, 3: botLogin},
    91  			callers:         []func(github.IssueComment) bool{testPruneFunc(errs, []int{1, 2}, nil)},
    92  			expectedDeleted: []int{1, 2},
    93  		},
    94  		{
    95  			name:            "One caller, no deletions.",
    96  			comments:        map[int]string{3: botLogin},
    97  			callers:         []func(github.IssueComment) bool{testPruneFunc(errs, []int{1, 2}, nil)},
    98  			expectedDeleted: []int{},
    99  		},
   100  		{
   101  			name:     "Two callers.",
   102  			comments: map[int]string{1: botLogin, 2: botLogin, 3: botLogin, 4: botLogin, 5: botLogin},
   103  			callers: []func(github.IssueComment) bool{
   104  				testPruneFunc(errs, []int{1, 2}, nil),
   105  				testPruneFunc(errs, []int{4}, []int{1, 2}),
   106  			},
   107  			expectedDeleted: []int{1, 2, 4},
   108  		},
   109  		{
   110  			name:     "Three callers. Some Human messages",
   111  			comments: map[int]string{1: humanLogin, 2: botLogin, 3: botLogin, 4: botLogin, 5: botLogin, 6: humanLogin, 7: botLogin},
   112  			callers: []func(github.IssueComment) bool{
   113  				testPruneFunc(errs, []int{2, 3}, []int{1, 6}),
   114  				testPruneFunc(errs, []int{5}, []int{1, 2, 3, 6}),
   115  				testPruneFunc(errs, []int{4}, []int{1, 2, 3, 5, 6}),
   116  			},
   117  			expectedDeleted: []int{2, 3, 4, 5},
   118  		},
   119  	}
   120  
   121  	/*
   122  		Ensure the following:
   123  		When multiple callers ask for comment deletion from the same client...
   124  		- They should not see comments deleted by previous caller.
   125  		- Comments should be listed only once.
   126  		- All comments that are stale should be deleted.
   127  	*/
   128  	for _, tc := range tcs {
   129  		errs = &[]int{}
   130  		fgc := newFakeGHClient(tc.comments)
   131  		client := NewEventClient(fgc, logrus.WithField("client", "commentpruner"), "org", "repo", 1)
   132  		for _, call := range tc.callers {
   133  			client.PruneComments(call)
   134  		}
   135  
   136  		if fgc.listCallCount != 1 {
   137  			t.Errorf("[%s]: Expected comments to be fetched exactly once, instead got %d.", tc.name, fgc.listCallCount)
   138  		}
   139  		if len(*errs) > 0 {
   140  			t.Errorf("[%s]: The following comments should not have been seen be subsequent callers: %v.", tc.name, *errs)
   141  		}
   142  		sort.Ints(tc.expectedDeleted)
   143  		sort.Ints(fgc.deletedComments)
   144  		if !reflect.DeepEqual(tc.expectedDeleted, fgc.deletedComments) {
   145  			t.Errorf("[%s]: Expected the comments %#v to be deleted, but %#v were deleted instead.", tc.name, tc.expectedDeleted, fgc.deletedComments)
   146  		}
   147  	}
   148  }