github.com/codemac/docker@v1.2.1-0.20150518222241-6a18412d5b9c/integration-cli/docker_cli_nat_test.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "net" 6 "os/exec" 7 "strings" 8 9 "github.com/go-check/check" 10 ) 11 12 func startServerContainer(c *check.C, proto string, port int) string { 13 pStr := fmt.Sprintf("%d:%d", port, port) 14 bCmd := fmt.Sprintf("nc -lp %d && echo bye", port) 15 cmd := []string{"-d", "-p", pStr, "busybox", "sh", "-c", bCmd} 16 if proto == "udp" { 17 cmd = append(cmd, "-u") 18 } 19 20 name := "server" 21 if err := waitForContainer(name, cmd...); err != nil { 22 c.Fatalf("Failed to launch server container: %v", err) 23 } 24 return name 25 } 26 27 func getExternalAddress(c *check.C) net.IP { 28 iface, err := net.InterfaceByName("eth0") 29 if err != nil { 30 c.Skip(fmt.Sprintf("Test not running with `make test`. Interface eth0 not found: %v", err)) 31 } 32 33 ifaceAddrs, err := iface.Addrs() 34 if err != nil || len(ifaceAddrs) == 0 { 35 c.Fatalf("Error retrieving addresses for eth0: %v (%d addresses)", err, len(ifaceAddrs)) 36 } 37 38 ifaceIP, _, err := net.ParseCIDR(ifaceAddrs[0].String()) 39 if err != nil { 40 c.Fatalf("Error retrieving the up for eth0: %s", err) 41 } 42 43 return ifaceIP 44 } 45 46 func getContainerLogs(c *check.C, containerID string) string { 47 runCmd := exec.Command(dockerBinary, "logs", containerID) 48 out, _, err := runCommandWithOutput(runCmd) 49 if err != nil { 50 c.Fatal(out, err) 51 } 52 return strings.Trim(out, "\r\n") 53 } 54 55 func getContainerStatus(c *check.C, containerID string) string { 56 out, err := inspectField(containerID, "State.Running") 57 c.Assert(err, check.IsNil) 58 return out 59 } 60 61 func (s *DockerSuite) TestNetworkNat(c *check.C) { 62 testRequires(c, SameHostDaemon, NativeExecDriver) 63 defer deleteAllContainers() 64 65 srv := startServerContainer(c, "tcp", 8080) 66 67 // Spawn a new container which connects to the server through the 68 // interface address. 69 endpoint := getExternalAddress(c) 70 runCmd := exec.Command(dockerBinary, "run", "busybox", "sh", "-c", fmt.Sprintf("echo hello world | nc -w 30 %s 8080", endpoint)) 71 if out, _, err := runCommandWithOutput(runCmd); err != nil { 72 c.Fatalf("Failed to connect to server: %v (output: %q)", err, string(out)) 73 } 74 75 result := getContainerLogs(c, srv) 76 77 // Ideally we'd like to check for "hello world" but sometimes 78 // nc doesn't show the data it received so instead let's look for 79 // the output of the 'echo bye' that should be printed once 80 // the nc command gets a connection 81 expected := "bye" 82 if !strings.Contains(result, expected) { 83 c.Fatalf("Unexpected output. Expected: %q, received: %q", expected, result) 84 } 85 } 86 87 func (s *DockerSuite) TestNetworkLocalhostTCPNat(c *check.C) { 88 testRequires(c, SameHostDaemon, NativeExecDriver) 89 defer deleteAllContainers() 90 91 srv := startServerContainer(c, "tcp", 8081) 92 93 // Attempt to connect from the host to the listening container. 94 conn, err := net.Dial("tcp", "localhost:8081") 95 if err != nil { 96 c.Fatalf("Failed to connect to container (%v)", err) 97 } 98 if _, err := conn.Write([]byte("hello world\n")); err != nil { 99 c.Fatal(err) 100 } 101 conn.Close() 102 103 result := getContainerLogs(c, srv) 104 105 // Ideally we'd like to check for "hello world" but sometimes 106 // nc doesn't show the data it received so instead let's look for 107 // the output of the 'echo bye' that should be printed once 108 // the nc command gets a connection 109 expected := "bye" 110 if !strings.Contains(result, expected) { 111 c.Fatalf("Unexpected output. Expected: %q, received: %q", expected, result) 112 } 113 }