These integration tests were basically testing if a
decent error message was printed when attempting
to remove a running, paused, or restarting container.
Moving these tests to a unit-test to make the tests
not flaky (especially on the "restarting" container
test).
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
| ... | ... |
@@ -9,35 +9,102 @@ import ( |
| 9 | 9 |
"github.com/docker/docker/api/types" |
| 10 | 10 |
containertypes "github.com/docker/docker/api/types/container" |
| 11 | 11 |
"github.com/docker/docker/container" |
| 12 |
+ "github.com/docker/docker/pkg/testutil/assert" |
|
| 12 | 13 |
) |
| 13 | 14 |
|
| 14 |
-func TestContainerDoubleDelete(t *testing.T) {
|
|
| 15 |
+func newDaemonWithTmpRoot(t *testing.T) (*Daemon, func()) {
|
|
| 15 | 16 |
tmp, err := ioutil.TempDir("", "docker-daemon-unix-test-")
|
| 16 |
- if err != nil {
|
|
| 17 |
- t.Fatal(err) |
|
| 18 |
- } |
|
| 19 |
- defer os.RemoveAll(tmp) |
|
| 20 |
- daemon := &Daemon{
|
|
| 17 |
+ assert.NilError(t, err) |
|
| 18 |
+ d := &Daemon{
|
|
| 21 | 19 |
repository: tmp, |
| 22 | 20 |
root: tmp, |
| 23 | 21 |
} |
| 24 |
- daemon.containers = container.NewMemoryStore() |
|
| 22 |
+ d.containers = container.NewMemoryStore() |
|
| 23 |
+ return d, func() { os.RemoveAll(tmp) }
|
|
| 24 |
+} |
|
| 25 |
+ |
|
| 26 |
+// TestContainerDeletePaused tests that a useful error message and instructions is given when attempting |
|
| 27 |
+// to remove a paused container (#30842) |
|
| 28 |
+func TestContainerDeletePaused(t *testing.T) {
|
|
| 29 |
+ c := &container.Container{
|
|
| 30 |
+ CommonContainer: container.CommonContainer{
|
|
| 31 |
+ ID: "test", |
|
| 32 |
+ State: &container.State{Paused: true, Running: true},
|
|
| 33 |
+ Config: &containertypes.Config{},
|
|
| 34 |
+ }, |
|
| 35 |
+ } |
|
| 36 |
+ |
|
| 37 |
+ d, cleanup := newDaemonWithTmpRoot(t) |
|
| 38 |
+ defer cleanup() |
|
| 39 |
+ d.containers.Add(c.ID, c) |
|
| 40 |
+ |
|
| 41 |
+ err := d.ContainerRm(c.ID, &types.ContainerRmConfig{ForceRemove: false})
|
|
| 42 |
+ |
|
| 43 |
+ assert.Error(t, err, "cannot remove a paused container") |
|
| 44 |
+ assert.Error(t, err, "Unpause and then stop the container before attempting removal or force remove") |
|
| 45 |
+} |
|
| 46 |
+ |
|
| 47 |
+// TestContainerDeleteRestarting tests that a useful error message and instructions is given when attempting |
|
| 48 |
+// to remove a container that is restarting (#30842) |
|
| 49 |
+func TestContainerDeleteRestarting(t *testing.T) {
|
|
| 50 |
+ c := &container.Container{
|
|
| 51 |
+ CommonContainer: container.CommonContainer{
|
|
| 52 |
+ ID: "test", |
|
| 53 |
+ State: container.NewState(), |
|
| 54 |
+ Config: &containertypes.Config{},
|
|
| 55 |
+ }, |
|
| 56 |
+ } |
|
| 57 |
+ |
|
| 58 |
+ c.SetRunning(0, true) |
|
| 59 |
+ c.SetRestarting(&container.ExitStatus{})
|
|
| 60 |
+ |
|
| 61 |
+ d, cleanup := newDaemonWithTmpRoot(t) |
|
| 62 |
+ defer cleanup() |
|
| 63 |
+ d.containers.Add(c.ID, c) |
|
| 64 |
+ |
|
| 65 |
+ err := d.ContainerRm(c.ID, &types.ContainerRmConfig{ForceRemove: false})
|
|
| 66 |
+ assert.Error(t, err, "cannot remove a restarting container") |
|
| 67 |
+ assert.Error(t, err, "Stop the container before attempting removal or force remove") |
|
| 68 |
+} |
|
| 69 |
+ |
|
| 70 |
+// TestContainerDeleteRunning tests that a useful error message and instructions is given when attempting |
|
| 71 |
+// to remove a running container (#30842) |
|
| 72 |
+func TestContainerDeleteRunning(t *testing.T) {
|
|
| 73 |
+ c := &container.Container{
|
|
| 74 |
+ CommonContainer: container.CommonContainer{
|
|
| 75 |
+ ID: "test", |
|
| 76 |
+ State: &container.State{Running: true},
|
|
| 77 |
+ Config: &containertypes.Config{},
|
|
| 78 |
+ }, |
|
| 79 |
+ } |
|
| 25 | 80 |
|
| 26 |
- container := &container.Container{
|
|
| 81 |
+ d, cleanup := newDaemonWithTmpRoot(t) |
|
| 82 |
+ defer cleanup() |
|
| 83 |
+ d.containers.Add(c.ID, c) |
|
| 84 |
+ |
|
| 85 |
+ err := d.ContainerRm(c.ID, &types.ContainerRmConfig{ForceRemove: false})
|
|
| 86 |
+ assert.Error(t, err, "cannot remove a running container") |
|
| 87 |
+ assert.Error(t, err, "Stop the container before attempting removal or force remove") |
|
| 88 |
+} |
|
| 89 |
+ |
|
| 90 |
+func TestContainerDoubleDelete(t *testing.T) {
|
|
| 91 |
+ c := &container.Container{
|
|
| 27 | 92 |
CommonContainer: container.CommonContainer{
|
| 28 | 93 |
ID: "test", |
| 29 | 94 |
State: container.NewState(), |
| 30 | 95 |
Config: &containertypes.Config{},
|
| 31 | 96 |
}, |
| 32 | 97 |
} |
| 33 |
- daemon.containers.Add(container.ID, container) |
|
| 34 | 98 |
|
| 35 | 99 |
// Mark the container as having a delete in progress |
| 36 |
- container.SetRemovalInProgress() |
|
| 100 |
+ c.SetRemovalInProgress() |
|
| 101 |
+ |
|
| 102 |
+ d, cleanup := newDaemonWithTmpRoot(t) |
|
| 103 |
+ defer cleanup() |
|
| 104 |
+ d.containers.Add(c.ID, c) |
|
| 37 | 105 |
|
| 38 | 106 |
// Try to remove the container when its state is removalInProgress. |
| 39 | 107 |
// It should return an error indicating it is under removal progress. |
| 40 |
- if err := daemon.ContainerRm(container.ID, &types.ContainerRmConfig{ForceRemove: true}); err == nil {
|
|
| 41 |
- t.Fatalf("expected err: %v, got nil", fmt.Sprintf("removal of container %s is already in progress", container.ID))
|
|
| 42 |
- } |
|
| 108 |
+ err := d.ContainerRm(c.ID, &types.ContainerRmConfig{ForceRemove: true})
|
|
| 109 |
+ assert.Error(t, err, fmt.Sprintf("removal of container %s is already in progress", c.ID))
|
|
| 43 | 110 |
} |
| ... | ... |
@@ -3,8 +3,6 @@ package main |
| 3 | 3 |
import ( |
| 4 | 4 |
"io/ioutil" |
| 5 | 5 |
"os" |
| 6 |
- "strings" |
|
| 7 |
- "time" |
|
| 8 | 6 |
|
| 9 | 7 |
"github.com/docker/docker/integration-cli/checker" |
| 10 | 8 |
"github.com/docker/docker/integration-cli/cli/build" |
| ... | ... |
@@ -44,7 +42,6 @@ func (s *DockerSuite) TestRmContainerRunning(c *check.C) {
|
| 44 | 44 |
res, _, err := dockerCmdWithError("rm", "foo")
|
| 45 | 45 |
c.Assert(err, checker.NotNil, check.Commentf("Expected error, can't rm a running container"))
|
| 46 | 46 |
c.Assert(res, checker.Contains, "cannot remove a running container") |
| 47 |
- c.Assert(res, checker.Contains, "Stop the container before attempting removal or force remove") |
|
| 48 | 47 |
} |
| 49 | 48 |
|
| 50 | 49 |
func (s *DockerSuite) TestRmContainerForceRemoveRunning(c *check.C) {
|
| ... | ... |
@@ -88,42 +85,3 @@ func (s *DockerSuite) TestRmInvalidContainer(c *check.C) {
|
| 88 | 88 |
func createRunningContainer(c *check.C, name string) {
|
| 89 | 89 |
runSleepingContainer(c, "-dt", "--name", name) |
| 90 | 90 |
} |
| 91 |
- |
|
| 92 |
-// #30842 |
|
| 93 |
-func (s *DockerSuite) TestRmRestartingContainer(c *check.C) {
|
|
| 94 |
- name := "rst" |
|
| 95 |
- dockerCmd(c, "run", "--name", name, "--restart=always", "busybox", "date") |
|
| 96 |
- |
|
| 97 |
- res, _, err := dockerCmdWithError("rm", name)
|
|
| 98 |
- |
|
| 99 |
- for strings.Contains(res, "cannot remove a running container") {
|
|
| 100 |
- // The `date` command hasn't exited yet. It should end |
|
| 101 |
- // up in a "restarting" state if we wait a bit, though |
|
| 102 |
- // it is possible that it might be running again by |
|
| 103 |
- // that time. The wait period between each restart |
|
| 104 |
- // increases though so we just loop in this condition. |
|
| 105 |
- time.Sleep(100 * time.Millisecond) |
|
| 106 |
- res, _, err = dockerCmdWithError("rm", name)
|
|
| 107 |
- } |
|
| 108 |
- |
|
| 109 |
- c.Assert(err, checker.NotNil, check.Commentf("Expected error on rm a restarting container, got none"))
|
|
| 110 |
- c.Assert(res, checker.Contains, "cannot remove a restarting container") |
|
| 111 |
- c.Assert(res, checker.Contains, "Stop the container before attempting removal or force remove") |
|
| 112 |
- dockerCmd(c, "rm", "-f", name) |
|
| 113 |
-} |
|
| 114 |
- |
|
| 115 |
-// #30842 |
|
| 116 |
-func (s *DockerSuite) TestRmPausedContainer(c *check.C) {
|
|
| 117 |
- testRequires(c, IsPausable) |
|
| 118 |
- name := "psd" |
|
| 119 |
- dockerCmd(c, "run", "--name", name, "-d", "busybox", "sleep", "1m") |
|
| 120 |
- dockerCmd(c, "pause", name) |
|
| 121 |
- |
|
| 122 |
- res, _, err := dockerCmdWithError("rm", name)
|
|
| 123 |
- c.Assert(err, checker.NotNil, check.Commentf("Expected error on rm a paused container, got none"))
|
|
| 124 |
- c.Assert(res, checker.Contains, "cannot remove a paused container") |
|
| 125 |
- c.Assert(res, checker.Contains, "Unpause and then stop the container before attempting removal or force remove") |
|
| 126 |
- unpauseContainer(c, name) |
|
| 127 |
- dockerCmd(c, "stop", name) |
|
| 128 |
- dockerCmd(c, "rm", name) |
|
| 129 |
-} |