github.com/zppinho/prow@v0.0.0-20240510014325-1738badeb017/cmd/deck/tide_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 main
    18  
    19  import (
    20  	"reflect"
    21  	"testing"
    22  
    23  	"github.com/sirupsen/logrus"
    24  	"k8s.io/apimachinery/pkg/api/equality"
    25  	"k8s.io/apimachinery/pkg/util/sets"
    26  
    27  	"sigs.k8s.io/prow/pkg/config"
    28  	"sigs.k8s.io/prow/pkg/tide"
    29  	"sigs.k8s.io/prow/pkg/tide/history"
    30  
    31  	prowapi "sigs.k8s.io/prow/pkg/apis/prowjobs/v1"
    32  )
    33  
    34  func TestFilter(t *testing.T) {
    35  	exampleConfigNoDefaults := config.Config{
    36  		ProwConfig: config.ProwConfig{
    37  			ProwJobDefaultEntries: []*config.ProwJobDefaultEntry{
    38  				{
    39  					OrgRepo: "tenanted",
    40  					Cluster: "*",
    41  					Config: &prowapi.ProwJobDefault{
    42  						TenantID: "t",
    43  					},
    44  				},
    45  				{
    46  					OrgRepo: "tenanted/repo",
    47  					Cluster: "*",
    48  					Config: &prowapi.ProwJobDefault{
    49  						TenantID: "t/r",
    50  					},
    51  				},
    52  				{
    53  					OrgRepo: "other",
    54  					Cluster: "*",
    55  					Config: &prowapi.ProwJobDefault{
    56  						TenantID: "o",
    57  					},
    58  				},
    59  			},
    60  		},
    61  	}
    62  	exampleConfigWithDefaults := config.Config{
    63  		ProwConfig: config.ProwConfig{
    64  			ProwJobDefaultEntries: []*config.ProwJobDefaultEntry{
    65  				{
    66  					OrgRepo: "*",
    67  					Cluster: "*",
    68  					Config: &prowapi.ProwJobDefault{
    69  						TenantID: "Default",
    70  					},
    71  				},
    72  				{
    73  					OrgRepo: "tenanted",
    74  					Cluster: "*",
    75  					Config: &prowapi.ProwJobDefault{
    76  						TenantID: "t",
    77  					},
    78  				},
    79  				{
    80  					OrgRepo: "tenanted/repo",
    81  					Cluster: "*",
    82  					Config: &prowapi.ProwJobDefault{
    83  						TenantID: "t/r",
    84  					},
    85  				},
    86  				{
    87  					OrgRepo: "other",
    88  					Cluster: "*",
    89  					Config: &prowapi.ProwJobDefault{
    90  						TenantID: "o",
    91  					},
    92  				},
    93  			},
    94  		},
    95  	}
    96  
    97  	tests := []struct {
    98  		name string
    99  
   100  		hiddenRepos []string
   101  		hiddenOnly  bool
   102  		showHidden  bool
   103  		tenantIDs   []string
   104  		queries     []config.TideQuery
   105  		pools       []tide.Pool
   106  		hist        map[string][]history.Record
   107  		cfg         config.Config
   108  
   109  		expectedQueries []config.TideQuery
   110  		expectedPools   []tide.Pool
   111  		expectedHist    map[string][]history.Record
   112  	}{
   113  		{
   114  			name: "public frontend",
   115  
   116  			hiddenRepos: []string{
   117  				"kubernetes-security",
   118  				"kubernetes/website",
   119  			},
   120  			hiddenOnly: false,
   121  			queries: []config.TideQuery{
   122  				{
   123  					Repos: []string{"kubernetes/test-infra", "kubernetes/kubernetes"},
   124  				},
   125  				{
   126  					Repos: []string{"kubernetes/website", "kubernetes/docs"},
   127  				},
   128  				{
   129  					Repos: []string{"kubernetes/apiserver", "kubernetes-security/apiserver"},
   130  				},
   131  				{
   132  					Orgs: []string{"kubernetes-test"},
   133  				},
   134  			},
   135  			pools: []tide.Pool{
   136  				{Org: "kubernetes", Repo: "test-infra"},
   137  				{Org: "kubernetes", Repo: "kubernetes"},
   138  				{Org: "kubernetes", Repo: "website"},
   139  				{Org: "kubernetes", Repo: "docs"},
   140  				{Org: "kubernetes", Repo: "apiserver"},
   141  				{Org: "kubernetes-security", Repo: "apiserver"},
   142  			},
   143  			hist: map[string][]history.Record{
   144  				"kubernetes/test-infra:master":         {{Action: "MERGE"}, {Action: "TRIGGER"}},
   145  				"kubernetes/website:master":            {{Action: "MERGE_BATCH"}, {Action: "TRIGGER_BATCH"}},
   146  				"kubernetes-security/apiserver:master": {{Action: "TRIGGER"}, {Action: "MERGE"}},
   147  				"kubernetes/kubernetes:master":         {{Action: "TRIGGER_BATCH"}, {Action: "MERGE_BATCH"}},
   148  			},
   149  
   150  			expectedQueries: []config.TideQuery{
   151  				{
   152  					Repos: []string{"kubernetes/test-infra", "kubernetes/kubernetes"},
   153  				},
   154  				{
   155  					Repos: []string{"kubernetes/docs"},
   156  				},
   157  				{
   158  					Repos: []string{"kubernetes/apiserver"},
   159  				},
   160  				{
   161  					Orgs: []string{"kubernetes-test"},
   162  				},
   163  			},
   164  			expectedPools: []tide.Pool{
   165  				{Org: "kubernetes", Repo: "test-infra"},
   166  				{Org: "kubernetes", Repo: "kubernetes"},
   167  				{Org: "kubernetes", Repo: "docs"},
   168  				{Org: "kubernetes", Repo: "apiserver"},
   169  			},
   170  			expectedHist: map[string][]history.Record{
   171  				"kubernetes/test-infra:master": {{Action: "MERGE"}, {Action: "TRIGGER"}},
   172  				"kubernetes/kubernetes:master": {{Action: "TRIGGER_BATCH"}, {Action: "MERGE_BATCH"}},
   173  			},
   174  		},
   175  		{
   176  			name: "private frontend",
   177  
   178  			hiddenRepos: []string{
   179  				"kubernetes-security",
   180  				"kubernetes/website",
   181  			},
   182  			hiddenOnly: true,
   183  			queries: []config.TideQuery{
   184  				{
   185  					Repos: []string{"kubernetes/test-infra", "kubernetes/kubernetes"},
   186  				},
   187  				{
   188  					Repos: []string{"kubernetes/website", "kubernetes/docs"},
   189  				},
   190  				{
   191  					Repos: []string{"kubernetes/apiserver", "kubernetes-security/apiserver"},
   192  				},
   193  			},
   194  			pools: []tide.Pool{
   195  				{Org: "kubernetes", Repo: "test-infra"},
   196  				{Org: "kubernetes", Repo: "kubernetes"},
   197  				{Org: "kubernetes", Repo: "website"},
   198  				{Org: "kubernetes", Repo: "docs"},
   199  				{Org: "kubernetes", Repo: "apiserver"},
   200  				{Org: "kubernetes-security", Repo: "apiserver"},
   201  			},
   202  			hist: map[string][]history.Record{
   203  				"kubernetes/test-infra:master":         {{Action: "MERGE"}, {Action: "TRIGGER"}},
   204  				"kubernetes/website:master":            {{Action: "MERGE_BATCH"}, {Action: "TRIGGER_BATCH"}},
   205  				"kubernetes-security/apiserver:master": {{Action: "TRIGGER"}, {Action: "MERGE"}},
   206  				"kubernetes/kubernetes:master":         {{Action: "TRIGGER_BATCH"}, {Action: "MERGE_BATCH"}},
   207  			},
   208  
   209  			expectedQueries: []config.TideQuery{
   210  				{
   211  					Repos: []string{"kubernetes/website", "kubernetes/docs"},
   212  				},
   213  				{
   214  					Repos: []string{"kubernetes/apiserver", "kubernetes-security/apiserver"},
   215  				},
   216  			},
   217  			expectedPools: []tide.Pool{
   218  				{Org: "kubernetes", Repo: "website"},
   219  				{Org: "kubernetes-security", Repo: "apiserver"},
   220  			},
   221  			expectedHist: map[string][]history.Record{
   222  				"kubernetes/website:master":            {{Action: "MERGE_BATCH"}, {Action: "TRIGGER_BATCH"}},
   223  				"kubernetes-security/apiserver:master": {{Action: "TRIGGER"}, {Action: "MERGE"}},
   224  			},
   225  		},
   226  		{
   227  			name: "frontend for everything",
   228  
   229  			showHidden: true,
   230  			hiddenRepos: []string{
   231  				"kubernetes-security",
   232  				"kubernetes/website",
   233  			},
   234  
   235  			pools: []tide.Pool{
   236  				{Org: "kubernetes", Repo: "test-infra"},
   237  				{Org: "kubernetes", Repo: "kubernetes"},
   238  				{Org: "kubernetes", Repo: "website"},
   239  				{Org: "kubernetes", Repo: "docs"},
   240  				{Org: "kubernetes", Repo: "apiserver"},
   241  				{Org: "kubernetes-security", Repo: "apiserver"},
   242  			},
   243  			expectedPools: []tide.Pool{
   244  				{Org: "kubernetes", Repo: "test-infra"},
   245  				{Org: "kubernetes", Repo: "kubernetes"},
   246  				{Org: "kubernetes", Repo: "website"},
   247  				{Org: "kubernetes", Repo: "docs"},
   248  				{Org: "kubernetes", Repo: "apiserver"},
   249  				{Org: "kubernetes-security", Repo: "apiserver"},
   250  			},
   251  
   252  			queries: []config.TideQuery{
   253  				{
   254  					Repos: []string{"kubernetes/test-infra", "kubernetes/kubernetes"},
   255  				},
   256  				{
   257  					Repos: []string{"kubernetes/website", "kubernetes/docs"},
   258  				},
   259  				{
   260  					Repos: []string{"kubernetes/apiserver", "kubernetes-security/apiserver"},
   261  				},
   262  			},
   263  			expectedQueries: []config.TideQuery{
   264  				{
   265  					Repos: []string{"kubernetes/test-infra", "kubernetes/kubernetes"},
   266  				},
   267  				{
   268  					Repos: []string{"kubernetes/website", "kubernetes/docs"},
   269  				},
   270  				{
   271  					Repos: []string{"kubernetes/apiserver", "kubernetes-security/apiserver"},
   272  				},
   273  			},
   274  
   275  			hist: map[string][]history.Record{
   276  				"kubernetes/test-infra:master":         {{Action: "MERGE"}, {Action: "TRIGGER"}},
   277  				"kubernetes/website:master":            {{Action: "MERGE_BATCH"}, {Action: "TRIGGER_BATCH"}},
   278  				"kubernetes-security/apiserver:master": {{Action: "TRIGGER"}, {Action: "MERGE"}},
   279  				"kubernetes/kubernetes:master":         {{Action: "TRIGGER_BATCH"}, {Action: "MERGE_BATCH"}},
   280  			},
   281  			expectedHist: map[string][]history.Record{
   282  				"kubernetes/test-infra:master":         {{Action: "MERGE"}, {Action: "TRIGGER"}},
   283  				"kubernetes/website:master":            {{Action: "MERGE_BATCH"}, {Action: "TRIGGER_BATCH"}},
   284  				"kubernetes-security/apiserver:master": {{Action: "TRIGGER"}, {Action: "MERGE"}},
   285  				"kubernetes/kubernetes:master":         {{Action: "TRIGGER_BATCH"}, {Action: "MERGE_BATCH"}},
   286  			},
   287  		},
   288  		{
   289  			name: "public frontend. Config has no defaults",
   290  			cfg:  exampleConfigNoDefaults,
   291  			hiddenRepos: []string{
   292  				"kubernetes-security",
   293  				"kubernetes/website",
   294  			},
   295  			hiddenOnly: false,
   296  			queries: []config.TideQuery{
   297  				{
   298  					Repos: []string{"kubernetes/test-infra", "kubernetes/kubernetes"},
   299  				},
   300  				{
   301  					Repos: []string{"kubernetes/website", "kubernetes/docs"},
   302  				},
   303  				{
   304  					Repos: []string{"kubernetes/apiserver", "kubernetes-security/apiserver"},
   305  				},
   306  			},
   307  			pools: []tide.Pool{
   308  				{Org: "kubernetes", Repo: "test-infra"},
   309  				{Org: "kubernetes", Repo: "kubernetes"},
   310  				{Org: "kubernetes", Repo: "website"},
   311  				{Org: "kubernetes", Repo: "docs"},
   312  				{Org: "kubernetes", Repo: "apiserver"},
   313  				{Org: "kubernetes-security", Repo: "apiserver"},
   314  			},
   315  			hist: map[string][]history.Record{
   316  				"kubernetes/test-infra:master":         {{Action: "MERGE"}, {Action: "TRIGGER"}},
   317  				"kubernetes/website:master":            {{Action: "MERGE_BATCH"}, {Action: "TRIGGER_BATCH"}},
   318  				"kubernetes-security/apiserver:master": {{Action: "TRIGGER"}, {Action: "MERGE"}},
   319  				"kubernetes/kubernetes:master":         {{Action: "TRIGGER_BATCH"}, {Action: "MERGE_BATCH"}},
   320  			},
   321  
   322  			expectedQueries: []config.TideQuery{
   323  				{
   324  					Repos: []string{"kubernetes/test-infra", "kubernetes/kubernetes"},
   325  				},
   326  				{
   327  					Repos: []string{"kubernetes/docs"},
   328  				},
   329  				{
   330  					Repos: []string{"kubernetes/apiserver"},
   331  				},
   332  			},
   333  			expectedPools: []tide.Pool{
   334  				{Org: "kubernetes", Repo: "test-infra"},
   335  				{Org: "kubernetes", Repo: "kubernetes"},
   336  				{Org: "kubernetes", Repo: "docs"},
   337  				{Org: "kubernetes", Repo: "apiserver"},
   338  			},
   339  			expectedHist: map[string][]history.Record{
   340  				"kubernetes/test-infra:master": {{Action: "MERGE"}, {Action: "TRIGGER"}},
   341  				"kubernetes/kubernetes:master": {{Action: "TRIGGER_BATCH"}, {Action: "MERGE_BATCH"}},
   342  			},
   343  		},
   344  		{
   345  			name: "private frontend config has no defaults",
   346  			cfg:  exampleConfigNoDefaults,
   347  			hiddenRepos: []string{
   348  				"kubernetes-security",
   349  				"kubernetes/website",
   350  			},
   351  			hiddenOnly: true,
   352  			queries: []config.TideQuery{
   353  				{
   354  					Repos: []string{"kubernetes/test-infra", "kubernetes/kubernetes"},
   355  				},
   356  				{
   357  					Repos: []string{"kubernetes/website", "kubernetes/docs"},
   358  				},
   359  				{
   360  					Repos: []string{"kubernetes/apiserver", "kubernetes-security/apiserver"},
   361  				},
   362  			},
   363  			pools: []tide.Pool{
   364  				{Org: "kubernetes", Repo: "test-infra"},
   365  				{Org: "kubernetes", Repo: "kubernetes"},
   366  				{Org: "kubernetes", Repo: "website"},
   367  				{Org: "kubernetes", Repo: "docs"},
   368  				{Org: "kubernetes", Repo: "apiserver"},
   369  				{Org: "kubernetes-security", Repo: "apiserver"},
   370  			},
   371  			hist: map[string][]history.Record{
   372  				"kubernetes/test-infra:master":         {{Action: "MERGE"}, {Action: "TRIGGER"}},
   373  				"kubernetes/website:master":            {{Action: "MERGE_BATCH"}, {Action: "TRIGGER_BATCH"}},
   374  				"kubernetes-security/apiserver:master": {{Action: "TRIGGER"}, {Action: "MERGE"}},
   375  				"kubernetes/kubernetes:master":         {{Action: "TRIGGER_BATCH"}, {Action: "MERGE_BATCH"}},
   376  			},
   377  
   378  			expectedQueries: []config.TideQuery{
   379  				{
   380  					Repos: []string{"kubernetes/website", "kubernetes/docs"},
   381  				},
   382  				{
   383  					Repos: []string{"kubernetes/apiserver", "kubernetes-security/apiserver"},
   384  				},
   385  			},
   386  			expectedPools: []tide.Pool{
   387  				{Org: "kubernetes", Repo: "website"},
   388  				{Org: "kubernetes-security", Repo: "apiserver"},
   389  			},
   390  			expectedHist: map[string][]history.Record{
   391  				"kubernetes/website:master":            {{Action: "MERGE_BATCH"}, {Action: "TRIGGER_BATCH"}},
   392  				"kubernetes-security/apiserver:master": {{Action: "TRIGGER"}, {Action: "MERGE"}},
   393  			},
   394  		},
   395  		{
   396  			name:      "Nothing matches tenantID",
   397  			tenantIDs: []string{"nothing"},
   398  			cfg:       exampleConfigWithDefaults,
   399  			queries: []config.TideQuery{
   400  				{
   401  					Repos: []string{"kubernetes/test-infra", "kubernetes/kubernetes"},
   402  				},
   403  				{
   404  					Repos: []string{"kubernetes/website", "kubernetes/docs"},
   405  				},
   406  				{
   407  					Repos: []string{"kubernetes/apiserver", "kubernetes-security/apiserver"},
   408  				},
   409  			},
   410  			pools: []tide.Pool{
   411  				{Org: "kubernetes", Repo: "test-infra"},
   412  				{Org: "kubernetes", Repo: "kubernetes"},
   413  				{Org: "kubernetes", Repo: "website"},
   414  				{Org: "kubernetes", Repo: "docs"},
   415  				{Org: "kubernetes", Repo: "apiserver"},
   416  				{Org: "kubernetes-security", Repo: "apiserver"},
   417  			},
   418  			hist: map[string][]history.Record{
   419  				"kubernetes/test-infra:master":         {{Action: "MERGE"}, {Action: "TRIGGER"}},
   420  				"kubernetes/website:master":            {{Action: "MERGE_BATCH"}, {Action: "TRIGGER_BATCH"}},
   421  				"kubernetes-security/apiserver:master": {{Action: "TRIGGER"}, {Action: "MERGE"}},
   422  				"kubernetes/kubernetes:master":         {{Action: "TRIGGER_BATCH"}, {Action: "MERGE_BATCH"}},
   423  			},
   424  
   425  			expectedQueries: []config.TideQuery{},
   426  			expectedPools:   []tide.Pool{},
   427  			expectedHist:    map[string][]history.Record{},
   428  		},
   429  		{
   430  			name:       "frontend for everything no tenantID",
   431  			cfg:        exampleConfigNoDefaults,
   432  			showHidden: true,
   433  			hiddenRepos: []string{
   434  				"kubernetes-security",
   435  				"kubernetes/website",
   436  			},
   437  
   438  			pools: []tide.Pool{
   439  				{Org: "kubernetes", Repo: "test-infra"},
   440  				{Org: "kubernetes", Repo: "kubernetes"},
   441  				{Org: "kubernetes", Repo: "website"},
   442  				{Org: "kubernetes", Repo: "docs"},
   443  				{Org: "kubernetes", Repo: "apiserver"},
   444  				{Org: "kubernetes-security", Repo: "apiserver"},
   445  			},
   446  			expectedPools: []tide.Pool{
   447  				{Org: "kubernetes", Repo: "test-infra"},
   448  				{Org: "kubernetes", Repo: "kubernetes"},
   449  				{Org: "kubernetes", Repo: "website"},
   450  				{Org: "kubernetes", Repo: "docs"},
   451  				{Org: "kubernetes", Repo: "apiserver"},
   452  				{Org: "kubernetes-security", Repo: "apiserver"},
   453  			},
   454  
   455  			queries: []config.TideQuery{
   456  				{
   457  					Repos: []string{"kubernetes/test-infra", "kubernetes/kubernetes"},
   458  				},
   459  				{
   460  					Repos: []string{"kubernetes/website", "kubernetes/docs"},
   461  				},
   462  				{
   463  					Repos: []string{"kubernetes/apiserver", "kubernetes-security/apiserver"},
   464  				},
   465  			},
   466  			expectedQueries: []config.TideQuery{
   467  				{
   468  					Repos: []string{"kubernetes/test-infra", "kubernetes/kubernetes"},
   469  				},
   470  				{
   471  					Repos: []string{"kubernetes/website", "kubernetes/docs"},
   472  				},
   473  				{
   474  					Repos: []string{"kubernetes/apiserver", "kubernetes-security/apiserver"},
   475  				},
   476  			},
   477  			hist: map[string][]history.Record{
   478  				"kubernetes/test-infra:master":         {{Action: "MERGE"}, {Action: "TRIGGER"}},
   479  				"kubernetes/website:master":            {{Action: "MERGE_BATCH"}, {Action: "TRIGGER_BATCH"}},
   480  				"kubernetes-security/apiserver:master": {{Action: "TRIGGER"}, {Action: "MERGE"}},
   481  				"kubernetes/kubernetes:master":         {{Action: "TRIGGER_BATCH"}, {Action: "MERGE_BATCH"}},
   482  			},
   483  			expectedHist: map[string][]history.Record{
   484  				"kubernetes/test-infra:master":         {{Action: "MERGE"}, {Action: "TRIGGER"}},
   485  				"kubernetes/website:master":            {{Action: "MERGE_BATCH"}, {Action: "TRIGGER_BATCH"}},
   486  				"kubernetes-security/apiserver:master": {{Action: "TRIGGER"}, {Action: "MERGE"}},
   487  				"kubernetes/kubernetes:master":         {{Action: "TRIGGER_BATCH"}, {Action: "MERGE_BATCH"}},
   488  			},
   489  		},
   490  		{
   491  			name:      "Tenated front end",
   492  			cfg:       exampleConfigNoDefaults,
   493  			tenantIDs: []string{"t"},
   494  			queries: []config.TideQuery{
   495  				{
   496  					Repos: []string{"kubernetes/test-infra", "kubernetes/kubernetes"},
   497  				},
   498  				{
   499  					Repos: []string{"kubernetes/website", "kubernetes/docs"},
   500  				},
   501  				{
   502  					Repos: []string{"kubernetes/apiserver", "kubernetes-security/apiserver"},
   503  				},
   504  				{
   505  					Repos: []string{"tenanted/test"},
   506  				},
   507  			},
   508  			pools: []tide.Pool{
   509  				{Org: "kubernetes", Repo: "test-infra"},
   510  				{Org: "kubernetes", Repo: "kubernetes"},
   511  				{Org: "kubernetes", Repo: "website"},
   512  				{Org: "kubernetes", Repo: "docs"},
   513  				{Org: "kubernetes", Repo: "apiserver"},
   514  				{Org: "kubernetes-security", Repo: "apiserver"},
   515  				{Org: "tenanted", Repo: "test"},
   516  				{Org: "clustered-tenant", Repo: "test", TenantIDs: []string{"t"}},
   517  			},
   518  			hist: map[string][]history.Record{
   519  				"kubernetes/test-infra:master":         {{Action: "MERGE"}, {Action: "TRIGGER"}},
   520  				"kubernetes/website:master":            {{Action: "MERGE_BATCH"}, {Action: "TRIGGER_BATCH"}},
   521  				"kubernetes-security/apiserver:master": {{Action: "TRIGGER"}, {Action: "MERGE"}},
   522  				"kubernetes/kubernetes:master":         {{Action: "TRIGGER_BATCH"}, {Action: "MERGE_BATCH"}},
   523  				"tenanted/test:master":                 {{Action: "TRIGGER_BATCH"}, {Action: "MERGE_BATCH"}},
   524  				"clustered-tenant/test:master":         {{Action: "TRIGGER_BATCH", TenantIDs: []string{"t"}}, {Action: "MERGE_BATCH"}},
   525  			},
   526  
   527  			expectedQueries: []config.TideQuery{
   528  				{
   529  					Repos: []string{"tenanted/test"},
   530  				},
   531  			},
   532  			expectedPools: []tide.Pool{
   533  				{Org: "tenanted", Repo: "test"},
   534  				{Org: "clustered-tenant", Repo: "test", TenantIDs: []string{"t"}},
   535  			},
   536  			expectedHist: map[string][]history.Record{
   537  				"tenanted/test:master":         {{Action: "TRIGGER_BATCH"}, {Action: "MERGE_BATCH"}},
   538  				"clustered-tenant/test:master": {{Action: "TRIGGER_BATCH", TenantIDs: []string{"t"}}, {Action: "MERGE_BATCH"}},
   539  			},
   540  		},
   541  		{
   542  			name: "tenantID on Deck ignores hidden repos",
   543  			cfg:  exampleConfigNoDefaults,
   544  			hiddenRepos: []string{
   545  				"tenanted",
   546  			},
   547  			tenantIDs: []string{"t"},
   548  			queries: []config.TideQuery{
   549  				{
   550  					Repos: []string{"kubernetes/test-infra", "kubernetes/kubernetes"},
   551  				},
   552  				{
   553  					Repos: []string{"kubernetes/website", "kubernetes/docs"},
   554  				},
   555  				{
   556  					Repos: []string{"kubernetes/apiserver", "kubernetes-security/apiserver"},
   557  				},
   558  				{
   559  					Repos: []string{"tenanted/test"},
   560  				},
   561  			},
   562  			pools: []tide.Pool{
   563  				{Org: "kubernetes", Repo: "test-infra"},
   564  				{Org: "kubernetes", Repo: "kubernetes"},
   565  				{Org: "kubernetes", Repo: "website"},
   566  				{Org: "kubernetes", Repo: "docs"},
   567  				{Org: "kubernetes", Repo: "apiserver"},
   568  				{Org: "kubernetes-security", Repo: "apiserver"},
   569  				{Org: "tenanted", Repo: "test"},
   570  				{Org: "clustered-tenant", Repo: "test", TenantIDs: []string{"t"}},
   571  			},
   572  			hist: map[string][]history.Record{
   573  				"kubernetes/test-infra:master":         {{Action: "MERGE"}, {Action: "TRIGGER"}},
   574  				"kubernetes/website:master":            {{Action: "MERGE_BATCH"}, {Action: "TRIGGER_BATCH"}},
   575  				"kubernetes-security/apiserver:master": {{Action: "TRIGGER"}, {Action: "MERGE"}},
   576  				"kubernetes/kubernetes:master":         {{Action: "TRIGGER_BATCH"}, {Action: "MERGE_BATCH"}},
   577  				"tenanted/test:master":                 {{Action: "TRIGGER_BATCH"}, {Action: "MERGE_BATCH"}},
   578  				"clustered-tenant/test:master":         {{Action: "TRIGGER_BATCH", TenantIDs: []string{"t"}}, {Action: "MERGE_BATCH"}},
   579  			},
   580  
   581  			expectedQueries: []config.TideQuery{
   582  				{
   583  					Repos: []string{"tenanted/test"},
   584  				},
   585  			},
   586  			expectedPools: []tide.Pool{
   587  				{Org: "tenanted", Repo: "test"},
   588  				{Org: "clustered-tenant", Repo: "test", TenantIDs: []string{"t"}},
   589  			},
   590  			expectedHist: map[string][]history.Record{
   591  				"tenanted/test:master":         {{Action: "TRIGGER_BATCH"}, {Action: "MERGE_BATCH"}},
   592  				"clustered-tenant/test:master": {{Action: "TRIGGER_BATCH", TenantIDs: []string{"t"}}, {Action: "MERGE_BATCH"}},
   593  			},
   594  		},
   595  		{
   596  			name: "hidden repos ignores tenanted",
   597  			cfg:  exampleConfigNoDefaults,
   598  			hiddenRepos: []string{
   599  				"kubernetes-security",
   600  				"kubernetes/website",
   601  				"tenanted",
   602  			},
   603  			hiddenOnly: true,
   604  			queries: []config.TideQuery{
   605  				{
   606  					Repos: []string{"kubernetes/test-infra", "kubernetes/kubernetes"},
   607  				},
   608  				{
   609  					Repos: []string{"kubernetes/website", "kubernetes/docs"},
   610  				},
   611  				{
   612  					Repos: []string{"kubernetes/apiserver", "kubernetes-security/apiserver"},
   613  				},
   614  				{
   615  					Repos: []string{"tenanted/test"},
   616  				},
   617  			},
   618  			pools: []tide.Pool{
   619  				{Org: "kubernetes", Repo: "test-infra"},
   620  				{Org: "kubernetes", Repo: "kubernetes"},
   621  				{Org: "kubernetes", Repo: "website"},
   622  				{Org: "kubernetes", Repo: "docs"},
   623  				{Org: "kubernetes", Repo: "apiserver"},
   624  				{Org: "kubernetes-security", Repo: "apiserver"},
   625  				{Org: "tenanted", Repo: "test"},
   626  				{Org: "clustered-tenant", Repo: "test", TenantIDs: []string{"t"}},
   627  			},
   628  			hist: map[string][]history.Record{
   629  				"kubernetes/test-infra:master":         {{Action: "MERGE", TenantIDs: []string{config.DefaultTenantID}}, {Action: "TRIGGER"}},
   630  				"kubernetes/website:master":            {{Action: "MERGE_BATCH"}, {Action: "TRIGGER_BATCH"}},
   631  				"kubernetes-security/apiserver:master": {{Action: "TRIGGER"}, {Action: "MERGE"}},
   632  				"kubernetes/kubernetes:master":         {{Action: "TRIGGER_BATCH"}, {Action: "MERGE_BATCH"}},
   633  				"tenanted/test:master":                 {{Action: "TRIGGER_BATCH"}, {Action: "MERGE_BATCH"}},
   634  			},
   635  
   636  			expectedQueries: []config.TideQuery{
   637  				{
   638  					Repos: []string{"kubernetes/website", "kubernetes/docs"},
   639  				},
   640  				{
   641  					Repos: []string{"kubernetes/apiserver", "kubernetes-security/apiserver"},
   642  				},
   643  				{
   644  					Repos: []string{"tenanted/test"},
   645  				},
   646  			},
   647  			expectedPools: []tide.Pool{
   648  				{Org: "kubernetes", Repo: "website"},
   649  				{Org: "kubernetes-security", Repo: "apiserver"},
   650  				{Org: "tenanted", Repo: "test"},
   651  			},
   652  			expectedHist: map[string][]history.Record{
   653  				"kubernetes/website:master":            {{Action: "MERGE_BATCH"}, {Action: "TRIGGER_BATCH"}},
   654  				"kubernetes-security/apiserver:master": {{Action: "TRIGGER"}, {Action: "MERGE"}},
   655  				"tenanted/test:master":                 {{Action: "TRIGGER_BATCH"}, {Action: "MERGE_BATCH"}},
   656  			},
   657  		},
   658  		{
   659  			name: "public frontend with default tenantIDs assigned still respects hidden repos",
   660  
   661  			hiddenRepos: []string{
   662  				"kubernetes-security",
   663  				"kubernetes/website",
   664  			},
   665  			hiddenOnly: false,
   666  			queries: []config.TideQuery{
   667  				{
   668  					Repos: []string{"kubernetes/test-infra", "kubernetes/kubernetes"},
   669  				},
   670  				{
   671  					Repos: []string{"kubernetes/website", "kubernetes/docs"},
   672  				},
   673  				{
   674  					Repos: []string{"kubernetes/apiserver", "kubernetes-security/apiserver"},
   675  				},
   676  			},
   677  			pools: []tide.Pool{
   678  				{Org: "kubernetes", Repo: "test-infra", TenantIDs: []string{config.DefaultTenantID}},
   679  				{Org: "kubernetes", Repo: "kubernetes", TenantIDs: []string{config.DefaultTenantID}},
   680  				{Org: "kubernetes", Repo: "website", TenantIDs: []string{config.DefaultTenantID}},
   681  				{Org: "kubernetes", Repo: "docs", TenantIDs: []string{config.DefaultTenantID}},
   682  				{Org: "kubernetes", Repo: "apiserver", TenantIDs: []string{config.DefaultTenantID}},
   683  				{Org: "kubernetes-security", Repo: "apiserver", TenantIDs: []string{config.DefaultTenantID}},
   684  			},
   685  			hist: map[string][]history.Record{
   686  				"kubernetes/test-infra:master":         {{Action: "MERGE", TenantIDs: []string{config.DefaultTenantID}}, {Action: "TRIGGER"}},
   687  				"kubernetes/website:master":            {{Action: "MERGE_BATCH", TenantIDs: []string{config.DefaultTenantID}}, {Action: "TRIGGER_BATCH"}},
   688  				"kubernetes-security/apiserver:master": {{Action: "TRIGGER", TenantIDs: []string{config.DefaultTenantID}}, {Action: "MERGE"}},
   689  				"kubernetes/kubernetes:master":         {{Action: "TRIGGER_BATCH", TenantIDs: []string{config.DefaultTenantID}}, {Action: "MERGE_BATCH"}},
   690  			},
   691  
   692  			expectedQueries: []config.TideQuery{
   693  				{
   694  					Repos: []string{"kubernetes/test-infra", "kubernetes/kubernetes"},
   695  				},
   696  				{
   697  					Repos: []string{"kubernetes/docs"},
   698  				},
   699  				{
   700  					Repos: []string{"kubernetes/apiserver"},
   701  				},
   702  			},
   703  			expectedPools: []tide.Pool{
   704  				{Org: "kubernetes", Repo: "test-infra", TenantIDs: []string{config.DefaultTenantID}},
   705  				{Org: "kubernetes", Repo: "kubernetes", TenantIDs: []string{config.DefaultTenantID}},
   706  				{Org: "kubernetes", Repo: "docs", TenantIDs: []string{config.DefaultTenantID}},
   707  				{Org: "kubernetes", Repo: "apiserver", TenantIDs: []string{config.DefaultTenantID}},
   708  			},
   709  			expectedHist: map[string][]history.Record{
   710  				"kubernetes/test-infra:master": {{Action: "MERGE", TenantIDs: []string{config.DefaultTenantID}}, {Action: "TRIGGER"}},
   711  				"kubernetes/kubernetes:master": {{Action: "TRIGGER_BATCH", TenantIDs: []string{config.DefaultTenantID}}, {Action: "MERGE_BATCH"}},
   712  			},
   713  		},
   714  	}
   715  
   716  	for _, test := range tests {
   717  		t.Logf("running scenario %q", test.name)
   718  
   719  		ta := &tideAgent{
   720  			hiddenRepos: func() []string {
   721  				return test.hiddenRepos
   722  			},
   723  			hiddenOnly: test.hiddenOnly,
   724  			showHidden: test.showHidden,
   725  			log:        logrus.WithField("agent", "tide"),
   726  			tenantIDs:  sets.New[string](test.tenantIDs...),
   727  			cfg:        func() *config.Config { return &test.cfg },
   728  		}
   729  
   730  		gotQueries := ta.filterQueries(test.queries)
   731  		gotPools := ta.filterPools(test.pools)
   732  		gotHist := ta.filterHistory(test.hist)
   733  		if !equality.Semantic.DeepEqual(gotQueries, test.expectedQueries) {
   734  			t.Errorf("expected queries:\n%v\ngot queries:\n%v\n", test.expectedQueries, gotQueries)
   735  		}
   736  		if !equality.Semantic.DeepEqual(gotPools, test.expectedPools) {
   737  			t.Errorf("expected pools:\n%v\ngot pools:\n%v\n", test.expectedPools, gotPools)
   738  		}
   739  		// equality.Semantic.DeepEqual doesn't like the unexported fields in time.Time.
   740  		// We don't care about that for this test.
   741  		if !reflect.DeepEqual(gotHist, test.expectedHist) {
   742  			t.Errorf("expected history:\n%v\ngot history:\n%v\n", test.expectedHist, gotHist)
   743  		}
   744  	}
   745  }
   746  
   747  func TestMatches(t *testing.T) {
   748  	tests := []struct {
   749  		name string
   750  
   751  		repo  string
   752  		repos []string
   753  
   754  		expected bool
   755  	}{
   756  		{
   757  			name: "repo exists - exact match",
   758  
   759  			repo: "kubernetes/test-infra",
   760  			repos: []string{
   761  				"kubernetes/kubernetes",
   762  				"kubernetes/test-infra",
   763  				"kubernetes/community",
   764  			},
   765  
   766  			expected: true,
   767  		},
   768  		{
   769  			name: "repo exists - org match",
   770  
   771  			repo: "kubernetes/test-infra",
   772  			repos: []string{
   773  				"openshift/test-infra",
   774  				"openshift/origin",
   775  				"kubernetes-security",
   776  				"kubernetes",
   777  			},
   778  
   779  			expected: true,
   780  		},
   781  		{
   782  			name: "repo does not exist",
   783  
   784  			repo: "kubernetes/website",
   785  			repos: []string{
   786  				"openshift/test-infra",
   787  				"openshift/origin",
   788  				"kubernetes-security",
   789  				"kubernetes/test-infra",
   790  				"kubernetes/kubernetes",
   791  			},
   792  
   793  			expected: false,
   794  		},
   795  	}
   796  
   797  	for _, test := range tests {
   798  		t.Logf("running scenario %q", test.name)
   799  
   800  		if got := matches(test.repo, test.repos); got != test.expected {
   801  			t.Errorf("unexpected result: expected %t, got %t", test.expected, got)
   802  		}
   803  	}
   804  }