Maison > développement back-end > Golang > le corps du texte

Comment utiliser de faux clients pour les tests unitaires du code intégré à Kubernetes ?

Mary-Kate Olsen
Libérer: 2024-10-27 03:14:29
original
859 Les gens l'ont consulté

How to Use Fake Clients for Unit Testing Kubernetes-Integrated Code?

Tests unitaires avec un faux client pour Kubernetes

Lors de l'écriture de tests pour du code qui interagit avec Kubernetes, il est avantageux d'isoler l'environnement de test du cluster réel. Ceci peut être réalisé en exploitant de faux clients, qui simulent le comportement de l'API Kubernetes sans nécessiter de cluster actif.

Problème

Considérez la méthode suivante :

<code class="go">import (
  "fmt"
  "k8s.io/api/core/v1"
  metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  fake "k8s.io/client-go/kubernetes/fake"
  "time"
)

func GetNamespaceCreationTime(namespace string) int64 {
  clientset, err := kubernetes.NewForConfig(rest.InClusterConfig())
  if err != nil {
    panic(err.Error())
  }
  
  ns, err := clientset.CoreV1().Namespaces().Get(namespace, metav1.GetOptions{})
  if err != nil {
    panic(err.Error())
  }
  
  fmt.Printf("%v \n", ns.CreationTimestamp)
  return (ns.GetCreationTimestamp().Unix())
}</code>
Copier après la connexion

Le le but est d'écrire un test unitaire pour cette méthode en utilisant un faux client.

Solution

Pour utiliser un faux client, nous devons modifier la fonction GetNamespaceCreationTime pour accepter un kubernetes.Interface comme paramètre :

<code class="go">func GetNamespaceCreationTime(kubeClient kubernetes.Interface, namespace string) int64 {
  ns, err := kubeClient.CoreV1().Namespaces().Get(namespace, metav1.GetOptions{})
  if err != nil {
    panic(err.Error())
  }
  
  fmt.Printf("%v \n", ns.CreationTimestamp)
  return (ns.GetCreationTimestamp().Unix())
}</code>
Copier après la connexion

Dans notre fonction de test, nous pouvons créer un faux ensemble de clients et le transmettre à la méthode GetNamespaceCreationTime comme suit :

<code class="go">func TestGetNamespaceCreationTime(t *testing.T) {
  kubeClient := fake.NewSimpleClientset()
  got := GetNamespaceCreationTime(kubeClient, "default")
  want := int64(1257894000)

  nsMock :=kubeClient.CoreV1().Namespaces()
  nsMock.Create(&v1.Namespace{
    ObjectMeta: metav1.ObjectMeta{
      Name:              "default",
      CreationTimestamp: metav1.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC),
    },
  })

  if got != want {
    t.Errorf("got %q want %q", got, want)
  }
}</code>
Copier après la connexion

Test complet avec stubbing de configuration en cluster

Le test complet avec stubbing pour la configuration en cluster pourrait ressembler à :

<code class="go">import (
  "fmt"
  "k8s.io/api/core/v1"
  metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  fake "k8s.io/client-go/kubernetes/fake"
  "k8s.io/client-go/kubernetes"
  "k8s.io/client-go/rest"
  "time"
)

var getInclusterConfigFunc = rest.InClusterConfig
var getNewKubeClientFunc = dynamic.NewForConfig

func GetNamespaceCreationTime(kubeClient kubernetes.Interface, namespace string) int64 {

  ns, err := kubeClient.CoreV1().Namespaces().Get(namespace, metav1.GetOptions{})
  if err != nil {
    panic(err.Error())
  }

  fmt.Printf("%v \n", ns.CreationTimestamp)
  return (ns.GetCreationTimestamp().Unix())
}

func GetClientSet() kubernetes.Interface {

  config, err := getInclusterConfigFunc()
  if err != nil {
    log.Warnf("Could not get in-cluster config: %s", err)
    return nil, err
  }

  client, err := getNewKubeClientFunc(config)
  if err != nil {
    log.Warnf("Could not connect to in-cluster API server: %s", err)
    return nil, err
  }

  return client, err
}

func TestGetNamespaceCreationTime(t *testing.T) {
  kubeClient := fake.NewSimpleClientset()
  got := GetNamespaceCreationTime(kubeClient, "default")
  want := int64(1257894000)

  nsMock :=kubeClient.CoreV1().Namespaces()
  nsMock.Create(&v1.Namespace{
    ObjectMeta: metav1.ObjectMeta{
      Name:              "default",
      CreationTimestamp: metav1.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC),
    },
  })

  if got != want {
    t.Errorf("got %q want %q", got, want)
  }
}

func fakeGetInclusterConfig() (*rest.Config, error) {
  return nil, nil
}

func fakeGetInclusterConfigWithError() (*rest.Config, error) {
  return nil, errors.New("fake error getting in-cluster config")
}

func TestGetInclusterKubeClient(t *testing.T) {
  origGetInclusterConfig := getInclusterConfigFunc
  getInclusterConfigFunc = fakeGetInclusterConfig
  origGetNewKubeClient := getNewKubeClientFunc
  getNewKubeClientFunc = fakeGetNewKubeClient

  defer func() {
    getInclusterConfigFunc = origGetInclusterConfig
    getNewKubeClientFunc = origGetNewKubeClient
  }()

  client, err := GetClientSet()
  assert.Nil(t, client, "Client is not nil")
  assert.Nil(t, err, "error is not nil")
}

func TestGetInclusterKubeClient_ConfigError(t *testing.T) {
  origGetInclusterConfig := getInclusterConfigFunc
  getInclusterConfigFunc = fakeGetInclusterConfigWithError

  defer func() {
    getInclusterConfigFunc = origGetInclusterConfig
  }()

  client, err := GetClientSet()
  assert.Nil(t, client, "Client is not nil")
  assert.NotNil(t, err, "error is nil")
}</code>
Copier après la connexion

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!