Browse code

integration: Deduplicate TestStopContainerWithTimeout

The test had 2 almost identical separate implementations (Linux and
Windows). The Windows one was skipped anyway.
Make one test that covers all test cases.

The test still needs to be fixed for Windows, so don't unskip it yet.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>

Paweł Gronowski authored on 2023/03/06 18:51:10
Showing 3 changed files
... ...
@@ -4,7 +4,6 @@ import (
4 4
 	"bytes"
5 5
 	"context"
6 6
 	"io"
7
-	"strconv"
8 7
 	"strings"
9 8
 	"testing"
10 9
 	"time"
... ...
@@ -14,64 +13,11 @@ import (
14 14
 	"github.com/docker/docker/errdefs"
15 15
 	"github.com/docker/docker/integration/internal/container"
16 16
 	"github.com/docker/docker/pkg/stdcopy"
17
-	"github.com/docker/docker/testutil"
18 17
 	"gotest.tools/v3/assert"
19 18
 	is "gotest.tools/v3/assert/cmp"
20 19
 	"gotest.tools/v3/poll"
21 20
 )
22 21
 
23
-// TestStopContainerWithTimeout checks that ContainerStop with
24
-// a timeout works as documented, i.e. in case of negative timeout
25
-// waiting is not limited (issue #35311).
26
-func TestStopContainerWithTimeout(t *testing.T) {
27
-	ctx := setupTest(t)
28
-
29
-	apiClient := testEnv.APIClient()
30
-
31
-	testCmd := container.WithCmd("sh", "-c", "sleep 2 && exit 42")
32
-	tests := []struct {
33
-		doc              string
34
-		timeout          int
35
-		expectedExitCode int
36
-	}{
37
-		// In case container is forcefully killed, 137 is returned,
38
-		// otherwise the exit code from the above script
39
-		{
40
-			"zero timeout: expect forceful container kill",
41
-			0, 137,
42
-		},
43
-		{
44
-			"too small timeout: expect forceful container kill",
45
-			1, 137,
46
-		},
47
-		{
48
-			"big enough timeout: expect graceful container stop",
49
-			3, 42,
50
-		},
51
-		{
52
-			"unlimited timeout: expect graceful container stop",
53
-			-1, 42,
54
-		},
55
-	}
56
-
57
-	for _, tc := range tests {
58
-		t.Run(strconv.Itoa(tc.timeout), func(t *testing.T) {
59
-			t.Parallel()
60
-			ctx := testutil.StartSpan(ctx, t)
61
-			id := container.Run(ctx, t, apiClient, testCmd)
62
-
63
-			err := apiClient.ContainerStop(ctx, id, containertypes.StopOptions{Timeout: &tc.timeout})
64
-			assert.NilError(t, err)
65
-
66
-			poll.WaitOn(t, container.IsStopped(ctx, apiClient, id))
67
-
68
-			inspect, err := apiClient.ContainerInspect(ctx, id)
69
-			assert.NilError(t, err)
70
-			assert.Equal(t, inspect.State.ExitCode, tc.expectedExitCode)
71
-		})
72
-	}
73
-}
74
-
75 22
 // TestStopContainerWithTimeoutCancel checks that ContainerStop is not cancelled
76 23
 // if the request is cancelled.
77 24
 // See issue https://github.com/moby/moby/issues/45731
... ...
@@ -7,7 +7,9 @@ import (
7 7
 	containertypes "github.com/docker/docker/api/types/container"
8 8
 	"github.com/docker/docker/integration/internal/container"
9 9
 	"gotest.tools/v3/assert"
10
+	is "gotest.tools/v3/assert/cmp"
10 11
 	"gotest.tools/v3/poll"
12
+	"gotest.tools/v3/skip"
11 13
 )
12 14
 
13 15
 // hcs can sometimes take a long time to stop container.
... ...
@@ -39,3 +41,71 @@ func TestStopContainerWithRestartPolicyAlways(t *testing.T) {
39 39
 		poll.WaitOn(t, container.IsStopped(ctx, apiClient, name))
40 40
 	}
41 41
 }
42
+
43
+// TestStopContainerWithTimeout checks that ContainerStop with
44
+// a timeout works as documented, i.e. in case of negative timeout
45
+// waiting is not limited (issue #35311).
46
+func TestStopContainerWithTimeout(t *testing.T) {
47
+	isWindows := testEnv.DaemonInfo.OSType == "windows"
48
+	// TODO(vvoland): Make this work on Windows
49
+	skip.If(t, isWindows)
50
+
51
+	ctx := setupTest(t)
52
+	apiClient := testEnv.APIClient()
53
+
54
+	forcefulKillExitCode := 137
55
+	if isWindows {
56
+		forcefulKillExitCode = 0x40010004
57
+	}
58
+
59
+	testCmd := container.WithCmd("sh", "-c", "sleep 2 && exit 42")
60
+	testData := []struct {
61
+		doc              string
62
+		timeout          int
63
+		expectedExitCode int
64
+	}{
65
+		// In case container is forcefully killed, 137 is returned,
66
+		// otherwise the exit code from the above script
67
+		{
68
+			doc:              "zero timeout: expect forceful container kill",
69
+			expectedExitCode: forcefulKillExitCode,
70
+			timeout:          0,
71
+		},
72
+		{
73
+			doc:              "too small timeout: expect forceful container kill",
74
+			expectedExitCode: forcefulKillExitCode,
75
+			timeout:          1,
76
+		},
77
+		{
78
+			doc:              "big enough timeout: expect graceful container stop",
79
+			expectedExitCode: 42,
80
+			timeout:          3, // longer than "sleep 5" cmd
81
+		},
82
+		{
83
+			doc:              "unlimited timeout: expect graceful container stop",
84
+			expectedExitCode: 42,
85
+			timeout:          -1,
86
+		},
87
+	}
88
+
89
+	var pollOpts []poll.SettingOp
90
+	if isWindows {
91
+		pollOpts = append(pollOpts, poll.WithTimeout(StopContainerWindowsPollTimeout))
92
+	}
93
+
94
+	for _, tc := range testData {
95
+		t.Run(tc.doc, func(t *testing.T) {
96
+			t.Parallel()
97
+			id := container.Run(ctx, t, apiClient, testCmd)
98
+
99
+			err := apiClient.ContainerStop(ctx, id, containertypes.StopOptions{Timeout: &tc.timeout})
100
+			assert.NilError(t, err)
101
+
102
+			poll.WaitOn(t, container.IsStopped(ctx, apiClient, id), pollOpts...)
103
+
104
+			inspect, err := apiClient.ContainerInspect(ctx, id)
105
+			assert.NilError(t, err)
106
+			assert.Check(t, is.Equal(inspect.State.ExitCode, tc.expectedExitCode))
107
+		})
108
+	}
109
+}
42 110
deleted file mode 100644
... ...
@@ -1,67 +0,0 @@
1
-package container // import "github.com/docker/docker/integration/container"
2
-
3
-import (
4
-	"strconv"
5
-	"testing"
6
-
7
-	containertypes "github.com/docker/docker/api/types/container"
8
-	"github.com/docker/docker/integration/internal/container"
9
-	"github.com/docker/docker/testutil"
10
-	"gotest.tools/v3/assert"
11
-	"gotest.tools/v3/poll"
12
-	"gotest.tools/v3/skip"
13
-)
14
-
15
-// TestStopContainerWithTimeout checks that ContainerStop with
16
-// a timeout works as documented, i.e. in case of negative timeout
17
-// waiting is not limited (issue #35311).
18
-func TestStopContainerWithTimeout(t *testing.T) {
19
-	skip.If(t, testEnv.DaemonInfo.OSType == "windows")
20
-	ctx := setupTest(t)
21
-
22
-	apiClient := testEnv.APIClient()
23
-
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
-			1, 0x40010004,
35
-		},
36
-		{
37
-			"too small timeout: expect forceful container kill",
38
-			2, 0x40010004,
39
-		},
40
-		{
41
-			"big enough timeout: expect graceful container stop",
42
-			120, 42,
43
-		},
44
-		{
45
-			"unlimited timeout: expect graceful container stop",
46
-			-1, 42,
47
-		},
48
-	}
49
-
50
-	for _, d := range testData {
51
-		d := d
52
-		t.Run(strconv.Itoa(d.timeout), func(t *testing.T) {
53
-			t.Parallel()
54
-			ctx := testutil.StartSpan(ctx, t)
55
-			id := container.Run(ctx, t, apiClient, testCmd)
56
-
57
-			err := apiClient.ContainerStop(ctx, id, containertypes.StopOptions{Timeout: &d.timeout})
58
-			assert.NilError(t, err)
59
-
60
-			poll.WaitOn(t, container.IsStopped(ctx, apiClient, id))
61
-
62
-			inspect, err := apiClient.ContainerInspect(ctx, id)
63
-			assert.NilError(t, err)
64
-			assert.Equal(t, inspect.State.ExitCode, d.expectedExitCode)
65
-		})
66
-	}
67
-}