forked from github/multus-cni
* 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
251 lines
6.2 KiB
Go
251 lines
6.2 KiB
Go
package kubeletclient
|
|
|
|
import (
|
|
"context"
|
|
"io/ioutil"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
. "github.com/onsi/ginkgo"
|
|
. "github.com/onsi/gomega"
|
|
"google.golang.org/grpc"
|
|
v1 "k8s.io/api/core/v1"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
k8sTypes "k8s.io/apimachinery/pkg/types"
|
|
"k8s.io/kubernetes/pkg/kubelet/util"
|
|
|
|
mtypes "github.com/intel/multus-cni/types"
|
|
podresourcesapi "k8s.io/kubernetes/pkg/kubelet/apis/podresources/v1alpha1"
|
|
)
|
|
|
|
var (
|
|
socketDir string
|
|
socketName string
|
|
fakeServer *fakeResourceServer
|
|
)
|
|
|
|
type fakeResourceServer struct {
|
|
server *grpc.Server
|
|
}
|
|
|
|
func (m *fakeResourceServer) List(ctx context.Context, req *podresourcesapi.ListPodResourcesRequest) (*podresourcesapi.ListPodResourcesResponse, error) {
|
|
podName := "pod-name"
|
|
podNamespace := "pod-namespace"
|
|
containerName := "container-name"
|
|
|
|
devs := []*podresourcesapi.ContainerDevices{
|
|
{
|
|
ResourceName: "resource",
|
|
DeviceIds: []string{"dev0", "dev1"},
|
|
},
|
|
}
|
|
|
|
resp := &podresourcesapi.ListPodResourcesResponse{
|
|
PodResources: []*podresourcesapi.PodResources{
|
|
{
|
|
Name: podName,
|
|
Namespace: podNamespace,
|
|
Containers: []*podresourcesapi.ContainerResources{
|
|
{
|
|
Name: containerName,
|
|
Devices: devs,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
return resp, nil
|
|
}
|
|
|
|
func TestKubeletclient(t *testing.T) {
|
|
RegisterFailHandler(Fail)
|
|
RunSpecs(t, "Kubeletclient Suite")
|
|
}
|
|
|
|
func setUp() error {
|
|
tempSocketDir, err := ioutil.TempDir("", "kubelet-resource-client")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defaultPodResourcesPath = filepath.Join(tempSocketDir, defaultPodResourcesPath)
|
|
|
|
if err := os.MkdirAll(defaultPodResourcesPath, os.ModeDir); err != nil {
|
|
return err
|
|
}
|
|
|
|
socketDir = defaultPodResourcesPath
|
|
socketName = filepath.Join(socketDir, "kubelet.sock")
|
|
|
|
fakeServer = &fakeResourceServer{server: grpc.NewServer()}
|
|
podresourcesapi.RegisterPodResourcesListerServer(fakeServer.server, fakeServer)
|
|
lis, err := util.CreateListener(socketName)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
go fakeServer.server.Serve(lis)
|
|
return nil
|
|
}
|
|
|
|
func tearDown(path string) error {
|
|
if fakeServer != nil {
|
|
fakeServer.server.Stop()
|
|
}
|
|
if err := os.RemoveAll(path); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
var _ = BeforeSuite(func() {
|
|
err := setUp()
|
|
Expect(err).NotTo(HaveOccurred())
|
|
})
|
|
|
|
var _ = AfterSuite(func() {
|
|
err := tearDown(socketDir)
|
|
Expect(err).NotTo(HaveOccurred())
|
|
})
|
|
|
|
var _ = Describe("Kubelet resource endpoint data read operations", func() {
|
|
|
|
Context("GetResourceClient()", func() {
|
|
It("should return no error", func() {
|
|
kubeletSocket = socketName
|
|
_, 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() {
|
|
It("should return no error", 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 = socketName
|
|
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 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() {
|
|
It("should return error", func() {
|
|
podUID := k8sTypes.UID("970a395d-bb3b-11e8-89df-408d5c537d23")
|
|
fakePod := &v1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "",
|
|
Namespace: "pod-namespace",
|
|
UID: podUID,
|
|
},
|
|
}
|
|
kubeletSocket = socketName
|
|
client, err := getKubeletClient()
|
|
Expect(err).NotTo(HaveOccurred())
|
|
_, err = client.GetPodResourceMap(fakePod)
|
|
Expect(err).To(HaveOccurred())
|
|
})
|
|
})
|
|
|
|
Context("GetPodResourceMap() with empty namespace", func() {
|
|
It("should return error", func() {
|
|
podUID := k8sTypes.UID("970a395d-bb3b-11e8-89df-408d5c537d23")
|
|
fakePod := &v1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "pod-name",
|
|
Namespace: "",
|
|
UID: podUID,
|
|
},
|
|
}
|
|
kubeletSocket = socketName
|
|
client, err := getKubeletClient()
|
|
Expect(err).NotTo(HaveOccurred())
|
|
_, err = client.GetPodResourceMap(fakePod)
|
|
Expect(err).To(HaveOccurred())
|
|
})
|
|
})
|
|
|
|
Context("GetPodResourceMap() with non-existent podname and namespace", func() {
|
|
It("should return no error", func() {
|
|
podUID := k8sTypes.UID("970a395d-bb3b-11e8-89df-408d5c537d23")
|
|
fakePod := &v1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "whateverpod",
|
|
Namespace: "whatevernamespace",
|
|
UID: podUID,
|
|
},
|
|
}
|
|
|
|
kubeletSocket = socketName
|
|
client, err := getKubeletClient()
|
|
Expect(err).NotTo(HaveOccurred())
|
|
|
|
emptyRMap := map[string]*mtypes.ResourceInfo{}
|
|
resourceMap, err := client.GetPodResourceMap(fakePod)
|
|
Expect(err).NotTo(HaveOccurred())
|
|
Expect(resourceMap).ShouldNot(BeNil())
|
|
Expect(resourceMap).To(Equal(emptyRMap))
|
|
})
|
|
})
|
|
})
|