mirror of
https://github.com/moby/moby.git
synced 2026-01-11 10:41:43 +00:00
Add option- and output structs for; - Client.ContainerKill - Client.ContainerPause - Client.ContainerRemove - Client.ContainerResize - Client.ContainerRestart - Client.ContainerStart - Client.ContainerStop - Client.ContainerUnpause Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
114 lines
3.2 KiB
Go
114 lines
3.2 KiB
Go
package container
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
containertypes "github.com/moby/moby/api/types/container"
|
|
"github.com/moby/moby/client"
|
|
"github.com/moby/moby/v2/integration/internal/container"
|
|
"gotest.tools/v3/assert"
|
|
is "gotest.tools/v3/assert/cmp"
|
|
"gotest.tools/v3/poll"
|
|
"gotest.tools/v3/skip"
|
|
)
|
|
|
|
// hcs can sometimes take a long time to stop container.
|
|
const StopContainerWindowsPollTimeout = 75 * time.Second
|
|
|
|
func TestStopContainerWithRestartPolicyAlways(t *testing.T) {
|
|
ctx := setupTest(t)
|
|
apiClient := testEnv.APIClient()
|
|
|
|
names := []string{"verifyRestart1-" + t.Name(), "verifyRestart2-" + t.Name()}
|
|
for _, name := range names {
|
|
container.Run(ctx, t, apiClient,
|
|
container.WithName(name),
|
|
container.WithCmd("false"),
|
|
container.WithRestartPolicy(containertypes.RestartPolicyAlways),
|
|
)
|
|
}
|
|
|
|
for _, name := range names {
|
|
poll.WaitOn(t, container.IsInState(ctx, apiClient, name, containertypes.StateRunning, containertypes.StateRestarting))
|
|
}
|
|
|
|
for _, name := range names {
|
|
_, err := apiClient.ContainerStop(ctx, name, client.ContainerStopOptions{})
|
|
assert.NilError(t, err)
|
|
}
|
|
|
|
for _, name := range names {
|
|
poll.WaitOn(t, container.IsStopped(ctx, apiClient, name))
|
|
}
|
|
}
|
|
|
|
// TestStopContainerWithTimeout checks that ContainerStop with
|
|
// a timeout works as documented, i.e. in case of negative timeout
|
|
// waiting is not limited (issue #35311).
|
|
func TestStopContainerWithTimeout(t *testing.T) {
|
|
isWindows := testEnv.DaemonInfo.OSType == "windows"
|
|
// TODO(vvoland): Make this work on Windows
|
|
skip.If(t, isWindows)
|
|
|
|
ctx := setupTest(t)
|
|
apiClient := testEnv.APIClient()
|
|
|
|
forcefulKillExitCode := 137
|
|
if isWindows {
|
|
forcefulKillExitCode = 0x40010004
|
|
}
|
|
|
|
testCmd := container.WithCmd("sh", "-c", "sleep 10 && exit 42")
|
|
testData := []struct {
|
|
doc string
|
|
timeout int
|
|
expectedExitCode int
|
|
}{
|
|
// In case container is forcefully killed, 137 is returned,
|
|
// otherwise the exit code from the above script
|
|
{
|
|
doc: "zero timeout: expect forceful container kill",
|
|
expectedExitCode: forcefulKillExitCode,
|
|
timeout: 0,
|
|
},
|
|
{
|
|
doc: "too small timeout: expect forceful container kill",
|
|
expectedExitCode: forcefulKillExitCode,
|
|
timeout: 2,
|
|
},
|
|
{
|
|
doc: "big enough timeout: expect graceful container stop",
|
|
expectedExitCode: 42,
|
|
timeout: 20, // longer than "sleep 10" cmd
|
|
},
|
|
{
|
|
doc: "unlimited timeout: expect graceful container stop",
|
|
expectedExitCode: 42,
|
|
timeout: -1,
|
|
},
|
|
}
|
|
|
|
var pollOpts []poll.SettingOp
|
|
if isWindows {
|
|
pollOpts = append(pollOpts, poll.WithTimeout(StopContainerWindowsPollTimeout))
|
|
}
|
|
|
|
for _, tc := range testData {
|
|
t.Run(tc.doc, func(t *testing.T) {
|
|
// TODO(vvoland): Investigate why it helps
|
|
// t.Parallel()
|
|
id := container.Run(ctx, t, apiClient, testCmd)
|
|
|
|
_, err := apiClient.ContainerStop(ctx, id, client.ContainerStopOptions{Timeout: &tc.timeout})
|
|
assert.NilError(t, err)
|
|
|
|
poll.WaitOn(t, container.IsStopped(ctx, apiClient, id), pollOpts...)
|
|
|
|
inspect, err := apiClient.ContainerInspect(ctx, id, client.ContainerInspectOptions{})
|
|
assert.NilError(t, err)
|
|
assert.Check(t, is.Equal(inspect.Container.State.ExitCode, tc.expectedExitCode))
|
|
})
|
|
}
|
|
}
|