github.com/munnerz/test-infra@v0.0.0-20190108210205-ce3d181dc989/prow/plugins/verify-owners/verify-owners_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 verifyowners
    18  
    19  import (
    20  	"fmt"
    21  	"strings"
    22  	"testing"
    23  
    24  	"github.com/sirupsen/logrus"
    25  
    26  	"k8s.io/test-infra/prow/git/localgit"
    27  	"k8s.io/test-infra/prow/github"
    28  	"k8s.io/test-infra/prow/github/fakegithub"
    29  	"k8s.io/test-infra/prow/labels"
    30  )
    31  
    32  var ownerFiles = map[string][]byte{
    33  	"emptyApprovers": []byte(`approvers:
    34  reviewers:
    35  - alice
    36  - bob
    37  labels:
    38  - label1
    39  `),
    40  	"emptyApproversFilters": []byte(`filters:
    41    ".*":
    42      approvers:
    43      reviewers:
    44      - alice
    45      - bob
    46      labels:
    47      - label1
    48  `),
    49  	"invalidSyntax": []byte(`approvers
    50  - jdoe
    51  reviewers:
    52  - alice
    53  - bob
    54  labels:
    55  - label1
    56  `),
    57  	"invalidSyntaxFilters": []byte(`filters:
    58    ".*":
    59      approvers
    60      - jdoe
    61      reviewers:
    62      - alice
    63      - bob
    64      labels:
    65      - label1
    66  `),
    67  	"invalidLabels": []byte(`approvers:
    68  - jdoe
    69  reviewers:
    70  - alice
    71  - bob
    72  labels:
    73  - lgtm
    74  `),
    75  	"invalidLabelsFilters": []byte(`filters:
    76    ".*":
    77      approvers:
    78      - jdoe
    79      reviewers:
    80      - alice
    81      - bob
    82      labels:
    83      - lgtm
    84  `),
    85  	"noApprovers": []byte(`reviewers:
    86  - alice
    87  - bob
    88  labels:
    89  - label1
    90  `),
    91  	"noApproversFilters": []byte(`filters:
    92    ".*":
    93      reviewers:
    94      - alice
    95      - bob
    96      labels:
    97      - label1
    98  `),
    99  	"valid": []byte(`approvers:
   100  - jdoe
   101  reviewers:
   102  - alice
   103  - bob
   104  labels:
   105  - label1
   106  `),
   107  	"validFilters": []byte(`filters:
   108    ".*":
   109      approvers:
   110      - jdoe
   111      reviewers:
   112      - alice
   113      - bob
   114      labels:
   115      - label1
   116  `),
   117  }
   118  
   119  func IssueLabelsAddedContain(arr []string, str string) bool {
   120  	for _, a := range arr {
   121  		// IssueLabelsAdded format is owner/repo#number:label
   122  		b := strings.Split(a, ":")
   123  		if b[len(b)-1] == str {
   124  			return true
   125  		}
   126  	}
   127  	return false
   128  }
   129  
   130  func newFakeGithubClient(files []string, pr int) *fakegithub.FakeClient {
   131  	var changes []github.PullRequestChange
   132  	for _, file := range files {
   133  		changes = append(changes, github.PullRequestChange{Filename: file})
   134  	}
   135  	return &fakegithub.FakeClient{
   136  		PullRequestChanges: map[int][]github.PullRequestChange{pr: changes},
   137  		Reviews:            map[int][]github.Review{},
   138  	}
   139  }
   140  
   141  func TestHandle(t *testing.T) {
   142  	var tests = []struct {
   143  		name         string
   144  		filesChanged []string
   145  		ownersFile   string
   146  		shouldLabel  bool
   147  	}{
   148  		{
   149  			name:         "no OWNERS file",
   150  			filesChanged: []string{"a.go", "b.go"},
   151  			ownersFile:   "valid",
   152  			shouldLabel:  false,
   153  		},
   154  		{
   155  			name:         "no OWNERS file with filters",
   156  			filesChanged: []string{"a.go", "b.go"},
   157  			ownersFile:   "validFilters",
   158  			shouldLabel:  false,
   159  		},
   160  		{
   161  			name:         "good OWNERS file",
   162  			filesChanged: []string{"OWNERS", "b.go"},
   163  			ownersFile:   "valid",
   164  			shouldLabel:  false,
   165  		},
   166  		{
   167  			name:         "good OWNERS file with filters",
   168  			filesChanged: []string{"OWNERS", "b.go"},
   169  			ownersFile:   "validFilters",
   170  			shouldLabel:  false,
   171  		},
   172  		{
   173  			name:         "invalid syntax OWNERS file",
   174  			filesChanged: []string{"OWNERS", "b.go"},
   175  			ownersFile:   "invalidSyntax",
   176  			shouldLabel:  true,
   177  		},
   178  		{
   179  			name:         "invalid syntax OWNERS file with filters",
   180  			filesChanged: []string{"OWNERS", "b.go"},
   181  			ownersFile:   "invalidSyntaxFilters",
   182  			shouldLabel:  true,
   183  		},
   184  		{
   185  			name:         "forbidden labels in OWNERS file",
   186  			filesChanged: []string{"OWNERS", "b.go"},
   187  			ownersFile:   "invalidLabels",
   188  			shouldLabel:  true,
   189  		},
   190  		{
   191  			name:         "forbidden labels in OWNERS file with filters",
   192  			filesChanged: []string{"OWNERS", "b.go"},
   193  			ownersFile:   "invalidLabelsFilters",
   194  			shouldLabel:  true,
   195  		},
   196  		{
   197  			name:         "empty approvers in OWNERS file",
   198  			filesChanged: []string{"OWNERS", "b.go"},
   199  			ownersFile:   "emptyApprovers",
   200  			shouldLabel:  true,
   201  		},
   202  		{
   203  			name:         "empty approvers in OWNERS file with filters",
   204  			filesChanged: []string{"OWNERS", "b.go"},
   205  			ownersFile:   "emptyApproversFilters",
   206  			shouldLabel:  true,
   207  		},
   208  		{
   209  			name:         "no approvers in OWNERS file",
   210  			filesChanged: []string{"OWNERS", "b.go"},
   211  			ownersFile:   "noApprovers",
   212  			shouldLabel:  true,
   213  		},
   214  		{
   215  			name:         "no approvers in OWNERS file with filters",
   216  			filesChanged: []string{"OWNERS", "b.go"},
   217  			ownersFile:   "noApproversFilters",
   218  			shouldLabel:  true,
   219  		},
   220  		{
   221  			name:         "no approvers in pkg/OWNERS file",
   222  			filesChanged: []string{"pkg/OWNERS", "b.go"},
   223  			ownersFile:   "noApprovers",
   224  			shouldLabel:  false,
   225  		},
   226  		{
   227  			name:         "no approvers in pkg/OWNERS file with filters",
   228  			filesChanged: []string{"pkg/OWNERS", "b.go"},
   229  			ownersFile:   "noApproversFilters",
   230  			shouldLabel:  false,
   231  		},
   232  	}
   233  	lg, c, err := localgit.New()
   234  	if err != nil {
   235  		t.Fatalf("Making localgit: %v", err)
   236  	}
   237  	defer func() {
   238  		if err := lg.Clean(); err != nil {
   239  			t.Errorf("Cleaning up localgit: %v", err)
   240  		}
   241  		if err := c.Clean(); err != nil {
   242  			t.Errorf("Cleaning up client: %v", err)
   243  		}
   244  	}()
   245  	if err := lg.MakeFakeRepo("org", "repo"); err != nil {
   246  		t.Fatalf("Making fake repo: %v", err)
   247  	}
   248  	for i, test := range tests {
   249  		pr := i + 1
   250  		// make sure we're on master before branching
   251  		if err := lg.Checkout("org", "repo", "master"); err != nil {
   252  			t.Fatalf("Switching to master branch: %v", err)
   253  		}
   254  		if err := lg.CheckoutNewBranch("org", "repo", fmt.Sprintf("pull/%d/head", pr)); err != nil {
   255  			t.Fatalf("Checking out pull branch: %v", err)
   256  		}
   257  		pullFiles := map[string][]byte{}
   258  		for _, file := range test.filesChanged {
   259  			if strings.Contains(file, "OWNERS") {
   260  				pullFiles[file] = ownerFiles[test.ownersFile]
   261  			} else {
   262  				pullFiles[file] = []byte("foo")
   263  			}
   264  		}
   265  		if err := lg.AddCommit("org", "repo", pullFiles); err != nil {
   266  			t.Fatalf("Adding PR commit: %v", err)
   267  		}
   268  		sha, err := lg.RevParse("org", "repo", "HEAD")
   269  		if err != nil {
   270  			t.Fatalf("Getting commit SHA: %v", err)
   271  		}
   272  		pre := &github.PullRequestEvent{
   273  			Number: pr,
   274  			PullRequest: github.PullRequest{
   275  				User: github.User{Login: "author"},
   276  				Head: github.PullRequestBranch{
   277  					SHA: sha,
   278  				},
   279  			},
   280  			Repo: github.Repo{FullName: "org/repo"},
   281  		}
   282  		fghc := newFakeGithubClient(test.filesChanged, pr)
   283  		if err := handle(fghc, c, logrus.WithField("plugin", PluginName), pre, []string{labels.Approved, labels.LGTM}); err != nil {
   284  			t.Fatalf("Handle PR: %v", err)
   285  		}
   286  		if !test.shouldLabel && IssueLabelsAddedContain(fghc.IssueLabelsAdded, labels.InvalidOwners) {
   287  			t.Errorf("%s: didn't expect label %s in %s", test.name, labels.InvalidOwners, fghc.IssueLabelsAdded)
   288  			continue
   289  		} else if test.shouldLabel && !IssueLabelsAddedContain(fghc.IssueLabelsAdded, labels.InvalidOwners) {
   290  			t.Errorf("%s: expected label %s in %s", test.name, labels.InvalidOwners, fghc.IssueLabelsAdded)
   291  			continue
   292  		}
   293  	}
   294  }