github.com/munnerz/test-infra@v0.0.0-20190108210205-ce3d181dc989/prow/tide/blockers/blockers_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 blockers
    18  
    19  import (
    20  	"reflect"
    21  	"strconv"
    22  	"strings"
    23  	"testing"
    24  
    25  	githubql "github.com/shurcooL/githubv4"
    26  
    27  	"k8s.io/apimachinery/pkg/util/sets"
    28  )
    29  
    30  func TestParseBranches(t *testing.T) {
    31  	tcs := []struct {
    32  		text     string
    33  		expected []string
    34  	}{
    35  		{
    36  			text:     "",
    37  			expected: nil,
    38  		},
    39  		{
    40  			text:     "BAD THINGS (all branches blocked)",
    41  			expected: nil,
    42  		},
    43  		{
    44  			text:     "branch:foo",
    45  			expected: []string{"foo"},
    46  		},
    47  		{
    48  			text:     "branch: foo-bar",
    49  			expected: []string{"foo-bar"},
    50  		},
    51  		{
    52  			text:     "BAD THINGS (BLOCKING BRANCH:foo branch:bar) AHHH",
    53  			expected: []string{"foo", "bar"},
    54  		},
    55  		{
    56  			text:     "branch:\"FOO-bar\"",
    57  			expected: []string{"FOO-bar"},
    58  		},
    59  		{
    60  			text:     "branch: \"foo\" branch: \"bar\"",
    61  			expected: []string{"foo", "bar"},
    62  		},
    63  	}
    64  
    65  	for _, tc := range tcs {
    66  		if got := parseBranches(tc.text); !reflect.DeepEqual(got, tc.expected) {
    67  			t.Errorf("Expected parseBranches(%q)==%q, but got %q.", tc.text, tc.expected, got)
    68  		}
    69  	}
    70  }
    71  
    72  func TestBlockerQuery(t *testing.T) {
    73  	tcs := []struct {
    74  		orgRepoQuery string
    75  		expected     sets.String
    76  	}{
    77  		{
    78  			orgRepoQuery: "org:\"k8s\"",
    79  			expected: sets.NewString(
    80  				"is:issue",
    81  				"state:open",
    82  				"label:\"blocker\"",
    83  				"org:\"k8s\"",
    84  			),
    85  		},
    86  		{
    87  			orgRepoQuery: "repo:\"k8s/t-i\"",
    88  			expected: sets.NewString(
    89  				"is:issue",
    90  				"state:open",
    91  				"label:\"blocker\"",
    92  				"repo:\"k8s/t-i\"",
    93  			),
    94  		},
    95  		{
    96  			orgRepoQuery: "org:\"k8s\" org:\"kuber\"",
    97  			expected: sets.NewString(
    98  				"is:issue",
    99  				"state:open",
   100  				"label:\"blocker\"",
   101  				"org:\"k8s\"",
   102  				"org:\"kuber\"",
   103  			),
   104  		},
   105  		{
   106  			orgRepoQuery: "repo:\"k8s/t-i\" repo:\"k8s/k8s\"",
   107  			expected: sets.NewString(
   108  				"is:issue",
   109  				"state:open",
   110  				"label:\"blocker\"",
   111  				"repo:\"k8s/t-i\"",
   112  				"repo:\"k8s/k8s\"",
   113  			),
   114  		},
   115  		{
   116  			orgRepoQuery: "org:\"k8s\" org:\"kuber\" repo:\"k8s/t-i\" repo:\"k8s/k8s\"",
   117  			expected: sets.NewString(
   118  				"is:issue",
   119  				"state:open",
   120  				"label:\"blocker\"",
   121  				"repo:\"k8s/t-i\"",
   122  				"repo:\"k8s/k8s\"",
   123  				"org:\"k8s\"",
   124  				"org:\"kuber\"",
   125  			),
   126  		},
   127  	}
   128  
   129  	for _, tc := range tcs {
   130  		got := sets.NewString(strings.Split(blockerQuery("blocker", tc.orgRepoQuery), " ")...)
   131  		if !reflect.DeepEqual(got, tc.expected) {
   132  			t.Errorf("Expected blockerQuery(\"blocker\", %q)==%q, but got %q.", tc.orgRepoQuery, tc.expected, got)
   133  		}
   134  	}
   135  }
   136  
   137  func testIssue(number int, title, org, repo string) Issue {
   138  	return Issue{
   139  		Number: githubql.Int(number),
   140  		Title:  githubql.String(title),
   141  		URL:    githubql.String(strconv.Itoa(number)),
   142  		Repository: struct {
   143  			Name  githubql.String
   144  			Owner struct {
   145  				Login githubql.String
   146  			}
   147  		}{
   148  			Name: githubql.String(repo),
   149  			Owner: struct {
   150  				Login githubql.String
   151  			}{
   152  				Login: githubql.String(org),
   153  			},
   154  		},
   155  	}
   156  }
   157  
   158  func TestBlockers(t *testing.T) {
   159  	type check struct {
   160  		org, repo, branch string
   161  		blockers          sets.Int
   162  	}
   163  
   164  	tcs := []struct {
   165  		name   string
   166  		issues []Issue
   167  		checks []check
   168  	}{
   169  		{
   170  			name:   "No blocker issues",
   171  			issues: []Issue{},
   172  			checks: []check{
   173  				{
   174  					org:      "org",
   175  					repo:     "repo",
   176  					branch:   "branch",
   177  					blockers: sets.NewInt(),
   178  				},
   179  			},
   180  		},
   181  		{
   182  			name: "1 repo blocker",
   183  			issues: []Issue{
   184  				testIssue(5, "BLOCK THE WHOLE REPO!", "k", "t-i"),
   185  			},
   186  			checks: []check{
   187  				{
   188  					org:      "k",
   189  					repo:     "t-i",
   190  					branch:   "feature",
   191  					blockers: sets.NewInt(5),
   192  				},
   193  				{
   194  					org:      "k",
   195  					repo:     "t-i",
   196  					branch:   "master",
   197  					blockers: sets.NewInt(5),
   198  				},
   199  				{
   200  					org:      "k",
   201  					repo:     "k",
   202  					branch:   "master",
   203  					blockers: sets.NewInt(),
   204  				},
   205  			},
   206  		},
   207  		{
   208  			name: "2 repo blockers for same repo",
   209  			issues: []Issue{
   210  				testIssue(5, "BLOCK THE WHOLE REPO!", "k", "t-i"),
   211  				testIssue(6, "BLOCK THE WHOLE REPO AGAIN!", "k", "t-i"),
   212  			},
   213  			checks: []check{
   214  				{
   215  					org:      "k",
   216  					repo:     "t-i",
   217  					branch:   "feature",
   218  					blockers: sets.NewInt(5, 6),
   219  				},
   220  				{
   221  					org:      "k",
   222  					repo:     "t-i",
   223  					branch:   "master",
   224  					blockers: sets.NewInt(5, 6),
   225  				},
   226  				{
   227  					org:      "k",
   228  					repo:     "k",
   229  					branch:   "master",
   230  					blockers: sets.NewInt(),
   231  				},
   232  			},
   233  		},
   234  		{
   235  			name: "2 repo blockers for different repos",
   236  			issues: []Issue{
   237  				testIssue(5, "BLOCK THE WHOLE REPO!", "k", "t-i"),
   238  				testIssue(6, "BLOCK THE WHOLE (different) REPO!", "k", "community"),
   239  			},
   240  			checks: []check{
   241  				{
   242  					org:      "k",
   243  					repo:     "t-i",
   244  					branch:   "feature",
   245  					blockers: sets.NewInt(5),
   246  				},
   247  				{
   248  					org:      "k",
   249  					repo:     "t-i",
   250  					branch:   "master",
   251  					blockers: sets.NewInt(5),
   252  				},
   253  				{
   254  					org:      "k",
   255  					repo:     "community",
   256  					branch:   "feature",
   257  					blockers: sets.NewInt(6),
   258  				},
   259  				{
   260  					org:      "k",
   261  					repo:     "community",
   262  					branch:   "master",
   263  					blockers: sets.NewInt(6),
   264  				},
   265  				{
   266  					org:      "k",
   267  					repo:     "k",
   268  					branch:   "master",
   269  					blockers: sets.NewInt(),
   270  				},
   271  			},
   272  		},
   273  		{
   274  			name: "1 repo blocker, 1 branch blocker for different repos",
   275  			issues: []Issue{
   276  				testIssue(5, "BLOCK THE WHOLE REPO!", "k", "t-i"),
   277  				testIssue(6, "BLOCK THE feature BRANCH! branch:feature", "k", "community"),
   278  			},
   279  			checks: []check{
   280  				{
   281  					org:      "k",
   282  					repo:     "t-i",
   283  					branch:   "feature",
   284  					blockers: sets.NewInt(5),
   285  				},
   286  				{
   287  					org:      "k",
   288  					repo:     "t-i",
   289  					branch:   "master",
   290  					blockers: sets.NewInt(5),
   291  				},
   292  				{
   293  					org:      "k",
   294  					repo:     "community",
   295  					branch:   "feature",
   296  					blockers: sets.NewInt(6),
   297  				},
   298  				{
   299  					org:      "k",
   300  					repo:     "community",
   301  					branch:   "master",
   302  					blockers: sets.NewInt(),
   303  				},
   304  				{
   305  					org:      "k",
   306  					repo:     "k",
   307  					branch:   "master",
   308  					blockers: sets.NewInt(),
   309  				},
   310  			},
   311  		},
   312  		{
   313  			name: "1 repo blocker, 1 branch blocker for same repo",
   314  			issues: []Issue{
   315  				testIssue(5, "BLOCK THE WHOLE REPO!", "k", "t-i"),
   316  				testIssue(6, "BLOCK THE feature BRANCH! branch:feature", "k", "t-i"),
   317  			},
   318  			checks: []check{
   319  				{
   320  					org:      "k",
   321  					repo:     "t-i",
   322  					branch:   "feature",
   323  					blockers: sets.NewInt(5, 6),
   324  				},
   325  				{
   326  					org:      "k",
   327  					repo:     "t-i",
   328  					branch:   "master",
   329  					blockers: sets.NewInt(5),
   330  				},
   331  				{
   332  					org:      "k",
   333  					repo:     "k",
   334  					branch:   "master",
   335  					blockers: sets.NewInt(),
   336  				},
   337  			},
   338  		},
   339  		{
   340  			name: "2 repo blockers, 3 branch blockers (with overlap) for same repo",
   341  			issues: []Issue{
   342  				testIssue(5, "BLOCK THE WHOLE REPO!", "k", "t-i"),
   343  				testIssue(6, "BLOCK THE WHOLE REPO AGAIN!", "k", "t-i"),
   344  				testIssue(7, "BLOCK THE feature BRANCH! branch:feature", "k", "t-i"),
   345  				testIssue(8, "BLOCK THE feature BRANCH! branch:master", "k", "t-i"),
   346  				testIssue(9, "BLOCK THE feature BRANCH! branch:feature branch: master branch:foo", "k", "t-i"),
   347  			},
   348  			checks: []check{
   349  				{
   350  					org:      "k",
   351  					repo:     "t-i",
   352  					branch:   "feature",
   353  					blockers: sets.NewInt(5, 6, 7, 9),
   354  				},
   355  				{
   356  					org:      "k",
   357  					repo:     "t-i",
   358  					branch:   "master",
   359  					blockers: sets.NewInt(5, 6, 8, 9),
   360  				},
   361  				{
   362  					org:      "k",
   363  					repo:     "t-i",
   364  					branch:   "foo",
   365  					blockers: sets.NewInt(5, 6, 9),
   366  				},
   367  				{
   368  					org:      "k",
   369  					repo:     "t-i",
   370  					branch:   "bar",
   371  					blockers: sets.NewInt(5, 6),
   372  				},
   373  				{
   374  					org:      "k",
   375  					repo:     "k",
   376  					branch:   "master",
   377  					blockers: sets.NewInt(),
   378  				},
   379  			},
   380  		},
   381  	}
   382  
   383  	for _, tc := range tcs {
   384  		t.Logf("Running test case %q.", tc.name)
   385  		b := fromIssues(tc.issues)
   386  		for _, c := range tc.checks {
   387  			actuals := b.GetApplicable(c.org, c.repo, c.branch)
   388  			nums := sets.NewInt()
   389  			for _, actual := range actuals {
   390  				// Check blocker URLs:
   391  				if actual.URL != strconv.Itoa(actual.Number) {
   392  					t.Errorf("blocker %d has URL %q, expected %q", actual.Number, actual.URL, strconv.Itoa(actual.Number))
   393  				}
   394  				nums.Insert(actual.Number)
   395  			}
   396  			// Check that correct blockers were selected:
   397  			if !reflect.DeepEqual(nums, c.blockers) {
   398  				t.Errorf("expected blockers %v, but got %v", c.blockers, nums)
   399  			}
   400  		}
   401  	}
   402  }