mac_addr_test.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. package networking
  2. import (
  3. "testing"
  4. containertypes "github.com/docker/docker/api/types/container"
  5. "github.com/docker/docker/integration/internal/container"
  6. "github.com/docker/docker/integration/internal/network"
  7. "github.com/docker/docker/libnetwork/drivers/bridge"
  8. "github.com/docker/docker/testutil/daemon"
  9. "gotest.tools/v3/assert"
  10. is "gotest.tools/v3/assert/cmp"
  11. "gotest.tools/v3/skip"
  12. )
  13. // TestMACAddrOnRestart is a regression test for https://github.com/moby/moby/issues/47146
  14. // - Start a container, let it use a generated MAC address.
  15. // - Stop that container.
  16. // - Start a second container, it'll also use a generated MAC address.
  17. // (It's likely to recycle the first container's MAC address.)
  18. // - Restart the first container.
  19. // (The bug was that it kept its original MAC address, now already in-use.)
  20. // - Check that the two containers have different MAC addresses.
  21. func TestMACAddrOnRestart(t *testing.T) {
  22. skip.If(t, testEnv.DaemonInfo.OSType == "windows")
  23. ctx := setupTest(t)
  24. d := daemon.New(t)
  25. d.StartWithBusybox(ctx, t)
  26. defer d.Stop(t)
  27. c := d.NewClientT(t)
  28. defer c.Close()
  29. const netName = "testmacaddrs"
  30. network.CreateNoError(ctx, t, c, netName,
  31. network.WithDriver("bridge"),
  32. network.WithOption(bridge.BridgeName, netName))
  33. defer network.RemoveNoError(ctx, t, c, netName)
  34. const ctr1Name = "ctr1"
  35. id1 := container.Run(ctx, t, c,
  36. container.WithName(ctr1Name),
  37. container.WithImage("busybox:latest"),
  38. container.WithCmd("top"),
  39. container.WithNetworkMode(netName))
  40. defer c.ContainerRemove(ctx, id1, containertypes.RemoveOptions{
  41. Force: true,
  42. })
  43. err := c.ContainerStop(ctx, ctr1Name, containertypes.StopOptions{})
  44. assert.Assert(t, is.Nil(err))
  45. // Start a second container, giving the daemon a chance to recycle the first container's
  46. // IP and MAC addresses.
  47. const ctr2Name = "ctr2"
  48. id2 := container.Run(ctx, t, c,
  49. container.WithName(ctr2Name),
  50. container.WithImage("busybox:latest"),
  51. container.WithCmd("top"),
  52. container.WithNetworkMode(netName))
  53. defer c.ContainerRemove(ctx, id2, containertypes.RemoveOptions{
  54. Force: true,
  55. })
  56. // Restart the first container.
  57. err = c.ContainerStart(ctx, ctr1Name, containertypes.StartOptions{})
  58. assert.Assert(t, is.Nil(err))
  59. // Check that the containers ended up with different MAC addresses.
  60. ctr1Inspect := container.Inspect(ctx, t, c, ctr1Name)
  61. ctr1MAC := ctr1Inspect.NetworkSettings.Networks[netName].MacAddress
  62. ctr2Inspect := container.Inspect(ctx, t, c, ctr2Name)
  63. ctr2MAC := ctr2Inspect.NetworkSettings.Networks[netName].MacAddress
  64. assert.Check(t, ctr1MAC != ctr2MAC,
  65. "expected containers to have different MAC addresses; got %q for both", ctr1MAC)
  66. }
  67. // Check that a configured MAC address is restored after a container restart,
  68. // and after a daemon restart.
  69. func TestCfgdMACAddrOnRestart(t *testing.T) {
  70. skip.If(t, testEnv.DaemonInfo.OSType == "windows")
  71. ctx := setupTest(t)
  72. d := daemon.New(t)
  73. d.StartWithBusybox(ctx, t)
  74. defer d.Stop(t)
  75. c := d.NewClientT(t)
  76. defer c.Close()
  77. const netName = "testcfgmacaddr"
  78. network.CreateNoError(ctx, t, c, netName,
  79. network.WithDriver("bridge"),
  80. network.WithOption(bridge.BridgeName, netName))
  81. defer network.RemoveNoError(ctx, t, c, netName)
  82. const wantMAC = "02:42:ac:11:00:42"
  83. const ctr1Name = "ctr1"
  84. id1 := container.Run(ctx, t, c,
  85. container.WithName(ctr1Name),
  86. container.WithImage("busybox:latest"),
  87. container.WithCmd("top"),
  88. container.WithNetworkMode(netName),
  89. container.WithMacAddress(netName, wantMAC))
  90. defer c.ContainerRemove(ctx, id1, containertypes.RemoveOptions{
  91. Force: true,
  92. })
  93. inspect := container.Inspect(ctx, t, c, ctr1Name)
  94. gotMAC := inspect.NetworkSettings.Networks[netName].MacAddress
  95. assert.Check(t, is.Equal(wantMAC, gotMAC))
  96. startAndCheck := func() {
  97. t.Helper()
  98. err := c.ContainerStart(ctx, ctr1Name, containertypes.StartOptions{})
  99. assert.Assert(t, is.Nil(err))
  100. inspect = container.Inspect(ctx, t, c, ctr1Name)
  101. gotMAC = inspect.NetworkSettings.Networks[netName].MacAddress
  102. assert.Check(t, is.Equal(wantMAC, gotMAC))
  103. }
  104. // Restart the container, check that the MAC address is restored.
  105. err := c.ContainerStop(ctx, ctr1Name, containertypes.StopOptions{})
  106. assert.Assert(t, is.Nil(err))
  107. startAndCheck()
  108. // Restart the daemon, check that the MAC address is restored.
  109. err = c.ContainerStop(ctx, ctr1Name, containertypes.StopOptions{})
  110. assert.Assert(t, is.Nil(err))
  111. d.Restart(t)
  112. startAndCheck()
  113. }