diff --git a/.travis.yml b/.travis.yml index d0335a1a..bb6097b0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: go sudo: required -dist: xenial +dist: bionic go: - 1.13.x diff --git a/integration/integration_linux_test.go b/integration/integration_linux_test.go index 82c8d488..08b2bfaf 100644 --- a/integration/integration_linux_test.go +++ b/integration/integration_linux_test.go @@ -225,23 +225,22 @@ func (n Namespace) Del() { } func makeTcpClientInNS(netns string, address string, port int, numBytes int) { - message := bytes.Repeat([]byte{'a'}, numBytes) + payload := bytes.Repeat([]byte{'a'}, numBytes) + message := string(payload) - bin, err := exec.LookPath("nc") - Expect(err).NotTo(HaveOccurred()) var cmd *exec.Cmd if netns != "" { netns = filepath.Base(netns) - cmd = exec.Command("ip", "netns", "exec", netns, bin, "-v", address, strconv.Itoa(port)) + cmd = exec.Command("ip", "netns", "exec", netns, echoClientBinaryPath, "--target", fmt.Sprintf("%s:%d", address, port), "--message", message) } else { - cmd = exec.Command("nc", address, strconv.Itoa(port)) + cmd = exec.Command(echoClientBinaryPath, "--target", fmt.Sprintf("%s:%d", address, port), "--message", message) } cmd.Stdin = bytes.NewBuffer([]byte(message)) cmd.Stderr = GinkgoWriter out, err := cmd.Output() Expect(err).NotTo(HaveOccurred()) - Expect(string(out)).To(Equal(string(message))) + Expect(string(out)).To(Equal(message)) } func startEchoServerInNamespace(netNS Namespace) (int, *gexec.Session, error) { diff --git a/integration/integration_suite_test.go b/integration/integration_suite_test.go index 4cff6e28..de861c45 100644 --- a/integration/integration_suite_test.go +++ b/integration/integration_suite_test.go @@ -14,11 +14,10 @@ package integration_test import ( - "math/rand" + "strings" "testing" . "github.com/onsi/ginkgo" - "github.com/onsi/ginkgo/config" . "github.com/onsi/gomega" "github.com/onsi/gomega/gexec" ) @@ -28,15 +27,18 @@ func TestIntegration(t *testing.T) { RunSpecs(t, "integration") } -var echoServerBinaryPath string +var echoServerBinaryPath, echoClientBinaryPath string var _ = SynchronizedBeforeSuite(func() []byte { - binaryPath, err := gexec.Build("github.com/containernetworking/plugins/pkg/testutils/echosvr") + serverBinaryPath, err := gexec.Build("github.com/containernetworking/plugins/pkg/testutils/echo/server") Expect(err).NotTo(HaveOccurred()) - return []byte(binaryPath) + clientBinaryPath, err := gexec.Build("github.com/containernetworking/plugins/pkg/testutils/echo/client") + Expect(err).NotTo(HaveOccurred()) + return []byte(strings.Join([]string{serverBinaryPath, clientBinaryPath}, ",")) }, func(data []byte) { - echoServerBinaryPath = string(data) - rand.Seed(config.GinkgoConfig.RandomSeed + int64(GinkgoParallelNode())) + binaries := strings.Split(string(data), ",") + echoServerBinaryPath = binaries[0] + echoClientBinaryPath = binaries[1] }) var _ = SynchronizedAfterSuite(func() {}, func() { diff --git a/pkg/testutils/echo/client/client.go b/pkg/testutils/echo/client/client.go new file mode 100644 index 00000000..97a8adec --- /dev/null +++ b/pkg/testutils/echo/client/client.go @@ -0,0 +1,45 @@ +package main + +import ( + "flag" + "fmt" + "io" + "net" +) + +func main() { + target := flag.String("target", "", "the server address") + payload := flag.String("message", "", "the message to send to the server") + flag.Parse() + + if *target == "" || *payload == "" { + flag.Usage() + panic("invalid arguments") + } + conn, err := net.Dial("tcp", *target) + if err != nil { + panic(fmt.Sprintf("Failed to open connection to [%s] %v", *target, err)) + } + defer conn.Close() + + _, err = conn.Write([]byte(*payload)) + if err != nil { + panic("Failed to send payload") + } + _, err = conn.Write([]byte("\n")) + if err != nil { + panic("Failed to send payload") + } + + buf := make([]byte, 4) + for { + n, err := conn.Read(buf) + fmt.Print(string(buf[:n])) + if err == io.EOF { + break + } + if err != nil { + panic("Failed to read from socket") + } + } +} diff --git a/pkg/testutils/echo/echo_test.go b/pkg/testutils/echo/echo_test.go new file mode 100644 index 00000000..12523a59 --- /dev/null +++ b/pkg/testutils/echo/echo_test.go @@ -0,0 +1,98 @@ +package main_test + +import ( + "fmt" + "io/ioutil" + "net" + "os/exec" + "strings" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + "github.com/onsi/gomega/gbytes" + "github.com/onsi/gomega/gexec" +) + +var serverBinaryPath, clientBinaryPath string + +var _ = SynchronizedBeforeSuite(func() []byte { + serverBinaryPath, err := gexec.Build("github.com/containernetworking/plugins/pkg/testutils/echo/server") + Expect(err).NotTo(HaveOccurred()) + clientBinaryPath, err := gexec.Build("github.com/containernetworking/plugins/pkg/testutils/echo/client") + Expect(err).NotTo(HaveOccurred()) + return []byte(strings.Join([]string{serverBinaryPath, clientBinaryPath}, ",")) +}, func(data []byte) { + binaries := strings.Split(string(data), ",") + serverBinaryPath = binaries[0] + clientBinaryPath = binaries[1] +}) + +var _ = SynchronizedAfterSuite(func() {}, func() { + gexec.CleanupBuildArtifacts() +}) + +var _ = Describe("Echosvr", func() { + var session *gexec.Session + BeforeEach(func() { + var err error + cmd := exec.Command(serverBinaryPath) + session, err = gexec.Start(cmd, GinkgoWriter, GinkgoWriter) + Expect(err).NotTo(HaveOccurred()) + }) + + AfterEach(func() { + session.Kill().Wait() + }) + + Context("Server test", func() { + It("starts and doesn't terminate immediately", func() { + Consistently(session).ShouldNot(gexec.Exit()) + }) + + tryConnect := func() (net.Conn, error) { + programOutput := session.Out.Contents() + addr := strings.TrimSpace(string(programOutput)) + + conn, err := net.Dial("tcp", addr) + if err != nil { + return nil, err + } + return conn, err + } + + It("prints its listening address to stdout", func() { + Eventually(session.Out).Should(gbytes.Say("\n")) + conn, err := tryConnect() + Expect(err).NotTo(HaveOccurred()) + conn.Close() + }) + + It("will echo data back to us", func() { + Eventually(session.Out).Should(gbytes.Say("\n")) + conn, err := tryConnect() + Expect(err).NotTo(HaveOccurred()) + defer conn.Close() + + fmt.Fprintf(conn, "hello\n") + Expect(ioutil.ReadAll(conn)).To(Equal([]byte("hello"))) + }) + }) + + Context("Client Server Test", func() { + It("starts and doesn't terminate immediately", func() { + Consistently(session).ShouldNot(gexec.Exit()) + }) + + It("connects successfully using echo client", func() { + Eventually(session.Out).Should(gbytes.Say("\n")) + serverAddress := strings.TrimSpace(string(session.Out.Contents())) + fmt.Println("Server address", string(serverAddress)) + + cmd := exec.Command(clientBinaryPath, "-target", serverAddress, "-message", "hello") + clientSession, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter) + Expect(err).NotTo(HaveOccurred()) + Eventually(clientSession.Out).Should(gbytes.Say("hello")) + Eventually(clientSession).Should(gexec.Exit()) + }) + }) +}) diff --git a/pkg/testutils/echosvr/init_test.go b/pkg/testutils/echo/init_test.go similarity index 100% rename from pkg/testutils/echosvr/init_test.go rename to pkg/testutils/echo/init_test.go diff --git a/pkg/testutils/echosvr/main.go b/pkg/testutils/echo/server/main.go similarity index 100% rename from pkg/testutils/echosvr/main.go rename to pkg/testutils/echo/server/main.go diff --git a/pkg/testutils/echosvr/echosvr_test.go b/pkg/testutils/echosvr/echosvr_test.go deleted file mode 100644 index cca1fffb..00000000 --- a/pkg/testutils/echosvr/echosvr_test.go +++ /dev/null @@ -1,74 +0,0 @@ -package main_test - -import ( - "fmt" - "io/ioutil" - "net" - "os/exec" - "strings" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - "github.com/onsi/gomega/gbytes" - "github.com/onsi/gomega/gexec" -) - -var binaryPath string - -var _ = SynchronizedBeforeSuite(func() []byte { - binaryPath, err := gexec.Build("github.com/containernetworking/plugins/pkg/testutils/echosvr") - Expect(err).NotTo(HaveOccurred()) - return []byte(binaryPath) -}, func(data []byte) { - binaryPath = string(data) -}) - -var _ = SynchronizedAfterSuite(func() {}, func() { - gexec.CleanupBuildArtifacts() -}) - -var _ = Describe("Echosvr", func() { - var session *gexec.Session - BeforeEach(func() { - var err error - cmd := exec.Command(binaryPath) - session, err = gexec.Start(cmd, GinkgoWriter, GinkgoWriter) - Expect(err).NotTo(HaveOccurred()) - }) - - AfterEach(func() { - session.Kill().Wait() - }) - - It("starts and doesn't terminate immediately", func() { - Consistently(session).ShouldNot(gexec.Exit()) - }) - - tryConnect := func() (net.Conn, error) { - programOutput := session.Out.Contents() - addr := strings.TrimSpace(string(programOutput)) - - conn, err := net.Dial("tcp", addr) - if err != nil { - return nil, err - } - return conn, err - } - - It("prints its listening address to stdout", func() { - Eventually(session.Out).Should(gbytes.Say("\n")) - conn, err := tryConnect() - Expect(err).NotTo(HaveOccurred()) - conn.Close() - }) - - It("will echo data back to us", func() { - Eventually(session.Out).Should(gbytes.Say("\n")) - conn, err := tryConnect() - Expect(err).NotTo(HaveOccurred()) - defer conn.Close() - - fmt.Fprintf(conn, "hello\n") - Expect(ioutil.ReadAll(conn)).To(Equal([]byte("hello"))) - }) -}) diff --git a/plugins/meta/bandwidth/bandwidth_suite_test.go b/plugins/meta/bandwidth/bandwidth_suite_test.go index 594cd9f3..a0e34ac0 100644 --- a/plugins/meta/bandwidth/bandwidth_suite_test.go +++ b/plugins/meta/bandwidth/bandwidth_suite_test.go @@ -39,14 +39,18 @@ func TestTBF(t *testing.T) { RunSpecs(t, "plugins/meta/bandwidth") } -var echoServerBinaryPath string +var echoServerBinaryPath, echoClientBinaryPath string var _ = SynchronizedBeforeSuite(func() []byte { - binaryPath, err := gexec.Build("github.com/containernetworking/plugins/pkg/testutils/echosvr") + serverBinaryPath, err := gexec.Build("github.com/containernetworking/plugins/pkg/testutils/echo/server") Expect(err).NotTo(HaveOccurred()) - return []byte(binaryPath) + clientBinaryPath, err := gexec.Build("github.com/containernetworking/plugins/pkg/testutils/echo/client") + Expect(err).NotTo(HaveOccurred()) + return []byte(strings.Join([]string{serverBinaryPath, clientBinaryPath}, ",")) }, func(data []byte) { - echoServerBinaryPath = string(data) + binaries := strings.Split(string(data), ",") + echoServerBinaryPath = binaries[0] + echoClientBinaryPath = binaries[1] }) var _ = SynchronizedAfterSuite(func() {}, func() { @@ -84,23 +88,22 @@ func startEchoServerInNamespace(netNS ns.NetNS) (int, *gexec.Session, error) { } func makeTcpClientInNS(netns string, address string, port int, numBytes int) { - message := bytes.Repeat([]byte{'a'}, numBytes) + payload := bytes.Repeat([]byte{'a'}, numBytes) + message := string(payload) - bin, err := exec.LookPath("nc") - Expect(err).NotTo(HaveOccurred()) var cmd *exec.Cmd if netns != "" { netns = filepath.Base(netns) - cmd = exec.Command("ip", "netns", "exec", netns, bin, "-v", address, strconv.Itoa(port)) + cmd = exec.Command("ip", "netns", "exec", netns, echoClientBinaryPath, "--target", fmt.Sprintf("%s:%d", address, port), "--message", message) } else { - cmd = exec.Command("nc", address, strconv.Itoa(port)) + cmd = exec.Command(echoClientBinaryPath, "--target", fmt.Sprintf("%s:%d", address, port), "--message", message) } cmd.Stdin = bytes.NewBuffer([]byte(message)) cmd.Stderr = GinkgoWriter out, err := cmd.Output() Expect(err).NotTo(HaveOccurred()) - Expect(string(out)).To(Equal(string(message))) + Expect(string(out)).To(Equal(message)) } func createVeth(hostNamespace string, hostVethIfName string, containerNamespace string, containerVethIfName string, hostIP []byte, containerIP []byte, hostIfaceMTU int) { diff --git a/plugins/meta/portmap/portmap_integ_test.go b/plugins/meta/portmap/portmap_integ_test.go index 22a7f5bd..63d67b4e 100644 --- a/plugins/meta/portmap/portmap_integ_test.go +++ b/plugins/meta/portmap/portmap_integ_test.go @@ -23,7 +23,6 @@ import ( "os" "os/exec" "path/filepath" - "strconv" "github.com/containernetworking/cni/libcni" "github.com/containernetworking/cni/pkg/types/current" @@ -227,16 +226,14 @@ var _ = Describe("portmap integration tests", func() { // testEchoServer returns true if we found an echo server on the port func testEchoServer(address string, port int, netns string) bool { - message := "Aliquid melius quam pessimum optimum non est." + message := "'Aliquid melius quam pessimum optimum non est.'" - bin, err := exec.LookPath("nc") - Expect(err).NotTo(HaveOccurred()) var cmd *exec.Cmd if netns != "" { netns = filepath.Base(netns) - cmd = exec.Command("ip", "netns", "exec", netns, bin, "-v", address, strconv.Itoa(port)) + cmd = exec.Command("ip", "netns", "exec", netns, echoClientBinaryPath, "--target", fmt.Sprintf("%s:%d", address, port), "--message", message) } else { - cmd = exec.Command("nc", address, strconv.Itoa(port)) + cmd = exec.Command(echoClientBinaryPath, "--target", fmt.Sprintf("%s:%d", address, port), "--message", message) } cmd.Stdin = bytes.NewBufferString(message) cmd.Stderr = GinkgoWriter diff --git a/plugins/meta/portmap/portmap_suite_test.go b/plugins/meta/portmap/portmap_suite_test.go index 5826cfce..55aee924 100644 --- a/plugins/meta/portmap/portmap_suite_test.go +++ b/plugins/meta/portmap/portmap_suite_test.go @@ -40,14 +40,18 @@ func TestPortmap(t *testing.T) { RunSpecs(t, "plugins/meta/portmap") } -var echoServerBinaryPath string +var echoServerBinaryPath, echoClientBinaryPath string var _ = SynchronizedBeforeSuite(func() []byte { - binaryPath, err := gexec.Build("github.com/containernetworking/plugins/pkg/testutils/echosvr") + serverBinaryPath, err := gexec.Build("github.com/containernetworking/plugins/pkg/testutils/echo/server") Expect(err).NotTo(HaveOccurred()) - return []byte(binaryPath) + clientBinaryPath, err := gexec.Build("github.com/containernetworking/plugins/pkg/testutils/echo/client") + Expect(err).NotTo(HaveOccurred()) + return []byte(strings.Join([]string{serverBinaryPath, clientBinaryPath}, ",")) }, func(data []byte) { - echoServerBinaryPath = string(data) + binaries := strings.Split(string(data), ",") + echoServerBinaryPath = binaries[0] + echoClientBinaryPath = binaries[1] }) var _ = SynchronizedAfterSuite(func() {}, func() {