github.com/zhyoulun/cilium@v1.6.12/test/k8sT/assertionHelpers.go (about) 1 // Copyright 2018-2019 Authors of Cilium 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 k8sTest 16 17 import ( 18 "context" 19 "fmt" 20 "time" 21 22 . "github.com/cilium/cilium/test/ginkgo-ext" 23 "github.com/cilium/cilium/test/helpers" 24 . "github.com/onsi/gomega" 25 "github.com/sirupsen/logrus" 26 ) 27 28 var longTimeout = 10 * time.Minute 29 30 // ExpectKubeDNSReady is a wrapper around helpers/WaitKubeDNS. It asserts that 31 // the error returned by that function is nil. 32 func ExpectKubeDNSReady(vm *helpers.Kubectl) { 33 err := vm.WaitKubeDNS() 34 ExpectWithOffset(1, err).Should(BeNil(), "kube-dns was not able to get into ready state") 35 36 err = vm.KubeDNSPreFlightCheck() 37 ExpectWithOffset(1, err).Should(BeNil(), "kube-dns service not ready") 38 } 39 40 // ExpectCiliumReady is a wrapper around helpers/WaitForPods. It asserts that 41 // the error returned by that function is nil. 42 func ExpectCiliumReady(vm *helpers.Kubectl) { 43 err := vm.WaitforPods(helpers.KubeSystemNamespace, "-l k8s-app=cilium", longTimeout) 44 ExpectWithOffset(1, err).Should(BeNil(), "cilium was not able to get into ready state") 45 46 err = vm.CiliumPreFlightCheck() 47 ExpectWithOffset(1, err).Should(BeNil(), "cilium pre-flight checks failed") 48 } 49 50 // ExpectCiliumOperatorReady is a wrapper around helpers/WaitForPods. It asserts that 51 // the error returned by that function is nil. 52 func ExpectCiliumOperatorReady(vm *helpers.Kubectl) { 53 err := vm.WaitforPods(helpers.KubeSystemNamespace, "-l name=cilium-operator", longTimeout) 54 ExpectWithOffset(1, err).Should(BeNil(), "Cilium operator was not able to get into ready state") 55 } 56 57 // ExpectCiliumRunning is a wrapper around helpers/WaitForNPods. It 58 // asserts the cilium pods are running on all nodes (but not yet ready!). 59 func ExpectCiliumRunning(vm *helpers.Kubectl) { 60 err := vm.WaitforNPodsRunning(helpers.KubeSystemNamespace, "-l k8s-app=cilium", vm.GetNumNodes(), longTimeout) 61 ExpectWithOffset(1, err).Should(BeNil(), "cilium was not able to get into ready state") 62 63 } 64 65 // ExpectAllPodsTerminated is a wrapper around helpers/WaitCleanAllTerminatingPods. 66 // It asserts that the error returned by that function is nil. 67 func ExpectAllPodsTerminated(vm *helpers.Kubectl) { 68 err := vm.WaitCleanAllTerminatingPods(helpers.HelperTimeout) 69 ExpectWithOffset(1, err).To(BeNil(), "terminating containers are not deleted after timeout") 70 } 71 72 // ExpectETCDOperatorReady is a wrapper around helpers/WaitForNPods. It asserts 73 // the error returned by that function is nil. 74 func ExpectETCDOperatorReady(vm *helpers.Kubectl) { 75 // Etcd operator creates 5 nodes (1 cilium-etcd-operator + 1 etcd-operator + 3 etcd nodes), 76 // the new pods are added when the previous is ready, 77 // so we need to wait until 5 pods are in ready state. 78 // This is to avoid cases where a few pods are ready, but the 79 // new one is not created yet. 80 By("Waiting for all etcd-operator pods to be ready") 81 82 err := vm.WaitforNPods(helpers.KubeSystemNamespace, "-l io.cilium/app=etcd-operator", 5, longTimeout) 83 warningMessage := "" 84 if err != nil { 85 res := vm.Exec(fmt.Sprintf( 86 "%s -n %s get pods -l io.cilium/app=etcd-operator", 87 helpers.KubectlCmd, helpers.KubeSystemNamespace)) 88 warningMessage = res.Output().String() 89 } 90 Expect(err).To(BeNil(), "etcd-operator is not ready after timeout, pods status:\n %s", warningMessage) 91 } 92 93 // ExpectCiliumPreFlightInstallReady is a wrapper around helpers/WaitForNPods. 94 // It asserts the error returned by that function is nil. 95 func ExpectCiliumPreFlightInstallReady(vm *helpers.Kubectl) { 96 By("Waiting for all cilium pre-flight pods to be ready") 97 98 err := vm.WaitforPods(helpers.KubeSystemNamespace, "-l k8s-app=cilium-pre-flight-check", longTimeout) 99 warningMessage := "" 100 if err != nil { 101 res := vm.Exec(fmt.Sprintf( 102 "%s -n %s get pods -l k8s-app=cilium-pre-flight-check", 103 helpers.KubectlCmd, helpers.KubeSystemNamespace)) 104 warningMessage = res.Output().String() 105 } 106 Expect(err).To(BeNil(), "cilium pre-flight check is not ready after timeout, pods status:\n %s", warningMessage) 107 } 108 109 // DeployCiliumAndDNS deploys DNS and cilium into the kubernetes cluster 110 func DeployCiliumAndDNS(vm *helpers.Kubectl) { 111 DeployCiliumOptionsAndDNS(vm, []string{}) 112 } 113 114 // DeployCiliumOptionsAndDNS deploys DNS and cilium with options into the kubernetes cluster 115 func DeployCiliumOptionsAndDNS(vm *helpers.Kubectl, options []string) { 116 By("Installing Cilium") 117 err := vm.CiliumInstall(options) 118 Expect(err).To(BeNil(), "Cilium cannot be installed") 119 120 ExpectCiliumRunning(vm) 121 122 By("Installing DNS Deployment") 123 _ = vm.ApplyDefault(helpers.DNSDeployment()) 124 125 switch helpers.GetCurrentIntegration() { 126 case helpers.CIIntegrationFlannel: 127 By("Installing Flannel") 128 vm.ApplyDefault(helpers.GetFilePath("../examples/kubernetes/addons/flannel/flannel.yaml")) 129 default: 130 } 131 132 ExpectCiliumReady(vm) 133 ExpectCiliumOperatorReady(vm) 134 ExpectKubeDNSReady(vm) 135 } 136 137 // SkipIfFlannel will skip the test if it's running over Flannel datapath mode. 138 func SkipIfFlannel() { 139 if helpers.GetCurrentIntegration() == helpers.CIIntegrationFlannel { 140 Skip(fmt.Sprintf( 141 "This feature is not supported in Cilium %q mode. Skipping test.", 142 helpers.CIIntegrationFlannel)) 143 } 144 } 145 146 func deleteCiliumDS(kubectl *helpers.Kubectl) { 147 // Do not assert on success in AfterEach intentionally to avoid 148 // incomplete teardown. 149 _ = kubectl.DeleteResource("ds", fmt.Sprintf("-n %s cilium", helpers.KubeSystemNamespace)) 150 Expect(waitToDeleteCilium(kubectl, logger)).To(BeNil(), "timed out deleting Cilium pods") 151 } 152 153 func deleteETCDOperator(kubectl *helpers.Kubectl) { 154 // Do not assert on success in AfterEach intentionally to avoid 155 // incomplete teardown. 156 _ = kubectl.DeleteResource("deploy", fmt.Sprintf("-n %s -l io.cilium/app=etcd-operator", helpers.KubeSystemNamespace)) 157 _ = kubectl.DeleteResource("pod", fmt.Sprintf("-n %s -l io.cilium/app=etcd-operator", helpers.KubeSystemNamespace)) 158 _ = kubectl.WaitCleanAllTerminatingPods(helpers.HelperTimeout) 159 } 160 161 func waitToDeleteCilium(kubectl *helpers.Kubectl, logger *logrus.Entry) error { 162 var ( 163 pods []string 164 err error 165 ) 166 167 ctx, cancel := context.WithTimeout(context.Background(), helpers.HelperTimeout) 168 defer cancel() 169 170 status := 1 171 for status > 0 { 172 173 select { 174 case <-ctx.Done(): 175 return fmt.Errorf("timed out waiting to delete Cilium: pods still remaining: %s", pods) 176 default: 177 } 178 179 pods, err = kubectl.GetCiliumPodsContext(ctx, helpers.KubeSystemNamespace) 180 status := len(pods) 181 logger.Infof("Cilium pods terminating '%d' err='%v' pods='%v'", status, err, pods) 182 if status == 0 { 183 return nil 184 } 185 time.Sleep(1 * time.Second) 186 } 187 return nil 188 }