rename_test.go 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. package container // import "github.com/docker/docker/integration/container"
  2. import (
  3. "context"
  4. "testing"
  5. "time"
  6. "github.com/docker/docker/api/types"
  7. "github.com/docker/docker/api/types/network"
  8. "github.com/docker/docker/integration/internal/container"
  9. "github.com/docker/docker/integration/internal/request"
  10. "github.com/docker/docker/internal/testutil"
  11. "github.com/docker/docker/pkg/stringid"
  12. "github.com/gotestyourself/gotestyourself/poll"
  13. "github.com/gotestyourself/gotestyourself/skip"
  14. "github.com/stretchr/testify/assert"
  15. "github.com/stretchr/testify/require"
  16. )
  17. // This test simulates the scenario mentioned in #31392:
  18. // Having two linked container, renaming the target and bringing a replacement
  19. // and then deleting and recreating the source container linked to the new target.
  20. // This checks that "rename" updates source container correctly and doesn't set it to null.
  21. func TestRenameLinkedContainer(t *testing.T) {
  22. defer setupTest(t)()
  23. ctx := context.Background()
  24. client := request.NewAPIClient(t)
  25. aID := container.Run(t, ctx, client, container.WithName("a0"))
  26. bID := container.Run(t, ctx, client, container.WithName("b0"), container.WithLinks("a0"))
  27. err := client.ContainerRename(ctx, aID, "a1")
  28. require.NoError(t, err)
  29. container.Run(t, ctx, client, container.WithName("a0"))
  30. err = client.ContainerRemove(ctx, bID, types.ContainerRemoveOptions{Force: true})
  31. require.NoError(t, err)
  32. bID = container.Run(t, ctx, client, container.WithName("b0"), container.WithLinks("a0"))
  33. inspect, err := client.ContainerInspect(ctx, bID)
  34. require.NoError(t, err)
  35. assert.Equal(t, []string{"/a0:/b0/a0"}, inspect.HostConfig.Links)
  36. }
  37. func TestRenameStoppedContainer(t *testing.T) {
  38. defer setupTest(t)()
  39. ctx := context.Background()
  40. client := request.NewAPIClient(t)
  41. oldName := "first_name"
  42. cID := container.Run(t, ctx, client, container.WithName(oldName), container.WithCmd("sh"))
  43. poll.WaitOn(t, container.IsInState(ctx, client, cID, "exited"), poll.WithDelay(100*time.Millisecond))
  44. inspect, err := client.ContainerInspect(ctx, cID)
  45. require.NoError(t, err)
  46. assert.Equal(t, "/"+oldName, inspect.Name)
  47. newName := "new_name" + stringid.GenerateNonCryptoID()
  48. err = client.ContainerRename(ctx, oldName, newName)
  49. require.NoError(t, err)
  50. inspect, err = client.ContainerInspect(ctx, cID)
  51. require.NoError(t, err)
  52. assert.Equal(t, "/"+newName, inspect.Name)
  53. }
  54. func TestRenameRunningContainerAndReuse(t *testing.T) {
  55. defer setupTest(t)()
  56. ctx := context.Background()
  57. client := request.NewAPIClient(t)
  58. oldName := "first_name"
  59. cID := container.Run(t, ctx, client, container.WithName(oldName))
  60. poll.WaitOn(t, container.IsInState(ctx, client, cID, "running"), poll.WithDelay(100*time.Millisecond))
  61. newName := "new_name" + stringid.GenerateNonCryptoID()
  62. err := client.ContainerRename(ctx, oldName, newName)
  63. require.NoError(t, err)
  64. inspect, err := client.ContainerInspect(ctx, cID)
  65. require.NoError(t, err)
  66. assert.Equal(t, "/"+newName, inspect.Name)
  67. _, err = client.ContainerInspect(ctx, oldName)
  68. testutil.ErrorContains(t, err, "No such container: "+oldName)
  69. cID = container.Run(t, ctx, client, container.WithName(oldName))
  70. poll.WaitOn(t, container.IsInState(ctx, client, cID, "running"), poll.WithDelay(100*time.Millisecond))
  71. inspect, err = client.ContainerInspect(ctx, cID)
  72. require.NoError(t, err)
  73. assert.Equal(t, "/"+oldName, inspect.Name)
  74. }
  75. func TestRenameInvalidName(t *testing.T) {
  76. defer setupTest(t)()
  77. ctx := context.Background()
  78. client := request.NewAPIClient(t)
  79. oldName := "first_name"
  80. cID := container.Run(t, ctx, client, container.WithName(oldName))
  81. poll.WaitOn(t, container.IsInState(ctx, client, cID, "running"), poll.WithDelay(100*time.Millisecond))
  82. err := client.ContainerRename(ctx, oldName, "new:invalid")
  83. testutil.ErrorContains(t, err, "Invalid container name")
  84. inspect, err := client.ContainerInspect(ctx, oldName)
  85. require.NoError(t, err)
  86. assert.Equal(t, cID, inspect.ID)
  87. }
  88. // Test case for GitHub issue 22466
  89. // Docker's service discovery works for named containers so
  90. // ping to a named container should work, and an anonymous
  91. // container without a name does not work with service discovery.
  92. // However, an anonymous could be renamed to a named container.
  93. // This test is to make sure once the container has been renamed,
  94. // the service discovery for the (re)named container works.
  95. func TestRenameAnonymousContainer(t *testing.T) {
  96. defer setupTest(t)()
  97. ctx := context.Background()
  98. client := request.NewAPIClient(t)
  99. _, err := client.NetworkCreate(ctx, "network1", types.NetworkCreate{})
  100. require.NoError(t, err)
  101. cID := container.Run(t, ctx, client, func(c *container.TestContainerConfig) {
  102. c.NetworkingConfig.EndpointsConfig = map[string]*network.EndpointSettings{
  103. "network1": {},
  104. }
  105. c.HostConfig.NetworkMode = "network1"
  106. })
  107. err = client.ContainerRename(ctx, cID, "container1")
  108. require.NoError(t, err)
  109. // Stop/Start the container to get registered
  110. // FIXME(vdemeester) this is a really weird behavior as it fails otherwise
  111. err = client.ContainerStop(ctx, "container1", nil)
  112. require.NoError(t, err)
  113. err = client.ContainerStart(ctx, "container1", types.ContainerStartOptions{})
  114. require.NoError(t, err)
  115. poll.WaitOn(t, container.IsInState(ctx, client, cID, "running"), poll.WithDelay(100*time.Millisecond))
  116. count := "-c"
  117. if testEnv.OSType == "windows" {
  118. count = "-n"
  119. }
  120. cID = container.Run(t, ctx, client, func(c *container.TestContainerConfig) {
  121. c.NetworkingConfig.EndpointsConfig = map[string]*network.EndpointSettings{
  122. "network1": {},
  123. }
  124. c.HostConfig.NetworkMode = "network1"
  125. }, container.WithCmd("ping", count, "1", "container1"))
  126. poll.WaitOn(t, container.IsInState(ctx, client, cID, "exited"), poll.WithDelay(100*time.Millisecond))
  127. inspect, err := client.ContainerInspect(ctx, cID)
  128. require.NoError(t, err)
  129. assert.Equal(t, 0, inspect.State.ExitCode, "container %s exited with the wrong exitcode: %+v", cID, inspect)
  130. }
  131. // TODO: should be a unit test
  132. func TestRenameContainerWithSameName(t *testing.T) {
  133. defer setupTest(t)()
  134. ctx := context.Background()
  135. client := request.NewAPIClient(t)
  136. cID := container.Run(t, ctx, client, container.WithName("old"))
  137. poll.WaitOn(t, container.IsInState(ctx, client, cID, "running"), poll.WithDelay(100*time.Millisecond))
  138. err := client.ContainerRename(ctx, "old", "old")
  139. testutil.ErrorContains(t, err, "Renaming a container with the same name")
  140. err = client.ContainerRename(ctx, cID, "old")
  141. testutil.ErrorContains(t, err, "Renaming a container with the same name")
  142. }
  143. // Test case for GitHub issue 23973
  144. // When a container is being renamed, the container might
  145. // be linked to another container. In that case, the meta data
  146. // of the linked container should be updated so that the other
  147. // container could still reference to the container that is renamed.
  148. func TestRenameContainerWithLinkedContainer(t *testing.T) {
  149. skip.If(t, testEnv.IsRemoteDaemon())
  150. defer setupTest(t)()
  151. ctx := context.Background()
  152. client := request.NewAPIClient(t)
  153. db1ID := container.Run(t, ctx, client, container.WithName("db1"))
  154. poll.WaitOn(t, container.IsInState(ctx, client, db1ID, "running"), poll.WithDelay(100*time.Millisecond))
  155. app1ID := container.Run(t, ctx, client, container.WithName("app1"), container.WithLinks("db1:/mysql"))
  156. poll.WaitOn(t, container.IsInState(ctx, client, app1ID, "running"), poll.WithDelay(100*time.Millisecond))
  157. err := client.ContainerRename(ctx, "app1", "app2")
  158. require.NoError(t, err)
  159. inspect, err := client.ContainerInspect(ctx, "app2/mysql")
  160. require.NoError(t, err)
  161. assert.Equal(t, db1ID, inspect.ID)
  162. }