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