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