github.com/verrazzano/verrazzano@v1.7.1/tests/e2e/pkg/update/validation.go (about)

     1  // Copyright (c) 2022, 2023, Oracle and/or its affiliates.
     2  // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
     3  
     4  package update
     5  
     6  import (
     7  	"fmt"
     8  	"strings"
     9  	"time"
    10  
    11  	"github.com/onsi/gomega"
    12  	"github.com/verrazzano/verrazzano/tests/e2e/pkg"
    13  	v12 "k8s.io/api/core/v1"
    14  	"k8s.io/apimachinery/pkg/api/resource"
    15  	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    16  	"k8s.io/apimachinery/pkg/util/wait"
    17  )
    18  
    19  const (
    20  	longWaitTimeout     = 10 * time.Minute
    21  	longPollingInterval = 30 * time.Second
    22  )
    23  
    24  func ValidatePods(deployName string, labelName string, nameSpace string, expectedPodsRunning uint32, hasPending bool) {
    25  	gomega.Eventually(func() error {
    26  		var runningPods uint32
    27  		var pendingPods = false
    28  
    29  		err := wait.ExponentialBackoff(wait.Backoff{
    30  			Duration: time.Second * 15,
    31  			Factor:   1,
    32  			Jitter:   0.2,
    33  			Steps:    15,
    34  		}, func() (bool, error) {
    35  			var err error
    36  			pods, err := pkg.GetPodsFromSelector(&v1.LabelSelector{MatchLabels: map[string]string{labelName: deployName}}, nameSpace)
    37  			if err != nil {
    38  				return false, err
    39  			}
    40  			runningPods, pendingPods = getReadyPods(pods)
    41  			// Compare the number of running/pending pods to the expected numbers
    42  			if runningPods != expectedPodsRunning || pendingPods != hasPending {
    43  				return false, nil
    44  			}
    45  			return true, nil
    46  		})
    47  		if err != nil {
    48  			pkg.Log(pkg.Error, err.Error())
    49  			return err
    50  		}
    51  		if runningPods != expectedPodsRunning {
    52  			return fmt.Errorf("Deployment name %s: expect %d running pods, but got %d", deployName, expectedPodsRunning, runningPods)
    53  		}
    54  		if pendingPods != hasPending {
    55  			return fmt.Errorf("Deployment name %s: expect pending pods %t, but got %t", deployName, hasPending, pendingPods)
    56  		}
    57  		return nil
    58  	}, longWaitTimeout, longPollingInterval).Should(gomega.BeNil(), "expect to get correct number of running and pending pods")
    59  }
    60  
    61  // getReadyPods returns the number of pending pods in the provided pod list
    62  // and a boolean value indicating if there are no pending pods.
    63  func getReadyPods(pods []v12.Pod) (uint32, bool) {
    64  	var runningPods uint32
    65  	pendingPods := false
    66  	for _, pod := range pods {
    67  		pkg.Log(pkg.Info, "checking pod: "+pod.Name)
    68  		var podReady = pod.ObjectMeta.DeletionTimestamp == nil
    69  		// Count the pod as not ready if one of its containers is not running or not ready
    70  		for _, container := range pod.Status.ContainerStatuses {
    71  			pkg.Log(pkg.Info, "checking container: "+container.Name)
    72  			pkg.Log(pkg.Info, fmt.Sprintf("container ready=%t, container running %s, container waiting %s", container.Ready, container.State.Running, container.State.Waiting))
    73  			if !container.Ready || container.State.Running == nil {
    74  				podReady = false
    75  			}
    76  		}
    77  		pkg.Log(pkg.Info, fmt.Sprintf("pod status phase: %s, pod ready: %t", pod.Status.Phase, podReady))
    78  		if pod.Status.Phase == v12.PodRunning && podReady {
    79  			runningPods++
    80  		}
    81  		if pod.Status.Phase == v12.PodPending {
    82  			pendingPods = true
    83  		}
    84  	}
    85  	return runningPods, pendingPods
    86  }
    87  
    88  func ValidatePodMemoryRequest(labels map[string]string, nameSpace, containerPrefix string, expectedMemory string) {
    89  	gomega.Eventually(func() bool {
    90  		var err error
    91  		pods, err := pkg.GetPodsFromSelector(&v1.LabelSelector{MatchLabels: labels}, nameSpace)
    92  		if err != nil {
    93  			return false
    94  		}
    95  		memoryMatchedContainers := 0
    96  		for _, pod := range pods {
    97  			for _, container := range pod.Spec.Containers {
    98  				if !strings.HasPrefix(container.Name, containerPrefix) {
    99  					continue
   100  				}
   101  				expectedNodeMemory, err := resource.ParseQuantity(expectedMemory)
   102  				if err != nil {
   103  					pkg.Log(pkg.Error, err.Error())
   104  					return false
   105  				}
   106  				pkg.Log(pkg.Info,
   107  					fmt.Sprintf("Checking container memory request %v to match the expected value %s",
   108  						container.Resources.Requests.Memory(), expectedMemory))
   109  				if *container.Resources.Requests.Memory() == expectedNodeMemory {
   110  					memoryMatchedContainers++
   111  				}
   112  			}
   113  		}
   114  		return memoryMatchedContainers == len(pods)
   115  	}, waitTimeout, pollingInterval).Should(gomega.BeTrue(), "Expected to find container with right memory settings")
   116  }