github.com/jk-he/cni@v0.8.1/plugins/test/noop/noop_test.go (about) 1 // Copyright 2016 CNI authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package main_test 16 17 import ( 18 "fmt" 19 "io/ioutil" 20 "os" 21 "os/exec" 22 "strings" 23 24 "github.com/containernetworking/cni/pkg/skel" 25 "github.com/containernetworking/cni/pkg/types" 26 "github.com/containernetworking/cni/pkg/version" 27 noop_debug "github.com/containernetworking/cni/plugins/test/noop/debug" 28 . "github.com/onsi/ginkgo" 29 . "github.com/onsi/gomega" 30 "github.com/onsi/gomega/gexec" 31 ) 32 33 var _ = Describe("No-op plugin", func() { 34 var ( 35 cmd *exec.Cmd 36 debugFileName string 37 debug *noop_debug.Debug 38 expectedCmdArgs skel.CmdArgs 39 ) 40 41 const reportResult = `{ "ips": [{ "version": "4", "address": "10.1.2.3/24" }], "dns": {} }` 42 43 BeforeEach(func() { 44 debug = &noop_debug.Debug{ 45 ReportResult: reportResult, 46 ReportVersionSupport: []string{"0.1.0", "0.2.0", "0.3.0", "0.3.1", "0.4.0"}, 47 } 48 49 debugFile, err := ioutil.TempFile("", "cni_debug") 50 Expect(err).NotTo(HaveOccurred()) 51 Expect(debugFile.Close()).To(Succeed()) 52 debugFileName = debugFile.Name() 53 54 Expect(debug.WriteDebug(debugFileName)).To(Succeed()) 55 56 cmd = exec.Command(pathToPlugin) 57 58 args := fmt.Sprintf("DEBUG=%s;FOO=BAR", debugFileName) 59 cmd.Env = []string{ 60 "CNI_COMMAND=ADD", 61 "CNI_CONTAINERID=some-container-id", 62 "CNI_NETNS=/some/netns/path", 63 "CNI_IFNAME=some-eth0", 64 "CNI_PATH=/some/bin/path", 65 // Keep this last 66 "CNI_ARGS=" + args, 67 } 68 stdinData := `{"name": "noop-test", "some":"stdin-json", "cniVersion": "0.3.1"}` 69 cmd.Stdin = strings.NewReader(stdinData) 70 expectedCmdArgs = skel.CmdArgs{ 71 ContainerID: "some-container-id", 72 Netns: "/some/netns/path", 73 IfName: "some-eth0", 74 Args: args, 75 Path: "/some/bin/path", 76 StdinData: []byte(stdinData), 77 } 78 }) 79 80 AfterEach(func() { 81 os.Remove(debugFileName) 82 }) 83 84 It("responds to ADD using the ReportResult debug field", func() { 85 session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter) 86 Expect(err).NotTo(HaveOccurred()) 87 Eventually(session).Should(gexec.Exit(0)) 88 Expect(session.Out.Contents()).To(MatchJSON(reportResult)) 89 }) 90 91 It("panics when no debug file is given", func() { 92 // Remove the DEBUG option from CNI_ARGS and regular args 93 cmd.Env[len(cmd.Env)-1] = "CNI_ARGS=FOO=BAR" 94 expectedCmdArgs.Args = "FOO=BAR" 95 96 session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter) 97 Expect(err).NotTo(HaveOccurred()) 98 Eventually(session).Should(gexec.Exit(2)) 99 }) 100 101 It("pass previous result 0.3.1 through when ReportResult is PASSTHROUGH", func() { 102 debug = &noop_debug.Debug{ReportResult: "PASSTHROUGH"} 103 Expect(debug.WriteDebug(debugFileName)).To(Succeed()) 104 105 cmd.Stdin = strings.NewReader(`{ 106 "name":"noop-test", 107 "some":"stdin-json", 108 "cniVersion": "0.3.1", 109 "prevResult": { 110 "ips": [{"version": "4", "address": "10.1.2.15/24"}] 111 } 112 }`) 113 session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter) 114 Expect(err).NotTo(HaveOccurred()) 115 Eventually(session).Should(gexec.Exit(0)) 116 Expect(session.Out.Contents()).To(MatchJSON(`{"cniVersion": "0.3.1", "ips": [{"version": "4", "address": "10.1.2.15/24"}], "dns": {}}`)) 117 }) 118 119 It("pass previous result 0.4.0 through when ReportResult is PASSTHROUGH", func() { 120 debug = &noop_debug.Debug{ReportResult: "PASSTHROUGH"} 121 Expect(debug.WriteDebug(debugFileName)).To(Succeed()) 122 123 cmd.Stdin = strings.NewReader(`{ 124 "name":"noop-test", 125 "some":"stdin-json", 126 "cniVersion": "0.4.0", 127 "prevResult": { 128 "ips": [{"version": "4", "address": "10.1.2.15/24"}] 129 } 130 }`) 131 session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter) 132 Expect(err).NotTo(HaveOccurred()) 133 Eventually(session).Should(gexec.Exit(0)) 134 Expect(session.Out.Contents()).To(MatchJSON(`{"cniVersion": "0.4.0", "ips": [{"version": "4", "address": "10.1.2.15/24"}], "dns": {}}`)) 135 }) 136 137 It("injects DNS into previous result when ReportResult is INJECT-DNS", func() { 138 debug = &noop_debug.Debug{ReportResult: "INJECT-DNS"} 139 Expect(debug.WriteDebug(debugFileName)).To(Succeed()) 140 141 cmd.Stdin = strings.NewReader(`{ 142 "name":"noop-test", 143 "some":"stdin-json", 144 "cniVersion": "0.4.0", 145 "prevResult": { 146 "cniVersion": "0.3.1", 147 "ips": [{"version": "4", "address": "10.1.2.3/24"}], 148 "dns": {} 149 } 150 }`) 151 152 session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter) 153 Expect(err).NotTo(HaveOccurred()) 154 Eventually(session).Should(gexec.Exit(0)) 155 Expect(session.Out.Contents()).To(MatchJSON(`{ 156 "cniVersion": "0.4.0", 157 "ips": [{"version": "4", "address": "10.1.2.3/24"}], 158 "dns": {"nameservers": ["1.2.3.4"]} 159 }`)) 160 }) 161 162 It("allows passing debug file in config JSON", func() { 163 // Remove the DEBUG option from CNI_ARGS and regular args 164 newArgs := "FOO=BAR" 165 cmd.Env[len(cmd.Env)-1] = "CNI_ARGS=" + newArgs 166 newStdin := fmt.Sprintf(`{"name":"noop-test", "some": "stdin-json", "cniVersion": "0.4.0", "debugFile": %q}`, debugFileName) 167 cmd.Stdin = strings.NewReader(newStdin) 168 expectedCmdArgs.Args = newArgs 169 expectedCmdArgs.StdinData = []byte(newStdin) 170 171 session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter) 172 Expect(err).NotTo(HaveOccurred()) 173 Eventually(session).Should(gexec.Exit(0)) 174 Expect(session.Out.Contents()).To(MatchJSON(reportResult)) 175 176 debug, err := noop_debug.ReadDebug(debugFileName) 177 Expect(err).NotTo(HaveOccurred()) 178 Expect(debug.Command).To(Equal("ADD")) 179 Expect(debug.CmdArgs).To(Equal(expectedCmdArgs)) 180 }) 181 182 It("records all the args provided by skel.PluginMain", func() { 183 session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter) 184 Expect(err).NotTo(HaveOccurred()) 185 Eventually(session).Should(gexec.Exit(0)) 186 187 debug, err := noop_debug.ReadDebug(debugFileName) 188 Expect(err).NotTo(HaveOccurred()) 189 Expect(debug.Command).To(Equal("ADD")) 190 Expect(debug.CmdArgs).To(Equal(expectedCmdArgs)) 191 }) 192 193 Context("when the ReportResult debug field is empty", func() { 194 BeforeEach(func() { 195 debug.ReportResult = "" 196 Expect(debug.WriteDebug(debugFileName)).To(Succeed()) 197 }) 198 199 It("returns no result", func() { 200 session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter) 201 Expect(err).NotTo(HaveOccurred()) 202 Eventually(session).Should(gexec.Exit(0)) 203 Expect(session.Out.Contents()).To(Equal([]byte{})) 204 205 debug, err := noop_debug.ReadDebug(debugFileName) 206 Expect(err).NotTo(HaveOccurred()) 207 Expect(debug.ReportResult).To(Equal("")) 208 }) 209 }) 210 211 Context("when the ExitWithCode debug field is set", func() { 212 BeforeEach(func() { 213 debug.ReportResult = "" 214 debug.ExitWithCode = 3 215 Expect(debug.WriteDebug(debugFileName)).To(Succeed()) 216 }) 217 218 It("returns no result and exits with the expected code", func() { 219 session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter) 220 Expect(err).NotTo(HaveOccurred()) 221 Eventually(session).Should(gexec.Exit(3)) 222 Expect(session.Out.Contents()).To(Equal([]byte{})) 223 224 debug, err := noop_debug.ReadDebug(debugFileName) 225 Expect(err).NotTo(HaveOccurred()) 226 Expect(debug.ReportResult).To(Equal("")) 227 }) 228 }) 229 230 Context("when the ReportResult debug field is set", func() { 231 var expectedResultString = fmt.Sprintf(` { "result": %q }`, noop_debug.EmptyReportResultMessage) 232 233 BeforeEach(func() { 234 debug.ReportResult = expectedResultString 235 Expect(debug.WriteDebug(debugFileName)).To(Succeed()) 236 }) 237 238 It("substitutes a helpful message for the test author", func() { 239 session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter) 240 Expect(err).NotTo(HaveOccurred()) 241 Eventually(session).Should(gexec.Exit(0)) 242 Expect(session.Out.Contents()).To(MatchJSON(expectedResultString)) 243 244 debug, err := noop_debug.ReadDebug(debugFileName) 245 Expect(err).NotTo(HaveOccurred()) 246 Expect(debug.ReportResult).To(MatchJSON(expectedResultString)) 247 }) 248 }) 249 250 Context("when the ReportError debug field is set", func() { 251 BeforeEach(func() { 252 debug.ReportError = "banana" 253 Expect(debug.WriteDebug(debugFileName)).To(Succeed()) 254 }) 255 256 It("returns an error to skel.PluginMain, causing the process to exit code 1", func() { 257 session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter) 258 Expect(err).NotTo(HaveOccurred()) 259 Eventually(session).Should(gexec.Exit(1)) 260 Expect(session.Out.Contents()).To(MatchJSON(fmt.Sprintf(`{ "code": %d, "msg": "banana" }`, types.ErrInternal))) 261 }) 262 }) 263 264 Context("when the CNI_COMMAND is DEL", func() { 265 BeforeEach(func() { 266 cmd.Env[0] = "CNI_COMMAND=DEL" 267 debug.ReportResult = `{ "some": "delete-data" }` 268 Expect(debug.WriteDebug(debugFileName)).To(Succeed()) 269 }) 270 271 It("still does all the debug behavior", func() { 272 session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter) 273 Expect(err).NotTo(HaveOccurred()) 274 Eventually(session).Should(gexec.Exit(0)) 275 Expect(session.Out.Contents()).To(MatchJSON(`{ 276 "some": "delete-data" 277 }`)) 278 debug, err := noop_debug.ReadDebug(debugFileName) 279 Expect(err).NotTo(HaveOccurred()) 280 Expect(debug.Command).To(Equal("DEL")) 281 Expect(debug.CmdArgs).To(Equal(expectedCmdArgs)) 282 }) 283 }) 284 285 Context("when the CNI_COMMAND is VERSION", func() { 286 BeforeEach(func() { 287 cmd.Env[0] = "CNI_COMMAND=VERSION" 288 debug.ReportVersionSupport = []string{"0.123.0", "0.2.0"} 289 290 Expect(debug.WriteDebug(debugFileName)).To(Succeed()) 291 }) 292 293 It("claims to support the specified versions", func() { 294 session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter) 295 Expect(err).NotTo(HaveOccurred()) 296 Eventually(session).Should(gexec.Exit(0)) 297 decoder := &version.PluginDecoder{} 298 pluginInfo, err := decoder.Decode(session.Out.Contents()) 299 Expect(err).NotTo(HaveOccurred()) 300 Expect(pluginInfo.SupportedVersions()).To(ConsistOf( 301 "0.123.0", "0.2.0")) 302 }) 303 }) 304 })