2

Background

Objective is to write a unit test in golang to check whether given deployment in a namespace is up or not. I am using the library "k8s.io/client-go/kubernetes/fake" to do the same.

These are the steps I plan to execute:

  1. Creata mock kubernetes API using client-go:
kubectl := &KubeClient{
        testclient.NewSimpleClientset(),
}
  1. Create mock deployment with replicas = 1 (initially):
deploymentSpec := &appsv1.Deployment{
    ObjectMeta: metav1.ObjectMeta{
        Name:      RESOURCE_NAME,
        Namespace: NAMESPACE,
        Labels:    resourceLabel,
    },
    Spec: appsv1.DeploymentSpec{
        Replicas: &replicas,
        Template: v1.PodTemplateSpec{
            Spec: v1.PodSpec{
                Containers: []v1.Container{
                    {
                    Name:  RESOURCE_NAME,
                    Image: image,
                    },
                },
            },
        },
    },
}
  1. Update the replica count to 3 using the client-go Update API:
var updateReplicas int32 = 3
replicaCountPtr := &updateReplicas
result.Spec.Replicas = replicaCountPtr

_, err = kubectl.AppsV1().Deployments(NAMESPACE).Update(context.TODO(), result, metav1.UpdateOptions{})
  1. Run a goroutine that checks for the deployment is up or not.

Problem

When I query (for example, using kubectl.AppsV1().Deployments(NAMESPACE).Get(...).Status.Replicas) for Replicas, ReadyReplicas, AvailableReplicas, UpdatedReplicas - These values return 0, and not 3.

Why are the replica status values not getting updated? Could trying to test using "k8s.io/client-go/kubernetes/fake" be the problem here?

Test code

package main

import (
    "context"
    "log"
    "time"

    appsv1 "k8s.io/api/apps/v1"
    v1 "k8s.io/api/core/v1"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/client-go/kubernetes"
    testclient "k8s.io/client-go/kubernetes/fake"
)

type KubeClient struct {
    kubernetes.Interface
}

const NAMESPACE = "default"
const RESOURCE_NAME = "TestResource"

func main() {
    var replicas int32 = 1
    image := NAMESPACE
    resourceLabel := map[string]string{
        "env": "test",
    }

    kubectl := &KubeClient{
        testclient.NewSimpleClientset(),
    }

    // Create deployment
    deploymentSpec := &appsv1.Deployment{
        ObjectMeta: metav1.ObjectMeta{
            Name:      RESOURCE_NAME,
            Namespace: NAMESPACE,
            Labels:    resourceLabel,
        },
        Spec: appsv1.DeploymentSpec{
            Replicas: &replicas,
            Template: v1.PodTemplateSpec{
                Spec: v1.PodSpec{
                    Containers: []v1.Container{
                        {
                            Name:  RESOURCE_NAME,
                            Image: image,
                        },
                    },
                },
            },
        },
    }

    deployResult, err := kubectl.AppsV1().Deployments(NAMESPACE).Create(context.TODO(), deploymentSpec, metav1.CreateOptions{})
    if err != nil {
        panic(err)
    }
    log.Printf("Created deployment %q in namespace '%s'\n", deployResult.GetObjectMeta().GetName(), deployResult.GetNamespace())

    result, err := kubectl.AppsV1().Deployments(NAMESPACE).Get(context.TODO(), RESOURCE_NAME, metav1.GetOptions{})
    if err != nil {
        log.Printf("Failed to fetch deployment %s in the namespace %s with error: %s\n", RESOURCE_NAME, NAMESPACE, err.Error())
    }

    var updateReplicas int32 = 3
    replicaCountPtr := &updateReplicas
    result.Spec.Replicas = replicaCountPtr

    _, err = kubectl.AppsV1().Deployments(NAMESPACE).Update(context.TODO(), result, metav1.UpdateOptions{})
    if err != nil {
        log.Printf("Failed to update replica value: %v\n", err)
    }
    time.Sleep(1 * time.Second)
    log.Printf("Updated replica count of deployment %q in namespace %q : (%d)\n", RESOURCE_NAME, NAMESPACE, &replicas)

    var status bool
    channel := make(chan bool, 1)
    go func(bool) {
        for {
            getResult, getErr := kubectl.AppsV1().Deployments(NAMESPACE).Get(context.TODO(), RESOURCE_NAME, metav1.GetOptions{})
            if getErr != nil {
                log.Printf("Failed to fetch deployment %s in the namespace %s with error: %s\n", RESOURCE_NAME, NAMESPACE, getErr.Error())
                status = false
                break
            }

            log.Printf("Replicas status: %d\n", getResult.Status.ReadyReplicas)
            log.Printf("ReadyReplicas status: %d\n", getResult.Status.Replicas)
            log.Printf("AvailableReplicas status: %d\n", getResult.Status.AvailableReplicas)
            log.Printf("UpdatedReplicas status: %d\n", getResult.Status.UpdatedReplicas)
            log.Printf("Replicas spec: %d\n", *(getResult.Spec.Replicas))
            if getResult.Status.ReadyReplicas == *(getResult.Spec.Replicas) {
                status = true
                break
            }
            status = false
        }
        channel <- (status)
    }(status)

    select {
    case <-channel:
        if status {
            log.Printf("Deployment '%s' is up", RESOURCE_NAME)
        } else {
            log.Printf("Deployment '%s' is NOT up", RESOURCE_NAME)
        }
    case <-time.After(1 * time.Second):
        log.Printf("Deployment '%s' timed out", RESOURCE_NAME)
    }
}

Logs

...
2022/11/25 17:46:55 UpdatedReplicas status: 0
2022/11/25 17:46:55 Replicas spec: 3
2022/11/25 17:46:55 Replicas status: 0
2022/11/25 17:46:55 ReadyReplicas status: 0
2022/11/25 17:46:55 AvailableReplicas status: 0
2022/11/25 17:46:55 UpdatedReplicas status: 0
2022/11/25 17:46:55 Replicas spec: 3
2022/11/25 17:46:55 Replicas status: 0
2022/11/25 17:46:55 ReadyReplicas status: 0
2022/11/25 17:46:55 AvailableReplicas status: 0
2022/11/25 17:46:55 UpdatedReplicas status: 0
2022/11/25 17:46:55 Replicas spec: 3
2022/11/25 17:46:55 Deployment 'TestResource' timed out
2022/11/25 17:46:55 Replicas status: 0
2022/11/25 17:46:55 ReadyReplicas status: 0
2022/11/25 17:46:55 AvailableReplicas status: 0
2022/11/25 17:46:55 UpdatedReplicas status: 0
2022/11/25 17:46:55 Replicas spec: 3
ayivaak
  • 67
  • 8

0 Answers0