Skip to content

Commit

Permalink
feat: add k8s unittest for k8s (#404)
Browse files Browse the repository at this point in the history
Add unittest for k8s logic

Signed-off-by: jcriadomarco <[email protected]>
  • Loading branch information
javiercri authored Jul 3, 2023
1 parent b55270e commit 514ac47
Show file tree
Hide file tree
Showing 6 changed files with 318 additions and 104 deletions.
2 changes: 1 addition & 1 deletion config-reloader/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# SPDX-License-Identifier: BSD-2-Clause

# builder image
FROM golang:1.18 as builder
FROM golang:1.19 as builder

WORKDIR /go/src/github.com/vmware/kube-fluentd-operator/config-reloader
COPY . .
Expand Down
2 changes: 1 addition & 1 deletion config-reloader/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ GO_OPTS = GO111MODULE=on GOARCH=amd64 CGO_ENABLED=0 GOBIN=$(GOBIN)
GO = $(GO_OPTS) go

CURRENT_DIR = $(shell pwd)
DEV_ENV_IMAGE := vmwaresaas.jfrog.io/vdp-public/go-dev:latest
DEV_ENV_IMAGE := vmwaresaas.jfrog.io/vdp-public/go-dev:latest-1.19-amd64
DEV_ENV_WORK_DIR := /go/src/${PKG}
DEV_ENV_CMD := docker run --rm -v ${CURRENT_DIR}:${DEV_ENV_WORK_DIR} -w ${DEV_ENV_WORK_DIR} ${DEV_ENV_IMAGE}

Expand Down
234 changes: 234 additions & 0 deletions config-reloader/datasource/kube_informer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
package datasource

import (
"context"
"testing"
"time"

"github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
"github.com/vmware/kube-fluentd-operator/config-reloader/config"
"github.com/vmware/kube-fluentd-operator/config-reloader/datasource/kubedatasource"
corev1 "k8s.io/api/core/v1"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/informers"
testclient "k8s.io/client-go/kubernetes/fake"
)

type testConfig struct {
config config.Config
expectErr bool
expectedResult int
namespaces []string
configmap map[string]string
configmapData map[string]string
}

func importK8sObjects(factory informers.SharedInformerFactory, namespaces []string, configmaps map[string]string, configmapData map[string]string) {
for _, ns := range namespaces {
factory.Core().V1().Namespaces().Informer().GetIndexer().Add(
&corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: ns,
},
},
)
}
for cm, ns := range configmaps {
factory.Core().V1().ConfigMaps().Informer().GetIndexer().Add(
&corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: cm,
Namespace: ns,
},
Data: configmapData,
},
)
}
}

// UnitTest for GetNamespaces while using configmap mode
func TestGetNamespaces(t *testing.T) {
assert := assert.New(t)
configs := []testConfig{
{
//TestCase: One Namespace without any fluentd config. Result empty
config: config.Config{
Datasource: "default",
AnnotConfigmapName: "logging.csp.vmware.com/fluentd-configmap",
AnnotStatus: "logging.csp.vmware.com/fluentd-status",
ID: "default",
},
expectErr: false,
expectedResult: 0,
namespaces: []string{
"test1",
},
},
{
//TestCase: Two Namespaces, one without cm and one with empty fluentd config. Result empty
config: config.Config{
Datasource: "default",
AnnotConfigmapName: "logging.csp.vmware.com/fluentd-configmap",
AnnotStatus: "logging.csp.vmware.com/fluentd-status",
ID: "default",
},
expectErr: false,
expectedResult: 0,
namespaces: []string{
"test-empty",
"test-empty-2",
},
configmap: map[string]string{
"fluentd-config": "test-empty",
"my-configmap1": "test-empty",
"my-configmap2": "test-empty-2",
},
},
{
//TestCase: Two Namespaces, one fluentd config. Result 1
config: config.Config{
Datasource: "default",
DefaultConfigmapName: "fluentd-config",
AnnotConfigmapName: "logging.csp.vmware.com/fluentd-configmap",
AnnotStatus: "logging.csp.vmware.com/fluentd-status",
ID: "default",
},
expectErr: false,
expectedResult: 1,
namespaces: []string{
"test-not-empty",
"test-not-empty-2",
},
configmap: map[string]string{
"fluentd-config": "test-not-empty",
},
configmapData: map[string]string{"fluent.conf": "<match **>\n@type stdout\n</match>"},
},
}
for _, config := range configs {
// Prepare TestCase
ctx := context.Background()
clientset := testclient.NewSimpleClientset()
factory := informers.NewSharedInformerFactory(clientset, 0)
kubeds, _ := kubedatasource.NewConfigMapDS(ctx, &config.config, factory, make(chan time.Time, 1))
var ds = &kubeInformerConnection{
client: clientset,
cfg: &config.config,
nslist: factory.Core().V1().Namespaces().Lister(),
cmlist: factory.Core().V1().ConfigMaps().Lister(),
podlist: factory.Core().V1().Pods().Lister(),
kubeds: kubeds,
mountedLabels: make(map[string][]map[string]string),
}
importK8sObjects(factory, config.namespaces, config.configmap, config.configmapData)
// Run Test GetNamespace
namespaces, err := ds.GetNamespaces(ctx)
// Check Test Result
if err != nil {
logrus.Fatalf(err.Error())
}
assert.Equal(config.expectedResult, len(namespaces))
for index, ns := range namespaces {
assert.Equal(config.namespaces[index], ns.Name)
}
}
}

func TestDiscoverNamespaces(t *testing.T) {
assert := assert.New(t)
configs := []testConfig{
{
//TestCase: Two Namespaces, emptu DefaultConfigmapName. Result 2
config: config.Config{
Datasource: "default",
AnnotConfigmapName: "logging.csp.vmware.com/fluentd-configmap",
AnnotStatus: "logging.csp.vmware.com/fluentd-status",
ID: "default",
},
expectErr: false,
expectedResult: 2,
namespaces: []string{
"test1",
"test2",
},
},
{
//TestCase: Two Namespaces, use DefaultConfigmapName. Result 1
config: config.Config{
Datasource: "default",
DefaultConfigmapName: "fluentd-config",
AnnotConfigmapName: "logging.csp.vmware.com/fluentd-configmap",
AnnotStatus: "logging.csp.vmware.com/fluentd-status",
ID: "default",
},
expectErr: false,
expectedResult: 1,
namespaces: []string{
"test1",
"test2",
},
configmap: map[string]string{
"configmap1": "test1",
"configmap2": "test2",
"fluentd-config": "test1",
},
},
}
for _, config := range configs {
// Prepare TestCase
ctx := context.Background()
clientset := testclient.NewSimpleClientset()
factory := informers.NewSharedInformerFactory(clientset, 0)
var ds = &kubeInformerConnection{
client: clientset,
cfg: &config.config,
nslist: factory.Core().V1().Namespaces().Lister(),
cmlist: factory.Core().V1().ConfigMaps().Lister(),
}
importK8sObjects(factory, config.namespaces, config.configmap, config.configmapData)
// Run Test discoverNamespaces
namespaces, err := ds.discoverNamespaces(ctx)
// Check Test Result
if err != nil {
logrus.Fatalf(err.Error())
}
assert.Equal(len(namespaces), config.expectedResult)
}
}

// Test the updateStatus config creating a namespace and check label and value
func TestUpdateStatus(t *testing.T) {
assert := assert.New(t)
annotationValue := "Example annotation"
namespace := "test-namespace"
testCfg := &config.Config{
Datasource: "default",
AnnotConfigmapName: "logging.csp.vmware.com/fluentd-configmap",
AnnotStatus: "logging.csp.vmware.com/fluentd-status",
ID: "default",
}
ctx := context.Background()
clientset := testclient.NewSimpleClientset(
&corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: namespace,
},
},
)
factory := informers.NewSharedInformerFactory(clientset, 0)
var ds = &kubeInformerConnection{
client: clientset,
cfg: testCfg,
nslist: factory.Core().V1().Namespaces().Lister(),
cmlist: factory.Core().V1().ConfigMaps().Lister(),
}

ds.UpdateStatus(ctx, namespace, annotationValue)
ns, err := clientset.CoreV1().Namespaces().Get(ctx, namespace, metav1.GetOptions{})
if err != nil {
logrus.Fatalf("Unable to read namespace in cluster: %+v", err)
}
assert.Equal(ns.Annotations[testCfg.AnnotStatus], annotationValue)
}
12 changes: 7 additions & 5 deletions config-reloader/fluentd/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,13 @@ type Params map[string]*Param

// Directive represents a fluentd directive:
// <Name Tag>
// Params[0]
// Params[n]
// <Nested[0].Name Nested[0].Tag>
// ...etc
// </Nested[0].Name>
//
// Params[0]
// Params[n]
// <Nested[0].Name Nested[0].Tag>
// ...etc
// </Nested[0].Name>
//
// </Name>
type Directive struct {
Name string
Expand Down
37 changes: 22 additions & 15 deletions config-reloader/go.mod
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
module github.com/vmware/kube-fluentd-operator/config-reloader

go 1.18
go 1.19

require (
github.com/alecthomas/kingpin v2.2.6+incompatible
github.com/prometheus/client_golang v1.15.1
github.com/sirupsen/logrus v1.9.0
github.com/stretchr/testify v1.8.0
k8s.io/api v0.23.17
k8s.io/apiextensions-apiserver v0.23.17
k8s.io/apimachinery v0.23.17
k8s.io/client-go v0.23.17
github.com/stretchr/testify v1.8.2
k8s.io/api v0.27.0
k8s.io/apiextensions-apiserver v0.27.0
k8s.io/apimachinery v0.27.0
k8s.io/client-go v0.27.0
)

require (
Expand All @@ -19,18 +19,26 @@ require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/emicklei/go-restful/v3 v3.9.0 // indirect
github.com/evanphx/json-patch v4.12.0+incompatible // indirect
github.com/go-logr/logr v1.2.0 // indirect
github.com/go-logr/logr v1.2.3 // indirect
github.com/go-openapi/jsonpointer v0.19.6 // indirect
github.com/go-openapi/jsonreference v0.20.1 // indirect
github.com/go-openapi/swag v0.22.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/gnostic v0.5.7-v3refs // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/gofuzz v1.1.0 // indirect
github.com/googleapis/gnostic v0.5.5 // indirect
github.com/imdario/mergo v0.3.5 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/imdario/mergo v0.3.6 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_model v0.4.0 // indirect
Expand All @@ -46,13 +54,12 @@ require (
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.30.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/klog/v2 v2.30.0 // indirect
k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 // indirect
k8s.io/utils v0.0.0-20211116205334-6203023598ed // indirect
sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 // indirect
k8s.io/klog/v2 v2.90.1 // indirect
k8s.io/kube-openapi v0.0.0-20230308215209-15aac26d736a // indirect
k8s.io/utils v0.0.0-20230209194617-a36077c30491 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
sigs.k8s.io/yaml v1.2.0 // indirect
sigs.k8s.io/yaml v1.3.0 // indirect
)
Loading

0 comments on commit 514ac47

Please sign in to comment.