sigs.k8s.io/prow@v0.0.0-20240503223140-c5e374dc7eb1/pkg/plugins/sigmention/sigmention_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 sigmention
    18  
    19  import (
    20  	"fmt"
    21  	"reflect"
    22  	"regexp"
    23  	"sort"
    24  	"strings"
    25  	"testing"
    26  
    27  	"github.com/sirupsen/logrus"
    28  
    29  	"sigs.k8s.io/prow/pkg/github"
    30  	"sigs.k8s.io/prow/pkg/github/fakegithub"
    31  	"sigs.k8s.io/prow/pkg/labels"
    32  )
    33  
    34  func formatLabels(labels []string) []string {
    35  	r := []string{}
    36  	for _, l := range labels {
    37  		r = append(r, fmt.Sprintf("%s/%s#%d:%s", "org", "repo", 1, l))
    38  	}
    39  	if len(r) == 0 {
    40  		return nil
    41  	}
    42  	return r
    43  }
    44  
    45  func TestSigMention(t *testing.T) {
    46  	orgMember := "cjwagner"
    47  	nonOrgMember := "john"
    48  	bot := "k8s-ci-robot"
    49  	type testCase struct {
    50  		name              string
    51  		body              string
    52  		commenter         string
    53  		expectedRepeats   []string
    54  		expectedNewLabels []string
    55  		issueLabels       []string
    56  		repoLabels        []string
    57  		regexp            string
    58  	}
    59  	testcases := []testCase{
    60  		{
    61  			name:              "Don't repeat when org member mentions sig",
    62  			body:              "@kubernetes/sig-node-misc",
    63  			expectedRepeats:   []string{},
    64  			expectedNewLabels: []string{"sig/node"},
    65  			repoLabels:        []string{"area/infra", "priority/urgent", "sig/node"},
    66  			issueLabels:       []string{},
    67  			commenter:         orgMember,
    68  		},
    69  		{
    70  			name:              "Don't repeat or label when bot adds mentions sig",
    71  			body:              "@kubernetes/sig-node-misc",
    72  			expectedRepeats:   []string{},
    73  			expectedNewLabels: []string{},
    74  			repoLabels:        []string{"area/infra", "priority/urgent", "sig/node"},
    75  			issueLabels:       []string{},
    76  			commenter:         bot,
    77  		},
    78  		{
    79  			name:              "Repeat when non org adds one sig label (sig label already present)",
    80  			body:              "@kubernetes/sig-node-bugs",
    81  			expectedRepeats:   []string{"@kubernetes/sig-node-bugs"},
    82  			expectedNewLabels: []string{labels.Bug},
    83  			repoLabels:        []string{"area/infra", "priority/urgent", "sig/node", labels.Bug},
    84  			issueLabels:       []string{"sig/node"},
    85  			commenter:         nonOrgMember,
    86  		},
    87  		{
    88  			name:              "Don't repeat non existent labels",
    89  			body:              "@kubernetes/sig-node-misc @kubernetes/sig-api-machinery-bugs",
    90  			expectedRepeats:   []string{},
    91  			expectedNewLabels: []string{},
    92  			repoLabels:        []string{},
    93  			issueLabels:       []string{},
    94  			commenter:         nonOrgMember,
    95  		},
    96  		{
    97  			name:              "Don't repeat multiple if org member (all labels present).",
    98  			body:              "@kubernetes/sig-node-misc @kubernetes/sig-api-machinery-bugs",
    99  			expectedRepeats:   []string{},
   100  			expectedNewLabels: []string{},
   101  			repoLabels:        []string{"sig/node", "sig/api-machinery", labels.Bug},
   102  			issueLabels:       []string{"sig/node", "sig/api-machinery", labels.Bug},
   103  			commenter:         orgMember,
   104  		},
   105  		{
   106  			name:              "Repeat multiple valid labels from non org member",
   107  			body:              "@kubernetes/sig-node-misc @kubernetes/sig-api-machinery-bugs",
   108  			expectedRepeats:   []string{"@kubernetes/sig-node-misc", "@kubernetes/sig-api-machinery-bugs"},
   109  			expectedNewLabels: []string{"sig/node", "sig/api-machinery", labels.Bug},
   110  			repoLabels:        []string{"sig/node", "sig/api-machinery", labels.Bug},
   111  			issueLabels:       []string{},
   112  			commenter:         nonOrgMember,
   113  		},
   114  		{
   115  			name:              "Repeat multiple valid labels with a line break from non org member.",
   116  			body:              "@kubernetes/sig-node-misc\n@kubernetes/sig-api-machinery-bugs",
   117  			expectedRepeats:   []string{"@kubernetes/sig-node-misc", "@kubernetes/sig-api-machinery-bugs"},
   118  			expectedNewLabels: []string{"sig/node", "sig/api-machinery", labels.Bug},
   119  			repoLabels:        []string{"sig/node", "sig/api-machinery", labels.Bug},
   120  			issueLabels:       []string{},
   121  			commenter:         nonOrgMember,
   122  		},
   123  		{
   124  			name:              "Repeat Multiple Sig Labels Different Lines With Other Text",
   125  			body:              "Code Comment.  Design Review\n@kubernetes/sig-node-proposals\ncc @kubernetes/sig-api-machinery-bugs",
   126  			expectedRepeats:   []string{"@kubernetes/sig-node-proposals", "@kubernetes/sig-api-machinery-bugs"},
   127  			expectedNewLabels: []string{"sig/node", "sig/api-machinery", labels.Bug},
   128  			repoLabels:        []string{"area/infra", "priority/urgent", "sig/node", "sig/api-machinery", labels.Bug},
   129  			issueLabels:       []string{},
   130  			commenter:         nonOrgMember,
   131  		},
   132  		{
   133  			name:              "Repeat when multiple label adding commands (sig labels present)",
   134  			body:              "/area infra\n/priority urgent Design Review\n@kubernetes/sig-node-misc\ncc @kubernetes/sig-api-machinery-bugs",
   135  			expectedRepeats:   []string{"@kubernetes/sig-node-misc", "@kubernetes/sig-api-machinery-bugs"},
   136  			expectedNewLabels: []string{"sig/node", labels.Bug},
   137  			repoLabels:        []string{"area/infra", "priority/urgent", "sig/node", "sig/api-machinery", "sig/testing", labels.Bug},
   138  			issueLabels:       []string{"sig/api-machinery", "sig/testing"},
   139  			commenter:         nonOrgMember,
   140  		},
   141  		{
   142  			name:              "Works for non-specialized teams",
   143  			body:              "@openshift/sig-node",
   144  			expectedRepeats:   []string{},
   145  			expectedNewLabels: []string{"sig/node"},
   146  			repoLabels:        []string{"area/infra", "priority/urgent", "sig/node"},
   147  			issueLabels:       []string{},
   148  			commenter:         orgMember,
   149  			regexp:            `(?m)@openshift/sig-([\w-]*)`,
   150  		},
   151  	}
   152  
   153  	for _, tc := range testcases {
   154  		fakeClient := fakegithub.NewFakeClient()
   155  		fakeClient.OrgMembers = map[string][]string{"org": {orgMember, bot}}
   156  		fakeClient.RepoLabelsExisting = tc.repoLabels
   157  		fakeClient.IssueComments = make(map[int][]github.IssueComment)
   158  		// Add initial labels to issue.
   159  		for _, label := range tc.issueLabels {
   160  			fakeClient.AddLabel("org", "repo", 1, label)
   161  		}
   162  		e := &github.GenericCommentEvent{
   163  			Action: github.GenericCommentActionCreated,
   164  			Body:   tc.body,
   165  			Number: 1,
   166  			Repo:   github.Repo{Owner: github.User{Login: "org"}, Name: "repo"},
   167  			User:   github.User{Login: tc.commenter},
   168  		}
   169  
   170  		testRe := tc.regexp
   171  		if testRe == "" {
   172  			testRe = `(?m)@kubernetes/sig-([\w-]*)-(misc|test-failures|bugs|feature-requests|proposals|pr-reviews|api-reviews)`
   173  		}
   174  		re, err := regexp.Compile(testRe)
   175  		if err != nil {
   176  			t.Errorf("unexpected error: %v", err)
   177  			continue
   178  		}
   179  
   180  		if err := handle(fakeClient, logrus.WithField("plugin", pluginName), e, re); err != nil {
   181  			t.Errorf("(%s): Unexpected error from handle: %v.", tc.name, err)
   182  			continue
   183  		}
   184  
   185  		// Check that all the correct labels (and only the correct labels) were added.
   186  		expectLabels := append(formatLabels(tc.expectedNewLabels), formatLabels(tc.issueLabels)...)
   187  		sort.Strings(expectLabels)
   188  		sort.Strings(fakeClient.IssueLabelsAdded)
   189  		if !reflect.DeepEqual(expectLabels, fakeClient.IssueLabelsAdded) {
   190  			t.Errorf("(%s): Expected issue to end with labels %q, but ended with %q.", tc.name, expectLabels, fakeClient.IssueLabelsAdded)
   191  		}
   192  
   193  		// Check that the comment contains the correct sig mentions repeats if it exists.
   194  		comments := fakeClient.IssueComments[1]
   195  		if len(tc.expectedRepeats) == 0 {
   196  			if len(comments) > 0 {
   197  				t.Errorf("(%s): No sig mentions should have been repeated, but a comment was still made.", tc.name)
   198  			}
   199  			continue
   200  		}
   201  		if len(comments) != 1 {
   202  			t.Errorf(
   203  				"(%s): Expected sig mentions to be repeated in 1 comment, but %d comments were created!",
   204  				tc.name,
   205  				len(comments),
   206  			)
   207  			continue
   208  		}
   209  		for _, repeat := range tc.expectedRepeats {
   210  			if !strings.Contains(comments[0].Body, repeat) {
   211  				t.Errorf("(%s): Comment body does not contain sig mention %q.", tc.name, repeat)
   212  			}
   213  		}
   214  	}
   215  }