nat_test.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. package container // import "github.com/docker/docker/integration/container"
  2. import (
  3. "bytes"
  4. "context"
  5. "fmt"
  6. "io"
  7. "io/ioutil"
  8. "net"
  9. "strings"
  10. "testing"
  11. "time"
  12. "github.com/docker/docker/api/types"
  13. "github.com/docker/docker/integration/internal/container"
  14. "github.com/docker/docker/integration/internal/request"
  15. "github.com/docker/go-connections/nat"
  16. "github.com/gotestyourself/gotestyourself/poll"
  17. "github.com/gotestyourself/gotestyourself/skip"
  18. "github.com/stretchr/testify/assert"
  19. "github.com/stretchr/testify/require"
  20. )
  21. func TestNetworkNat(t *testing.T) {
  22. skip.If(t, testEnv.IsRemoteDaemon())
  23. defer setupTest(t)()
  24. msg := "it works"
  25. startServerContainer(t, msg, 8080)
  26. endpoint := getExternalAddress(t)
  27. conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", endpoint.String(), 8080))
  28. require.NoError(t, err)
  29. defer conn.Close()
  30. data, err := ioutil.ReadAll(conn)
  31. require.NoError(t, err)
  32. assert.Equal(t, msg, strings.TrimSpace(string(data)))
  33. }
  34. func TestNetworkLocalhostTCPNat(t *testing.T) {
  35. skip.If(t, testEnv.IsRemoteDaemon())
  36. defer setupTest(t)()
  37. msg := "hi yall"
  38. startServerContainer(t, msg, 8081)
  39. conn, err := net.Dial("tcp", "localhost:8081")
  40. require.NoError(t, err)
  41. defer conn.Close()
  42. data, err := ioutil.ReadAll(conn)
  43. require.NoError(t, err)
  44. assert.Equal(t, msg, strings.TrimSpace(string(data)))
  45. }
  46. func TestNetworkLoopbackNat(t *testing.T) {
  47. skip.If(t, testEnv.IsRemoteDaemon())
  48. msg := "it works"
  49. startServerContainer(t, msg, 8080)
  50. endpoint := getExternalAddress(t)
  51. client := request.NewAPIClient(t)
  52. ctx := context.Background()
  53. cID := container.Run(t, ctx, client, container.WithCmd("sh", "-c", fmt.Sprintf("stty raw && nc -w 5 %s 8080", endpoint.String())), container.WithTty(true), container.WithNetworkMode("container:server"))
  54. poll.WaitOn(t, container.IsStopped(ctx, client, cID), poll.WithDelay(100*time.Millisecond))
  55. body, err := client.ContainerLogs(ctx, cID, types.ContainerLogsOptions{
  56. ShowStdout: true,
  57. })
  58. require.NoError(t, err)
  59. defer body.Close()
  60. var b bytes.Buffer
  61. _, err = io.Copy(&b, body)
  62. require.NoError(t, err)
  63. assert.Equal(t, msg, strings.TrimSpace(b.String()))
  64. }
  65. func startServerContainer(t *testing.T, msg string, port int) string {
  66. client := request.NewAPIClient(t)
  67. ctx := context.Background()
  68. cID := container.Run(t, ctx, client, container.WithName("server"), container.WithCmd("sh", "-c", fmt.Sprintf("echo %q | nc -lp %d", msg, port)), container.WithExposedPorts(fmt.Sprintf("%d/tcp", port)), func(c *container.TestContainerConfig) {
  69. c.HostConfig.PortBindings = nat.PortMap{
  70. nat.Port(fmt.Sprintf("%d/tcp", port)): []nat.PortBinding{
  71. {
  72. HostPort: fmt.Sprintf("%d", port),
  73. },
  74. },
  75. }
  76. })
  77. poll.WaitOn(t, container.IsInState(ctx, client, cID, "running"), poll.WithDelay(100*time.Millisecond))
  78. return cID
  79. }
  80. func getExternalAddress(t *testing.T) net.IP {
  81. iface, err := net.InterfaceByName("eth0")
  82. skip.If(t, err != nil, "Test not running with `make test-integration`. Interface eth0 not found: %s", err)
  83. ifaceAddrs, err := iface.Addrs()
  84. require.NoError(t, err)
  85. assert.NotEqual(t, 0, len(ifaceAddrs))
  86. ifaceIP, _, err := net.ParseCIDR(ifaceAddrs[0].String())
  87. require.NoError(t, err)
  88. return ifaceIP
  89. }