...

Source file src/sigs.k8s.io/controller-runtime/pkg/predicate/predicate_test.go

Documentation: sigs.k8s.io/controller-runtime/pkg/predicate

     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 predicate_test
    18  
    19  import (
    20  	. "github.com/onsi/ginkgo/v2"
    21  	. "github.com/onsi/gomega"
    22  	corev1 "k8s.io/api/core/v1"
    23  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    24  
    25  	"sigs.k8s.io/controller-runtime/pkg/client"
    26  	"sigs.k8s.io/controller-runtime/pkg/event"
    27  	"sigs.k8s.io/controller-runtime/pkg/predicate"
    28  )
    29  
    30  var _ = Describe("Predicate", func() {
    31  	var pod *corev1.Pod
    32  	BeforeEach(func() {
    33  		pod = &corev1.Pod{
    34  			ObjectMeta: metav1.ObjectMeta{Namespace: "biz", Name: "baz"},
    35  		}
    36  	})
    37  
    38  	Describe("Funcs", func() {
    39  		failingFuncs := predicate.Funcs{
    40  			CreateFunc: func(event.CreateEvent) bool {
    41  				defer GinkgoRecover()
    42  				Fail("Did not expect CreateFunc to be called.")
    43  				return false
    44  			},
    45  			DeleteFunc: func(event.DeleteEvent) bool {
    46  				defer GinkgoRecover()
    47  				Fail("Did not expect DeleteFunc to be called.")
    48  				return false
    49  			},
    50  			UpdateFunc: func(event.UpdateEvent) bool {
    51  				defer GinkgoRecover()
    52  				Fail("Did not expect UpdateFunc to be called.")
    53  				return false
    54  			},
    55  			GenericFunc: func(event.GenericEvent) bool {
    56  				defer GinkgoRecover()
    57  				Fail("Did not expect GenericFunc to be called.")
    58  				return false
    59  			},
    60  		}
    61  
    62  		It("should call Create", func() {
    63  			instance := failingFuncs
    64  			instance.CreateFunc = func(evt event.CreateEvent) bool {
    65  				defer GinkgoRecover()
    66  				Expect(evt.Object).To(Equal(pod))
    67  				return false
    68  			}
    69  			evt := event.CreateEvent{
    70  				Object: pod,
    71  			}
    72  			Expect(instance.Create(evt)).To(BeFalse())
    73  
    74  			instance.CreateFunc = func(evt event.CreateEvent) bool {
    75  				defer GinkgoRecover()
    76  				Expect(evt.Object).To(Equal(pod))
    77  				return true
    78  			}
    79  			Expect(instance.Create(evt)).To(BeTrue())
    80  
    81  			instance.CreateFunc = nil
    82  			Expect(instance.Create(evt)).To(BeTrue())
    83  		})
    84  
    85  		It("should call Update", func() {
    86  			newPod := pod.DeepCopy()
    87  			newPod.Name = "baz2"
    88  			newPod.Namespace = "biz2"
    89  
    90  			instance := failingFuncs
    91  			instance.UpdateFunc = func(evt event.UpdateEvent) bool {
    92  				defer GinkgoRecover()
    93  				Expect(evt.ObjectOld).To(Equal(pod))
    94  				Expect(evt.ObjectNew).To(Equal(newPod))
    95  				return false
    96  			}
    97  			evt := event.UpdateEvent{
    98  				ObjectOld: pod,
    99  				ObjectNew: newPod,
   100  			}
   101  			Expect(instance.Update(evt)).To(BeFalse())
   102  
   103  			instance.UpdateFunc = func(evt event.UpdateEvent) bool {
   104  				defer GinkgoRecover()
   105  				Expect(evt.ObjectOld).To(Equal(pod))
   106  				Expect(evt.ObjectNew).To(Equal(newPod))
   107  				return true
   108  			}
   109  			Expect(instance.Update(evt)).To(BeTrue())
   110  
   111  			instance.UpdateFunc = nil
   112  			Expect(instance.Update(evt)).To(BeTrue())
   113  		})
   114  
   115  		It("should call Delete", func() {
   116  			instance := failingFuncs
   117  			instance.DeleteFunc = func(evt event.DeleteEvent) bool {
   118  				defer GinkgoRecover()
   119  				Expect(evt.Object).To(Equal(pod))
   120  				return false
   121  			}
   122  			evt := event.DeleteEvent{
   123  				Object: pod,
   124  			}
   125  			Expect(instance.Delete(evt)).To(BeFalse())
   126  
   127  			instance.DeleteFunc = func(evt event.DeleteEvent) bool {
   128  				defer GinkgoRecover()
   129  				Expect(evt.Object).To(Equal(pod))
   130  				return true
   131  			}
   132  			Expect(instance.Delete(evt)).To(BeTrue())
   133  
   134  			instance.DeleteFunc = nil
   135  			Expect(instance.Delete(evt)).To(BeTrue())
   136  		})
   137  
   138  		It("should call Generic", func() {
   139  			instance := failingFuncs
   140  			instance.GenericFunc = func(evt event.GenericEvent) bool {
   141  				defer GinkgoRecover()
   142  				Expect(evt.Object).To(Equal(pod))
   143  				return false
   144  			}
   145  			evt := event.GenericEvent{
   146  				Object: pod,
   147  			}
   148  			Expect(instance.Generic(evt)).To(BeFalse())
   149  
   150  			instance.GenericFunc = func(evt event.GenericEvent) bool {
   151  				defer GinkgoRecover()
   152  				Expect(evt.Object).To(Equal(pod))
   153  				return true
   154  			}
   155  			Expect(instance.Generic(evt)).To(BeTrue())
   156  
   157  			instance.GenericFunc = nil
   158  			Expect(instance.Generic(evt)).To(BeTrue())
   159  		})
   160  	})
   161  
   162  	Describe("When checking a ResourceVersionChangedPredicate", func() {
   163  		instance := predicate.ResourceVersionChangedPredicate{}
   164  
   165  		Context("Where the old object doesn't have a ResourceVersion or metadata", func() {
   166  			It("should return false", func() {
   167  				newPod := &corev1.Pod{
   168  					ObjectMeta: metav1.ObjectMeta{
   169  						Name:            "baz",
   170  						Namespace:       "biz",
   171  						ResourceVersion: "1",
   172  					}}
   173  
   174  				failEvnt := event.UpdateEvent{
   175  					ObjectNew: newPod,
   176  				}
   177  				Expect(instance.Create(event.CreateEvent{})).Should(BeTrue())
   178  				Expect(instance.Delete(event.DeleteEvent{})).Should(BeTrue())
   179  				Expect(instance.Generic(event.GenericEvent{})).Should(BeTrue())
   180  				Expect(instance.Update(failEvnt)).Should(BeFalse())
   181  			})
   182  		})
   183  
   184  		Context("Where the new object doesn't have a ResourceVersion or metadata", func() {
   185  			It("should return false", func() {
   186  				oldPod := &corev1.Pod{
   187  					ObjectMeta: metav1.ObjectMeta{
   188  						Name:            "baz",
   189  						Namespace:       "biz",
   190  						ResourceVersion: "1",
   191  					}}
   192  
   193  				failEvnt := event.UpdateEvent{
   194  					ObjectOld: oldPod,
   195  				}
   196  				Expect(instance.Create(event.CreateEvent{})).Should(BeTrue())
   197  				Expect(instance.Delete(event.DeleteEvent{})).Should(BeTrue())
   198  				Expect(instance.Generic(event.GenericEvent{})).Should(BeTrue())
   199  				Expect(instance.Update(failEvnt)).Should(BeFalse())
   200  				Expect(instance.Update(failEvnt)).Should(BeFalse())
   201  			})
   202  		})
   203  
   204  		Context("Where the ResourceVersion hasn't changed", func() {
   205  			It("should return false", func() {
   206  				newPod := &corev1.Pod{
   207  					ObjectMeta: metav1.ObjectMeta{
   208  						Name:            "baz",
   209  						Namespace:       "biz",
   210  						ResourceVersion: "v1",
   211  					}}
   212  
   213  				oldPod := &corev1.Pod{
   214  					ObjectMeta: metav1.ObjectMeta{
   215  						Name:            "baz",
   216  						Namespace:       "biz",
   217  						ResourceVersion: "v1",
   218  					}}
   219  
   220  				failEvnt := event.UpdateEvent{
   221  					ObjectOld: oldPod,
   222  					ObjectNew: newPod,
   223  				}
   224  				Expect(instance.Create(event.CreateEvent{})).Should(BeTrue())
   225  				Expect(instance.Delete(event.DeleteEvent{})).Should(BeTrue())
   226  				Expect(instance.Generic(event.GenericEvent{})).Should(BeTrue())
   227  				Expect(instance.Update(failEvnt)).Should(BeFalse())
   228  				Expect(instance.Update(failEvnt)).Should(BeFalse())
   229  			})
   230  		})
   231  
   232  		Context("Where the ResourceVersion has changed", func() {
   233  			It("should return true", func() {
   234  				newPod := &corev1.Pod{
   235  					ObjectMeta: metav1.ObjectMeta{
   236  						Name:            "baz",
   237  						Namespace:       "biz",
   238  						ResourceVersion: "v1",
   239  					}}
   240  
   241  				oldPod := &corev1.Pod{
   242  					ObjectMeta: metav1.ObjectMeta{
   243  						Name:            "baz",
   244  						Namespace:       "biz",
   245  						ResourceVersion: "v2",
   246  					}}
   247  				passEvt := event.UpdateEvent{
   248  					ObjectOld: oldPod,
   249  					ObjectNew: newPod,
   250  				}
   251  				Expect(instance.Create(event.CreateEvent{})).Should(BeTrue())
   252  				Expect(instance.Delete(event.DeleteEvent{})).Should(BeTrue())
   253  				Expect(instance.Generic(event.GenericEvent{})).Should(BeTrue())
   254  				Expect(instance.Update(passEvt)).Should(BeTrue())
   255  			})
   256  		})
   257  
   258  		Context("Where the objects or metadata are missing", func() {
   259  
   260  			It("should return false", func() {
   261  				newPod := &corev1.Pod{
   262  					ObjectMeta: metav1.ObjectMeta{
   263  						Name:            "baz",
   264  						Namespace:       "biz",
   265  						ResourceVersion: "v1",
   266  					}}
   267  
   268  				oldPod := &corev1.Pod{
   269  					ObjectMeta: metav1.ObjectMeta{
   270  						Name:            "baz",
   271  						Namespace:       "biz",
   272  						ResourceVersion: "v1",
   273  					}}
   274  
   275  				failEvt1 := event.UpdateEvent{ObjectOld: oldPod}
   276  				failEvt2 := event.UpdateEvent{ObjectNew: newPod}
   277  				failEvt3 := event.UpdateEvent{ObjectOld: oldPod, ObjectNew: newPod}
   278  				Expect(instance.Create(event.CreateEvent{})).Should(BeTrue())
   279  				Expect(instance.Delete(event.DeleteEvent{})).Should(BeTrue())
   280  				Expect(instance.Generic(event.GenericEvent{})).Should(BeTrue())
   281  				Expect(instance.Update(failEvt1)).Should(BeFalse())
   282  				Expect(instance.Update(failEvt2)).Should(BeFalse())
   283  				Expect(instance.Update(failEvt3)).Should(BeFalse())
   284  			})
   285  		})
   286  
   287  	})
   288  
   289  	Describe("When checking a GenerationChangedPredicate", func() {
   290  		instance := predicate.GenerationChangedPredicate{}
   291  		Context("Where the old object doesn't have a Generation or metadata", func() {
   292  			It("should return false", func() {
   293  				newPod := &corev1.Pod{
   294  					ObjectMeta: metav1.ObjectMeta{
   295  						Name:       "baz",
   296  						Namespace:  "biz",
   297  						Generation: 1,
   298  					}}
   299  
   300  				failEvnt := event.UpdateEvent{
   301  					ObjectNew: newPod,
   302  				}
   303  				Expect(instance.Create(event.CreateEvent{})).To(BeTrue())
   304  				Expect(instance.Delete(event.DeleteEvent{})).To(BeTrue())
   305  				Expect(instance.Generic(event.GenericEvent{})).To(BeTrue())
   306  				Expect(instance.Update(failEvnt)).To(BeFalse())
   307  			})
   308  		})
   309  
   310  		Context("Where the new object doesn't have a Generation or metadata", func() {
   311  			It("should return false", func() {
   312  				oldPod := &corev1.Pod{
   313  					ObjectMeta: metav1.ObjectMeta{
   314  						Name:       "baz",
   315  						Namespace:  "biz",
   316  						Generation: 1,
   317  					}}
   318  
   319  				failEvnt := event.UpdateEvent{
   320  					ObjectOld: oldPod,
   321  				}
   322  				Expect(instance.Create(event.CreateEvent{})).To(BeTrue())
   323  				Expect(instance.Delete(event.DeleteEvent{})).To(BeTrue())
   324  				Expect(instance.Generic(event.GenericEvent{})).To(BeTrue())
   325  				Expect(instance.Update(failEvnt)).To(BeFalse())
   326  			})
   327  		})
   328  
   329  		Context("Where the Generation hasn't changed", func() {
   330  			It("should return false", func() {
   331  				newPod := &corev1.Pod{
   332  					ObjectMeta: metav1.ObjectMeta{
   333  						Name:       "baz",
   334  						Namespace:  "biz",
   335  						Generation: 1,
   336  					}}
   337  
   338  				oldPod := &corev1.Pod{
   339  					ObjectMeta: metav1.ObjectMeta{
   340  						Name:       "baz",
   341  						Namespace:  "biz",
   342  						Generation: 1,
   343  					}}
   344  
   345  				failEvnt := event.UpdateEvent{
   346  					ObjectOld: oldPod,
   347  					ObjectNew: newPod,
   348  				}
   349  				Expect(instance.Create(event.CreateEvent{})).To(BeTrue())
   350  				Expect(instance.Delete(event.DeleteEvent{})).To(BeTrue())
   351  				Expect(instance.Generic(event.GenericEvent{})).To(BeTrue())
   352  				Expect(instance.Update(failEvnt)).To(BeFalse())
   353  			})
   354  		})
   355  
   356  		Context("Where the Generation has changed", func() {
   357  			It("should return true", func() {
   358  				newPod := &corev1.Pod{
   359  					ObjectMeta: metav1.ObjectMeta{
   360  						Name:       "baz",
   361  						Namespace:  "biz",
   362  						Generation: 1,
   363  					}}
   364  
   365  				oldPod := &corev1.Pod{
   366  					ObjectMeta: metav1.ObjectMeta{
   367  						Name:       "baz",
   368  						Namespace:  "biz",
   369  						Generation: 2,
   370  					}}
   371  				passEvt := event.UpdateEvent{
   372  					ObjectOld: oldPod,
   373  					ObjectNew: newPod,
   374  				}
   375  				Expect(instance.Create(event.CreateEvent{})).To(BeTrue())
   376  				Expect(instance.Delete(event.DeleteEvent{})).To(BeTrue())
   377  				Expect(instance.Generic(event.GenericEvent{})).To(BeTrue())
   378  				Expect(instance.Update(passEvt)).To(BeTrue())
   379  			})
   380  		})
   381  
   382  		Context("Where the objects or metadata are missing", func() {
   383  
   384  			It("should return false", func() {
   385  				newPod := &corev1.Pod{
   386  					ObjectMeta: metav1.ObjectMeta{
   387  						Name:       "baz",
   388  						Namespace:  "biz",
   389  						Generation: 1,
   390  					}}
   391  
   392  				oldPod := &corev1.Pod{
   393  					ObjectMeta: metav1.ObjectMeta{
   394  						Name:       "baz",
   395  						Namespace:  "biz",
   396  						Generation: 1,
   397  					}}
   398  
   399  				failEvt1 := event.UpdateEvent{ObjectOld: oldPod}
   400  				failEvt2 := event.UpdateEvent{ObjectNew: newPod}
   401  				failEvt3 := event.UpdateEvent{ObjectOld: oldPod, ObjectNew: newPod}
   402  				Expect(instance.Create(event.CreateEvent{})).To(BeTrue())
   403  				Expect(instance.Delete(event.DeleteEvent{})).To(BeTrue())
   404  				Expect(instance.Generic(event.GenericEvent{})).To(BeTrue())
   405  				Expect(instance.Update(failEvt1)).To(BeFalse())
   406  				Expect(instance.Update(failEvt2)).To(BeFalse())
   407  				Expect(instance.Update(failEvt3)).To(BeFalse())
   408  			})
   409  		})
   410  
   411  	})
   412  
   413  	// AnnotationChangedPredicate has almost identical test cases as LabelChangedPredicates,
   414  	// so the duplication linter should be muted on both two test suites.
   415  	Describe("When checking an AnnotationChangedPredicate", func() {
   416  		instance := predicate.AnnotationChangedPredicate{}
   417  		Context("Where the old object is missing", func() {
   418  			It("should return false", func() {
   419  				newPod := &corev1.Pod{
   420  					ObjectMeta: metav1.ObjectMeta{
   421  						Name:      "baz",
   422  						Namespace: "biz",
   423  						Annotations: map[string]string{
   424  							"booz": "wooz",
   425  						},
   426  					}}
   427  
   428  				failEvnt := event.UpdateEvent{
   429  					ObjectNew: newPod,
   430  				}
   431  				Expect(instance.Create(event.CreateEvent{})).To(BeTrue())
   432  				Expect(instance.Delete(event.DeleteEvent{})).To(BeTrue())
   433  				Expect(instance.Generic(event.GenericEvent{})).To(BeTrue())
   434  				Expect(instance.Update(failEvnt)).To(BeFalse())
   435  			})
   436  		})
   437  
   438  		Context("Where the new object is missing", func() {
   439  			It("should return false", func() {
   440  				oldPod := &corev1.Pod{
   441  					ObjectMeta: metav1.ObjectMeta{
   442  						Name:      "baz",
   443  						Namespace: "biz",
   444  						Annotations: map[string]string{
   445  							"booz": "wooz",
   446  						},
   447  					}}
   448  
   449  				failEvnt := event.UpdateEvent{
   450  					ObjectOld: oldPod,
   451  				}
   452  				Expect(instance.Create(event.CreateEvent{})).To(BeTrue())
   453  				Expect(instance.Delete(event.DeleteEvent{})).To(BeTrue())
   454  				Expect(instance.Generic(event.GenericEvent{})).To(BeTrue())
   455  				Expect(instance.Update(failEvnt)).To(BeFalse())
   456  			})
   457  		})
   458  
   459  		Context("Where the annotations are empty", func() {
   460  			It("should return false", func() {
   461  				newPod := &corev1.Pod{
   462  					ObjectMeta: metav1.ObjectMeta{
   463  						Name:      "baz",
   464  						Namespace: "biz",
   465  					}}
   466  
   467  				oldPod := &corev1.Pod{
   468  					ObjectMeta: metav1.ObjectMeta{
   469  						Name:      "baz",
   470  						Namespace: "biz",
   471  					}}
   472  
   473  				failEvnt := event.UpdateEvent{
   474  					ObjectOld: oldPod,
   475  					ObjectNew: newPod,
   476  				}
   477  				Expect(instance.Create(event.CreateEvent{})).To(BeTrue())
   478  				Expect(instance.Delete(event.DeleteEvent{})).To(BeTrue())
   479  				Expect(instance.Generic(event.GenericEvent{})).To(BeTrue())
   480  				Expect(instance.Update(failEvnt)).To(BeFalse())
   481  			})
   482  		})
   483  
   484  		Context("Where the annotations haven't changed", func() {
   485  			It("should return false", func() {
   486  				newPod := &corev1.Pod{
   487  					ObjectMeta: metav1.ObjectMeta{
   488  						Name:      "baz",
   489  						Namespace: "biz",
   490  						Annotations: map[string]string{
   491  							"booz": "wooz",
   492  						},
   493  					}}
   494  
   495  				oldPod := &corev1.Pod{
   496  					ObjectMeta: metav1.ObjectMeta{
   497  						Name:      "baz",
   498  						Namespace: "biz",
   499  						Annotations: map[string]string{
   500  							"booz": "wooz",
   501  						},
   502  					}}
   503  
   504  				failEvnt := event.UpdateEvent{
   505  					ObjectOld: oldPod,
   506  					ObjectNew: newPod,
   507  				}
   508  				Expect(instance.Create(event.CreateEvent{})).To(BeTrue())
   509  				Expect(instance.Delete(event.DeleteEvent{})).To(BeTrue())
   510  				Expect(instance.Generic(event.GenericEvent{})).To(BeTrue())
   511  				Expect(instance.Update(failEvnt)).To(BeFalse())
   512  			})
   513  		})
   514  
   515  		Context("Where an annotation value has changed", func() {
   516  			It("should return true", func() {
   517  				newPod := &corev1.Pod{
   518  					ObjectMeta: metav1.ObjectMeta{
   519  						Name:      "baz",
   520  						Namespace: "biz",
   521  						Annotations: map[string]string{
   522  							"booz": "wooz",
   523  						},
   524  					}}
   525  
   526  				oldPod := &corev1.Pod{
   527  					ObjectMeta: metav1.ObjectMeta{
   528  						Name:      "baz",
   529  						Namespace: "biz",
   530  						Annotations: map[string]string{
   531  							"booz": "weez",
   532  						},
   533  					}}
   534  
   535  				passEvt := event.UpdateEvent{
   536  					ObjectOld: oldPod,
   537  					ObjectNew: newPod,
   538  				}
   539  				Expect(instance.Create(event.CreateEvent{})).To(BeTrue())
   540  				Expect(instance.Delete(event.DeleteEvent{})).To(BeTrue())
   541  				Expect(instance.Generic(event.GenericEvent{})).To(BeTrue())
   542  				Expect(instance.Update(passEvt)).To(BeTrue())
   543  			})
   544  		})
   545  
   546  		Context("Where an annotation has been added", func() {
   547  			It("should return true", func() {
   548  				newPod := &corev1.Pod{
   549  					ObjectMeta: metav1.ObjectMeta{
   550  						Name:      "baz",
   551  						Namespace: "biz",
   552  						Annotations: map[string]string{
   553  							"booz": "wooz",
   554  						},
   555  					}}
   556  
   557  				oldPod := &corev1.Pod{
   558  					ObjectMeta: metav1.ObjectMeta{
   559  						Name:      "baz",
   560  						Namespace: "biz",
   561  						Annotations: map[string]string{
   562  							"booz": "wooz",
   563  							"zooz": "qooz",
   564  						},
   565  					}}
   566  
   567  				passEvt := event.UpdateEvent{
   568  					ObjectOld: oldPod,
   569  					ObjectNew: newPod,
   570  				}
   571  				Expect(instance.Create(event.CreateEvent{})).To(BeTrue())
   572  				Expect(instance.Delete(event.DeleteEvent{})).To(BeTrue())
   573  				Expect(instance.Generic(event.GenericEvent{})).To(BeTrue())
   574  				Expect(instance.Update(passEvt)).To(BeTrue())
   575  			})
   576  		})
   577  
   578  		Context("Where an annotation has been removed", func() {
   579  			It("should return true", func() {
   580  				newPod := &corev1.Pod{
   581  					ObjectMeta: metav1.ObjectMeta{
   582  						Name:      "baz",
   583  						Namespace: "biz",
   584  						Annotations: map[string]string{
   585  							"booz": "wooz",
   586  							"zooz": "qooz",
   587  						},
   588  					}}
   589  
   590  				oldPod := &corev1.Pod{
   591  					ObjectMeta: metav1.ObjectMeta{
   592  						Name:      "baz",
   593  						Namespace: "biz",
   594  						Annotations: map[string]string{
   595  							"booz": "wooz",
   596  						},
   597  					}}
   598  
   599  				passEvt := event.UpdateEvent{
   600  					ObjectOld: oldPod,
   601  					ObjectNew: newPod,
   602  				}
   603  				Expect(instance.Create(event.CreateEvent{})).To(BeTrue())
   604  				Expect(instance.Delete(event.DeleteEvent{})).To(BeTrue())
   605  				Expect(instance.Generic(event.GenericEvent{})).To(BeTrue())
   606  				Expect(instance.Update(passEvt)).To(BeTrue())
   607  			})
   608  		})
   609  	})
   610  
   611  	// LabelChangedPredicates has almost identical test cases as AnnotationChangedPredicates,
   612  	// so the duplication linter should be muted on both two test suites.
   613  	Describe("When checking a LabelChangedPredicate", func() {
   614  		instance := predicate.LabelChangedPredicate{}
   615  		Context("Where the old object is missing", func() {
   616  			It("should return false", func() {
   617  				newPod := &corev1.Pod{
   618  					ObjectMeta: metav1.ObjectMeta{
   619  						Name:      "baz",
   620  						Namespace: "biz",
   621  						Labels: map[string]string{
   622  							"foo": "bar",
   623  						},
   624  					}}
   625  
   626  				evt := event.UpdateEvent{
   627  					ObjectNew: newPod,
   628  				}
   629  				Expect(instance.Create(event.CreateEvent{})).To(BeTrue())
   630  				Expect(instance.Delete(event.DeleteEvent{})).To(BeTrue())
   631  				Expect(instance.Generic(event.GenericEvent{})).To(BeTrue())
   632  				Expect(instance.Update(evt)).To(BeFalse())
   633  			})
   634  		})
   635  
   636  		Context("Where the new object is missing", func() {
   637  			It("should return false", func() {
   638  				oldPod := &corev1.Pod{
   639  					ObjectMeta: metav1.ObjectMeta{
   640  						Name:      "baz",
   641  						Namespace: "biz",
   642  						Labels: map[string]string{
   643  							"foo": "bar",
   644  						},
   645  					}}
   646  
   647  				evt := event.UpdateEvent{
   648  					ObjectOld: oldPod,
   649  				}
   650  				Expect(instance.Create(event.CreateEvent{})).To(BeTrue())
   651  				Expect(instance.Delete(event.DeleteEvent{})).To(BeTrue())
   652  				Expect(instance.Generic(event.GenericEvent{})).To(BeTrue())
   653  				Expect(instance.Update(evt)).To(BeFalse())
   654  			})
   655  		})
   656  
   657  		Context("Where the labels are empty", func() {
   658  			It("should return false", func() {
   659  				newPod := &corev1.Pod{
   660  					ObjectMeta: metav1.ObjectMeta{
   661  						Name:      "baz",
   662  						Namespace: "biz",
   663  					}}
   664  
   665  				oldPod := &corev1.Pod{
   666  					ObjectMeta: metav1.ObjectMeta{
   667  						Name:      "baz",
   668  						Namespace: "biz",
   669  					}}
   670  
   671  				evt := event.UpdateEvent{
   672  					ObjectOld: oldPod,
   673  					ObjectNew: newPod,
   674  				}
   675  				Expect(instance.Create(event.CreateEvent{})).To(BeTrue())
   676  				Expect(instance.Delete(event.DeleteEvent{})).To(BeTrue())
   677  				Expect(instance.Generic(event.GenericEvent{})).To(BeTrue())
   678  				Expect(instance.Update(evt)).To(BeFalse())
   679  			})
   680  		})
   681  
   682  		Context("Where the labels haven't changed", func() {
   683  			It("should return false", func() {
   684  				newPod := &corev1.Pod{
   685  					ObjectMeta: metav1.ObjectMeta{
   686  						Name:      "baz",
   687  						Namespace: "biz",
   688  						Labels: map[string]string{
   689  							"foo": "bar",
   690  						},
   691  					}}
   692  
   693  				oldPod := &corev1.Pod{
   694  					ObjectMeta: metav1.ObjectMeta{
   695  						Name:      "baz",
   696  						Namespace: "biz",
   697  						Labels: map[string]string{
   698  							"foo": "bar",
   699  						},
   700  					}}
   701  
   702  				evt := event.UpdateEvent{
   703  					ObjectOld: oldPod,
   704  					ObjectNew: newPod,
   705  				}
   706  				Expect(instance.Create(event.CreateEvent{})).To(BeTrue())
   707  				Expect(instance.Delete(event.DeleteEvent{})).To(BeTrue())
   708  				Expect(instance.Generic(event.GenericEvent{})).To(BeTrue())
   709  				Expect(instance.Update(evt)).To(BeFalse())
   710  			})
   711  		})
   712  
   713  		Context("Where a label value has changed", func() {
   714  			It("should return true", func() {
   715  				newPod := &corev1.Pod{
   716  					ObjectMeta: metav1.ObjectMeta{
   717  						Name:      "baz",
   718  						Namespace: "biz",
   719  						Labels: map[string]string{
   720  							"foo": "bar",
   721  						},
   722  					}}
   723  
   724  				oldPod := &corev1.Pod{
   725  					ObjectMeta: metav1.ObjectMeta{
   726  						Name:      "baz",
   727  						Namespace: "biz",
   728  						Labels: map[string]string{
   729  							"foo": "bee",
   730  						},
   731  					}}
   732  
   733  				evt := event.UpdateEvent{
   734  					ObjectOld: oldPod,
   735  					ObjectNew: newPod,
   736  				}
   737  				Expect(instance.Create(event.CreateEvent{})).To(BeTrue())
   738  				Expect(instance.Delete(event.DeleteEvent{})).To(BeTrue())
   739  				Expect(instance.Generic(event.GenericEvent{})).To(BeTrue())
   740  				Expect(instance.Update(evt)).To(BeTrue())
   741  			})
   742  		})
   743  
   744  		Context("Where a label has been added", func() {
   745  			It("should return true", func() {
   746  				newPod := &corev1.Pod{
   747  					ObjectMeta: metav1.ObjectMeta{
   748  						Name:      "baz",
   749  						Namespace: "biz",
   750  						Labels: map[string]string{
   751  							"foo": "bar",
   752  						},
   753  					}}
   754  
   755  				oldPod := &corev1.Pod{
   756  					ObjectMeta: metav1.ObjectMeta{
   757  						Name:      "baz",
   758  						Namespace: "biz",
   759  						Labels: map[string]string{
   760  							"foo": "bar",
   761  							"faa": "bor",
   762  						},
   763  					}}
   764  
   765  				evt := event.UpdateEvent{
   766  					ObjectOld: oldPod,
   767  					ObjectNew: newPod,
   768  				}
   769  				Expect(instance.Create(event.CreateEvent{})).To(BeTrue())
   770  				Expect(instance.Delete(event.DeleteEvent{})).To(BeTrue())
   771  				Expect(instance.Generic(event.GenericEvent{})).To(BeTrue())
   772  				Expect(instance.Update(evt)).To(BeTrue())
   773  			})
   774  		})
   775  
   776  		Context("Where a label has been removed", func() {
   777  			It("should return true", func() {
   778  				newPod := &corev1.Pod{
   779  					ObjectMeta: metav1.ObjectMeta{
   780  						Name:      "baz",
   781  						Namespace: "biz",
   782  						Labels: map[string]string{
   783  							"foo": "bar",
   784  							"faa": "bor",
   785  						},
   786  					}}
   787  
   788  				oldPod := &corev1.Pod{
   789  					ObjectMeta: metav1.ObjectMeta{
   790  						Name:      "baz",
   791  						Namespace: "biz",
   792  						Labels: map[string]string{
   793  							"foo": "bar",
   794  						},
   795  					}}
   796  
   797  				evt := event.UpdateEvent{
   798  					ObjectOld: oldPod,
   799  					ObjectNew: newPod,
   800  				}
   801  				Expect(instance.Create(event.CreateEvent{})).To(BeTrue())
   802  				Expect(instance.Delete(event.DeleteEvent{})).To(BeTrue())
   803  				Expect(instance.Generic(event.GenericEvent{})).To(BeTrue())
   804  				Expect(instance.Update(evt)).To(BeTrue())
   805  			})
   806  		})
   807  	})
   808  
   809  	Context("With a boolean predicate", func() {
   810  		funcs := func(pass bool) predicate.Funcs {
   811  			return predicate.Funcs{
   812  				CreateFunc: func(event.CreateEvent) bool {
   813  					return pass
   814  				},
   815  				DeleteFunc: func(event.DeleteEvent) bool {
   816  					return pass
   817  				},
   818  				UpdateFunc: func(event.UpdateEvent) bool {
   819  					return pass
   820  				},
   821  				GenericFunc: func(event.GenericEvent) bool {
   822  					return pass
   823  				},
   824  			}
   825  		}
   826  		passFuncs := funcs(true)
   827  		failFuncs := funcs(false)
   828  
   829  		Describe("When checking an And predicate", func() {
   830  			It("should return false when one of its predicates returns false", func() {
   831  				a := predicate.And(passFuncs, failFuncs)
   832  				Expect(a.Create(event.CreateEvent{})).To(BeFalse())
   833  				Expect(a.Update(event.UpdateEvent{})).To(BeFalse())
   834  				Expect(a.Delete(event.DeleteEvent{})).To(BeFalse())
   835  				Expect(a.Generic(event.GenericEvent{})).To(BeFalse())
   836  			})
   837  			It("should return true when all of its predicates return true", func() {
   838  				a := predicate.And(passFuncs, passFuncs)
   839  				Expect(a.Create(event.CreateEvent{})).To(BeTrue())
   840  				Expect(a.Update(event.UpdateEvent{})).To(BeTrue())
   841  				Expect(a.Delete(event.DeleteEvent{})).To(BeTrue())
   842  				Expect(a.Generic(event.GenericEvent{})).To(BeTrue())
   843  			})
   844  		})
   845  		Describe("When checking an Or predicate", func() {
   846  			It("should return true when one of its predicates returns true", func() {
   847  				o := predicate.Or(passFuncs, failFuncs)
   848  				Expect(o.Create(event.CreateEvent{})).To(BeTrue())
   849  				Expect(o.Update(event.UpdateEvent{})).To(BeTrue())
   850  				Expect(o.Delete(event.DeleteEvent{})).To(BeTrue())
   851  				Expect(o.Generic(event.GenericEvent{})).To(BeTrue())
   852  			})
   853  			It("should return false when all of its predicates return false", func() {
   854  				o := predicate.Or(failFuncs, failFuncs)
   855  				Expect(o.Create(event.CreateEvent{})).To(BeFalse())
   856  				Expect(o.Update(event.UpdateEvent{})).To(BeFalse())
   857  				Expect(o.Delete(event.DeleteEvent{})).To(BeFalse())
   858  				Expect(o.Generic(event.GenericEvent{})).To(BeFalse())
   859  			})
   860  		})
   861  		Describe("When checking a Not predicate", func() {
   862  			It("should return false when its predicate returns true", func() {
   863  				n := predicate.Not(passFuncs)
   864  				Expect(n.Create(event.CreateEvent{})).To(BeFalse())
   865  				Expect(n.Update(event.UpdateEvent{})).To(BeFalse())
   866  				Expect(n.Delete(event.DeleteEvent{})).To(BeFalse())
   867  				Expect(n.Generic(event.GenericEvent{})).To(BeFalse())
   868  			})
   869  			It("should return true when its predicate returns false", func() {
   870  				n := predicate.Not(failFuncs)
   871  				Expect(n.Create(event.CreateEvent{})).To(BeTrue())
   872  				Expect(n.Update(event.UpdateEvent{})).To(BeTrue())
   873  				Expect(n.Delete(event.DeleteEvent{})).To(BeTrue())
   874  				Expect(n.Generic(event.GenericEvent{})).To(BeTrue())
   875  			})
   876  		})
   877  	})
   878  
   879  	Describe("NewPredicateFuncs with a namespace filter function", func() {
   880  		byNamespaceFilter := func(namespace string) func(object client.Object) bool {
   881  			return func(object client.Object) bool {
   882  				return object.GetNamespace() == namespace
   883  			}
   884  		}
   885  		byNamespaceFuncs := predicate.NewPredicateFuncs(byNamespaceFilter("biz"))
   886  		Context("Where the namespace is matching", func() {
   887  			It("should return true", func() {
   888  				newPod := &corev1.Pod{
   889  					ObjectMeta: metav1.ObjectMeta{
   890  						Name:      "baz",
   891  						Namespace: "biz",
   892  					}}
   893  
   894  				oldPod := &corev1.Pod{
   895  					ObjectMeta: metav1.ObjectMeta{
   896  						Name:      "baz",
   897  						Namespace: "biz",
   898  					}}
   899  				passEvt1 := event.UpdateEvent{ObjectOld: oldPod, ObjectNew: newPod}
   900  				Expect(byNamespaceFuncs.Create(event.CreateEvent{Object: newPod})).To(BeTrue())
   901  				Expect(byNamespaceFuncs.Delete(event.DeleteEvent{Object: oldPod})).To(BeTrue())
   902  				Expect(byNamespaceFuncs.Generic(event.GenericEvent{Object: newPod})).To(BeTrue())
   903  				Expect(byNamespaceFuncs.Update(passEvt1)).To(BeTrue())
   904  			})
   905  		})
   906  
   907  		Context("Where the namespace is not matching", func() {
   908  			It("should return false", func() {
   909  				newPod := &corev1.Pod{
   910  					ObjectMeta: metav1.ObjectMeta{
   911  						Name:      "baz",
   912  						Namespace: "bizz",
   913  					}}
   914  
   915  				oldPod := &corev1.Pod{
   916  					ObjectMeta: metav1.ObjectMeta{
   917  						Name:      "baz",
   918  						Namespace: "biz",
   919  					}}
   920  				failEvt1 := event.UpdateEvent{ObjectOld: oldPod, ObjectNew: newPod}
   921  				Expect(byNamespaceFuncs.Create(event.CreateEvent{Object: newPod})).To(BeFalse())
   922  				Expect(byNamespaceFuncs.Delete(event.DeleteEvent{Object: newPod})).To(BeFalse())
   923  				Expect(byNamespaceFuncs.Generic(event.GenericEvent{Object: newPod})).To(BeFalse())
   924  				Expect(byNamespaceFuncs.Update(failEvt1)).To(BeFalse())
   925  			})
   926  		})
   927  	})
   928  
   929  	Describe("When checking a LabelSelectorPredicate", func() {
   930  		instance, err := predicate.LabelSelectorPredicate(metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}})
   931  		if err != nil {
   932  			Fail("Improper Label Selector passed during predicate instantiation.")
   933  		}
   934  
   935  		Context("When the Selector does not match the event labels", func() {
   936  			It("should return false", func() {
   937  				failMatch := &corev1.Pod{}
   938  				Expect(instance.Create(event.CreateEvent{Object: failMatch})).To(BeFalse())
   939  				Expect(instance.Delete(event.DeleteEvent{Object: failMatch})).To(BeFalse())
   940  				Expect(instance.Generic(event.GenericEvent{Object: failMatch})).To(BeFalse())
   941  				Expect(instance.Update(event.UpdateEvent{ObjectNew: failMatch})).To(BeFalse())
   942  			})
   943  		})
   944  
   945  		Context("When the Selector matches the event labels", func() {
   946  			It("should return true", func() {
   947  				successMatch := &corev1.Pod{
   948  					ObjectMeta: metav1.ObjectMeta{
   949  						Labels: map[string]string{"foo": "bar"},
   950  					},
   951  				}
   952  				Expect(instance.Create(event.CreateEvent{Object: successMatch})).To(BeTrue())
   953  				Expect(instance.Delete(event.DeleteEvent{Object: successMatch})).To(BeTrue())
   954  				Expect(instance.Generic(event.GenericEvent{Object: successMatch})).To(BeTrue())
   955  				Expect(instance.Update(event.UpdateEvent{ObjectNew: successMatch})).To(BeTrue())
   956  			})
   957  		})
   958  	})
   959  })
   960  

View as plain text