github.com/jiasir/docker@v1.3.3-0.20170609024000-252e610103e7/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/pkg/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 CommonContainer: container.CommonContainer{ 30 ID: "test", 31 State: state, 32 Config: &containertypes.Config{}, 33 }, 34 } 35 36 } 37 38 // TestContainerDelete tests that a useful error message and instructions is 39 // given when attempting to remove a container (#30842) 40 func TestContainerDelete(t *testing.T) { 41 tt := []struct { 42 errMsg string 43 fixMsg string 44 initContainer func() *container.Container 45 }{ 46 // a paused container 47 { 48 errMsg: "cannot remove a paused container", 49 fixMsg: "Unpause and then stop the container before attempting removal or force remove", 50 initContainer: func() *container.Container { 51 return newContainerWithState(&container.State{Paused: true, Running: true}) 52 }}, 53 // a restarting container 54 { 55 errMsg: "cannot remove a restarting container", 56 fixMsg: "Stop the container before attempting removal or force remove", 57 initContainer: func() *container.Container { 58 c := newContainerWithState(container.NewState()) 59 c.SetRunning(0, true) 60 c.SetRestarting(&container.ExitStatus{}) 61 return c 62 }}, 63 // a running container 64 { 65 errMsg: "cannot remove a running container", 66 fixMsg: "Stop the container before attempting removal or force remove", 67 initContainer: func() *container.Container { 68 return newContainerWithState(&container.State{Running: true}) 69 }}, 70 } 71 72 for _, te := range tt { 73 c := te.initContainer() 74 d, cleanup := newDaemonWithTmpRoot(t) 75 defer cleanup() 76 d.containers.Add(c.ID, c) 77 78 err := d.ContainerRm(c.ID, &types.ContainerRmConfig{ForceRemove: false}) 79 testutil.ErrorContains(t, err, te.errMsg) 80 testutil.ErrorContains(t, err, te.fixMsg) 81 } 82 } 83 84 func TestContainerDoubleDelete(t *testing.T) { 85 c := newContainerWithState(container.NewState()) 86 87 // Mark the container as having a delete in progress 88 c.SetRemovalInProgress() 89 90 d, cleanup := newDaemonWithTmpRoot(t) 91 defer cleanup() 92 d.containers.Add(c.ID, c) 93 94 // Try to remove the container when its state is removalInProgress. 95 // It should return an error indicating it is under removal progress. 96 err := d.ContainerRm(c.ID, &types.ContainerRmConfig{ForceRemove: true}) 97 testutil.ErrorContains(t, err, fmt.Sprintf("removal of container %s is already in progress", c.ID)) 98 }