forked from github/multus-cni
Add unit-test to increase test coverage
This commit is contained in:
@@ -198,7 +198,7 @@ func main() {
|
|||||||
defer func() {
|
defer func() {
|
||||||
stopChannel <- struct{}{}
|
stopChannel <- struct{}{}
|
||||||
}()
|
}()
|
||||||
if err := configManager.MonitorPluginConfiguration(stopChannel, configWatcherDoneChannel); err != nil {
|
if err := configManager.MonitorPluginConfiguration(configWatcherDoneChannel, stopChannel); err != nil {
|
||||||
_ = logging.Errorf("error watching file: %v", err)
|
_ = logging.Errorf("error watching file: %v", err)
|
||||||
}
|
}
|
||||||
}(make(chan struct{}), configWatcherDoneChannel)
|
}(make(chan struct{}), configWatcherDoneChannel)
|
||||||
|
@@ -15,9 +15,13 @@
|
|||||||
package logging
|
package logging
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
|
||||||
testutils "gopkg.in/k8snetworkplumbingwg/multus-cni.v3/pkg/testing"
|
testutils "gopkg.in/k8snetworkplumbingwg/multus-cni.v3/pkg/testing"
|
||||||
"gopkg.in/natefinch/lumberjack.v2"
|
"gopkg.in/natefinch/lumberjack.v2"
|
||||||
"testing"
|
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
@@ -56,12 +60,16 @@ var _ = Describe("logging operations", func() {
|
|||||||
It("Check loglevel setter", func() {
|
It("Check loglevel setter", func() {
|
||||||
SetLogLevel("debug")
|
SetLogLevel("debug")
|
||||||
Expect(loggingLevel).To(Equal(DebugLevel))
|
Expect(loggingLevel).To(Equal(DebugLevel))
|
||||||
|
Expect(loggingLevel.String()).To(Equal("debug"))
|
||||||
SetLogLevel("Error")
|
SetLogLevel("Error")
|
||||||
Expect(loggingLevel).To(Equal(ErrorLevel))
|
Expect(loggingLevel).To(Equal(ErrorLevel))
|
||||||
|
Expect(loggingLevel.String()).To(Equal("error"))
|
||||||
SetLogLevel("VERbose")
|
SetLogLevel("VERbose")
|
||||||
Expect(loggingLevel).To(Equal(VerboseLevel))
|
Expect(loggingLevel).To(Equal(VerboseLevel))
|
||||||
|
Expect(loggingLevel.String()).To(Equal("verbose"))
|
||||||
SetLogLevel("PANIC")
|
SetLogLevel("PANIC")
|
||||||
Expect(loggingLevel).To(Equal(PanicLevel))
|
Expect(loggingLevel).To(Equal(PanicLevel))
|
||||||
|
Expect(loggingLevel.String()).To(Equal("panic"))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("Check loglevel setter with invalid level", func() {
|
It("Check loglevel setter with invalid level", func() {
|
||||||
@@ -76,6 +84,37 @@ var _ = Describe("logging operations", func() {
|
|||||||
Expect(loggingStderr).NotTo(Equal(currentVal))
|
Expect(loggingStderr).NotTo(Equal(currentVal))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("Check log function is worked", func() {
|
||||||
|
Debugf("foobar")
|
||||||
|
Verbosef("foobar")
|
||||||
|
Expect(Errorf("foobar")).NotTo(BeNil())
|
||||||
|
Panicf("foobar")
|
||||||
|
})
|
||||||
|
|
||||||
|
It("Check log function is worked with stderr", func() {
|
||||||
|
SetLogStderr(true)
|
||||||
|
Debugf("foobar")
|
||||||
|
Verbosef("foobar")
|
||||||
|
Expect(Errorf("foobar")).NotTo(BeNil())
|
||||||
|
Panicf("foobar")
|
||||||
|
})
|
||||||
|
|
||||||
|
It("Check log function is worked with stderr", func() {
|
||||||
|
tmpDir, err := ioutil.TempDir("", "multus_tmp")
|
||||||
|
SetLogFile(fmt.Sprintf("%s/log.txt", tmpDir))
|
||||||
|
Debugf("foobar")
|
||||||
|
Verbosef("foobar")
|
||||||
|
Expect(Errorf("foobar")).NotTo(BeNil())
|
||||||
|
Panicf("foobar")
|
||||||
|
logger.Filename = ""
|
||||||
|
loggingW = nil
|
||||||
|
err = os.RemoveAll(tmpDir)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
// Revert the log variable to init
|
||||||
|
loggingW = nil
|
||||||
|
logger = &lumberjack.Logger{}
|
||||||
|
})
|
||||||
|
|
||||||
// Tests public getter
|
// Tests public getter
|
||||||
It("Check getter for logging level with current level", func() {
|
It("Check getter for logging level with current level", func() {
|
||||||
currentLevel := loggingLevel
|
currentLevel := loggingLevel
|
||||||
|
@@ -47,7 +47,7 @@ type Manager struct {
|
|||||||
// configuration to `multusAutoconfigDir`. This constructor will auto-discover
|
// configuration to `multusAutoconfigDir`. This constructor will auto-discover
|
||||||
// the primary CNI for which it will delegate.
|
// the primary CNI for which it will delegate.
|
||||||
func NewManager(config MultusConf, multusAutoconfigDir string, forceCNIVersion bool) (*Manager, error) {
|
func NewManager(config MultusConf, multusAutoconfigDir string, forceCNIVersion bool) (*Manager, error) {
|
||||||
defaultCNIPluginName, err := primaryCNIPluginName(multusAutoconfigDir)
|
defaultCNIPluginName, err := getPrimaryCNIPluginName(multusAutoconfigDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = logging.Errorf("failed to find the primary CNI plugin: %v", err)
|
_ = logging.Errorf("failed to find the primary CNI plugin: %v", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -218,7 +218,7 @@ func (m Manager) PersistMultusConfig(config string) error {
|
|||||||
return ioutil.WriteFile(m.multusConfigFilePath, []byte(config), UserRWPermission)
|
return ioutil.WriteFile(m.multusConfigFilePath, []byte(config), UserRWPermission)
|
||||||
}
|
}
|
||||||
|
|
||||||
func primaryCNIPluginName(multusAutoconfigDir string) (string, error) {
|
func getPrimaryCNIPluginName(multusAutoconfigDir string) (string, error) {
|
||||||
masterCniConfigFileName, err := findMasterPlugin(multusAutoconfigDir, 120)
|
masterCniConfigFileName, err := findMasterPlugin(multusAutoconfigDir, 120)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("failed to find the cluster master CNI plugin: %w", err)
|
return "", fmt.Errorf("failed to find the cluster master CNI plugin: %w", err)
|
||||||
|
@@ -16,9 +16,11 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
@@ -69,6 +71,62 @@ var _ = Describe("Configuration Manager", func() {
|
|||||||
Expect(config).To(Equal(expectedResult))
|
Expect(config).To(Equal(expectedResult))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("Check overrideCNIVersion is worked", func() {
|
||||||
|
err := overrideCNIVersion(defaultCniConfig, "1.1.1")
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
raw, err := ioutil.ReadFile(defaultCniConfig)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
var jsonConfig map[string]interface{}
|
||||||
|
err = json.Unmarshal(raw, &jsonConfig)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(jsonConfig["cniVersion"].(string)).To(Equal("1.1.1"))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("Check primaryCNIPlugin can be identified", func() {
|
||||||
|
fileName, err := getPrimaryCNIPluginName(multusConfigDir)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(fileName).To(Equal(primaryCNIPluginName))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("Check MonitorPluginConfiguration", func() {
|
||||||
|
config, err := configManager.GenerateConfig()
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
err = configManager.PersistMultusConfig(config)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
configWatcherDoneChannel := make(chan struct{})
|
||||||
|
go func(stopChannel chan struct{}, doneChannel chan struct{}) {
|
||||||
|
defer func() {
|
||||||
|
stopChannel <- struct{}{}
|
||||||
|
}()
|
||||||
|
err := configManager.MonitorPluginConfiguration(configWatcherDoneChannel, stopChannel)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
}(make(chan struct{}), configWatcherDoneChannel)
|
||||||
|
|
||||||
|
updatedCNIConfig := `
|
||||||
|
{
|
||||||
|
"cniVersion": "0.4.0",
|
||||||
|
"name": "mycni-name",
|
||||||
|
"type": "mycni2",
|
||||||
|
"ipam": {},
|
||||||
|
"dns": {}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
// update the CNI config to update the master config
|
||||||
|
Expect(ioutil.WriteFile(defaultCniConfig, []byte(updatedCNIConfig), UserRWPermission)).To(Succeed())
|
||||||
|
|
||||||
|
// wait for a while to get fsnotify event
|
||||||
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
file, err := ioutil.ReadFile(configManager.multusConfigFilePath)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(string(file)).To(Equal(config))
|
||||||
|
|
||||||
|
// stop groutine
|
||||||
|
configWatcherDoneChannel <- struct{}{}
|
||||||
|
})
|
||||||
|
|
||||||
When("the user requests the name of the multus configuration to be overridden", func() {
|
When("the user requests the name of the multus configuration to be overridden", func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
Expect(configManager.OverrideNetworkName()).To(Succeed())
|
Expect(configManager.OverrideNetworkName()).To(Succeed())
|
||||||
|
58
pkg/server/exec_chroot_test.go
Normal file
58
pkg/server/exec_chroot_test.go
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
// Copyright (c) 2021 Multus 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 server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = Describe("exec_chroot", func() {
|
||||||
|
|
||||||
|
It("Call ChrootExec.ExecPlugin with dummy", func() {
|
||||||
|
chrootExec := &ChrootExec{
|
||||||
|
Stderr: os.Stderr,
|
||||||
|
chrootDir: "/usr",
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := chrootExec.ExecPlugin(context.Background(), "/bin/true", nil, nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("Call invalid ChrootExec.ExecPlugin with dummy", func() {
|
||||||
|
chrootExec := &ChrootExec{
|
||||||
|
Stderr: os.Stderr,
|
||||||
|
chrootDir: "/tmp",
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := chrootExec.ExecPlugin(context.Background(), "/bin/true", nil, nil)
|
||||||
|
Expect(err).To(HaveOccurred())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("Call ChrootExec.FindInPath with dummy", func() {
|
||||||
|
chrootExec := &ChrootExec{
|
||||||
|
Stderr: os.Stderr,
|
||||||
|
chrootDir: "/usr/bin",
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := chrootExec.FindInPath("true", []string{"/"})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
28
pkg/server/server_suite_test.go
Normal file
28
pkg/server/server_suite_test.go
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
// Copyright (c) 2021 Multus 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 server
|
||||||
|
|
||||||
|
import (
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestServer(t *testing.T) {
|
||||||
|
RegisterFailHandler(Fail)
|
||||||
|
RunSpecs(t, "server")
|
||||||
|
}
|
@@ -72,9 +72,11 @@ func postRequest(args *skel.CmdArgs) (*Response, string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
response := &Response{}
|
response := &Response{}
|
||||||
if err = json.Unmarshal(body, response); err != nil {
|
if len(body) != 0 {
|
||||||
err = fmt.Errorf("failed to unmarshal response '%s': %v", string(body), err)
|
if err = json.Unmarshal(body, response); err != nil {
|
||||||
return nil, multusShimConfig.CNIVersion, err
|
err = fmt.Errorf("failed to unmarshal response '%s': %v", string(body), err)
|
||||||
|
return nil, multusShimConfig.CNIVersion, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return response, multusShimConfig.CNIVersion, nil
|
return response, multusShimConfig.CNIVersion, nil
|
||||||
}
|
}
|
||||||
|
@@ -20,7 +20,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
@@ -43,11 +42,6 @@ import (
|
|||||||
|
|
||||||
const suiteName = "Thick CNI architecture"
|
const suiteName = "Thick CNI architecture"
|
||||||
|
|
||||||
func TestMultusThickCNIArchitecture(t *testing.T) {
|
|
||||||
RegisterFailHandler(Fail)
|
|
||||||
RunSpecs(t, suiteName)
|
|
||||||
}
|
|
||||||
|
|
||||||
type fakeExec struct{}
|
type fakeExec struct{}
|
||||||
|
|
||||||
// ExecPlugin executes the plugin
|
// ExecPlugin executes the plugin
|
||||||
@@ -132,16 +126,15 @@ var _ = Describe(suiteName, func() {
|
|||||||
context.TODO(), podName, metav1.DeleteOptions{}))
|
context.TODO(), podName, metav1.DeleteOptions{}))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("ADD works successfully", func() {
|
It("ADD/CHECK/DEL works successfully", func() {
|
||||||
|
Expect(os.Setenv("CNI_COMMAND", "ADD")).NotTo(HaveOccurred())
|
||||||
Expect(CmdAdd(cniCmdArgs(containerID, netns.Path(), ifaceName, referenceConfig(thickPluginRunDir)))).To(Succeed())
|
Expect(CmdAdd(cniCmdArgs(containerID, netns.Path(), ifaceName, referenceConfig(thickPluginRunDir)))).To(Succeed())
|
||||||
})
|
|
||||||
|
|
||||||
It("DEL works successfully", func() {
|
Expect(os.Setenv("CNI_COMMAND", "CHECK")).NotTo(HaveOccurred())
|
||||||
Expect(CmdDel(cniCmdArgs(containerID, netns.Path(), ifaceName, referenceConfig(thickPluginRunDir)))).To(Succeed())
|
|
||||||
})
|
|
||||||
|
|
||||||
It("CHECK works successfully", func() {
|
|
||||||
Expect(CmdCheck(cniCmdArgs(containerID, netns.Path(), ifaceName, referenceConfig(thickPluginRunDir)))).To(Succeed())
|
Expect(CmdCheck(cniCmdArgs(containerID, netns.Path(), ifaceName, referenceConfig(thickPluginRunDir)))).To(Succeed())
|
||||||
|
|
||||||
|
Expect(os.Setenv("CNI_COMMAND", "DEL")).NotTo(HaveOccurred())
|
||||||
|
Expect(CmdDel(cniCmdArgs(containerID, netns.Path(), ifaceName, referenceConfig(thickPluginRunDir)))).To(Succeed())
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -186,16 +179,16 @@ var _ = Describe(suiteName, func() {
|
|||||||
context.TODO(), podName, metav1.DeleteOptions{}))
|
context.TODO(), podName, metav1.DeleteOptions{}))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("ADD works successfully", func() {
|
It("ADD/CHECK/DEL works successfully", func() {
|
||||||
|
Expect(os.Setenv("CNI_COMMAND", "ADD")).NotTo(HaveOccurred())
|
||||||
Expect(CmdAdd(cniCmdArgs(containerID, netns.Path(), ifaceName, referenceConfig(thickPluginRunDir)))).To(Succeed())
|
Expect(CmdAdd(cniCmdArgs(containerID, netns.Path(), ifaceName, referenceConfig(thickPluginRunDir)))).To(Succeed())
|
||||||
})
|
|
||||||
|
|
||||||
It("DEL works successfully", func() {
|
Expect(os.Setenv("CNI_COMMAND", "CHECK")).NotTo(HaveOccurred())
|
||||||
Expect(CmdDel(cniCmdArgs(containerID, netns.Path(), ifaceName, referenceConfig(thickPluginRunDir)))).To(Succeed())
|
|
||||||
})
|
|
||||||
|
|
||||||
It("CHECK works successfully", func() {
|
|
||||||
Expect(CmdCheck(cniCmdArgs(containerID, netns.Path(), ifaceName, referenceConfig(thickPluginRunDir)))).To(Succeed())
|
Expect(CmdCheck(cniCmdArgs(containerID, netns.Path(), ifaceName, referenceConfig(thickPluginRunDir)))).To(Succeed())
|
||||||
|
|
||||||
|
Expect(os.Setenv("CNI_COMMAND", "DEL")).NotTo(HaveOccurred())
|
||||||
|
Expect(CmdDel(cniCmdArgs(containerID, netns.Path(), ifaceName, referenceConfig(thickPluginRunDir)))).To(Succeed())
|
||||||
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -219,9 +212,6 @@ func cniCmdArgs(containerID string, netnsPath string, ifName string, stdinData s
|
|||||||
|
|
||||||
func prepareCNIEnv(netnsPath string, namespaceName string, podName string, podUID string) error {
|
func prepareCNIEnv(netnsPath string, namespaceName string, podName string, podUID string) error {
|
||||||
cniArgs := fmt.Sprintf("K8S_POD_NAMESPACE=%s;K8S_POD_NAME=%s;K8S_POD_INFRA_CONTAINER_ID=;K8S_POD_UID=%s", namespaceName, podName, podUID)
|
cniArgs := fmt.Sprintf("K8S_POD_NAMESPACE=%s;K8S_POD_NAME=%s;K8S_POD_INFRA_CONTAINER_ID=;K8S_POD_UID=%s", namespaceName, podName, podUID)
|
||||||
if err := os.Setenv("CNI_COMMAND", "ADD"); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := os.Setenv("CNI_CONTAINERID", "123456789"); err != nil {
|
if err := os.Setenv("CNI_CONTAINERID", "123456789"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -290,7 +280,7 @@ func referenceConfig(thickPluginSocketDir string) string {
|
|||||||
"defaultnetworkwaitseconds": 3,
|
"defaultnetworkwaitseconds": 3,
|
||||||
"delegates": [{
|
"delegates": [{
|
||||||
"name": "weave1",
|
"name": "weave1",
|
||||||
"cniVersion": "0.3.1",
|
"cniVersion": "0.4.0",
|
||||||
"type": "weave-net"
|
"type": "weave-net"
|
||||||
}]}`
|
}]}`
|
||||||
return fmt.Sprintf(referenceConfigTemplate, thickPluginSocketDir)
|
return fmt.Sprintf(referenceConfigTemplate, thickPluginSocketDir)
|
||||||
|
Reference in New Issue
Block a user