From f0daefa63d3ee4ca0f63fe4d94ffff9b4d69a8a5 Mon Sep 17 00:00:00 2001 From: "Mark St.Godard" Date: Sat, 5 Nov 2016 23:27:14 -0500 Subject: [PATCH] flannel: add unit tests for config loading backfill unit tests to add coverage for loadFlannelNetConf and loadFlannelSubnetEnv --- plugins/meta/flannel/flannel_suite_test.go | 2 +- plugins/meta/flannel/flannel_test.go | 161 ++++++++++++++------- 2 files changed, 109 insertions(+), 54 deletions(-) diff --git a/plugins/meta/flannel/flannel_suite_test.go b/plugins/meta/flannel/flannel_suite_test.go index ec8c6119..fc96d4a5 100644 --- a/plugins/meta/flannel/flannel_suite_test.go +++ b/plugins/meta/flannel/flannel_suite_test.go @@ -11,7 +11,7 @@ // 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 main_test +package main import ( "encoding/json" diff --git a/plugins/meta/flannel/flannel_test.go b/plugins/meta/flannel/flannel_test.go index d7b47eb5..177c3c71 100644 --- a/plugins/meta/flannel/flannel_test.go +++ b/plugins/meta/flannel/flannel_test.go @@ -11,7 +11,7 @@ // 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 main_test +package main import ( "fmt" @@ -35,6 +35,8 @@ var _ = Describe("Flannel", func() { input string debug *noop_debug.Debug expectedCmdArgs skel.CmdArgs + subnetFile string + stateDir string ) const delegateInput = ` @@ -61,6 +63,14 @@ FLANNEL_MTU=1472 FLANNEL_IPMASQ=true ` + var writeSubnetEnv = func(contents string) string { + file, err := ioutil.TempFile("", "subnet.env") + Expect(err).NotTo(HaveOccurred()) + _, err = file.WriteString(contents) + Expect(err).NotTo(HaveOccurred()) + return file.Name() + } + var cniCommand = func(command, input string) *exec.Cmd { toReturn := exec.Command(paths.PathToPlugin) toReturn.Env = []string{ @@ -86,61 +96,50 @@ FLANNEL_IPMASQ=true ReportVersionSupport: []string{"0.1.0", "0.2.0", "0.3.0"}, } Expect(debug.WriteDebug(debugFileName)).To(Succeed()) + + // flannel subnet.env + subnetFile = writeSubnetEnv(flannelSubnetEnv) + + // flannel state dir + stateDir, err = ioutil.TempDir("", "stateDir") + Expect(err).NotTo(HaveOccurred()) + input = fmt.Sprintf(inputTemplate, subnetFile, stateDir) }) AfterEach(func() { os.Remove(debugFileName) + os.Remove(subnetFile) + os.Remove(stateDir) }) Describe("CNI lifecycle", func() { - Context("when subnetFile and stateDir are specified", func() { - var ( - subnetFile string - stateDir string - ) - BeforeEach(func() { - var err error - file, err := ioutil.TempFile("", "subnet.env") - Expect(err).NotTo(HaveOccurred()) - _, err = file.WriteString(flannelSubnetEnv) - Expect(err).NotTo(HaveOccurred()) - subnetFile = file.Name() + BeforeEach(func() { + expectedCmdArgs = skel.CmdArgs{ + ContainerID: "some-container-id", + Netns: "/some/netns/path", + IfName: "some-eth0", + Args: "DEBUG=" + debugFileName, + Path: "/some/bin/path", + StdinData: []byte(input), + } + cmd = cniCommand("ADD", input) + }) - stateDir, err = ioutil.TempDir("", "stateDir") - Expect(err).NotTo(HaveOccurred()) - input = fmt.Sprintf(inputTemplate, subnetFile, stateDir) + It("uses stateDir for storing network configuration", func() { + By("calling ADD") + session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter) + Expect(err).NotTo(HaveOccurred()) + Eventually(session).Should(gexec.Exit(0)) + Expect(session.Out.Contents()).To(MatchJSON(`{ "ip4": { "ip": "1.2.3.4/32" }, "dns":{} }`)) - expectedCmdArgs = skel.CmdArgs{ - ContainerID: "some-container-id", - Netns: "/some/netns/path", - IfName: "some-eth0", - Args: "DEBUG=" + debugFileName, - Path: "/some/bin/path", - StdinData: []byte(input), - } - cmd = cniCommand("ADD", input) - }) + By("check that plugin writes to net config to stateDir") + path := fmt.Sprintf("%s/%s", stateDir, "some-container-id") + Expect(path).Should(BeAnExistingFile()) - AfterEach(func() { - os.Remove(subnetFile) - os.Remove(stateDir) - }) - - It("uses stateDir for storing network configuration", func() { - By("calling ADD") - session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter) - Expect(err).NotTo(HaveOccurred()) - Eventually(session).Should(gexec.Exit(0)) - Expect(session.Out.Contents()).To(MatchJSON(`{ "ip4": { "ip": "1.2.3.4/32" }, "dns":{} }`)) - - By("check that plugin writes to net config to stateDir") - path := fmt.Sprintf("%s/%s", stateDir, "some-container-id") - Expect(path).Should(BeAnExistingFile()) - - netConfBytes, err := ioutil.ReadFile(path) - Expect(err).NotTo(HaveOccurred()) - expected := `{ + netConfBytes, err := ioutil.ReadFile(path) + Expect(err).NotTo(HaveOccurred()) + expected := `{ "name" : "cni-flannel", "type" : "noop", "ipam" : { @@ -157,16 +156,72 @@ FLANNEL_IPMASQ=true "some" : "other data" } ` - Expect(netConfBytes).Should(MatchJSON(expected)) + Expect(netConfBytes).Should(MatchJSON(expected)) - By("calling DEL") - cmd = cniCommand("DEL", input) - session, err = gexec.Start(cmd, GinkgoWriter, GinkgoWriter) - Expect(err).NotTo(HaveOccurred()) - Eventually(session).Should(gexec.Exit(0)) + By("calling DEL") + cmd = cniCommand("DEL", input) + session, err = gexec.Start(cmd, GinkgoWriter, GinkgoWriter) + Expect(err).NotTo(HaveOccurred()) + Eventually(session).Should(gexec.Exit(0)) - By("check that plugin removes net config from state dir") - Expect(path).ShouldNot(BeAnExistingFile()) + By("check that plugin removes net config from state dir") + Expect(path).ShouldNot(BeAnExistingFile()) + }) + }) + + Describe("loadFlannelNetConf", func() { + Context("when subnetFile and stateDir are specified", func() { + It("loads flannel network config", func() { + conf, err := loadFlannelNetConf([]byte(input)) + Expect(err).ShouldNot(HaveOccurred()) + Expect(conf.Name).To(Equal("cni-flannel")) + Expect(conf.Type).To(Equal("flannel")) + Expect(conf.SubnetFile).To(Equal(subnetFile)) + Expect(conf.StateDir).To(Equal(stateDir)) + }) + }) + + Context("when defaulting subnetFile and stateDir", func() { + BeforeEach(func() { + input = `{ +"name": "cni-flannel", +"type": "flannel", +"delegate": ` + + delegateInput + + `}` + }) + + It("loads flannel network config with defaults", func() { + conf, err := loadFlannelNetConf([]byte(input)) + Expect(err).ShouldNot(HaveOccurred()) + Expect(conf.Name).To(Equal("cni-flannel")) + Expect(conf.Type).To(Equal("flannel")) + Expect(conf.SubnetFile).To(Equal(defaultSubnetFile)) + Expect(conf.StateDir).To(Equal(defaultStateDir)) + }) + }) + + Describe("loadFlannelSubnetEnv", func() { + Context("when flannel subnet env is valid", func() { + It("loads flannel subnet config", func() { + conf, err := loadFlannelSubnetEnv(subnetFile) + Expect(err).ShouldNot(HaveOccurred()) + Expect(conf.nw.String()).To(Equal("10.1.0.0/16")) + Expect(conf.sn.String()).To(Equal("10.1.17.0/24")) + var mtu uint = 1472 + Expect(*conf.mtu).To(Equal(mtu)) + Expect(*conf.ipmasq).To(BeTrue()) + }) + }) + + Context("when flannel subnet env is invalid", func() { + BeforeEach(func() { + subnetFile = writeSubnetEnv("foo=bar") + }) + It("returns an error", func() { + _, err := loadFlannelSubnetEnv(subnetFile) + Expect(err).To(MatchError(ContainSubstring("missing FLANNEL_NETWORK, FLANNEL_SUBNET, FLANNEL_MTU, FLANNEL_IPMASQ"))) + }) }) }) })