github.com/skanehira/moby@v17.12.1-ce-rc2+incompatible/daemon/delete_test.go (about) 1 package daemon 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "os" 7 "testing" 8 9 "github.com/docker/docker/api/types" 10 containertypes "github.com/docker/docker/api/types/container" 11 "github.com/docker/docker/container" 12 "github.com/docker/docker/internal/testutil" 13 "github.com/stretchr/testify/require" 14 ) 15 16 func newDaemonWithTmpRoot(t *testing.T) (*Daemon, func()) { 17 tmp, err := ioutil.TempDir("", "docker-daemon-unix-test-") 18 require.NoError(t, err) 19 d := &Daemon{ 20 repository: tmp, 21 root: tmp, 22 } 23 d.containers = container.NewMemoryStore() 24 return d, func() { os.RemoveAll(tmp) } 25 } 26 27 func newContainerWithState(state *container.State) *container.Container { 28 return &container.Container{ 29 ID: "test", 30 State: state, 31 Config: &containertypes.Config{}, 32 } 33 34 } 35 36 // TestContainerDelete tests that a useful error message and instructions is 37 // given when attempting to remove a container (#30842) 38 func TestContainerDelete(t *testing.T) { 39 tt := []struct { 40 errMsg string 41 fixMsg string 42 initContainer func() *container.Container 43 }{ 44 // a paused container 45 { 46 errMsg: "cannot remove a paused container", 47 fixMsg: "Unpause and then stop the container before attempting removal or force remove", 48 initContainer: func() *container.Container { 49 return newContainerWithState(&container.State{Paused: true, Running: true}) 50 }}, 51 // a restarting container 52 { 53 errMsg: "cannot remove a restarting container", 54 fixMsg: "Stop the container before attempting removal or force remove", 55 initContainer: func() *container.Container { 56 c := newContainerWithState(container.NewState()) 57 c.SetRunning(0, true) 58 c.SetRestarting(&container.ExitStatus{}) 59 return c 60 }}, 61 // a running container 62 { 63 errMsg: "cannot remove a running container", 64 fixMsg: "Stop the container before attempting removal or force remove", 65 initContainer: func() *container.Container { 66 return newContainerWithState(&container.State{Running: true}) 67 }}, 68 } 69 70 for _, te := range tt { 71 c := te.initContainer() 72 d, cleanup := newDaemonWithTmpRoot(t) 73 defer cleanup() 74 d.containers.Add(c.ID, c) 75 76 err := d.ContainerRm(c.ID, &types.ContainerRmConfig{ForceRemove: false}) 77 testutil.ErrorContains(t, err, te.errMsg) 78 testutil.ErrorContains(t, err, te.fixMsg) 79 } 80 } 81 82 func TestContainerDoubleDelete(t *testing.T) { 83 c := newContainerWithState(container.NewState()) 84 85 // Mark the container as having a delete in progress 86 c.SetRemovalInProgress() 87 88 d, cleanup := newDaemonWithTmpRoot(t) 89 defer cleanup() 90 d.containers.Add(c.ID, c) 91 92 // Try to remove the container when its state is removalInProgress. 93 // It should return an error indicating it is under removal progress. 94 err := d.ContainerRm(c.ID, &types.ContainerRmConfig{ForceRemove: true}) 95 testutil.ErrorContains(t, err, fmt.Sprintf("removal of container %s is already in progress", c.ID)) 96 }