Skip to content

Commit

Permalink
Improved unit test coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
vklohiya committed Feb 29, 2024
1 parent ba79d69 commit 793b1ac
Show file tree
Hide file tree
Showing 6 changed files with 177 additions and 31 deletions.
41 changes: 34 additions & 7 deletions cmd/k8s-bigip-ctlr/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,18 @@
package main

import (
"context"
"fmt"
"github.com/F5Networks/k8s-bigip-ctlr/v2/pkg/agent/as3"
"github.com/F5Networks/k8s-bigip-ctlr/v2/pkg/agent/cccl"
"io/ioutil"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/rest"
"os"
"os/exec"
"sort"
"strconv"
"strings"
"time"

"github.com/F5Networks/k8s-bigip-ctlr/v2/pkg/appmanager"
Expand Down Expand Up @@ -457,19 +460,43 @@ var _ = Describe("Main Tests", func() {
"--bigip-partition=velcro1",
"--bigip-url=bigip.example.com",
"--pool-member-type=nodeport",
"--trusted-certs-cfgmap=default/foomap",
}
flags.Parse(os.Args)
os.Mkdir("/tmp/k8s-test-creds", 0755)
err := ioutil.WriteFile("/tmp/k8s-test-creds/username", []byte("user"), 0755)
err := os.WriteFile("/tmp/k8s-test-creds/username", []byte("user"), 0755)
Expect(err).ToNot(HaveOccurred())
err = ioutil.WriteFile("/tmp/k8s-test-creds/password", []byte("pass"), 0755)
err = os.WriteFile("/tmp/k8s-test-creds/password", []byte("pass"), 0755)
Expect(err).ToNot(HaveOccurred())

err = getCredentials()
Expect(err).ToNot(HaveOccurred())
Expect(*bigIPURL).To(Equal("https://bigip.example.com"))
Expect(*bigIPUsername).To(Equal("user"))
Expect(*bigIPPassword).To(Equal("pass"))
kubeClient = fake.NewSimpleClientset()
cfgFoo := &v1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Name: "foomap", Namespace: "default"}, Data: map[string]string{"data": "foo"}}
_, err = kubeClient.CoreV1().ConfigMaps("default").Create(context.TODO(), cfgFoo, metav1.CreateOptions{})
Expect(err).ToNot(HaveOccurred())
cfgFoo, err = getConfigMapUsingNamespaceAndName("default", "foomap")
Expect(err).ToNot(HaveOccurred())
Expect(cfgFoo.Data["data"]).To(Equal("foo"))
//check for invlaid configmap
_, err = getConfigMapUsingNamespaceAndName("default", "invalid")
Expect(err).ToNot(BeNil())
//check for valid bigip trusted certs
os.Args[6] = "--trusted-certs-cfgmap=default/foomap"
out := getBIGIPTrustedCerts()
Expect(strings.TrimSpace(out)).To(Equal("foo"))
//check for invalid bigip trusted certs
os.Args[6] = "--trusted-certs-cfgmap= "
flags.Parse(os.Args)
out = getBIGIPTrustedCerts()
Expect(out).To(Equal(""))
os.Args[6] = "--trusted-certs-cfgmap=default"
flags.Parse(os.Args)
out = getBIGIPTrustedCerts()
Expect(out).To(Equal(""))

// Test url variations
os.Args[4] = "--bigip-url=fail://bigip.example.com"
Expand Down Expand Up @@ -503,14 +530,14 @@ var _ = Describe("Main Tests", func() {
}
flags.Parse(os.Args)
os.Mkdir("/tmp/k8s-test-creds", 0755)
err := ioutil.WriteFile("/tmp/k8s-test-creds/username", []byte("user"), 0755)
err := os.WriteFile("/tmp/k8s-test-creds/username", []byte("user"), 0755)
Expect(err).ToNot(HaveOccurred())
err = ioutil.WriteFile("/tmp/k8s-test-creds/password", []byte("pass"), 0755)
err = os.WriteFile("/tmp/k8s-test-creds/password", []byte("pass"), 0755)
Expect(err).ToNot(HaveOccurred())
os.Mkdir("/tmp/k8s-test-gtm-creds", 0755)
err = ioutil.WriteFile("/tmp/k8s-test-gtm-creds/username", []byte("user-gtm"), 0755)
err = os.WriteFile("/tmp/k8s-test-gtm-creds/username", []byte("user-gtm"), 0755)
Expect(err).ToNot(HaveOccurred())
err = ioutil.WriteFile("/tmp/k8s-test-gtm-creds/password", []byte("pass-gtm"), 0755)
err = os.WriteFile("/tmp/k8s-test-gtm-creds/password", []byte("pass-gtm"), 0755)
Expect(err).ToNot(HaveOccurred())

err = getCredentials()
Expand Down
44 changes: 24 additions & 20 deletions pkg/controller/multiClusterInformers.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,12 +228,14 @@ func (ctlr *Controller) stopDeletedGlobalCMMultiClusterInformers() error {
return nil
}

func (ctlr *Controller) stopMultiClusterInformers(clusterName string) error {
func (ctlr *Controller) stopMultiClusterInformers(clusterName string, stopInformer bool) error {

// remove the informers for clusters whose config has been removed
if clsSet, ok := ctlr.multiClusterPoolInformers[clusterName]; ok {
for _, nsPoolInf := range clsSet {
nsPoolInf.stop()
if stopInformer {
nsPoolInf.stop()
}
delete(ctlr.multiClusterPoolInformers, clusterName)
}
}
Expand All @@ -244,14 +246,14 @@ func (ctlr *Controller) stopMultiClusterInformers(clusterName string) error {
}

// setup multi cluster informer
func (ctlr *Controller) setupAndStartMultiClusterInformers(svcKey MultiClusterServiceKey) error {
func (ctlr *Controller) setupAndStartMultiClusterInformers(svcKey MultiClusterServiceKey, startInformer bool) error {
if config, ok := ctlr.multiClusterConfigs.ClusterConfigs[svcKey.clusterName]; ok {
restClient := config.KubeClient.CoreV1().RESTClient()
if err := ctlr.addMultiClusterNamespacedInformers(svcKey.clusterName, svcKey.namespace, restClient, true); err != nil {
if err := ctlr.addMultiClusterNamespacedInformers(svcKey.clusterName, svcKey.namespace, restClient, startInformer); err != nil {
log.Errorf("[MultiCluster] unable to setup informer for cluster: %v, namespace: %v, Error: %v", svcKey.clusterName, svcKey.namespace, err)
return err
}
err := ctlr.setupMultiClusterNodeInformers(svcKey.clusterName)
err := ctlr.setupMultiClusterNodeInformers(svcKey.clusterName, startInformer)
if err != nil {
return err
}
Expand All @@ -271,33 +273,35 @@ func (ctlr *Controller) setupAndStartHAClusterInformers(clusterName string) erro
return err
}
}
err := ctlr.setupMultiClusterNodeInformers(clusterName)
err := ctlr.setupMultiClusterNodeInformers(clusterName, true)
if err != nil {
return err
}
return nil
}

// setupMultiClusterNodeInformers sets up and starts node informers for cluster if it hasn't been started
func (ctlr *Controller) setupMultiClusterNodeInformers(clusterName string) error {
func (ctlr *Controller) setupMultiClusterNodeInformers(clusterName string, startInformer bool) error {
if _, ok := ctlr.multiClusterNodeInformers[clusterName]; !ok {
nodeInf := ctlr.getNodeInformer(clusterName)
ctlr.addNodeEventUpdateHandler(&nodeInf)
nodeInf.start()
time.Sleep(100 * time.Millisecond)
ctlr.multiClusterNodeInformers[clusterName] = &nodeInf
nodesIntfc := nodeInf.nodeInformer.GetIndexer().List()
var nodesList []corev1.Node
for _, obj := range nodesIntfc {
node := obj.(*corev1.Node)
nodesList = append(nodesList, *node)
}
sort.Sort(NodeList(nodesList))
nodes, err := ctlr.getNodes(nodesList)
if err != nil {
return err
if startInformer {
nodeInf.start()
time.Sleep(100 * time.Millisecond)
nodesIntfc := nodeInf.nodeInformer.GetIndexer().List()
var nodesList []corev1.Node
for _, obj := range nodesIntfc {
node := obj.(*corev1.Node)
nodesList = append(nodesList, *node)
}
sort.Sort(NodeList(nodesList))
nodes, err := ctlr.getNodes(nodesList)
if err != nil {
return err
}
nodeInf.oldNodes = nodes
}
nodeInf.oldNodes = nodes
}
return nil
}
Expand Down
47 changes: 47 additions & 0 deletions pkg/controller/multiClusterInformers_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package controller

import (
"github.com/F5Networks/k8s-bigip-ctlr/v2/pkg/clustermanager"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
k8sfake "k8s.io/client-go/kubernetes/fake"
)

var _ = Describe("MultiClusterInformers", func() {
var mockCtlr *mockController
BeforeEach(func() {
mockCtlr = newMockController()
mockCtlr.multiClusterConfigs = clustermanager.NewMultiClusterConfig()
clusterName := "cluster-1"
mockCtlr.multiClusterConfigs.ClusterConfigs[clusterName] = clustermanager.ClusterConfig{KubeClient: k8sfake.NewSimpleClientset()}
mockCtlr.multiClusterPoolInformers = make(map[string]map[string]*MultiClusterPoolInformer)
mockCtlr.multiClusterNodeInformers = make(map[string]*NodeInformer)
mockCtlr.multiClusterResources = newMultiClusterResourceStore()
})
It("Setup and start multi-cluster informers NodePortLocal", func() {
mockCtlr.PoolMemberType = NodePortLocal
svcKey := MultiClusterServiceKey{
serviceName: "svc-1",
namespace: "ns",
clusterName: "cluster-1",
}
err := mockCtlr.setupAndStartMultiClusterInformers(svcKey, false)
Expect(err).To(BeNil())
poolInf, found := mockCtlr.getNamespaceMultiClusterPoolInformer(svcKey.namespace, svcKey.clusterName)
Expect(found).To(BeTrue())
Expect(poolInf).ToNot(BeNil())
mockCtlr.stopMultiClusterInformers(svcKey.clusterName, false)
Expect(len(mockCtlr.multiClusterPoolInformers)).To(Equal(0))
Expect(len(mockCtlr.multiClusterNodeInformers)).To(Equal(0))
})
It("Setup and start multi-cluster informers Cluster", func() {
mockCtlr.PoolMemberType = Cluster
svcKey := MultiClusterServiceKey{
serviceName: "svc-1",
namespace: "ns",
clusterName: "cluster-1",
}
err := mockCtlr.setupAndStartMultiClusterInformers(svcKey, false)
Expect(err).To(BeNil())
})
})
6 changes: 3 additions & 3 deletions pkg/controller/multiClusterWorker.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ func (ctlr *Controller) processResourceExternalClusterServices(rscKey resourceRe
// if informer not found for cluster, setup and start informer
_, clusterKeyFound := ctlr.multiClusterPoolInformers[svc.ClusterName]
if !clusterKeyFound {
ctlr.setupAndStartMultiClusterInformers(svcKey)
ctlr.setupAndStartMultiClusterInformers(svcKey, true)
} else if _, found := ctlr.multiClusterPoolInformers[svc.ClusterName][svc.Namespace]; !found {
ctlr.setupAndStartMultiClusterInformers(svcKey)
ctlr.setupAndStartMultiClusterInformers(svcKey, true)
}
} else {
log.Warningf("[MultiCluster] invalid cluster reference found cluster: %v resource:%v", svc.ClusterName, rscKey)
Expand Down Expand Up @@ -127,7 +127,7 @@ func (ctlr *Controller) deleteUnrefereedMultiClusterInformers() {
if len(svcs) == 0 && ((ctlr.haModeType == StandAloneCIS || ctlr.haModeType == StandBy) ||
ctlr.multiClusterConfigs.HAPairClusterName != clusterName) {
delete(ctlr.multiClusterResources.clusterSvcMap, clusterName)
ctlr.stopMultiClusterInformers(clusterName)
ctlr.stopMultiClusterInformers(clusterName, true)
}
}
}
Expand Down
64 changes: 64 additions & 0 deletions pkg/controller/multiClusterWorker_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package controller

import (
"github.com/F5Networks/k8s-bigip-ctlr/v2/pkg/clustermanager"
"github.com/F5Networks/k8s-bigip-ctlr/v2/pkg/test"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
v1 "k8s.io/api/core/v1"
k8sfake "k8s.io/client-go/kubernetes/fake"
)

var _ = Describe("MultiClusterWorker", func() {
var mockCtlr *mockController
var svc *v1.Service
var clusterName string
var clusterName2 string
BeforeEach(func() {
mockCtlr = newMockController()
mockCtlr.multiClusterConfigs = clustermanager.NewMultiClusterConfig()
clusterName = "cluster-1"
clusterName2 = "cluster-2"
mockCtlr.multiClusterConfigs.HAPairClusterName = "cluster-2"
svc = test.NewService(
"svc1",
"1",
"ns",
v1.ServiceTypeClusterIP,
[]v1.ServicePort{
{
Port: 80,
Name: "port0",
},
},
)
mockCtlr.multiClusterConfigs.ClusterConfigs[clusterName] = clustermanager.ClusterConfig{KubeClient: k8sfake.NewSimpleClientset(svc)}
mockCtlr.multiClusterConfigs.ClusterConfigs[clusterName2] = clustermanager.ClusterConfig{KubeClient: k8sfake.NewSimpleClientset(svc)}
mockCtlr.multiClusterPoolInformers = make(map[string]map[string]*MultiClusterPoolInformer)
mockCtlr.multiClusterNodeInformers = make(map[string]*NodeInformer)
mockCtlr.multiClusterResources = newMultiClusterResourceStore()
})
It("Get service from HA cluster", func() {
mockCtlr.haModeType = Active
svcKey := MultiClusterServiceKey{
serviceName: "svc1",
namespace: "ns",
clusterName: clusterName,
}
err := mockCtlr.setupAndStartMultiClusterInformers(svcKey, false)
Expect(err).To(BeNil())
_, exists, err := mockCtlr.getSvcFromHACluster(svcKey.namespace, svcKey.serviceName)
Expect(err).NotTo(BeNil())
Expect(exists).To(BeFalse())
svcKey2 := MultiClusterServiceKey{
serviceName: "svc-1",
namespace: "ns",
clusterName: clusterName2,
}
err2 := mockCtlr.setupAndStartMultiClusterInformers(svcKey2, false)
Expect(err2).To(BeNil())
port, err := mockCtlr.getSvcPortFromHACluster(svcKey.namespace, svcKey.serviceName, "port0", "")
Expect(err).NotTo(BeNil())
Expect(port).To(BeZero())
})
})
6 changes: 5 additions & 1 deletion pkg/controller/worker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2335,7 +2335,11 @@ var _ = Describe("Worker Tests", func() {

_, status = mockCtlr.requestIP("test", "", key)
Expect(status).To(Equal(Allocated), "Failed to fetch Allocated IP")

mockCtlr.firstPostResponse = false
mockCtlr.removeUnusedIPAMEntries(TransportServer)
//check cache is not updated
ipamCR = mockCtlr.getIPAMCR()
Expect(len(ipamCR.Status.IPStatus)).To(Equal(1), "IPAM cache not updated")
mockCtlr.ipamCli = nil
mockCtlr.addTransportServer(ts)
mockCtlr.processResources()
Expand Down

0 comments on commit 793b1ac

Please sign in to comment.