github.com/munnerz/test-infra@v0.0.0-20190108210205-ce3d181dc989/prow/plugins/updateconfig/updateconfig_test.go (about)

     1  /*
     2  Copyright 2017 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 updateconfig
    18  
    19  import (
    20  	"fmt"
    21  	"strings"
    22  	"testing"
    23  
    24  	"github.com/sirupsen/logrus"
    25  	"k8s.io/apimachinery/pkg/api/equality"
    26  	"k8s.io/apimachinery/pkg/util/diff"
    27  
    28  	"k8s.io/test-infra/prow/github"
    29  	"k8s.io/test-infra/prow/github/fakegithub"
    30  	"k8s.io/test-infra/prow/kube"
    31  	"k8s.io/test-infra/prow/plugins"
    32  )
    33  
    34  const defaultNamespace = "default"
    35  
    36  type fakeKubeClient struct {
    37  	maps        map[string]kube.ConfigMap
    38  	updatedMaps []string
    39  	createdMaps []string
    40  }
    41  
    42  func (c *fakeKubeClient) GetConfigMap(name, namespace string) (kube.ConfigMap, error) {
    43  	data, exists := c.maps[name]
    44  	var err error
    45  	if !exists {
    46  		err = kube.NotFoundError{}
    47  	}
    48  	return data, err
    49  }
    50  
    51  func (c *fakeKubeClient) ReplaceConfigMap(name string, config kube.ConfigMap) (kube.ConfigMap, error) {
    52  	if config.ObjectMeta.Name != name {
    53  		return kube.ConfigMap{}, fmt.Errorf("name %s does not match configmap name %s", name, config.ObjectMeta.Name)
    54  	}
    55  	if config.Namespace == "" {
    56  		config.Namespace = defaultNamespace
    57  	}
    58  	if _, exists := c.maps[name]; !exists {
    59  		return kube.ConfigMap{}, fmt.Errorf("called update on non-existent configmap %s", name)
    60  	}
    61  	c.maps[name] = config
    62  	c.updatedMaps = append(c.updatedMaps, name)
    63  	return c.maps[name], nil
    64  }
    65  
    66  func (c *fakeKubeClient) CreateConfigMap(content kube.ConfigMap) (kube.ConfigMap, error) {
    67  	if content.Namespace == "" {
    68  		content.Namespace = defaultNamespace
    69  	}
    70  	c.maps[content.Name] = content
    71  	c.createdMaps = append(c.createdMaps, content.Name)
    72  	return c.maps[content.Name], nil
    73  }
    74  
    75  func TestUpdateConfig(t *testing.T) {
    76  	basicPR := github.PullRequest{
    77  		Number: 1,
    78  		Base: github.PullRequestBranch{
    79  			Repo: github.Repo{
    80  				Owner: github.User{
    81  					Login: "kubernetes",
    82  				},
    83  				Name: "kubernetes",
    84  			},
    85  		},
    86  		User: github.User{
    87  			Login: "foo",
    88  		},
    89  	}
    90  
    91  	testcases := []struct {
    92  		name               string
    93  		prAction           github.PullRequestEventAction
    94  		merged             bool
    95  		mergeCommit        string
    96  		changes            []github.PullRequestChange
    97  		existConfigMaps    map[string]kube.ConfigMap
    98  		expectedConfigMaps map[string]kube.ConfigMap
    99  	}{
   100  		{
   101  			name:     "Opened PR, no update",
   102  			prAction: github.PullRequestActionOpened,
   103  			merged:   false,
   104  			changes: []github.PullRequestChange{
   105  				{
   106  					Filename:  "prow/config.yaml",
   107  					Additions: 1,
   108  				},
   109  			},
   110  			existConfigMaps: map[string]kube.ConfigMap{},
   111  		},
   112  		{
   113  			name:   "Opened PR, not merged, no update",
   114  			merged: false,
   115  			changes: []github.PullRequestChange{
   116  				{
   117  					Filename:  "prow/config.yaml",
   118  					Additions: 1,
   119  				},
   120  			},
   121  			existConfigMaps: map[string]kube.ConfigMap{},
   122  		},
   123  		{
   124  			name:     "Closed PR, no prow changes, no update",
   125  			prAction: github.PullRequestActionClosed,
   126  			merged:   false,
   127  			changes: []github.PullRequestChange{
   128  				{
   129  					Filename:  "foo.txt",
   130  					Additions: 1,
   131  				},
   132  			},
   133  			existConfigMaps: map[string]kube.ConfigMap{},
   134  		},
   135  		{
   136  			name:     "For whatever reason no merge commit SHA",
   137  			prAction: github.PullRequestActionClosed,
   138  			merged:   true,
   139  			changes: []github.PullRequestChange{
   140  				{
   141  					Filename:  "prow/config.yaml",
   142  					Additions: 1,
   143  				},
   144  			},
   145  			existConfigMaps: map[string]kube.ConfigMap{},
   146  		},
   147  		{
   148  			name:        "changed config.yaml, 1 update",
   149  			prAction:    github.PullRequestActionClosed,
   150  			merged:      true,
   151  			mergeCommit: "12345",
   152  			changes: []github.PullRequestChange{
   153  				{
   154  					Filename:  "prow/config.yaml",
   155  					Additions: 1,
   156  				},
   157  			},
   158  			existConfigMaps: map[string]kube.ConfigMap{
   159  				"config": {
   160  					ObjectMeta: kube.ObjectMeta{
   161  						Name:      "config",
   162  						Namespace: defaultNamespace,
   163  					},
   164  					Data: map[string]string{
   165  						"config.yaml": "old-config",
   166  					},
   167  				},
   168  			},
   169  			expectedConfigMaps: map[string]kube.ConfigMap{
   170  				"config": {
   171  					ObjectMeta: kube.ObjectMeta{
   172  						Name:      "config",
   173  						Namespace: defaultNamespace,
   174  					},
   175  					Data: map[string]string{
   176  						"config.yaml": "new-config",
   177  					},
   178  				},
   179  			},
   180  		},
   181  		{
   182  			name:        "changed config.yaml, existed configmap, 1 update",
   183  			prAction:    github.PullRequestActionClosed,
   184  			merged:      true,
   185  			mergeCommit: "12345",
   186  			changes: []github.PullRequestChange{
   187  				{
   188  					Filename:  "prow/config.yaml",
   189  					Additions: 1,
   190  				},
   191  			},
   192  			existConfigMaps: map[string]kube.ConfigMap{
   193  				"config": {
   194  					ObjectMeta: kube.ObjectMeta{
   195  						Name:      "config",
   196  						Namespace: defaultNamespace,
   197  					},
   198  					Data: map[string]string{
   199  						"config.yaml": "old-config",
   200  					},
   201  				},
   202  			},
   203  			expectedConfigMaps: map[string]kube.ConfigMap{
   204  				"config": {
   205  					ObjectMeta: kube.ObjectMeta{
   206  						Name:      "config",
   207  						Namespace: defaultNamespace,
   208  					},
   209  					Data: map[string]string{
   210  						"config.yaml": "new-config",
   211  					},
   212  				},
   213  			},
   214  		},
   215  		{
   216  			name:        "changed plugins.yaml, 1 update with custom key",
   217  			prAction:    github.PullRequestActionClosed,
   218  			merged:      true,
   219  			mergeCommit: "12345",
   220  			changes: []github.PullRequestChange{
   221  				{
   222  					Filename:  "prow/plugins.yaml",
   223  					Additions: 1,
   224  				},
   225  			},
   226  			existConfigMaps: map[string]kube.ConfigMap{
   227  				"plugins": {
   228  					ObjectMeta: kube.ObjectMeta{
   229  						Name:      "plugins",
   230  						Namespace: defaultNamespace,
   231  					},
   232  					Data: map[string]string{
   233  						"test-key": "old-plugins",
   234  					},
   235  				},
   236  			},
   237  			expectedConfigMaps: map[string]kube.ConfigMap{
   238  				"plugins": {
   239  					ObjectMeta: kube.ObjectMeta{
   240  						Name:      "plugins",
   241  						Namespace: defaultNamespace,
   242  					},
   243  					Data: map[string]string{
   244  						"test-key": "new-plugins",
   245  					},
   246  				},
   247  			},
   248  		},
   249  		{
   250  			name:        "changed resources.yaml, 1 update with custom namespace",
   251  			prAction:    github.PullRequestActionClosed,
   252  			merged:      true,
   253  			mergeCommit: "12345",
   254  			changes: []github.PullRequestChange{
   255  				{
   256  					Filename:  "boskos/resources.yaml",
   257  					Additions: 1,
   258  				},
   259  			},
   260  			existConfigMaps: map[string]kube.ConfigMap{
   261  				"boskos-config": {
   262  					ObjectMeta: kube.ObjectMeta{
   263  						Name:      "boskos-config",
   264  						Namespace: "boskos",
   265  					},
   266  					Data: map[string]string{
   267  						"resources.yaml": "old-boskos-config",
   268  					},
   269  				},
   270  			},
   271  			expectedConfigMaps: map[string]kube.ConfigMap{
   272  				"boskos-config": {
   273  					ObjectMeta: kube.ObjectMeta{
   274  						Name:      "boskos-config",
   275  						Namespace: "boskos",
   276  					},
   277  					Data: map[string]string{
   278  						"resources.yaml": "new-boskos-config",
   279  					},
   280  				},
   281  			},
   282  		},
   283  		{
   284  			name:        "changed config.yaml, plugins.yaml and resources.yaml, 3 update",
   285  			prAction:    github.PullRequestActionClosed,
   286  			merged:      true,
   287  			mergeCommit: "12345",
   288  			changes: []github.PullRequestChange{
   289  				{
   290  					Filename:  "prow/plugins.yaml",
   291  					Additions: 1,
   292  				},
   293  				{
   294  					Filename:  "prow/config.yaml",
   295  					Additions: 1,
   296  				},
   297  				{
   298  					Filename:  "boskos/resources.yaml",
   299  					Additions: 1,
   300  				},
   301  			},
   302  			existConfigMaps: map[string]kube.ConfigMap{
   303  				"config": {
   304  					ObjectMeta: kube.ObjectMeta{
   305  						Name:      "config",
   306  						Namespace: defaultNamespace,
   307  					},
   308  					Data: map[string]string{
   309  						"config.yaml": "old-config",
   310  					},
   311  				},
   312  				"plugins": {
   313  					ObjectMeta: kube.ObjectMeta{
   314  						Name:      "plugins",
   315  						Namespace: defaultNamespace,
   316  					},
   317  					Data: map[string]string{
   318  						"test-key": "old-plugins",
   319  					},
   320  				},
   321  				"boskos-config": {
   322  					ObjectMeta: kube.ObjectMeta{
   323  						Name:      "boskos-config",
   324  						Namespace: "boskos",
   325  					},
   326  					Data: map[string]string{
   327  						"resources.yaml": "old-boskos-config",
   328  					},
   329  				},
   330  			},
   331  			expectedConfigMaps: map[string]kube.ConfigMap{
   332  				"config": {
   333  					ObjectMeta: kube.ObjectMeta{
   334  						Name:      "config",
   335  						Namespace: defaultNamespace,
   336  					},
   337  					Data: map[string]string{
   338  						"config.yaml": "new-config",
   339  					},
   340  				},
   341  				"plugins": {
   342  					ObjectMeta: kube.ObjectMeta{
   343  						Name:      "plugins",
   344  						Namespace: defaultNamespace,
   345  					},
   346  					Data: map[string]string{
   347  						"test-key": "new-plugins",
   348  					},
   349  				},
   350  				"boskos-config": {
   351  					ObjectMeta: kube.ObjectMeta{
   352  						Name:      "boskos-config",
   353  						Namespace: "boskos",
   354  					},
   355  					Data: map[string]string{
   356  						"resources.yaml": "new-boskos-config",
   357  					},
   358  				},
   359  			},
   360  		},
   361  		{
   362  			name:        "edited both config/foo.yaml and config/bar.yaml, 2 update",
   363  			prAction:    github.PullRequestActionClosed,
   364  			merged:      true,
   365  			mergeCommit: "12345",
   366  			changes: []github.PullRequestChange{
   367  				{
   368  					Filename:  "config/foo.yaml",
   369  					Additions: 1,
   370  				},
   371  				{
   372  					Filename:  "config/bar.yaml",
   373  					Additions: 1,
   374  				},
   375  			},
   376  			existConfigMaps: map[string]kube.ConfigMap{
   377  				"multikey-config": {
   378  					ObjectMeta: kube.ObjectMeta{
   379  						Name:      "multikey-config",
   380  						Namespace: defaultNamespace,
   381  					},
   382  					Data: map[string]string{
   383  						"foo.yaml": "old-foo-config",
   384  						"bar.yaml": "old-bar-config",
   385  					},
   386  				},
   387  			},
   388  			expectedConfigMaps: map[string]kube.ConfigMap{
   389  				"multikey-config": {
   390  					ObjectMeta: kube.ObjectMeta{
   391  						Name:      "multikey-config",
   392  						Namespace: defaultNamespace,
   393  					},
   394  					Data: map[string]string{
   395  						"foo.yaml": "new-foo-config",
   396  						"bar.yaml": "new-bar-config",
   397  					},
   398  				},
   399  			},
   400  		},
   401  		{
   402  			name:        "edited config/foo.yaml, 1 update",
   403  			prAction:    github.PullRequestActionClosed,
   404  			merged:      true,
   405  			mergeCommit: "12345",
   406  			changes: []github.PullRequestChange{
   407  				{
   408  					Filename:  "config/foo.yaml",
   409  					Status:    "modified",
   410  					Additions: 1,
   411  				},
   412  			},
   413  			existConfigMaps: map[string]kube.ConfigMap{
   414  				"unaffected-config": {
   415  					ObjectMeta: kube.ObjectMeta{
   416  						Name:      "unaffected-config",
   417  						Namespace: defaultNamespace,
   418  					},
   419  					Data: map[string]string{
   420  						"config.yaml": "old-config",
   421  					},
   422  				},
   423  				"multikey-config": {
   424  					ObjectMeta: kube.ObjectMeta{
   425  						Name:      "multikey-config",
   426  						Namespace: defaultNamespace,
   427  					},
   428  					Data: map[string]string{
   429  						"foo.yaml": "old-foo-config",
   430  						"bar.yaml": "old-bar-config",
   431  					},
   432  				},
   433  			},
   434  			expectedConfigMaps: map[string]kube.ConfigMap{
   435  				"unaffected-config": {
   436  					ObjectMeta: kube.ObjectMeta{
   437  						Name:      "unaffected-config",
   438  						Namespace: defaultNamespace,
   439  					},
   440  					Data: map[string]string{
   441  						"config.yaml": "old-config",
   442  					},
   443  				},
   444  				"multikey-config": {
   445  					ObjectMeta: kube.ObjectMeta{
   446  						Name:      "multikey-config",
   447  						Namespace: defaultNamespace,
   448  					},
   449  					Data: map[string]string{
   450  						"foo.yaml": "new-foo-config",
   451  						"bar.yaml": "old-bar-config",
   452  					},
   453  				},
   454  			},
   455  		},
   456  		{
   457  			name:        "remove config/foo.yaml, 1 update",
   458  			prAction:    github.PullRequestActionClosed,
   459  			merged:      true,
   460  			mergeCommit: "12345",
   461  			changes: []github.PullRequestChange{
   462  				{
   463  					Filename: "config/foo.yaml",
   464  					Status:   "removed",
   465  				},
   466  			},
   467  			existConfigMaps: map[string]kube.ConfigMap{
   468  				"multikey-config": {
   469  					ObjectMeta: kube.ObjectMeta{
   470  						Name:      "multikey-config",
   471  						Namespace: defaultNamespace,
   472  					},
   473  					Data: map[string]string{
   474  						"foo.yaml": "old-foo-config",
   475  						"bar.yaml": "old-bar-config",
   476  					},
   477  				},
   478  			},
   479  			expectedConfigMaps: map[string]kube.ConfigMap{
   480  				"multikey-config": {
   481  					ObjectMeta: kube.ObjectMeta{
   482  						Name:      "multikey-config",
   483  						Namespace: defaultNamespace,
   484  					},
   485  					Data: map[string]string{
   486  						"bar.yaml": "old-bar-config",
   487  					},
   488  				},
   489  			},
   490  		},
   491  		{
   492  			name:        "edited dir/subdir/fejtaverse/krzyzacy.yaml, 1 update",
   493  			prAction:    github.PullRequestActionClosed,
   494  			merged:      true,
   495  			mergeCommit: "12345",
   496  			changes: []github.PullRequestChange{
   497  				{
   498  					Filename:  "dir/subdir/fejtaverse/krzyzacy.yaml",
   499  					Status:    "modified",
   500  					Additions: 1,
   501  				},
   502  			},
   503  			existConfigMaps: map[string]kube.ConfigMap{
   504  				"glob-config": {
   505  					ObjectMeta: kube.ObjectMeta{
   506  						Name:      "glob-config",
   507  						Namespace: defaultNamespace,
   508  					},
   509  					Data: map[string]string{
   510  						"fejta.yaml":    "old-fejta-config",
   511  						"krzyzacy.yaml": "old-krzyzacy-config",
   512  					},
   513  				},
   514  			},
   515  			expectedConfigMaps: map[string]kube.ConfigMap{
   516  				"glob-config": {
   517  					ObjectMeta: kube.ObjectMeta{
   518  						Name:      "glob-config",
   519  						Namespace: defaultNamespace,
   520  					},
   521  					Data: map[string]string{
   522  						"fejta.yaml":    "old-fejta-config",
   523  						"krzyzacy.yaml": "new-krzyzacy-config",
   524  					},
   525  				},
   526  			},
   527  		},
   528  		{
   529  			name:        "renamed dir/subdir/fejtaverse/krzyzacy.yaml, 1 update",
   530  			prAction:    github.PullRequestActionClosed,
   531  			merged:      true,
   532  			mergeCommit: "54321",
   533  			changes: []github.PullRequestChange{
   534  				{
   535  					Filename:         "dir/subdir/fejtaverse/fejtabot.yaml",
   536  					PreviousFilename: "dir/subdir/fejtaverse/krzyzacy.yaml",
   537  					Status:           "renamed",
   538  					Additions:        1,
   539  				},
   540  			},
   541  			existConfigMaps: map[string]kube.ConfigMap{
   542  				"glob-config": {
   543  					ObjectMeta: kube.ObjectMeta{
   544  						Name:      "glob-config",
   545  						Namespace: defaultNamespace,
   546  					},
   547  					Data: map[string]string{
   548  						"krzyzacy.yaml": "old-krzyzacy-config",
   549  					},
   550  				},
   551  			},
   552  			expectedConfigMaps: map[string]kube.ConfigMap{
   553  				"glob-config": {
   554  					ObjectMeta: kube.ObjectMeta{
   555  						Name:      "glob-config",
   556  						Namespace: defaultNamespace,
   557  					},
   558  					Data: map[string]string{
   559  						"fejtabot.yaml": "new-fejtabot-config",
   560  					},
   561  				},
   562  			},
   563  		},
   564  		{
   565  			name:        "add delete edit glob config, 3 update",
   566  			prAction:    github.PullRequestActionClosed,
   567  			merged:      true,
   568  			mergeCommit: "12345",
   569  			changes: []github.PullRequestChange{
   570  				{
   571  					Filename:  "dir/subdir/fejta.yaml",
   572  					Status:    "modified",
   573  					Additions: 1,
   574  				},
   575  				{
   576  					Filename:  "dir/subdir/fejtaverse/sig-foo/added.yaml",
   577  					Status:    "added",
   578  					Additions: 1,
   579  				},
   580  				{
   581  					Filename: "dir/subdir/fejtaverse/sig-bar/removed.yaml",
   582  					Status:   "removed",
   583  				},
   584  			},
   585  			existConfigMaps: map[string]kube.ConfigMap{
   586  				"glob-config": {
   587  					ObjectMeta: kube.ObjectMeta{
   588  						Name:      "glob-config",
   589  						Namespace: defaultNamespace,
   590  					},
   591  					Data: map[string]string{
   592  						"fejta.yaml":    "old-fejta-config",
   593  						"krzyzacy.yaml": "old-krzyzacy-config",
   594  						"removed.yaml":  "old-removed-config",
   595  					},
   596  				},
   597  			},
   598  			expectedConfigMaps: map[string]kube.ConfigMap{
   599  				"glob-config": {
   600  					ObjectMeta: kube.ObjectMeta{
   601  						Name:      "glob-config",
   602  						Namespace: defaultNamespace,
   603  					},
   604  					Data: map[string]string{
   605  						"fejta.yaml":    "new-fejta-config",
   606  						"krzyzacy.yaml": "old-krzyzacy-config",
   607  						"added.yaml":    "new-added-config",
   608  					},
   609  				},
   610  			},
   611  		},
   612  		{
   613  			name:        "config changes without a backing configmap causes creation",
   614  			prAction:    github.PullRequestActionClosed,
   615  			merged:      true,
   616  			mergeCommit: "12345",
   617  			changes: []github.PullRequestChange{
   618  				{
   619  					Filename:  "prow/config.yaml",
   620  					Status:    "modified",
   621  					Additions: 1,
   622  				},
   623  			},
   624  			existConfigMaps: map[string]kube.ConfigMap{},
   625  			expectedConfigMaps: map[string]kube.ConfigMap{
   626  				"config": {
   627  					ObjectMeta: kube.ObjectMeta{
   628  						Name:      "config",
   629  						Namespace: defaultNamespace,
   630  					},
   631  					Data: map[string]string{
   632  						"config.yaml": "new-config",
   633  					},
   634  				},
   635  			},
   636  		},
   637  	}
   638  
   639  	for _, tc := range testcases {
   640  		log := logrus.WithField("plugin", pluginName)
   641  		event := github.PullRequestEvent{
   642  			Action:      tc.prAction,
   643  			Number:      basicPR.Number,
   644  			PullRequest: basicPR,
   645  		}
   646  		event.PullRequest.Merged = tc.merged
   647  		if tc.mergeCommit != "" {
   648  			event.PullRequest.MergeSHA = &tc.mergeCommit
   649  		}
   650  
   651  		fgc := &fakegithub.FakeClient{
   652  			PullRequests: map[int]*github.PullRequest{
   653  				basicPR.Number: &basicPR,
   654  			},
   655  			PullRequestChanges: map[int][]github.PullRequestChange{
   656  				basicPR.Number: tc.changes,
   657  			},
   658  			IssueComments: map[int][]github.IssueComment{},
   659  			RemoteFiles: map[string]map[string]string{
   660  				"prow/config.yaml": {
   661  					"master": "old-config",
   662  					"12345":  "new-config",
   663  				},
   664  				"prow/plugins.yaml": {
   665  					"master": "old-plugins",
   666  					"12345":  "new-plugins",
   667  				},
   668  				"boskos/resources.yaml": {
   669  					"master": "old-boskos-config",
   670  					"12345":  "new-boskos-config",
   671  				},
   672  				"config/foo.yaml": {
   673  					"master": "old-foo-config",
   674  					"12345":  "new-foo-config",
   675  				},
   676  				"config/bar.yaml": {
   677  					"master": "old-bar-config",
   678  					"12345":  "new-bar-config",
   679  				},
   680  				"dir/subdir/fejta.yaml": {
   681  					"master": "old-fejta-config",
   682  					"12345":  "new-fejta-config",
   683  				},
   684  				"dir/subdir/fejtaverse/krzyzacy.yaml": {
   685  					"master": "old-krzyzacy-config",
   686  					"12345":  "new-krzyzacy-config",
   687  				},
   688  				"dir/subdir/fejtaverse/fejtabot.yaml": {
   689  					"54321": "new-fejtabot-config",
   690  				},
   691  				"dir/subdir/fejtaverse/sig-foo/added.yaml": {
   692  					"12345": "new-added-config",
   693  				},
   694  				"dir/subdir/fejtaverse/sig-bar/removed.yaml": {
   695  					"master": "old-removed-config",
   696  				},
   697  			},
   698  		}
   699  		fkc := &fakeKubeClient{
   700  			maps: tc.existConfigMaps,
   701  		}
   702  
   703  		m := map[string]plugins.ConfigMapSpec{
   704  			"prow/config.yaml": {
   705  				Name: "config",
   706  			},
   707  			"prow/plugins.yaml": {
   708  				Name: "plugins",
   709  				Key:  "test-key",
   710  			},
   711  			"boskos/resources.yaml": {
   712  				Name:      "boskos-config",
   713  				Namespace: "boskos",
   714  			},
   715  			"config/foo.yaml": {
   716  				Name: "multikey-config",
   717  			},
   718  			"config/bar.yaml": {
   719  				Name: "multikey-config",
   720  			},
   721  			"dir/subdir/**/*.yaml": {
   722  				Name: "glob-config",
   723  			},
   724  		}
   725  
   726  		if err := handle(fgc, fkc, log, event, m); err != nil {
   727  			t.Errorf("tc: %s, err: %s", tc.name, err)
   728  		}
   729  
   730  		if tc.expectedConfigMaps != nil {
   731  			if len(fgc.IssueComments[basicPR.Number]) != 1 {
   732  				t.Errorf("tc %s : Expect 1 comment, actually got %d", tc.name, len(fgc.IssueComments[basicPR.Number]))
   733  			} else {
   734  				comment := fgc.IssueComments[basicPR.Number][0].Body
   735  				if !strings.Contains(comment, "Updated the") {
   736  					t.Errorf("%s: missing Updated the from %s", tc.name, comment)
   737  				}
   738  				for configName := range tc.expectedConfigMaps {
   739  					found := false
   740  					for _, collection := range [][]string{fkc.updatedMaps, fkc.createdMaps} {
   741  						for _, name := range collection {
   742  							if name == configName {
   743  								if !strings.Contains(comment, configName) {
   744  									t.Errorf("%s: missing %s from %s", tc.name, configName, comment)
   745  								}
   746  								found = true
   747  							}
   748  						}
   749  
   750  					}
   751  					if !found {
   752  						if strings.Contains(comment, configName) {
   753  							t.Errorf("%s: should not contain %s in %s", tc.name, configName, comment)
   754  						}
   755  					}
   756  				}
   757  			}
   758  		}
   759  
   760  		actions := map[string][]string{
   761  			"update": fkc.updatedMaps,
   762  			"create": fkc.createdMaps,
   763  		}
   764  		for action, names := range actions {
   765  			for _, name := range names {
   766  				found := false
   767  				for expected := range tc.expectedConfigMaps {
   768  					if name == expected {
   769  						found = true
   770  					}
   771  				}
   772  
   773  				if !found {
   774  					t.Errorf("%s: should not %s unexpected configmap %s", tc.name, action, name)
   775  				}
   776  			}
   777  		}
   778  
   779  		for configName := range tc.expectedConfigMaps {
   780  			if config, ok := fkc.maps[configName]; !ok {
   781  				t.Errorf("tc %s : Should have updated or created configmap for '%s'", tc.name, configName)
   782  			} else if expected, actual := tc.expectedConfigMaps[configName], config; !equality.Semantic.DeepEqual(expected, actual) {
   783  				t.Errorf("%s: incorrect ConfigMap state after update: %v", tc.name, diff.ObjectReflectDiff(expected, actual))
   784  			}
   785  		}
   786  	}
   787  }