github.com/midokura/kubeedge@v1.2.0-mido.0/tests/e2e/utils/pod.go (about) 1 /* 2 Copyright 2019 The KubeEdge 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 utils 18 19 import ( 20 "encoding/json" 21 "io/ioutil" 22 "net/http" 23 "strings" 24 "time" 25 26 . "github.com/onsi/gomega" 27 v1 "k8s.io/api/core/v1" 28 "k8s.io/apimachinery/pkg/fields" 29 "k8s.io/client-go/kubernetes" 30 "k8s.io/client-go/tools/cache" 31 "k8s.io/client-go/tools/clientcmd" 32 ) 33 34 const ( 35 podLabelSelector = "?fieldSelector=spec.nodeName=" 36 ) 37 38 //GetPods function to get the pods from Edged 39 func GetPods(apiserver, label string) (v1.PodList, error) { 40 var pods v1.PodList 41 var resp *http.Response 42 var err error 43 44 if len(label) > 0 { 45 err, resp = SendHttpRequest(http.MethodGet, apiserver+podLabelSelector+label) 46 } else { 47 err, resp = SendHttpRequest(http.MethodGet, apiserver) 48 } 49 if err != nil { 50 Fatalf("Frame HTTP request failed: %v", err) 51 return pods, nil 52 } 53 defer resp.Body.Close() 54 contents, err := ioutil.ReadAll(resp.Body) 55 if err != nil { 56 Fatalf("HTTP Response reading has failed: %v", err) 57 return pods, nil 58 } 59 err = json.Unmarshal(contents, &pods) 60 if err != nil { 61 Fatalf("Unmarshal HTTP Response has failed: %v", err) 62 return pods, nil 63 } 64 return pods, nil 65 } 66 67 //GetPodState function to get the pod status and response code 68 func GetPodState(apiserver string) (string, int) { 69 var pod v1.Pod 70 71 err, resp := SendHttpRequest(http.MethodGet, apiserver) 72 if err != nil { 73 Fatalf("GetPodState :SenHttpRequest failed: %v", err) 74 } 75 defer resp.Body.Close() 76 77 if resp.StatusCode != http.StatusNotFound { 78 contents, err := ioutil.ReadAll(resp.Body) 79 if err != nil { 80 Fatalf("HTTP Response reading has failed: %v", err) 81 } 82 err = json.Unmarshal(contents, &pod) 83 if err != nil { 84 Fatalf("Unmarshal HTTP Response has failed: %v", err) 85 } 86 return string(pod.Status.Phase), resp.StatusCode 87 } 88 89 return "", resp.StatusCode 90 } 91 92 //DeletePods function to get the pod status and response code 93 func DeletePods(apiserver string) (string, int) { 94 var pod v1.Pod 95 err, resp := SendHttpRequest(http.MethodDelete, apiserver) 96 if err != nil { 97 Fatalf("GetPodState :SenHttpRequest failed: %v", err) 98 } 99 defer resp.Body.Close() 100 101 if resp.StatusCode != http.StatusNotFound { 102 contents, err := ioutil.ReadAll(resp.Body) 103 if err != nil { 104 Fatalf("HTTP Response reading has failed: %v", err) 105 } 106 err = json.Unmarshal(contents, &pod) 107 if err != nil { 108 Fatalf("Unmarshal HTTP Response has failed: %v", err) 109 } 110 return string(pod.Status.Phase), resp.StatusCode 111 } 112 113 return "", resp.StatusCode 114 } 115 116 //CheckPodRunningState function to check the Pod state 117 func CheckPodRunningState(apiserver string, podlist v1.PodList) { 118 Eventually(func() int { 119 var count int 120 for _, pod := range podlist.Items { 121 state, _ := GetPodState(apiserver + "/" + pod.Name) 122 Infof("PodName: %s PodStatus: %s", pod.Name, state) 123 if state == "Running" { 124 count++ 125 } 126 } 127 return count 128 }, "600s", "2s").Should(Equal(len(podlist.Items)), "Application deployment is Unsuccessfull, Pod has not come to Running State") 129 130 } 131 132 //CheckPodDeleteState function to check the Pod state 133 func CheckPodDeleteState(apiserver string, podlist v1.PodList) { 134 var count int 135 //skip the edgecore/cloudcore deployment pods and count only application pods deployed on KubeEdge edgen node 136 for _, pod := range podlist.Items { 137 if strings.Contains(pod.Name, "deployment-") { 138 count++ 139 } 140 } 141 podCount := len(podlist.Items) - count 142 Eventually(func() int { 143 var count int 144 for _, pod := range podlist.Items { 145 status, statusCode := GetPodState(apiserver + "/" + pod.Name) 146 Infof("PodName: %s status: %s StatusCode: %d", pod.Name, status, statusCode) 147 if statusCode == 404 { 148 count++ 149 } 150 } 151 return count 152 }, "600s", "4s").Should(Equal(podCount), "Delete Application deployment is Unsuccessfull, Pods are not deleted within the time") 153 154 } 155 156 //CheckDeploymentPodDeleteState function to check the Pod state 157 func CheckDeploymentPodDeleteState(apiserver string, podlist v1.PodList) { 158 var count int 159 //count the edgecore/cloudcore deployment pods and count only application pods deployed on KubeEdge edgen node 160 for _, pod := range podlist.Items { 161 if strings.Contains(pod.Name, "deployment-") { 162 count++ 163 } 164 } 165 //podCount := len(podlist.Items) - count 166 Eventually(func() int { 167 var count int 168 for _, pod := range podlist.Items { 169 status, statusCode := GetPodState(apiserver + "/" + pod.Name) 170 Infof("PodName: %s status: %s StatusCode: %d", pod.Name, status, statusCode) 171 if statusCode == 404 { 172 count++ 173 } 174 } 175 return count 176 }, "240s", "4s").Should(Equal(count), "Delete Application deployment is Unsuccessfull, Pods are not deleted within the time") 177 178 } 179 180 // NewKubeClient creates kube client from config 181 func NewKubeClient(kubeConfigPath string) *kubernetes.Clientset { 182 kubeConfig, err := clientcmd.BuildConfigFromFlags("", kubeConfigPath) 183 if err != nil { 184 Fatalf("Get kube config failed with error: %v", err) 185 return nil 186 } 187 kubeConfig.QPS = 5 188 kubeConfig.Burst = 10 189 kubeConfig.ContentType = "application/vnd.kubernetes.protobuf" 190 kubeClient, err := kubernetes.NewForConfig(kubeConfig) 191 if err != nil { 192 Fatalf("Get kube client failed with error: %v", err) 193 return nil 194 } 195 return kubeClient 196 } 197 198 // WaitforPodsRunning waits util all pods are in running status or timeout 199 func WaitforPodsRunning(kubeConfigPath string, podlist v1.PodList, timout time.Duration) { 200 if len(podlist.Items) == 0 { 201 Fatalf("podlist should not be empty") 202 } 203 204 podRunningCount := 0 205 for _, pod := range podlist.Items { 206 if pod.Status.Phase == v1.PodRunning { 207 podRunningCount++ 208 } 209 } 210 if podRunningCount == len(podlist.Items) { 211 Infof("All pods come into running status") 212 return 213 } 214 215 // new kube client 216 kubeClient := NewKubeClient(kubeConfigPath) 217 // define signal 218 signal := make(chan struct{}) 219 // define list watcher 220 listWatcher := cache.NewListWatchFromClient( 221 kubeClient.CoreV1().RESTClient(), 222 "pods", 223 v1.NamespaceAll, 224 fields.Everything()) 225 // new controller 226 _, controller := cache.NewInformer( 227 listWatcher, 228 &v1.Pod{}, 229 time.Second*0, 230 cache.ResourceEventHandlerFuncs{ 231 // receive update events 232 UpdateFunc: func(oldObj, newObj interface{}) { 233 // check update obj 234 p, ok := newObj.(*v1.Pod) 235 if !ok { 236 Fatalf("Failed to cast observed object to pod") 237 } 238 // calculate the pods in running status 239 count := 0 240 for i := range podlist.Items { 241 // update pod status in podlist 242 if podlist.Items[i].Name == p.Name { 243 Infof("PodName: %s PodStatus: %s", p.Name, p.Status.Phase) 244 podlist.Items[i].Status = p.Status 245 } 246 // check if the pod is in running status 247 if podlist.Items[i].Status.Phase == v1.PodRunning { 248 count++ 249 } 250 } 251 // send an end signal when all pods are in running status 252 if len(podlist.Items) == count { 253 signal <- struct{}{} 254 } 255 }, 256 }, 257 ) 258 259 // run controoler 260 podChan := make(chan struct{}) 261 go controller.Run(podChan) 262 defer close(podChan) 263 264 // wait for a signal or timeout 265 select { 266 case <-signal: 267 Infof("All pods come into running status") 268 case <-time.After(timout): 269 Fatalf("Wait for pods come into running status timeout: %v", timout) 270 } 271 }