stop_linux_test.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  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. "gotest.tools/assert"
  12. "gotest.tools/icmd"
  13. "gotest.tools/poll"
  14. "gotest.tools/skip"
  15. )
  16. // TestStopContainerWithTimeout checks that ContainerStop with
  17. // a timeout works as documented, i.e. in case of negative timeout
  18. // waiting is not limited (issue #35311).
  19. func TestStopContainerWithTimeout(t *testing.T) {
  20. defer setupTest(t)()
  21. client := testEnv.APIClient()
  22. ctx := context.Background()
  23. testCmd := container.WithCmd("sh", "-c", "sleep 2 && exit 42")
  24. testData := []struct {
  25. doc string
  26. timeout int
  27. expectedExitCode int
  28. }{
  29. // In case container is forcefully killed, 137 is returned,
  30. // otherwise the exit code from the above script
  31. {
  32. "zero timeout: expect forceful container kill",
  33. 0, 137,
  34. },
  35. {
  36. "too small timeout: expect forceful container kill",
  37. 1, 137,
  38. },
  39. {
  40. "big enough timeout: expect graceful container stop",
  41. 3, 42,
  42. },
  43. {
  44. "unlimited timeout: expect graceful container stop",
  45. -1, 42,
  46. },
  47. }
  48. for _, d := range testData {
  49. d := d
  50. t.Run(strconv.Itoa(d.timeout), func(t *testing.T) {
  51. t.Parallel()
  52. id := container.Run(t, ctx, client, testCmd)
  53. timeout := time.Duration(d.timeout) * time.Second
  54. err := client.ContainerStop(ctx, id, &timeout)
  55. assert.NilError(t, err)
  56. poll.WaitOn(t, container.IsStopped(ctx, client, id),
  57. poll.WithDelay(100*time.Millisecond))
  58. inspect, err := client.ContainerInspect(ctx, id)
  59. assert.NilError(t, err)
  60. assert.Equal(t, inspect.State.ExitCode, d.expectedExitCode)
  61. })
  62. }
  63. }
  64. func TestDeleteDevicemapper(t *testing.T) {
  65. skip.If(t, testEnv.DaemonInfo.Driver != "devicemapper")
  66. skip.If(t, testEnv.IsRemoteDaemon)
  67. defer setupTest(t)()
  68. client := testEnv.APIClient()
  69. ctx := context.Background()
  70. id := container.Run(t, ctx, client, container.WithName("foo-"+t.Name()), container.WithCmd("echo"))
  71. poll.WaitOn(t, container.IsStopped(ctx, client, id), poll.WithDelay(100*time.Millisecond))
  72. inspect, err := client.ContainerInspect(ctx, id)
  73. assert.NilError(t, err)
  74. deviceID := inspect.GraphDriver.Data["DeviceId"]
  75. // Find pool name from device name
  76. deviceName := inspect.GraphDriver.Data["DeviceName"]
  77. devicePrefix := deviceName[:strings.LastIndex(deviceName, "-")]
  78. devicePool := fmt.Sprintf("/dev/mapper/%s-pool", devicePrefix)
  79. result := icmd.RunCommand("dmsetup", "message", devicePool, "0", fmt.Sprintf("delete %s", deviceID))
  80. result.Assert(t, icmd.Success)
  81. err = client.ContainerRemove(ctx, id, types.ContainerRemoveOptions{})
  82. assert.NilError(t, err)
  83. }