| package daemon |
| |
| import ( |
| "fmt" |
| "io/ioutil" |
| "os" |
| "testing" |
| |
| "github.com/docker/docker/api/types" |
| containertypes "github.com/docker/docker/api/types/container" |
| "github.com/docker/docker/container" |
| "github.com/docker/docker/pkg/testutil/assert" |
| ) |
| |
| func newDaemonWithTmpRoot(t *testing.T) (*Daemon, func()) { |
| tmp, err := ioutil.TempDir("", "docker-daemon-unix-test-") |
| assert.NilError(t, err) |
| d := &Daemon{ |
| repository: tmp, |
| root: tmp, |
| } |
| d.containers = container.NewMemoryStore() |
| return d, func() { os.RemoveAll(tmp) } |
| } |
| |
| // TestContainerDeletePaused tests that a useful error message and instructions is given when attempting |
| // to remove a paused container (#30842) |
| func TestContainerDeletePaused(t *testing.T) { |
| c := &container.Container{ |
| CommonContainer: container.CommonContainer{ |
| ID: "test", |
| State: &container.State{Paused: true, Running: true}, |
| Config: &containertypes.Config{}, |
| }, |
| } |
| |
| d, cleanup := newDaemonWithTmpRoot(t) |
| defer cleanup() |
| d.containers.Add(c.ID, c) |
| |
| err := d.ContainerRm(c.ID, &types.ContainerRmConfig{ForceRemove: false}) |
| |
| assert.Error(t, err, "cannot remove a paused container") |
| assert.Error(t, err, "Unpause and then stop the container before attempting removal or force remove") |
| } |
| |
| // TestContainerDeleteRestarting tests that a useful error message and instructions is given when attempting |
| // to remove a container that is restarting (#30842) |
| func TestContainerDeleteRestarting(t *testing.T) { |
| c := &container.Container{ |
| CommonContainer: container.CommonContainer{ |
| ID: "test", |
| State: container.NewState(), |
| Config: &containertypes.Config{}, |
| }, |
| } |
| |
| c.SetRunning(0, true) |
| c.SetRestarting(&container.ExitStatus{}) |
| |
| d, cleanup := newDaemonWithTmpRoot(t) |
| defer cleanup() |
| d.containers.Add(c.ID, c) |
| |
| err := d.ContainerRm(c.ID, &types.ContainerRmConfig{ForceRemove: false}) |
| assert.Error(t, err, "cannot remove a restarting container") |
| assert.Error(t, err, "Stop the container before attempting removal or force remove") |
| } |
| |
| // TestContainerDeleteRunning tests that a useful error message and instructions is given when attempting |
| // to remove a running container (#30842) |
| func TestContainerDeleteRunning(t *testing.T) { |
| c := &container.Container{ |
| CommonContainer: container.CommonContainer{ |
| ID: "test", |
| State: &container.State{Running: true}, |
| Config: &containertypes.Config{}, |
| }, |
| } |
| |
| d, cleanup := newDaemonWithTmpRoot(t) |
| defer cleanup() |
| d.containers.Add(c.ID, c) |
| |
| err := d.ContainerRm(c.ID, &types.ContainerRmConfig{ForceRemove: false}) |
| assert.Error(t, err, "cannot remove a running container") |
| assert.Error(t, err, "Stop the container before attempting removal or force remove") |
| } |
| |
| func TestContainerDoubleDelete(t *testing.T) { |
| c := &container.Container{ |
| CommonContainer: container.CommonContainer{ |
| ID: "test", |
| State: container.NewState(), |
| Config: &containertypes.Config{}, |
| }, |
| } |
| |
| // Mark the container as having a delete in progress |
| c.SetRemovalInProgress() |
| |
| d, cleanup := newDaemonWithTmpRoot(t) |
| defer cleanup() |
| d.containers.Add(c.ID, c) |
| |
| // Try to remove the container when its state is removalInProgress. |
| // It should return an error indicating it is under removal progress. |
| err := d.ContainerRm(c.ID, &types.ContainerRmConfig{ForceRemove: true}) |
| assert.Error(t, err, fmt.Sprintf("removal of container %s is already in progress", c.ID)) |
| } |