Add unit test

Signed-off-by: Xianglin Gao <xlgao@zju.edu.cn>
This commit is contained in:
Xianglin Gao 2017-05-22 22:58:26 +08:00
parent 6d2b9fabca
commit 4a4414987f
8 changed files with 403 additions and 37 deletions

View File

@ -42,8 +42,8 @@ func main() {
if err != nil {
glog.Exitf("Failed to connect containerd endpoint %q: %v", o.ContainerdEndpoint, err)
}
glog.V(2).Infof("Run cri-containerd grpc server on socket %q", o.SocketPath)
glog.V(2).Infof("Run cri-containerd grpc server on socket %q", o.SocketPath)
service, err := server.NewCRIContainerdService(conn, o.RootDir, o.NetworkPluginBinDir, o.NetworkPluginConfDir)
if err != nil {
glog.Exitf("Failed to create CRI containerd service %+v: %v", o, err)

View File

@ -19,6 +19,7 @@ package testing
import (
"io"
"os"
"sync"
"golang.org/x/net/context"
@ -29,20 +30,64 @@ import (
// If a member of the form `*Fn` is set, that function will be called in place
// of the real call.
type FakeOS struct {
sync.Mutex
MkdirAllFn func(string, os.FileMode) error
RemoveAllFn func(string) error
OpenFifoFn func(context.Context, string, int, os.FileMode) (io.ReadWriteCloser, error)
StatFn func(name string) (os.FileInfo, error)
errors map[string]error
}
var _ osInterface.OS = &FakeOS{}
// getError get error for call
func (f *FakeOS) getError(op string) error {
f.Lock()
defer f.Unlock()
err, ok := f.errors[op]
if ok {
delete(f.errors, op)
return err
}
return nil
}
// InjectError inject error for call
func (f *FakeOS) InjectError(fn string, err error) {
f.Lock()
defer f.Unlock()
f.errors[fn] = err
}
// InjectErrors inject errors for calls
func (f *FakeOS) InjectErrors(errs map[string]error) {
f.Lock()
defer f.Unlock()
for fn, err := range errs {
f.errors[fn] = err
}
}
// ClearErrors clear errors for call
func (f *FakeOS) ClearErrors() {
f.Lock()
defer f.Unlock()
f.errors = make(map[string]error)
}
// NewFakeOS creates a FakeOS.
func NewFakeOS() *FakeOS {
return &FakeOS{}
return &FakeOS{
errors: make(map[string]error),
}
}
// MkdirAll is a fake call that invokes MkdirAllFn or just returns nil.
func (f *FakeOS) MkdirAll(path string, perm os.FileMode) error {
if err := f.getError("MkdirAll"); err != nil {
return err
}
if f.MkdirAllFn != nil {
return f.MkdirAllFn(path, perm)
}
@ -51,6 +96,10 @@ func (f *FakeOS) MkdirAll(path string, perm os.FileMode) error {
// RemoveAll is a fake call that invokes RemoveAllFn or just returns nil.
func (f *FakeOS) RemoveAll(path string) error {
if err := f.getError("RemoveAll"); err != nil {
return err
}
if f.RemoveAllFn != nil {
return f.RemoveAllFn(path)
}
@ -59,8 +108,24 @@ func (f *FakeOS) RemoveAll(path string) error {
// OpenFifo is a fake call that invokes OpenFifoFn or just returns nil.
func (f *FakeOS) OpenFifo(ctx context.Context, fn string, flag int, perm os.FileMode) (io.ReadWriteCloser, error) {
if err := f.getError("OpenFifo"); err != nil {
return nil, err
}
if f.OpenFifoFn != nil {
return f.OpenFifoFn(ctx, fn, flag, perm)
}
return nil, nil
}
// Stat is a fake call that invokes Stat or just return nil.
func (f *FakeOS) Stat(name string) (os.FileInfo, error) {
if err := f.getError("Stat"); err != nil {
return nil, err
}
if f.StatFn != nil {
return f.StatFn(name)
}
return nil, nil
}

View File

@ -164,7 +164,7 @@ func (c *criContainerdService) RunPodSandbox(ctx context.Context, r *runtime.Run
defer func() {
if retErr != nil {
// Cleanup the sandbox container if an error is returned.
if _, err := c.containerService.Delete(ctx, &execution.DeleteRequest{ID: id}); err != nil {
if _, err = c.containerService.Delete(ctx, &execution.DeleteRequest{ID: id}); err != nil {
glog.Errorf("Failed to delete sandbox container %q: %v",
id, err)
}

View File

@ -124,7 +124,8 @@ func TestGenerateSandboxContainerSpec(t *testing.T) {
func TestRunPodSandbox(t *testing.T) {
config, specCheck := getRunPodSandboxTestData()
c := newTestCRIContainerdService()
fake := c.containerService.(*servertesting.FakeExecutionClient)
fakeExecutionClient := c.containerService.(*servertesting.FakeExecutionClient)
fakeCNIPlugin := c.netPlugin.(*servertesting.FakeCNIPlugin)
fakeOS := c.os.(*ostesting.FakeOS)
var dirs []string
var pipes []string
@ -139,7 +140,7 @@ func TestRunPodSandbox(t *testing.T) {
assert.Equal(t, os.FileMode(0700), perm)
return nopReadWriteCloser{}, nil
}
expectCalls := []string{"create", "start"}
expectExecutionClientCalls := []string{"create", "start"}
res, err := c.RunPodSandbox(context.Background(), &runtime.RunPodSandboxRequest{Config: config})
assert.NoError(t, err)
@ -154,8 +155,8 @@ func TestRunPodSandbox(t *testing.T) {
assert.Contains(t, pipes, stdout, "sandbox stdout pipe should be created")
assert.Contains(t, pipes, stderr, "sandbox stderr pipe should be created")
assert.Equal(t, expectCalls, fake.GetCalledNames(), "expect containerd functions should be called")
calls := fake.GetCalledDetails()
assert.Equal(t, expectExecutionClientCalls, fakeExecutionClient.GetCalledNames(), "expect containerd functions should be called")
calls := fakeExecutionClient.GetCalledDetails()
createOpts := calls[0].Argument.(*execution.CreateRequest)
assert.Equal(t, id, createOpts.ID, "create id should be correct")
// TODO(random-liu): Test rootfs mount when image management part is integrated.
@ -177,7 +178,7 @@ func TestRunPodSandbox(t *testing.T) {
assert.Equal(t, config, meta.Config, "metadata config should be correct")
// TODO(random-liu): [P2] Add clock interface and use fake clock.
assert.NotZero(t, meta.CreatedAt, "metadata CreatedAt should be set")
info, err := fake.Info(context.Background(), &execution.InfoRequest{ID: id})
info, err := fakeExecutionClient.Info(context.Background(), &execution.InfoRequest{ID: id})
assert.NoError(t, err)
pid := info.Pid
assert.Equal(t, meta.NetNS, getNetworkNamespace(pid), "metadata network namespace should be correct")
@ -185,6 +186,13 @@ func TestRunPodSandbox(t *testing.T) {
gotID, err := c.sandboxIDIndex.Get(id)
assert.NoError(t, err)
assert.Equal(t, id, gotID, "sandbox id should be indexed")
expectedCNICalls := []string{"SetUpPod"}
assert.Equal(t, expectedCNICalls, fakeCNIPlugin.GetCalledNames(), "expect SetUpPod should be called")
calls = fakeCNIPlugin.GetCalledDetails()
pluginArgument := calls[0].Argument.(servertesting.CNIPluginArgument)
expectedPluginArgument := servertesting.CNIPluginArgument{meta.NetNS, config.GetMetadata().GetNamespace(), config.GetMetadata().GetName(), id}
assert.Equal(t, expectedPluginArgument, pluginArgument, "SetUpPod should be called with correct arguments")
}
// TODO(random-liu): [P1] Add unit test for different error cases to make sure

View File

@ -35,7 +35,11 @@ import (
// Variables used in the following test.
const sandboxStatusTestID = "test-id"
const (
sandboxStatusTestID = "test-id"
sandboxStatusTestIP = "10.10.10.10"
sandboxStatusTestNetNS = "test-netns"
)
func getSandboxStatusTestData() (*metadata.SandboxMetadata, *runtime.PodSandboxStatus) {
config := &runtime.PodSandboxConfig{
@ -65,15 +69,17 @@ func getSandboxStatusTestData() (*metadata.SandboxMetadata, *runtime.PodSandboxS
Name: "test-name",
Config: config,
CreatedAt: createdAt,
NetNS: sandboxStatusTestNetNS,
}
expectedStatus := &runtime.PodSandboxStatus{
Id: sandboxStatusTestID,
Metadata: config.GetMetadata(),
CreatedAt: createdAt,
Network: &runtime.PodSandboxNetworkStatus{},
Network: &runtime.PodSandboxNetworkStatus{Ip: ""},
Linux: &runtime.LinuxPodSandboxStatus{
Namespaces: &runtime.Namespace{
Network: sandboxStatusTestNetNS,
Options: &runtime.NamespaceOption{
HostNetwork: true,
HostPid: false,
@ -95,7 +101,7 @@ func TestToCRISandboxStatus(t *testing.T) {
}{
"ready sandbox should have network namespace": {
state: runtime.PodSandboxState_SANDBOX_READY,
expectNetNS: "test-netns",
expectNetNS: sandboxStatusTestNetNS,
},
"not ready sandbox should not have network namespace": {
state: runtime.PodSandboxState_SANDBOX_NOTREADY,
@ -103,10 +109,10 @@ func TestToCRISandboxStatus(t *testing.T) {
},
} {
metadata, expect := getSandboxStatusTestData()
metadata.NetNS = "test-netns"
status := toCRISandboxStatus(metadata, test.state)
status := toCRISandboxStatus(metadata, test.state, sandboxStatusTestIP)
expect.Linux.Namespaces.Network = test.expectNetNS
expect.State = test.state
expect.Network.Ip = sandboxStatusTestIP
assert.Equal(t, expect, status, desc)
}
}
@ -116,14 +122,18 @@ func TestPodSandboxStatus(t *testing.T) {
sandboxContainers []container.Container
injectMetadata bool
injectErr error
injectIP bool
injectCNIErr error
expectState runtime.PodSandboxState
expectErr bool
expectCalls []string
expectedCNICalls []string
}{
"sandbox status without metadata": {
injectMetadata: false,
expectErr: true,
expectCalls: []string{},
injectMetadata: false,
expectErr: true,
expectCalls: []string{},
expectedCNICalls: []string{},
},
"sandbox status with running sandbox container": {
sandboxContainers: []container.Container{{
@ -131,9 +141,10 @@ func TestPodSandboxStatus(t *testing.T) {
Pid: 1,
Status: container.Status_RUNNING,
}},
injectMetadata: true,
expectState: runtime.PodSandboxState_SANDBOX_READY,
expectCalls: []string{"info"},
injectMetadata: true,
expectState: runtime.PodSandboxState_SANDBOX_READY,
expectCalls: []string{"info"},
expectedCNICalls: []string{"GetContainerNetworkStatus"},
},
"sandbox status with stopped sandbox container": {
sandboxContainers: []container.Container{{
@ -141,15 +152,17 @@ func TestPodSandboxStatus(t *testing.T) {
Pid: 1,
Status: container.Status_STOPPED,
}},
injectMetadata: true,
expectState: runtime.PodSandboxState_SANDBOX_NOTREADY,
expectCalls: []string{"info"},
injectMetadata: true,
expectState: runtime.PodSandboxState_SANDBOX_NOTREADY,
expectCalls: []string{"info"},
expectedCNICalls: []string{"GetContainerNetworkStatus"},
},
"sandbox status with non-existing sandbox container": {
sandboxContainers: []container.Container{},
injectMetadata: true,
expectState: runtime.PodSandboxState_SANDBOX_NOTREADY,
expectCalls: []string{"info"},
expectedCNICalls: []string{"GetContainerNetworkStatus"},
},
"sandbox status with arbitrary error": {
sandboxContainers: []container.Container{{
@ -157,16 +170,44 @@ func TestPodSandboxStatus(t *testing.T) {
Pid: 1,
Status: container.Status_RUNNING,
}},
injectMetadata: true,
injectErr: errors.New("arbitrary error"),
expectErr: true,
expectCalls: []string{"info"},
injectMetadata: true,
expectState: runtime.PodSandboxState_SANDBOX_READY,
injectErr: errors.New("arbitrary error"),
expectErr: true,
expectCalls: []string{"info"},
expectedCNICalls: []string{},
},
"sandbox status with IP address": {
sandboxContainers: []container.Container{{
ID: sandboxStatusTestID,
Pid: 1,
Status: container.Status_RUNNING,
}},
injectMetadata: true,
expectState: runtime.PodSandboxState_SANDBOX_READY,
expectCalls: []string{"info"},
injectIP: true,
expectedCNICalls: []string{"GetContainerNetworkStatus"},
},
"sandbox status with GetContainerNetworkStatus returns error": {
sandboxContainers: []container.Container{{
ID: sandboxStatusTestID,
Pid: 1,
Status: container.Status_RUNNING,
}},
injectMetadata: true,
expectState: runtime.PodSandboxState_SANDBOX_READY,
expectCalls: []string{"info"},
expectedCNICalls: []string{"GetContainerNetworkStatus"},
injectCNIErr: errors.New("get container network status error"),
},
} {
t.Logf("TestCase %q", desc)
metadata, expect := getSandboxStatusTestData()
expect.Network.Ip = ""
c := newTestCRIContainerdService()
fake := c.containerService.(*servertesting.FakeExecutionClient)
fakeCNIPlugin := c.netPlugin.(*servertesting.FakeCNIPlugin)
fake.SetFakeContainers(test.sandboxContainers)
if test.injectMetadata {
assert.NoError(t, c.sandboxIDIndex.Add(metadata.ID))
@ -175,18 +216,31 @@ func TestPodSandboxStatus(t *testing.T) {
if test.injectErr != nil {
fake.InjectError("info", test.injectErr)
}
if test.injectCNIErr != nil {
fakeCNIPlugin.InjectError("GetContainerNetworkStatus", test.injectCNIErr)
}
if test.injectIP {
fakeCNIPlugin.SetFakePodNetwork(metadata.NetNS, metadata.Config.GetMetadata().GetNamespace(),
metadata.Config.GetMetadata().GetName(), sandboxStatusTestID, sandboxStatusTestIP)
expect.Network.Ip = sandboxStatusTestIP
}
res, err := c.PodSandboxStatus(context.Background(), &runtime.PodSandboxStatusRequest{
PodSandboxId: sandboxStatusTestID,
})
assert.Equal(t, test.expectCalls, fake.GetCalledNames())
assert.Equal(t, test.expectedCNICalls, fakeCNIPlugin.GetCalledNames())
if test.expectErr {
assert.Error(t, err)
assert.Nil(t, res)
continue
}
assert.NoError(t, err)
require.NotNil(t, res)
expect.State = test.expectState
if expect.State == runtime.PodSandboxState_SANDBOX_NOTREADY {
expect.Linux.Namespaces.Network = ""
}
assert.Equal(t, expect, res.GetStatus())
}
}

View File

@ -17,6 +17,8 @@ limitations under the License.
package server
import (
"errors"
"os"
"testing"
"github.com/stretchr/testify/assert"
@ -30,6 +32,7 @@ import (
"k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
"github.com/kubernetes-incubator/cri-containerd/pkg/metadata"
ostesting "github.com/kubernetes-incubator/cri-containerd/pkg/os/testing"
servertesting "github.com/kubernetes-incubator/cri-containerd/pkg/server/testing"
)
@ -38,6 +41,13 @@ func TestStopPodSandbox(t *testing.T) {
testSandbox := metadata.SandboxMetadata{
ID: testID,
Name: "test-name",
Config: &runtime.PodSandboxConfig{
Metadata: &runtime.PodSandboxMetadata{
Name: "test-name",
Uid: "test-uid",
Namespace: "test-ns",
}},
NetNS: "test-netns",
}
testContainer := container.Container{
ID: testID,
@ -49,38 +59,71 @@ func TestStopPodSandbox(t *testing.T) {
sandboxContainers []container.Container
injectSandbox bool
injectErr error
injectStatErr error
injectCNIErr error
expectErr bool
expectCalls []string
expectedCNICalls []string
}{
"stop non-existing sandbox": {
injectSandbox: false,
expectErr: true,
expectCalls: []string{},
injectSandbox: false,
expectErr: true,
expectCalls: []string{},
expectedCNICalls: []string{},
},
"stop sandbox with sandbox container": {
sandboxContainers: []container.Container{testContainer},
injectSandbox: true,
expectErr: false,
expectCalls: []string{"delete"},
expectedCNICalls: []string{"TearDownPod"},
},
"stop sandbox with sandbox container not exist error": {
sandboxContainers: []container.Container{},
injectSandbox: true,
// Inject error to make sure fake execution client returns error.
injectErr: grpc.Errorf(codes.Unknown, containerd.ErrContainerNotExist.Error()),
expectErr: false,
expectCalls: []string{"delete"},
injectErr: grpc.Errorf(codes.Unknown, containerd.ErrContainerNotExist.Error()),
expectErr: false,
expectCalls: []string{"delete"},
expectedCNICalls: []string{"TearDownPod"},
},
"stop sandbox with with arbitrary error": {
injectSandbox: true,
injectErr: grpc.Errorf(codes.Unknown, "arbitrary error"),
expectErr: true,
expectCalls: []string{"delete"},
injectSandbox: true,
injectErr: grpc.Errorf(codes.Unknown, "arbitrary error"),
expectErr: true,
expectCalls: []string{"delete"},
expectedCNICalls: []string{"TearDownPod"},
},
"stop sandbox with Stat returns arbitrary error": {
sandboxContainers: []container.Container{testContainer},
injectSandbox: true,
expectErr: true,
injectStatErr: errors.New("arbitrary error"),
expectCalls: []string{},
expectedCNICalls: []string{},
},
"stop sandbox with Stat returns not exist error": {
sandboxContainers: []container.Container{testContainer},
injectSandbox: true,
expectErr: false,
expectCalls: []string{"delete"},
injectStatErr: os.ErrNotExist,
expectedCNICalls: []string{},
},
"stop sandbox with TearDownPod fails": {
sandboxContainers: []container.Container{testContainer},
injectSandbox: true,
expectErr: true,
expectedCNICalls: []string{"TearDownPod"},
injectCNIErr: errors.New("arbitrary error"),
expectCalls: []string{},
},
} {
t.Logf("TestCase %q", desc)
c := newTestCRIContainerdService()
fake := c.containerService.(*servertesting.FakeExecutionClient)
fakeCNIPlugin := c.netPlugin.(*servertesting.FakeCNIPlugin)
fakeOS := c.os.(*ostesting.FakeOS)
fake.SetFakeContainers(test.sandboxContainers)
if test.injectSandbox {
@ -90,6 +133,14 @@ func TestStopPodSandbox(t *testing.T) {
if test.injectErr != nil {
fake.InjectError("delete", test.injectErr)
}
if test.injectCNIErr != nil {
fakeCNIPlugin.InjectError("TearDownPod", test.injectCNIErr)
}
if test.injectStatErr != nil {
fakeOS.InjectError("Stat", test.injectStatErr)
}
fakeCNIPlugin.SetFakePodNetwork(testSandbox.NetNS, testSandbox.Config.GetMetadata().GetNamespace(),
testSandbox.Config.GetMetadata().GetName(), testID, sandboxStatusTestIP)
res, err := c.StopPodSandbox(context.Background(), &runtime.StopPodSandboxRequest{
PodSandboxId: testID,
@ -102,5 +153,6 @@ func TestStopPodSandbox(t *testing.T) {
assert.NotNil(t, res)
}
assert.Equal(t, test.expectCalls, fake.GetCalledNames())
assert.Equal(t, test.expectedCNICalls, fakeCNIPlugin.GetCalledNames())
}
}

View File

@ -57,6 +57,7 @@ func newTestCRIContainerdService() *criContainerdService {
sandboxIDIndex: truncindex.NewTruncIndex(nil),
containerStore: metadata.NewContainerStore(store.NewMetadataStore()),
containerNameIndex: registrar.NewRegistrar(),
netPlugin: servertesting.NewFakeCNIPlugin(),
}
}
@ -65,6 +66,7 @@ func TestSandboxOperations(t *testing.T) {
c := newTestCRIContainerdService()
fake := c.containerService.(*servertesting.FakeExecutionClient)
fakeOS := c.os.(*ostesting.FakeOS)
fakeCNIPlugin := c.netPlugin.(*servertesting.FakeCNIPlugin)
fakeOS.OpenFifoFn = func(ctx context.Context, fn string, flag int, perm os.FileMode) (io.ReadWriteCloser, error) {
return nopReadWriteCloser{}, nil
}
@ -89,6 +91,7 @@ func TestSandboxOperations(t *testing.T) {
t.Logf("should be able to get pod sandbox status")
info, err := fake.Info(context.Background(), &execution.InfoRequest{ID: id})
netns := getNetworkNamespace(info.Pid)
assert.NoError(t, err)
expectSandboxStatus := &runtime.PodSandboxStatus{
Id: id,
@ -97,7 +100,7 @@ func TestSandboxOperations(t *testing.T) {
Network: &runtime.PodSandboxNetworkStatus{},
Linux: &runtime.LinuxPodSandboxStatus{
Namespaces: &runtime.Namespace{
Network: getNetworkNamespace(info.Pid),
Network: netns,
Options: &runtime.NamespaceOption{
HostNetwork: false,
HostPid: false,
@ -113,6 +116,9 @@ func TestSandboxOperations(t *testing.T) {
require.NotNil(t, statusRes)
status := statusRes.GetStatus()
expectSandboxStatus.CreatedAt = status.GetCreatedAt()
ip, err := fakeCNIPlugin.GetContainerNetworkStatus(netns, config.GetMetadata().GetNamespace(), config.GetMetadata().GetName(), id)
assert.NoError(t, err)
expectSandboxStatus.Network.Ip = ip
assert.Equal(t, expectSandboxStatus, status)
t.Logf("should be able to list pod sandboxes")

View File

@ -0,0 +1,181 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package testing
import (
"fmt"
"math/rand"
"strconv"
"sync"
"time"
"github.com/kubernetes-incubator/cri-o/pkg/ocicni"
)
// CNIPluginArgument is arguments used to call CNI related functions.
type CNIPluginArgument struct {
NetnsPath string
Namespace string
Name string
ContainerID string
}
// FakeCNIPlugin is a fake plugin used for test.
type FakeCNIPlugin struct {
sync.Mutex
called []CalledDetail
errors map[string]error
IPMap map[CNIPluginArgument]string
}
// getError get error for call
func (f *FakeCNIPlugin) getError(op string) error {
err, ok := f.errors[op]
if ok {
delete(f.errors, op)
return err
}
return nil
}
// InjectError inject error for call
func (f *FakeCNIPlugin) InjectError(fn string, err error) {
f.Lock()
defer f.Unlock()
f.errors[fn] = err
}
// InjectErrors inject errors for calls
func (f *FakeCNIPlugin) InjectErrors(errs map[string]error) {
f.Lock()
defer f.Unlock()
for fn, err := range errs {
f.errors[fn] = err
}
}
// ClearErrors clear errors for call
func (f *FakeCNIPlugin) ClearErrors() {
f.Lock()
defer f.Unlock()
f.errors = make(map[string]error)
}
func (f *FakeCNIPlugin) appendCalled(name string, argument interface{}) {
call := CalledDetail{Name: name, Argument: argument}
f.called = append(f.called, call)
}
// GetCalledNames get names of call
func (f *FakeCNIPlugin) GetCalledNames() []string {
f.Lock()
defer f.Unlock()
names := []string{}
for _, detail := range f.called {
names = append(names, detail.Name)
}
return names
}
// GetCalledDetails get detail of each call.
func (f *FakeCNIPlugin) GetCalledDetails() []CalledDetail {
f.Lock()
defer f.Unlock()
// Copy the list and return.
return append([]CalledDetail{}, f.called...)
}
// SetFakePodNetwork sets the given IP for given arguments.
func (f *FakeCNIPlugin) SetFakePodNetwork(netnsPath string, namespace string, name string, containerID string, ip string) {
f.Lock()
defer f.Unlock()
arg := CNIPluginArgument{netnsPath, namespace, name, containerID}
f.IPMap[arg] = ip
}
// NewFakeCNIPlugin create a FakeCNIPlugin.
func NewFakeCNIPlugin() ocicni.CNIPlugin {
return &FakeCNIPlugin{
errors: make(map[string]error),
IPMap: make(map[CNIPluginArgument]string),
}
}
// Name return the name of fake CNI plugin.
func (f *FakeCNIPlugin) Name() string {
return "fake-CNI-plugin"
}
// SetUpPod setup the network of PodSandbox.
func (f *FakeCNIPlugin) SetUpPod(netnsPath string, namespace string, name string, containerID string) error {
f.Lock()
defer f.Unlock()
arg := CNIPluginArgument{netnsPath, namespace, name, containerID}
f.appendCalled("SetUpPod", arg)
if err := f.getError("SetUpPod"); err != nil {
return err
}
f.IPMap[arg] = generateIP()
return nil
}
// TearDownPod teardown the network of PodSandbox.
func (f *FakeCNIPlugin) TearDownPod(netnsPath string, namespace string, name string, containerID string) error {
f.Lock()
defer f.Unlock()
arg := CNIPluginArgument{netnsPath, namespace, name, containerID}
f.appendCalled("TearDownPod", arg)
if err := f.getError("TearDownPod"); err != nil {
return err
}
_, ok := f.IPMap[arg]
if !ok {
return fmt.Errorf("failed to find the IP")
}
delete(f.IPMap, arg)
return nil
}
// GetContainerNetworkStatus get the status of network.
func (f *FakeCNIPlugin) GetContainerNetworkStatus(netnsPath string, namespace string, name string, containerID string) (string, error) {
f.Lock()
defer f.Unlock()
arg := CNIPluginArgument{netnsPath, namespace, name, containerID}
f.appendCalled("GetContainerNetworkStatus", arg)
if err := f.getError("GetContainerNetworkStatus"); err != nil {
return "", err
}
ip, ok := f.IPMap[arg]
if !ok {
return "", fmt.Errorf("failed to find the IP")
}
return ip, nil
}
// Status get the status of the plugin.
func (f *FakeCNIPlugin) Status() error {
return nil
}
func generateIP() string {
rand.Seed(time.Now().Unix())
p1 := strconv.Itoa(rand.Intn(266))
p2 := strconv.Itoa(rand.Intn(266))
p3 := strconv.Itoa(rand.Intn(266))
p4 := strconv.Itoa(rand.Intn(266))
return p1 + "." + p2 + "." + p3 + "." + p4
}