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  })