Skip to content
Permalink
Browse files

Unit tests and update to quickstart guide (#354)

* Added a test for GetLoggingLevel

* Added up to 96% coverage for checkpoint.go

* Improved coverage of checkpoint.go to 96.4%

* Improved coverage of checkpoint.go to 96.4%

* Adding changes so i will have them saved for my remote fork thingy

* Fixed unit tests in checkpoint_test.go and conf_test.go

* Removed unnecessary comments

* improved conf code coverage by an amount that is greater than 0!

* improved coverage, but line 144 of conf.go needs a look

* Added unit tests to multus and types, also fixed a bug in conf.go

* added label to import types/020 in types.go

* hopefully resolved merge conflicts

* increased code coverage in multus.go and conf.go, also added bug fixes and formatting

* addressed all comments in review

* Updated testing.go with better comments

* changed 'thejohn' to '_not_type' for readability

* added additional unit tests

* added tests to kubeletclient.go

* added more unit tests to k8sclient.go and kubeletclient.go

* Added network status annotations section to quickstart and added more unit tests

* made changes to tests based on code review
  • Loading branch information...
nicklesimba authored and dougbtv committed Aug 5, 2019
1 parent 6e8fac5 commit 9085c8467204ca146a85e488d30abdc3215acc87
Showing with 647 additions and 2 deletions.
  1. +28 −1 doc/quickstart.md
  2. +185 −0 k8sclient/k8sclient_test.go
  3. +41 −0 kubeletclient/kubeletclient_test.go
  4. +6 −0 logging/logging_test.go
  5. +343 −1 multus/multus_test.go
  6. +44 −0 types/conf_test.go
@@ -176,6 +176,33 @@ You should note that there's 3 interfaces:
* `eth0` our default network
* `net1` the new interface we created with the macvlan configuration.

### Network Status Annotations

For additional confirmation, use `kubectl describe pod samplepod` and there will be an annotations section, similar to the following:

```
Annotations: k8s.v1.cni.cncf.io/networks: macvlan-conf
k8s.v1.cni.cncf.io/networks-status:
[{
"name": "cbr0",
"ips": [
"10.244.1.73"
],
"default": true,
"dns": {}
},{
"name": "macvlan-conf",
"interface": "net1",
"ips": [
"192.168.1.205"
],
"mac": "86:1d:96:ff:55:0d",
"dns": {}
}]
```

This metadata tells us that we have two CNI plugins running successfully.

### What if I want more interfaces?

You can add more interfaces to a pod by creating more custom resources and then referring to them in pod's annotation. You can also reuse configurations, so for example, to attach two macvlan interfaces to a pod, you could create a pod like so:
@@ -198,4 +225,4 @@ EOF

Note that the annotation now reads `k8s.v1.cni.cncf.io/networks: macvlan-conf,macvlan-conf`. Where we have the same configuration used twice, separated by a comma.

If you were to create another custom resource with the name `foo` you could use that such as: `k8s.v1.cni.cncf.io/networks: foo,macvlan-conf`, and use any number of attachments.
If you were to create another custom resource with the name `foo` you could use that such as: `k8s.v1.cni.cncf.io/networks: foo,macvlan-conf`, and use any number of attachments.
@@ -22,6 +22,8 @@ import (
"path/filepath"
"testing"

types020 "github.com/containernetworking/cni/pkg/types/020"
testhelpers "github.com/intel/multus-cni/testing"
testutils "github.com/intel/multus-cni/testing"

"github.com/containernetworking/cni/pkg/skel"
@@ -611,4 +613,187 @@ var _ = Describe("k8sclient operations", func() {
Expect(err).To(MatchError("GetPodNetwork: namespace isolation violation: podnamespace: test / target namespace: kube-system"))

})

It("Returns proper error message", func() {
// getPodNetwork will give us the error, then this test will use that error on the top func boi
err := &NoK8sNetworkError{"no kubernetes network found"}
Expect(err.Error()).To(Equal("no kubernetes network found"))
})

It("Sets pod network annotations without error", func() {
fakePod := testutils.NewFakePod("testpod", "kube-system/net1", "")

net1 := `{
"name": "net1",
"type": "mynet",
"cniVersion": "0.2.0"
}`

args := &skel.CmdArgs{
Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s", fakePod.ObjectMeta.Name, fakePod.ObjectMeta.Namespace),
}

fKubeClient := testutils.NewFakeKubeClient()
fKubeClient.AddPod(fakePod)
fKubeClient.AddNetConfig("kube-system", "net1", net1)

kubeClient, err := GetK8sClient("", fKubeClient)
Expect(err).NotTo(HaveOccurred())
k8sArgs, err := GetK8sArgs(args)
Expect(err).NotTo(HaveOccurred())

pod, err := kubeClient.GetPod(string(k8sArgs.K8S_POD_NAMESPACE), string(k8sArgs.K8S_POD_NAME))
Expect(err).NotTo(HaveOccurred())

networkstatus := "test status"
_, err = setPodNetworkAnnotation(kubeClient, "test", pod, networkstatus)
Expect(err).NotTo(HaveOccurred())
})

// Still figuring this one out. need to make "setPodNetworkAnnotation throw an error
// It("Fails to set pod network annotations without error", func() {
// fakePod := testutils.NewFakePod("testpod", "kube-system/net1", "")

// net1 := `{
// "name": "net1",
// "type": "mynet",
// "cniVersion": "0.2.0"
// }`

// args := &skel.CmdArgs{
// Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s", fakePod.ObjectMeta.Name, fakePod.ObjectMeta.Namespace),
// }

// fKubeClient := testutils.NewFakeKubeClient()
// fKubeClient.AddPod(fakePod)
// fKubeClient.AddNetConfig("kube-system", "net1", net1)

// kubeClient, err := GetK8sClient("", fKubeClient)
// Expect(err).NotTo(HaveOccurred())
// k8sArgs, err := GetK8sArgs(args)
// Expect(err).NotTo(HaveOccurred())

// pod, err := kubeClient.GetPod(string(k8sArgs.K8S_POD_NAMESPACE), string(k8sArgs.K8S_POD_NAME))
// Expect(err).NotTo(HaveOccurred())

// networkstatus := "test status"
// _, err = setPodNetworkAnnotation(kubeClient, "test", pod, networkstatus)
// Expect(err).NotTo(HaveOccurred())
// })

It("Sets network status without error", func() {
result := &types020.Result{
CNIVersion: "0.2.0",
IP4: &types020.IPConfig{
IP: *testhelpers.EnsureCIDR("1.1.1.2/24"),
},
}

conf := `{
"name": "node-cni-network",
"type": "multus",
"kubeconfig": "/etc/kubernetes/node-kubeconfig.yaml",
"delegates": [{
"type": "weave-net"
}],
"runtimeConfig": {
"portMappings": [
{"hostPort": 8080, "containerPort": 80, "protocol": "tcp"}
]
}
}`

delegate, err := types.LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.0")
Expect(err).NotTo(HaveOccurred())

delegateNetStatus, err := types.LoadNetworkStatus(result, delegate.Conf.Name, delegate.MasterPlugin)
GinkgoT().Logf("delegateNetStatus %+v\n", delegateNetStatus)
Expect(err).NotTo(HaveOccurred())

netstatus := []*types.NetworkStatus{delegateNetStatus}

fakePod := testutils.NewFakePod("testpod", "kube-system/net1", "")

netConf, err := types.LoadNetConf([]byte(conf))
Expect(err).NotTo(HaveOccurred())

net1 := `{
"name": "net1",
"type": "mynet",
"cniVersion": "0.2.0"
}`

args := &skel.CmdArgs{
Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s", fakePod.ObjectMeta.Name, fakePod.ObjectMeta.Namespace),
}

fKubeClient := testutils.NewFakeKubeClient()
fKubeClient.AddPod(fakePod)
fKubeClient.AddNetConfig("kube-system", "net1", net1)

kubeClient, err := GetK8sClient("", fKubeClient)
Expect(err).NotTo(HaveOccurred())
k8sArgs, err := GetK8sArgs(args)
Expect(err).NotTo(HaveOccurred())

err = SetNetworkStatus(kubeClient, k8sArgs, netstatus, netConf)
Expect(err).NotTo(HaveOccurred())
})

It("Fails to set network status without error", func() {
result := &types020.Result{
CNIVersion: "0.2.0",
IP4: &types020.IPConfig{
IP: *testhelpers.EnsureCIDR("1.1.1.2/24"),
},
}

conf := `{
"name": "node-cni-network",
"type": "multus",
"kubeconfig": "/etc/kubernetes/node-kubeconfig.yaml",
"delegates": [{
"type": "weave-net"
}],
"runtimeConfig": {
"portMappings": [
{"hostPort": 8080, "containerPort": 80, "protocol": "tcp"}
]
}
}`

delegate, err := types.LoadDelegateNetConf([]byte(conf), nil, "")
Expect(err).NotTo(HaveOccurred())

delegateNetStatus, err := types.LoadNetworkStatus(result, delegate.Conf.Name, delegate.MasterPlugin)
GinkgoT().Logf("delegateNetStatus %+v\n", delegateNetStatus)
Expect(err).NotTo(HaveOccurred())

netstatus := []*types.NetworkStatus{delegateNetStatus}

fakePod := testutils.NewFakePod("testpod", "kube-system/net1", "")

netConf, err := types.LoadNetConf([]byte(conf))
Expect(err).NotTo(HaveOccurred())

net1 := `{
"name": "net1",
"type": "mynet",
"cniVersion": "0.2.0"
}`

args := &skel.CmdArgs{
Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s", fakePod.ObjectMeta.Name, fakePod.ObjectMeta.Namespace),
}

fKubeClient := testutils.NewFakeKubeClient()
fKubeClient.AddPod(fakePod)
fKubeClient.AddNetConfig("kube-system", "net1", net1)

k8sArgs, err := GetK8sArgs(args)
Expect(err).NotTo(HaveOccurred())

err = SetNetworkStatus(nil, k8sArgs, netstatus, netConf)
Expect(err).To(HaveOccurred())
})
})
@@ -115,6 +115,12 @@ var _ = Describe("Kubelet resource endpoint data read operations", func() {
_, err := GetResourceClient()
Expect(err).NotTo(HaveOccurred())
})

It("should fail with missing file", func() {
kubeletSocket = "sampleSocketString"
_, err := GetResourceClient()
Expect(err).To(HaveOccurred())
})
})

Context("GetPodResourceMap() with valid pod name and namespace", func() {
@@ -146,6 +152,41 @@ var _ = Describe("Kubelet resource endpoint data read operations", func() {
Expect(resourceMap).ShouldNot(BeNil())
Expect(resourceMap).To(Equal(outputRMap))
})

It("should return no error with empty socket", func() {
podUID := k8sTypes.UID("970a395d-bb3b-11e8-89df-408d5c537d23")
fakePod := &v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "pod-name",
Namespace: "pod-namespace",
UID: podUID,
},
Spec: v1.PodSpec{
Containers: []v1.Container{
{
Name: "container-name",
},
},
},
}
kubeletSocket = ""
client, err := getKubeletClient()
Expect(err).NotTo(HaveOccurred())

outputRMap := map[string]*mtypes.ResourceInfo{
"resource": &mtypes.ResourceInfo{DeviceIDs: []string{"dev0", "dev1"}},
}
resourceMap, err := client.GetPodResourceMap(fakePod)
Expect(err).NotTo(HaveOccurred())
Expect(resourceMap).ShouldNot(BeNil())
Expect(resourceMap).To(Equal(outputRMap))
})

It("should return an error with garbage socket value", func() {
kubeletSocket = "/badfilepath!?//"
_, err := getKubeletClient()
Expect(err).To(HaveOccurred())
})
})

Context("GetPodResourceMap() with empty podname", func() {
@@ -45,6 +45,12 @@ var _ = Describe("logging operations", func() {
// check file existance
})

It("Check file setter with bad filepath", func() {
SetLogFile("/invalid/filepath")
Expect(loggingFp).NotTo(Equal(nil))
// check file existance
})

It("Check loglevel setter", func() {
SetLogLevel("debug")
Expect(loggingLevel).To(Equal(DebugLevel))

0 comments on commit 9085c84

Please sign in to comment.
You can’t perform that action at this time.