stop_test.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. package container // import "github.com/docker/docker/integration/container"
  2. import (
  3. "context"
  4. "fmt"
  5. "strconv"
  6. "strings"
  7. "testing"
  8. "time"
  9. "github.com/docker/docker/api/types"
  10. "github.com/docker/docker/integration/internal/container"
  11. "github.com/docker/docker/internal/test/request"
  12. "github.com/gotestyourself/gotestyourself/assert"
  13. "github.com/gotestyourself/gotestyourself/icmd"
  14. "github.com/gotestyourself/gotestyourself/poll"
  15. "github.com/gotestyourself/gotestyourself/skip"
  16. )
  17. func TestStopContainerWithRestartPolicyAlways(t *testing.T) {
  18. defer setupTest(t)()
  19. client := request.NewAPIClient(t)
  20. ctx := context.Background()
  21. names := []string{"verifyRestart1-" + t.Name(), "verifyRestart2-" + t.Name()}
  22. for _, name := range names {
  23. container.Run(t, ctx, client, container.WithName(name), container.WithCmd("false"), func(c *container.TestContainerConfig) {
  24. c.HostConfig.RestartPolicy.Name = "always"
  25. })
  26. }
  27. for _, name := range names {
  28. poll.WaitOn(t, container.IsInState(ctx, client, name, "running", "restarting"), poll.WithDelay(100*time.Millisecond))
  29. }
  30. for _, name := range names {
  31. err := client.ContainerStop(ctx, name, nil)
  32. assert.NilError(t, err)
  33. }
  34. for _, name := range names {
  35. poll.WaitOn(t, container.IsStopped(ctx, client, name), poll.WithDelay(100*time.Millisecond))
  36. }
  37. }
  38. // TestStopContainerWithTimeout checks that ContainerStop with
  39. // a timeout works as documented, i.e. in case of negative timeout
  40. // waiting is not limited (issue #35311).
  41. func TestStopContainerWithTimeout(t *testing.T) {
  42. defer setupTest(t)()
  43. client := request.NewAPIClient(t)
  44. ctx := context.Background()
  45. testCmd := container.WithCmd("sh", "-c", "sleep 2 && exit 42")
  46. testData := []struct {
  47. doc string
  48. timeout int
  49. expectedExitCode int
  50. }{
  51. // In case container is forcefully killed, 137 is returned,
  52. // otherwise the exit code from the above script
  53. {
  54. "zero timeout: expect forceful container kill",
  55. 0, 137,
  56. },
  57. {
  58. "too small timeout: expect forceful container kill",
  59. 1, 137,
  60. },
  61. {
  62. "big enough timeout: expect graceful container stop",
  63. 3, 42,
  64. },
  65. {
  66. "unlimited timeout: expect graceful container stop",
  67. -1, 42,
  68. },
  69. }
  70. for _, d := range testData {
  71. d := d
  72. t.Run(strconv.Itoa(d.timeout), func(t *testing.T) {
  73. t.Parallel()
  74. id := container.Run(t, ctx, client, testCmd)
  75. timeout := time.Duration(d.timeout) * time.Second
  76. err := client.ContainerStop(ctx, id, &timeout)
  77. assert.NilError(t, err)
  78. poll.WaitOn(t, container.IsStopped(ctx, client, id),
  79. poll.WithDelay(100*time.Millisecond))
  80. inspect, err := client.ContainerInspect(ctx, id)
  81. assert.NilError(t, err)
  82. assert.Equal(t, inspect.State.ExitCode, d.expectedExitCode)
  83. })
  84. }
  85. }
  86. func TestDeleteDevicemapper(t *testing.T) {
  87. skip.IfCondition(t, testEnv.DaemonInfo.Driver != "devicemapper")
  88. defer setupTest(t)()
  89. client := request.NewAPIClient(t)
  90. ctx := context.Background()
  91. id := container.Run(t, ctx, client, container.WithName("foo-"+t.Name()), container.WithCmd("echo"))
  92. poll.WaitOn(t, container.IsStopped(ctx, client, id), poll.WithDelay(100*time.Millisecond))
  93. inspect, err := client.ContainerInspect(ctx, id)
  94. assert.NilError(t, err)
  95. deviceID := inspect.GraphDriver.Data["DeviceId"]
  96. // Find pool name from device name
  97. deviceName := inspect.GraphDriver.Data["DeviceName"]
  98. devicePrefix := deviceName[:strings.LastIndex(deviceName, "-")]
  99. devicePool := fmt.Sprintf("/dev/mapper/%s-pool", devicePrefix)
  100. result := icmd.RunCommand("dmsetup", "message", devicePool, "0", fmt.Sprintf("delete %s", deviceID))
  101. result.Assert(t, icmd.Success)
  102. err = client.ContainerRemove(ctx, id, types.ContainerRemoveOptions{})
  103. assert.NilError(t, err)
  104. }