github.com/demonoid81/moby@v0.0.0-20200517203328-62dd8e17c460/integration/container/nat_test.go (about) 1 package container // import "github.com/demonoid81/moby/integration/container" 2 3 import ( 4 "bytes" 5 "context" 6 "fmt" 7 "io" 8 "io/ioutil" 9 "net" 10 "strings" 11 "testing" 12 "time" 13 14 "github.com/demonoid81/moby/api/types" 15 "github.com/demonoid81/moby/integration/internal/container" 16 "github.com/docker/go-connections/nat" 17 "gotest.tools/v3/assert" 18 is "gotest.tools/v3/assert/cmp" 19 "gotest.tools/v3/poll" 20 "gotest.tools/v3/skip" 21 ) 22 23 func TestNetworkNat(t *testing.T) { 24 skip.If(t, testEnv.OSType == "windows", "FIXME") 25 skip.If(t, testEnv.IsRemoteDaemon) 26 27 defer setupTest(t)() 28 29 msg := "it works" 30 startServerContainer(t, msg, 8080) 31 32 endpoint := getExternalAddress(t) 33 conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", endpoint.String(), 8080)) 34 assert.NilError(t, err) 35 defer conn.Close() 36 37 data, err := ioutil.ReadAll(conn) 38 assert.NilError(t, err) 39 assert.Check(t, is.Equal(msg, strings.TrimSpace(string(data)))) 40 } 41 42 func TestNetworkLocalhostTCPNat(t *testing.T) { 43 skip.If(t, testEnv.DaemonInfo.OSType == "windows", "FIXME") 44 skip.If(t, testEnv.IsRemoteDaemon) 45 46 defer setupTest(t)() 47 48 msg := "hi yall" 49 startServerContainer(t, msg, 8081) 50 51 conn, err := net.Dial("tcp", "localhost:8081") 52 assert.NilError(t, err) 53 defer conn.Close() 54 55 data, err := ioutil.ReadAll(conn) 56 assert.NilError(t, err) 57 assert.Check(t, is.Equal(msg, strings.TrimSpace(string(data)))) 58 } 59 60 func TestNetworkLoopbackNat(t *testing.T) { 61 skip.If(t, testEnv.OSType == "windows", "FIXME") 62 skip.If(t, testEnv.IsRemoteDaemon) 63 64 defer setupTest(t)() 65 66 msg := "it works" 67 serverContainerID := startServerContainer(t, msg, 8080) 68 69 endpoint := getExternalAddress(t) 70 71 client := testEnv.APIClient() 72 ctx := context.Background() 73 74 cID := container.Run(ctx, t, client, container.WithCmd("sh", "-c", fmt.Sprintf("stty raw && nc -w 5 %s 8080", endpoint.String())), container.WithTty(true), container.WithNetworkMode("container:"+serverContainerID)) 75 76 poll.WaitOn(t, container.IsStopped(ctx, client, cID), poll.WithDelay(100*time.Millisecond)) 77 78 body, err := client.ContainerLogs(ctx, cID, types.ContainerLogsOptions{ 79 ShowStdout: true, 80 }) 81 assert.NilError(t, err) 82 defer body.Close() 83 84 var b bytes.Buffer 85 _, err = io.Copy(&b, body) 86 assert.NilError(t, err) 87 88 assert.Check(t, is.Equal(msg, strings.TrimSpace(b.String()))) 89 } 90 91 func startServerContainer(t *testing.T, msg string, port int) string { 92 t.Helper() 93 client := testEnv.APIClient() 94 ctx := context.Background() 95 96 cID := container.Run(ctx, t, client, container.WithName("server-"+t.Name()), container.WithCmd("sh", "-c", fmt.Sprintf("echo %q | nc -lp %d", msg, port)), container.WithExposedPorts(fmt.Sprintf("%d/tcp", port)), func(c *container.TestContainerConfig) { 97 c.HostConfig.PortBindings = nat.PortMap{ 98 nat.Port(fmt.Sprintf("%d/tcp", port)): []nat.PortBinding{ 99 { 100 HostPort: fmt.Sprintf("%d", port), 101 }, 102 }, 103 } 104 }) 105 106 poll.WaitOn(t, container.IsInState(ctx, client, cID, "running"), poll.WithDelay(100*time.Millisecond)) 107 108 return cID 109 } 110 111 func getExternalAddress(t *testing.T) net.IP { 112 t.Helper() 113 iface, err := net.InterfaceByName("eth0") 114 skip.If(t, err != nil, "Test not running with `make test-integration`. Interface eth0 not found: %s", err) 115 116 ifaceAddrs, err := iface.Addrs() 117 assert.NilError(t, err) 118 assert.Check(t, 0 != len(ifaceAddrs)) 119 120 ifaceIP, _, err := net.ParseCIDR(ifaceAddrs[0].String()) 121 assert.NilError(t, err) 122 123 return ifaceIP 124 }