stop_linux_test.go 2.8 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. containertypes "github.com/docker/docker/api/types/container"
  11. "github.com/docker/docker/integration/internal/container"
  12. "gotest.tools/v3/assert"
  13. "gotest.tools/v3/icmd"
  14. "gotest.tools/v3/poll"
  15. "gotest.tools/v3/skip"
  16. )
  17. // TestStopContainerWithTimeout checks that ContainerStop with
  18. // a timeout works as documented, i.e. in case of negative timeout
  19. // waiting is not limited (issue #35311).
  20. func TestStopContainerWithTimeout(t *testing.T) {
  21. defer setupTest(t)()
  22. client := testEnv.APIClient()
  23. ctx := context.Background()
  24. testCmd := container.WithCmd("sh", "-c", "sleep 2 && exit 42")
  25. testData := []struct {
  26. doc string
  27. timeout int
  28. expectedExitCode int
  29. }{
  30. // In case container is forcefully killed, 137 is returned,
  31. // otherwise the exit code from the above script
  32. {
  33. "zero timeout: expect forceful container kill",
  34. 0, 137,
  35. },
  36. {
  37. "too small timeout: expect forceful container kill",
  38. 1, 137,
  39. },
  40. {
  41. "big enough timeout: expect graceful container stop",
  42. 3, 42,
  43. },
  44. {
  45. "unlimited timeout: expect graceful container stop",
  46. -1, 42,
  47. },
  48. }
  49. for _, d := range testData {
  50. d := d
  51. t.Run(strconv.Itoa(d.timeout), func(t *testing.T) {
  52. t.Parallel()
  53. id := container.Run(ctx, t, client, testCmd)
  54. err := client.ContainerStop(ctx, id, containertypes.StopOptions{Timeout: &d.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(ctx, t, 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. }