github.com/munnerz/test-infra@v0.0.0-20190108210205-ce3d181dc989/prow/plugins/require-matching-label/require-matching-label_test.go (about)

     1  /*
     2  Copyright 2018 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 requirematchinglabel
    18  
    19  import (
    20  	"regexp"
    21  	"testing"
    22  
    23  	"github.com/sirupsen/logrus"
    24  	"k8s.io/apimachinery/pkg/util/sets"
    25  	"k8s.io/test-infra/prow/github"
    26  	"k8s.io/test-infra/prow/labels"
    27  	"k8s.io/test-infra/prow/plugins"
    28  )
    29  
    30  type fakeGitHub struct {
    31  	labels                               sets.String
    32  	IssueLabelsAdded, IssueLabelsRemoved sets.String
    33  	commented                            bool
    34  }
    35  
    36  func newFakeGitHub(initialLabels ...string) *fakeGitHub {
    37  	return &fakeGitHub{
    38  		labels:             sets.NewString(initialLabels...),
    39  		IssueLabelsAdded:   sets.NewString(),
    40  		IssueLabelsRemoved: sets.NewString(),
    41  	}
    42  }
    43  
    44  func (f *fakeGitHub) AddLabel(org, repo string, number int, label string) error {
    45  	f.labels.Insert(label)
    46  	f.IssueLabelsAdded.Insert(label)
    47  	return nil
    48  }
    49  
    50  func (f *fakeGitHub) RemoveLabel(org, repo string, number int, label string) error {
    51  	f.labels.Delete(label)
    52  	f.IssueLabelsRemoved.Insert(label)
    53  	return nil
    54  }
    55  
    56  func (f *fakeGitHub) CreateComment(org, repo string, number int, content string) error {
    57  	f.commented = true
    58  	return nil
    59  }
    60  
    61  func (f *fakeGitHub) GetIssueLabels(org, repo string, number int) ([]github.Label, error) {
    62  	res := make([]github.Label, 0, len(f.labels))
    63  	for label := range f.labels {
    64  		res = append(res, github.Label{Name: label})
    65  	}
    66  	return res, nil
    67  }
    68  
    69  type fakePruner struct{}
    70  
    71  func (fp *fakePruner) PruneComments(shouldPrune func(github.IssueComment) bool) {}
    72  
    73  func TestHandle(t *testing.T) {
    74  	configs := []plugins.RequireMatchingLabel{
    75  		// needs-sig over k8s org (issues)
    76  		{
    77  			Org:          "k8s",
    78  			Issues:       true,
    79  			Re:           regexp.MustCompile(`^(sig|wg|committee)/`),
    80  			MissingLabel: labels.NeedsSig,
    81  		},
    82  
    83  		// needs-kind over k8s/t-i repo (PRs)
    84  		{
    85  			Org:          "k8s",
    86  			Repo:         "t-i",
    87  			PRs:          true,
    88  			Re:           regexp.MustCompile(`^kind/`),
    89  			MissingLabel: "needs-kind",
    90  		},
    91  		// needs-cat over k8s/t-i:meow branch (issues and PRs) (will comment)
    92  		{
    93  			Org:            "k8s",
    94  			Repo:           "t-i",
    95  			Branch:         "meow",
    96  			Issues:         true,
    97  			PRs:            true,
    98  			Re:             regexp.MustCompile(`^(cat|floof|loaf)$`),
    99  			MissingLabel:   "needs-cat",
   100  			MissingComment: "Meow?",
   101  		},
   102  	}
   103  
   104  	tcs := []struct {
   105  		name          string
   106  		event         *event
   107  		initialLabels []string
   108  
   109  		expectComment   bool
   110  		expectedAdded   sets.String
   111  		expectedRemoved sets.String
   112  	}{
   113  		{
   114  			name: "ignore PRs",
   115  			event: &event{
   116  				org:    "k8s",
   117  				repo:   "k8s",
   118  				branch: "foo",
   119  			},
   120  			initialLabels: []string{labels.LGTM},
   121  		},
   122  		{
   123  			name: "ignore wrong org",
   124  			event: &event{
   125  				org:  "fejtaverse",
   126  				repo: "repo",
   127  			},
   128  			initialLabels: []string{labels.LGTM},
   129  		},
   130  		{
   131  			name: "ignore unrelated label change",
   132  			event: &event{
   133  				org:    "k8s",
   134  				repo:   "t-i",
   135  				branch: "master",
   136  				label:  "unrelated",
   137  			},
   138  			initialLabels: []string{labels.LGTM},
   139  		},
   140  		{
   141  			name: "add needs-kind label to PR",
   142  			event: &event{
   143  				org:    "k8s",
   144  				repo:   "t-i",
   145  				branch: "master",
   146  			},
   147  			initialLabels: []string{labels.LGTM},
   148  			expectedAdded: sets.NewString("needs-kind"),
   149  		},
   150  		{
   151  			name: "remove needs-kind label from PR based on label change",
   152  			event: &event{
   153  				org:    "k8s",
   154  				repo:   "t-i",
   155  				branch: "master",
   156  				label:  "kind/best",
   157  			},
   158  			initialLabels:   []string{labels.LGTM, "needs-kind", "kind/best"},
   159  			expectedRemoved: sets.NewString("needs-kind"),
   160  		},
   161  		{
   162  			name: "don't remove needs-kind label from issue based on label change (ignore issues)",
   163  			event: &event{
   164  				org:   "k8s",
   165  				repo:  "t-i",
   166  				label: "kind/best",
   167  			},
   168  			initialLabels: []string{labels.LGTM, "needs-kind", "kind/best", "sig/cats"},
   169  		},
   170  		{
   171  			name: "don't remove needs-kind label from PR already missing it",
   172  			event: &event{
   173  				org:    "k8s",
   174  				repo:   "t-i",
   175  				branch: "master",
   176  				label:  "kind/best",
   177  			},
   178  			initialLabels: []string{labels.LGTM, "kind/best"},
   179  		},
   180  		{
   181  			name: "add org scoped needs-sig to issue",
   182  			event: &event{
   183  				org:   "k8s",
   184  				repo:  "k8s",
   185  				label: "sig/bash",
   186  			},
   187  			initialLabels: []string{labels.LGTM, "kind/best"},
   188  			expectedAdded: sets.NewString(labels.NeedsSig),
   189  		},
   190  		{
   191  			name: "don't add org scoped needs-sig to issue when another sig/* label remains",
   192  			event: &event{
   193  				org:   "k8s",
   194  				repo:  "k8s",
   195  				label: "sig/bash",
   196  			},
   197  			initialLabels: []string{labels.LGTM, "kind/best", "wg/foo"},
   198  		},
   199  		{
   200  			name: "add branch scoped needs-cat to issue",
   201  			event: &event{
   202  				org:   "k8s",
   203  				repo:  "t-i",
   204  				label: "cat",
   205  			},
   206  			initialLabels: []string{labels.LGTM, "wg/foo"},
   207  			expectedAdded: sets.NewString("needs-cat"),
   208  			expectComment: true,
   209  		},
   210  		{
   211  			name: "add branch scoped needs-cat to PR",
   212  			event: &event{
   213  				org:    "k8s",
   214  				repo:   "t-i",
   215  				branch: "meow",
   216  			},
   217  			initialLabels: []string{labels.LGTM, "kind/best"},
   218  			expectedAdded: sets.NewString("needs-cat"),
   219  			expectComment: true,
   220  		},
   221  		{
   222  			name: "remove branch scoped needs-cat from PR, add repo scoped needs-kind",
   223  			event: &event{
   224  				org:    "k8s",
   225  				repo:   "t-i",
   226  				branch: "meow",
   227  			},
   228  			initialLabels:   []string{labels.LGTM, "needs-cat", "cat", "floof"},
   229  			expectedAdded:   sets.NewString("needs-kind"),
   230  			expectedRemoved: sets.NewString("needs-cat"),
   231  		},
   232  		{
   233  			name: "add branch scoped needs-cat to issue, remove org scoped needs-sig",
   234  			event: &event{
   235  				org:  "k8s",
   236  				repo: "t-i",
   237  			},
   238  			initialLabels:   []string{labels.LGTM, labels.NeedsSig, "wg/foo"},
   239  			expectedAdded:   sets.NewString("needs-cat"),
   240  			expectedRemoved: sets.NewString(labels.NeedsSig),
   241  			expectComment:   true,
   242  		},
   243  	}
   244  
   245  	for _, tc := range tcs {
   246  		t.Logf("Running test case %q...", tc.name)
   247  		log := logrus.WithField("plugin", "require-matching-label")
   248  		fghc := newFakeGitHub(tc.initialLabels...)
   249  		if err := handle(log, fghc, &fakePruner{}, configs, tc.event); err != nil {
   250  			t.Fatalf("Unexpected error from handle: %v.", err)
   251  		}
   252  
   253  		if tc.expectComment && !fghc.commented {
   254  			t.Error("Expected a comment, but didn't get one.")
   255  		} else if !tc.expectComment && fghc.commented {
   256  			t.Error("Expected no comments to be created but got one.")
   257  		}
   258  
   259  		if !tc.expectedAdded.Equal(fghc.IssueLabelsAdded) {
   260  			t.Errorf("Expected the %q labels to be added, but got %q.", tc.expectedAdded.List(), fghc.IssueLabelsAdded.List())
   261  		}
   262  
   263  		if !tc.expectedRemoved.Equal(fghc.IssueLabelsRemoved) {
   264  			t.Errorf("Expected the %q labels to be removed, but got %q.", tc.expectedRemoved.List(), fghc.IssueLabelsRemoved.List())
   265  		}
   266  	}
   267  }