github.com/cilium/cilium@v1.16.2/operator/pkg/ciliumendpointslice/reconciler_test.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Cilium 3 4 package ciliumendpointslice 5 6 import ( 7 "context" 8 "testing" 9 10 "github.com/cilium/hive/cell" 11 "github.com/cilium/hive/hivetest" 12 "github.com/stretchr/testify/assert" 13 "k8s.io/apimachinery/pkg/runtime" 14 k8sTesting "k8s.io/client-go/testing" 15 16 "github.com/cilium/cilium/operator/k8s" 17 tu "github.com/cilium/cilium/operator/pkg/ciliumendpointslice/testutils" 18 "github.com/cilium/cilium/pkg/hive" 19 cilium_v2 "github.com/cilium/cilium/pkg/k8s/apis/cilium.io/v2" 20 cilium_v2a1 "github.com/cilium/cilium/pkg/k8s/apis/cilium.io/v2alpha1" 21 k8sClient "github.com/cilium/cilium/pkg/k8s/client" 22 "github.com/cilium/cilium/pkg/k8s/resource" 23 "github.com/cilium/cilium/pkg/logging" 24 "github.com/cilium/cilium/pkg/logging/logfields" 25 "github.com/cilium/cilium/pkg/metrics" 26 ) 27 28 var log = logging.DefaultLogger.WithField(logfields.LogSubsys, "ces-controller") 29 30 func TestReconcileCreate(t *testing.T) { 31 var r *reconciler 32 var fakeClient k8sClient.FakeClientset 33 m := newCESManagerFcfs(2, log).(*cesManagerFcfs) 34 var ciliumEndpoint resource.Resource[*cilium_v2.CiliumEndpoint] 35 var ciliumEndpointSlice resource.Resource[*cilium_v2a1.CiliumEndpointSlice] 36 var cesMetrics *Metrics 37 hive := hive.New( 38 k8sClient.FakeClientCell, 39 k8s.ResourcesCell, 40 metrics.Metric(NewMetrics), 41 cell.Invoke(func( 42 c *k8sClient.FakeClientset, 43 cep resource.Resource[*cilium_v2.CiliumEndpoint], 44 ces resource.Resource[*cilium_v2a1.CiliumEndpointSlice], 45 metrics *Metrics, 46 ) error { 47 fakeClient = *c 48 ciliumEndpoint = cep 49 ciliumEndpointSlice = ces 50 cesMetrics = metrics 51 return nil 52 }), 53 ) 54 tlog := hivetest.Logger(t) 55 hive.Start(tlog, context.Background()) 56 r = newReconciler(context.Background(), fakeClient.CiliumFakeClientset.CiliumV2alpha1(), m, log, ciliumEndpoint, ciliumEndpointSlice, cesMetrics) 57 cepStore, _ := ciliumEndpoint.Store(context.Background()) 58 59 var createdSlice *cilium_v2a1.CiliumEndpointSlice 60 fakeClient.CiliumFakeClientset.PrependReactor("create", "*", func(action k8sTesting.Action) (handled bool, ret runtime.Object, err error) { 61 pa := action.(k8sTesting.CreateAction) 62 createdSlice = pa.GetObject().(*cilium_v2a1.CiliumEndpointSlice) 63 return true, nil, nil 64 }) 65 66 cep1 := tu.CreateStoreEndpoint("cep1", "ns", 1) 67 cepStore.CacheStore().Add(cep1) 68 cep2 := tu.CreateStoreEndpoint("cep2", "ns", 2) 69 cepStore.CacheStore().Add(cep2) 70 cep3 := tu.CreateStoreEndpoint("cep3", "ns", 2) 71 cepStore.CacheStore().Add(cep3) 72 m.mapping.insertCES(NewCESName("ces1"), "ns") 73 m.mapping.insertCES(NewCESName("ces2"), "ns") 74 m.mapping.insertCEP(NewCEPName("cep1", "ns"), NewCESName("ces1")) 75 m.mapping.insertCEP(NewCEPName("cep2", "ns"), NewCESName("ces1")) 76 m.mapping.insertCEP(NewCEPName("cep3", "ns"), NewCESName("ces2")) 77 r.reconcileCES(NewCESName("ces1")) 78 79 assert.Equal(t, "ces1", createdSlice.Name) 80 assert.Equal(t, 2, len(createdSlice.Endpoints)) 81 assert.Equal(t, "ns", createdSlice.Namespace) 82 eps := []string{createdSlice.Endpoints[0].Name, createdSlice.Endpoints[1].Name} 83 assert.Contains(t, eps, "cep1") 84 assert.Contains(t, eps, "cep2") 85 86 hive.Stop(tlog, context.Background()) 87 } 88 89 func TestReconcileUpdate(t *testing.T) { 90 var r *reconciler 91 var fakeClient k8sClient.FakeClientset 92 m := newCESManagerFcfs(2, log).(*cesManagerFcfs) 93 var ciliumEndpoint resource.Resource[*cilium_v2.CiliumEndpoint] 94 var ciliumEndpointSlice resource.Resource[*cilium_v2a1.CiliumEndpointSlice] 95 var cesMetrics *Metrics 96 hive := hive.New( 97 k8sClient.FakeClientCell, 98 k8s.ResourcesCell, 99 metrics.Metric(NewMetrics), 100 cell.Invoke(func( 101 c *k8sClient.FakeClientset, 102 cep resource.Resource[*cilium_v2.CiliumEndpoint], 103 ces resource.Resource[*cilium_v2a1.CiliumEndpointSlice], 104 metrics *Metrics, 105 ) error { 106 fakeClient = *c 107 ciliumEndpoint = cep 108 ciliumEndpointSlice = ces 109 cesMetrics = metrics 110 return nil 111 }), 112 ) 113 114 tlog := hivetest.Logger(t) 115 hive.Start(tlog, context.Background()) 116 r = newReconciler(context.Background(), fakeClient.CiliumFakeClientset.CiliumV2alpha1(), m, log, ciliumEndpoint, ciliumEndpointSlice, cesMetrics) 117 cepStore, _ := ciliumEndpoint.Store(context.Background()) 118 cesStore, _ := ciliumEndpointSlice.Store(context.Background()) 119 120 var updatedSlice *cilium_v2a1.CiliumEndpointSlice 121 fakeClient.CiliumFakeClientset.PrependReactor("update", "*", func(action k8sTesting.Action) (handled bool, ret runtime.Object, err error) { 122 pa := action.(k8sTesting.UpdateAction) 123 updatedSlice = pa.GetObject().(*cilium_v2a1.CiliumEndpointSlice) 124 return true, nil, nil 125 }) 126 127 cep1 := tu.CreateStoreEndpoint("cep1", "ns", 1) 128 cepStore.CacheStore().Add(cep1) 129 cep2 := tu.CreateStoreEndpoint("cep2", "ns", 2) 130 cepStore.CacheStore().Add(cep2) 131 cep3 := tu.CreateStoreEndpoint("cep3", "ns", 2) 132 cepStore.CacheStore().Add(cep3) 133 ces1 := tu.CreateStoreEndpointSlice("ces1", "ns", []cilium_v2a1.CoreCiliumEndpoint{tu.CreateManagerEndpoint("cep1", 1), tu.CreateManagerEndpoint("cep3", 2)}) 134 cesStore.CacheStore().Add(ces1) 135 m.mapping.insertCES(NewCESName("ces1"), "ns") 136 m.mapping.insertCES(NewCESName("ces2"), "ns") 137 m.mapping.insertCEP(NewCEPName("cep1", "ns"), NewCESName("ces1")) 138 m.mapping.insertCEP(NewCEPName("cep2", "ns"), NewCESName("ces1")) 139 m.mapping.insertCEP(NewCEPName("cep3", "ns"), NewCESName("ces2")) 140 // ces1 contains cep1 and cep3, but it's mapped to cep1 and cep2 141 // so it's expected that after update it would contain cep1 and cep2 142 r.reconcileCES(NewCESName("ces1")) 143 144 assert.Equal(t, "ces1", updatedSlice.Name) 145 assert.Equal(t, 2, len(updatedSlice.Endpoints)) 146 assert.Equal(t, "ns", updatedSlice.Namespace) 147 eps := []string{updatedSlice.Endpoints[0].Name, updatedSlice.Endpoints[1].Name} 148 assert.Contains(t, eps, "cep1") 149 assert.Contains(t, eps, "cep2") 150 151 hive.Stop(tlog, context.Background()) 152 } 153 154 func TestReconcileDelete(t *testing.T) { 155 var r *reconciler 156 var fakeClient k8sClient.FakeClientset 157 m := newCESManagerFcfs(2, log).(*cesManagerFcfs) 158 var ciliumEndpoint resource.Resource[*cilium_v2.CiliumEndpoint] 159 var ciliumEndpointSlice resource.Resource[*cilium_v2a1.CiliumEndpointSlice] 160 var cesMetrics *Metrics 161 hive := hive.New( 162 k8sClient.FakeClientCell, 163 k8s.ResourcesCell, 164 metrics.Metric(NewMetrics), 165 cell.Invoke(func( 166 c *k8sClient.FakeClientset, 167 cep resource.Resource[*cilium_v2.CiliumEndpoint], 168 ces resource.Resource[*cilium_v2a1.CiliumEndpointSlice], 169 metrics *Metrics, 170 ) error { 171 fakeClient = *c 172 ciliumEndpoint = cep 173 ciliumEndpointSlice = ces 174 cesMetrics = metrics 175 return nil 176 }), 177 ) 178 179 tlog := hivetest.Logger(t) 180 hive.Start(tlog, context.Background()) 181 r = newReconciler(context.Background(), fakeClient.CiliumFakeClientset.CiliumV2alpha1(), m, log, ciliumEndpoint, ciliumEndpointSlice, cesMetrics) 182 cepStore, _ := ciliumEndpoint.Store(context.Background()) 183 cesStore, _ := ciliumEndpointSlice.Store(context.Background()) 184 185 var deletedSlice string 186 fakeClient.CiliumFakeClientset.PrependReactor("delete", "*", func(action k8sTesting.Action) (handled bool, ret runtime.Object, err error) { 187 pa := action.(k8sTesting.DeleteAction) 188 deletedSlice = pa.GetName() 189 return true, nil, nil 190 }) 191 192 cep1 := tu.CreateStoreEndpoint("cep1", "ns", 1) 193 cepStore.CacheStore().Add(cep1) 194 cep2 := tu.CreateStoreEndpoint("cep2", "ns", 2) 195 cepStore.CacheStore().Add(cep2) 196 cep3 := tu.CreateStoreEndpoint("cep3", "ns", 2) 197 cepStore.CacheStore().Add(cep3) 198 ces1 := tu.CreateStoreEndpointSlice("ces1", "ns", []cilium_v2a1.CoreCiliumEndpoint{tu.CreateManagerEndpoint("cep1", 1), tu.CreateManagerEndpoint("cep3", 2)}) 199 cesStore.CacheStore().Add(ces1) 200 m.mapping.insertCES(NewCESName("ces1"), "ns") 201 m.mapping.insertCES(NewCESName("ces2"), "ns") 202 m.mapping.insertCEP(NewCEPName("cep1", "ns"), NewCESName("ces2")) 203 m.mapping.insertCEP(NewCEPName("cep2", "ns"), NewCESName("ces2")) 204 m.mapping.insertCEP(NewCEPName("cep3", "ns"), NewCESName("ces2")) 205 // ces1 contains cep1 and cep3, but it's mapped to nothing so it should be deleted 206 r.reconcileCES(NewCESName("ces1")) 207 208 assert.Equal(t, "ces1", deletedSlice) 209 210 hive.Stop(tlog, context.Background()) 211 } 212 213 func TestReconcileNoop(t *testing.T) { 214 var r *reconciler 215 var fakeClient k8sClient.FakeClientset 216 m := newCESManagerFcfs(2, log).(*cesManagerFcfs) 217 var ciliumEndpoint resource.Resource[*cilium_v2.CiliumEndpoint] 218 var ciliumEndpointSlice resource.Resource[*cilium_v2a1.CiliumEndpointSlice] 219 var cesMetrics *Metrics 220 hive := hive.New( 221 k8sClient.FakeClientCell, 222 k8s.ResourcesCell, 223 metrics.Metric(NewMetrics), 224 cell.Invoke(func( 225 c *k8sClient.FakeClientset, 226 cep resource.Resource[*cilium_v2.CiliumEndpoint], 227 ces resource.Resource[*cilium_v2a1.CiliumEndpointSlice], 228 metrics *Metrics, 229 ) error { 230 fakeClient = *c 231 ciliumEndpoint = cep 232 ciliumEndpointSlice = ces 233 cesMetrics = metrics 234 return nil 235 }), 236 ) 237 tlog := hivetest.Logger(t) 238 hive.Start(tlog, context.Background()) 239 r = newReconciler(context.Background(), fakeClient.CiliumFakeClientset.CiliumV2alpha1(), m, log, ciliumEndpoint, ciliumEndpointSlice, cesMetrics) 240 cepStore, _ := ciliumEndpoint.Store(context.Background()) 241 242 noRequest := true 243 fakeClient.CiliumFakeClientset.PrependReactor("*", "*", func(action k8sTesting.Action) (handled bool, ret runtime.Object, err error) { 244 noRequest = false 245 return true, nil, nil 246 }) 247 248 cep1 := tu.CreateStoreEndpoint("cep1", "ns", 1) 249 cepStore.CacheStore().Add(cep1) 250 cep2 := tu.CreateStoreEndpoint("cep2", "ns", 2) 251 cepStore.CacheStore().Add(cep2) 252 cep3 := tu.CreateStoreEndpoint("cep3", "ns", 2) 253 cepStore.CacheStore().Add(cep3) 254 m.mapping.insertCES(NewCESName("ces1"), "ns") 255 m.mapping.insertCES(NewCESName("ces2"), "ns") 256 m.mapping.insertCEP(NewCEPName("cep1", "ns"), NewCESName("ces2")) 257 m.mapping.insertCEP(NewCEPName("cep2", "ns"), NewCESName("ces2")) 258 m.mapping.insertCEP(NewCEPName("cep3", "ns"), NewCESName("ces2")) 259 // ces1 contains cep1 and cep3, but it's mapped to nothing so it should be deleted 260 r.reconcileCES(NewCESName("ces1")) 261 262 assert.Equal(t, true, noRequest) 263 264 hive.Stop(tlog, context.Background()) 265 }