kill_test.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. package container
  2. import (
  3. "context"
  4. "testing"
  5. "time"
  6. "github.com/docker/docker/api/types"
  7. "github.com/docker/docker/api/types/container"
  8. "github.com/docker/docker/api/types/network"
  9. "github.com/docker/docker/api/types/strslice"
  10. "github.com/docker/docker/client"
  11. "github.com/docker/docker/integration/util/request"
  12. "github.com/gotestyourself/gotestyourself/poll"
  13. "github.com/gotestyourself/gotestyourself/skip"
  14. "github.com/stretchr/testify/require"
  15. )
  16. func TestKillContainerInvalidSignal(t *testing.T) {
  17. defer setupTest(t)()
  18. client := request.NewAPIClient(t)
  19. ctx := context.Background()
  20. c, err := client.ContainerCreate(ctx,
  21. &container.Config{
  22. Image: "busybox",
  23. Cmd: strslice.StrSlice([]string{"top"}),
  24. },
  25. &container.HostConfig{},
  26. &network.NetworkingConfig{},
  27. "")
  28. require.NoError(t, err)
  29. err = client.ContainerStart(ctx, c.ID, types.ContainerStartOptions{})
  30. require.NoError(t, err)
  31. err = client.ContainerKill(ctx, c.ID, "0")
  32. require.EqualError(t, err, "Error response from daemon: Invalid signal: 0")
  33. poll.WaitOn(t, containerIsInState(ctx, client, c.ID, "running"), poll.WithDelay(100*time.Millisecond))
  34. err = client.ContainerKill(ctx, c.ID, "SIG42")
  35. require.EqualError(t, err, "Error response from daemon: Invalid signal: SIG42")
  36. poll.WaitOn(t, containerIsInState(ctx, client, c.ID, "running"), poll.WithDelay(100*time.Millisecond))
  37. }
  38. func TestKillContainer(t *testing.T) {
  39. defer setupTest(t)()
  40. client := request.NewAPIClient(t)
  41. testCases := []struct {
  42. doc string
  43. signal string
  44. status string
  45. }{
  46. {
  47. doc: "no signal",
  48. signal: "",
  49. status: "exited",
  50. },
  51. {
  52. doc: "non killing signal",
  53. signal: "SIGWINCH",
  54. status: "running",
  55. },
  56. {
  57. doc: "killing signal",
  58. signal: "SIGTERM",
  59. status: "exited",
  60. },
  61. }
  62. for _, tc := range testCases {
  63. tc := tc
  64. t.Run(tc.doc, func(t *testing.T) {
  65. ctx := context.Background()
  66. c, err := client.ContainerCreate(ctx,
  67. &container.Config{
  68. Image: "busybox",
  69. Cmd: strslice.StrSlice([]string{"top"}),
  70. },
  71. &container.HostConfig{},
  72. &network.NetworkingConfig{},
  73. "")
  74. require.NoError(t, err)
  75. err = client.ContainerStart(ctx, c.ID, types.ContainerStartOptions{})
  76. require.NoError(t, err)
  77. err = client.ContainerKill(ctx, c.ID, tc.signal)
  78. require.NoError(t, err)
  79. poll.WaitOn(t, containerIsInState(ctx, client, c.ID, tc.status), poll.WithDelay(100*time.Millisecond))
  80. })
  81. }
  82. }
  83. func TestKillWithStopSignalAndRestartPolicies(t *testing.T) {
  84. skip.If(t, testEnv.OSType != "linux", "Windows only supports 1.25 or later")
  85. defer setupTest(t)()
  86. client := request.NewAPIClient(t)
  87. testCases := []struct {
  88. doc string
  89. stopsignal string
  90. status string
  91. }{
  92. {
  93. doc: "same-signal-disables-restart-policy",
  94. stopsignal: "TERM",
  95. status: "exited",
  96. },
  97. {
  98. doc: "different-signal-keep-restart-policy",
  99. stopsignal: "CONT",
  100. status: "running",
  101. },
  102. }
  103. for _, tc := range testCases {
  104. tc := tc
  105. t.Run(tc.doc, func(t *testing.T) {
  106. ctx := context.Background()
  107. c, err := client.ContainerCreate(ctx,
  108. &container.Config{
  109. Image: "busybox",
  110. Cmd: strslice.StrSlice([]string{"top"}),
  111. StopSignal: tc.stopsignal,
  112. },
  113. &container.HostConfig{
  114. RestartPolicy: container.RestartPolicy{
  115. Name: "always",
  116. }},
  117. &network.NetworkingConfig{},
  118. "")
  119. require.NoError(t, err)
  120. err = client.ContainerStart(ctx, c.ID, types.ContainerStartOptions{})
  121. require.NoError(t, err)
  122. err = client.ContainerKill(ctx, c.ID, "TERM")
  123. require.NoError(t, err)
  124. poll.WaitOn(t, containerIsInState(ctx, client, c.ID, tc.status), poll.WithDelay(100*time.Millisecond))
  125. })
  126. }
  127. }
  128. func TestKillStoppedContainer(t *testing.T) {
  129. skip.If(t, testEnv.OSType != "linux") // Windows only supports 1.25 or later
  130. defer setupTest(t)()
  131. ctx := context.Background()
  132. client := request.NewAPIClient(t)
  133. c, err := client.ContainerCreate(ctx,
  134. &container.Config{
  135. Image: "busybox",
  136. Cmd: strslice.StrSlice([]string{"top"}),
  137. },
  138. &container.HostConfig{},
  139. &network.NetworkingConfig{},
  140. "")
  141. require.NoError(t, err)
  142. err = client.ContainerKill(ctx, c.ID, "SIGKILL")
  143. require.Error(t, err)
  144. require.Contains(t, err.Error(), "is not running")
  145. }
  146. func TestKillStoppedContainerAPIPre120(t *testing.T) {
  147. skip.If(t, testEnv.OSType != "linux") // Windows only supports 1.25 or later
  148. defer setupTest(t)()
  149. ctx := context.Background()
  150. client := request.NewAPIClient(t, client.WithVersion("1.19"))
  151. c, err := client.ContainerCreate(ctx,
  152. &container.Config{
  153. Image: "busybox",
  154. Cmd: strslice.StrSlice([]string{"top"}),
  155. },
  156. &container.HostConfig{},
  157. &network.NetworkingConfig{},
  158. "")
  159. require.NoError(t, err)
  160. err = client.ContainerKill(ctx, c.ID, "SIGKILL")
  161. require.NoError(t, err)
  162. }