istio.io/istio@v0.0.0-20240520182934-d79c90f27776/operator/pkg/helmreconciler/prune_test.go (about) 1 // Copyright Istio Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package helmreconciler 16 17 import ( 18 _ "embed" 19 "sync" 20 "testing" 21 22 v1 "k8s.io/api/core/v1" 23 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 24 "k8s.io/apimachinery/pkg/runtime/schema" 25 "sigs.k8s.io/controller-runtime/pkg/client/fake" 26 "sigs.k8s.io/yaml" 27 28 "istio.io/api/label" 29 "istio.io/istio/operator/pkg/apis/istio/v1alpha1" 30 "istio.io/istio/operator/pkg/name" 31 "istio.io/istio/operator/pkg/object" 32 "istio.io/istio/operator/pkg/util/clog" 33 "istio.io/istio/operator/pkg/util/progress" 34 "istio.io/istio/pkg/kube" 35 "istio.io/istio/pkg/test/util/assert" 36 ) 37 38 var ( 39 //go:embed testdata/iop-test-gw-1.yaml 40 iopTestGwData1 []byte 41 //go:embed testdata/iop-test-gw-2.yaml 42 iopTestGwData2 []byte 43 ) 44 45 func applyResourcesIntoCluster(t *testing.T, h *HelmReconciler, manifestMap name.ManifestMap) { 46 for cn, ms := range manifestMap.Consolidated() { 47 objects, err := object.ParseK8sObjectsFromYAMLManifest(ms) 48 if err != nil { 49 t.Fatalf("failed parse k8s objects from yaml: %v", err) 50 } 51 for _, obj := range objects { 52 obju := obj.UnstructuredObject() 53 if err := h.applyLabelsAndAnnotations(obju, cn); err != nil { 54 t.Errorf("failed to apply label and annotations: %v", err) 55 } 56 if err := h.ApplyObject(obj.UnstructuredObject()); err != nil { 57 t.Errorf("HelmReconciler.ApplyObject() error = %v", err) 58 } 59 } 60 } 61 } 62 63 func TestHelmReconciler_GetPrunedResources(t *testing.T) { 64 t.Run("get gateway pruned resources", func(t *testing.T) { 65 var h1 *HelmReconciler 66 cl := fake.NewClientBuilder().WithInterceptorFuncs(interceptorFunc).Build() 67 // init two custom gateways with revision 68 gateways := [][]byte{iopTestGwData1, iopTestGwData2} 69 for i, data := range gateways { 70 iop := &v1alpha1.IstioOperator{} 71 err := yaml.UnmarshalStrict(data, iop) 72 assert.NoError(t, err) 73 h := &HelmReconciler{ 74 client: cl, 75 kubeClient: kube.NewFakeClientWithVersion("24"), 76 opts: &Options{ 77 ProgressLog: progress.NewLog(), 78 Log: clog.NewDefaultLogger(), 79 }, 80 iop: iop, 81 countLock: &sync.Mutex{}, 82 prunedKindSet: map[schema.GroupKind]struct{}{}, 83 } 84 if i == 0 { 85 h1 = h 86 } 87 manifestMap, err := h.RenderCharts() 88 if err != nil { 89 t.Fatalf("failed to render manifest: %v", err) 90 } 91 applyResourcesIntoCluster(t, h, manifestMap) 92 } 93 // delete one iop: iop-test-gw-1, get its pruned resources 94 componentName := string(name.IngressComponentName) 95 resources, err := h1.GetPrunedResources(h1.iop.Spec.Revision, false, componentName) 96 assert.NoError(t, err) 97 assert.Equal(t, true, len(resources) > 0) 98 // check resources, only associated with iop-test-gw-1 istiooperator CR, 99 // otherwise, the resources of all IngressGateways components will be deleted. 100 // See https://github.com/istio/istio/issues/40577 for more details. 101 for _, uslist := range resources { 102 for _, u := range uslist.Items { 103 assert.Equal(t, h1.iop.Spec.Revision, u.GetLabels()[label.IoIstioRev.Name]) 104 assert.Equal(t, componentName, u.GetLabels()[IstioComponentLabelStr]) 105 assert.Equal(t, h1.iop.GetName(), u.GetLabels()[OwningResourceName]) 106 assert.Equal(t, h1.iop.GetNamespace(), u.GetLabels()[OwningResourceNamespace]) 107 } 108 } 109 }) 110 } 111 112 func TestPilotExist(t *testing.T) { 113 t.Run("exist", func(t *testing.T) { 114 cl := fake.NewClientBuilder().WithInterceptorFuncs(interceptorFunc).Build() 115 iop := &v1alpha1.IstioOperator{} 116 h := &HelmReconciler{ 117 client: cl, 118 kubeClient: kube.NewFakeClientWithVersion("24"), 119 opts: &Options{ 120 ProgressLog: progress.NewLog(), 121 Log: clog.NewDefaultLogger(), 122 }, 123 iop: iop, 124 countLock: &sync.Mutex{}, 125 prunedKindSet: map[schema.GroupKind]struct{}{}, 126 } 127 mockClient := kube.NewFakeClient(&v1.Pod{ 128 ObjectMeta: metav1.ObjectMeta{ 129 Name: "istiod", 130 Namespace: "istio-system", 131 Labels: map[string]string{"app": "istiod"}, 132 }, 133 }) 134 135 if exist, err := h.pilotExists(mockClient, "istio-system"); err != nil { 136 t.Fatalf("HelmReconciler.pilotExists error = %v", err) 137 } else if !exist { 138 t.Errorf("HelmReconciler.pilotExists fail") 139 } 140 }) 141 142 t.Run("non-exist", func(t *testing.T) { 143 cl := fake.NewClientBuilder().WithInterceptorFuncs(interceptorFunc).Build() 144 iop := &v1alpha1.IstioOperator{} 145 kc := kube.NewFakeClientWithVersion("24") 146 h := &HelmReconciler{ 147 client: cl, 148 kubeClient: kc, 149 opts: &Options{ 150 ProgressLog: progress.NewLog(), 151 Log: clog.NewDefaultLogger(), 152 }, 153 iop: iop, 154 countLock: &sync.Mutex{}, 155 prunedKindSet: map[schema.GroupKind]struct{}{}, 156 } 157 if exist, err := h.pilotExists(kc, "istio-system"); err != nil { 158 t.Fatalf("HelmReconciler.pilotExists error = %v", err) 159 } else if exist { 160 t.Errorf("HelmReconciler.pilotExists fail") 161 } 162 }) 163 }