Heim >Backend-Entwicklung >Golang >Wie verwende ich gefälschte Clients zum Unit-Testen von Kubernetes-integriertem Code?

Wie verwende ich gefälschte Clients zum Unit-Testen von Kubernetes-integriertem Code?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-10-27 03:14:29942Durchsuche

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

Unit-Tests mit Fake-Client für Kubernetes

Beim Schreiben von Tests für Code, der mit Kubernetes interagiert, ist es von Vorteil, die Testumgebung vom eigentlichen Cluster zu isolieren. Dies kann durch die Nutzung gefälschter Clients erreicht werden, die das Verhalten der Kubernetes-API simulieren, ohne dass ein Live-Cluster erforderlich ist.

Problem

Betrachten Sie die folgende Methode:

<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>

Die Ziel ist es, einen Komponententest für diese Methode mit einem gefälschten Client zu schreiben.

Lösung

Um einen gefälschten Client zu verwenden, müssen wir die GetNamespaceCreationTime-Funktion ändern, um ein kubernetes.Interface als Parameter zu akzeptieren :

<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>

In unserer Testfunktion können wir ein gefälschtes Clientset erstellen und es wie folgt an die GetNamespaceCreationTime-Methode übergeben:

<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>

Test mit In-Cluster-Konfigurationsstubbing abschließen

Der vollständige Test mit Stubbing für die In-Cluster-Konfiguration könnte wie folgt aussehen:

<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>

Das obige ist der detaillierte Inhalt vonWie verwende ich gefälschte Clients zum Unit-Testen von Kubernetes-integriertem Code?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn