|
@@ -14,6 +14,7 @@ import (
|
|
|
"strings"
|
|
|
"syscall"
|
|
|
"testing"
|
|
|
+ "time"
|
|
|
|
|
|
"github.com/docker/docker/api/types"
|
|
|
"github.com/docker/docker/api/types/mount"
|
|
@@ -370,6 +371,66 @@ func TestLiveRestore(t *testing.T) {
|
|
|
skip.If(t, runtime.GOOS == "windows", "cannot start multiple daemons on windows")
|
|
|
|
|
|
t.Run("volume references", testLiveRestoreVolumeReferences)
|
|
|
+ t.Run("autoremove", testLiveRestoreAutoRemove)
|
|
|
+}
|
|
|
+
|
|
|
+func testLiveRestoreAutoRemove(t *testing.T) {
|
|
|
+ skip.If(t, testEnv.IsRootless(), "restarted rootless daemon will have a new process namespace")
|
|
|
+
|
|
|
+ t.Parallel()
|
|
|
+ ctx := context.Background()
|
|
|
+
|
|
|
+ run := func(t *testing.T) (*daemon.Daemon, func(), string) {
|
|
|
+ d := daemon.New(t)
|
|
|
+ d.StartWithBusybox(t, "--live-restore", "--iptables=false")
|
|
|
+ t.Cleanup(func() {
|
|
|
+ d.Stop(t)
|
|
|
+ d.Cleanup(t)
|
|
|
+ })
|
|
|
+
|
|
|
+ tmpDir := t.TempDir()
|
|
|
+
|
|
|
+ apiClient := d.NewClientT(t)
|
|
|
+
|
|
|
+ cID := container.Run(ctx, t, apiClient,
|
|
|
+ container.WithBind(tmpDir, "/v"),
|
|
|
+ // Run until a 'stop' file is created.
|
|
|
+ container.WithCmd("sh", "-c", "while [ ! -f /v/stop ]; do sleep 0.1; done"),
|
|
|
+ container.WithAutoRemove)
|
|
|
+ t.Cleanup(func() { apiClient.ContainerRemove(ctx, cID, types.ContainerRemoveOptions{Force: true}) })
|
|
|
+ finishContainer := func() {
|
|
|
+ file, err := os.Create(filepath.Join(tmpDir, "stop"))
|
|
|
+ assert.NilError(t, err, "Failed to create 'stop' file")
|
|
|
+ file.Close()
|
|
|
+ }
|
|
|
+ return d, finishContainer, cID
|
|
|
+ }
|
|
|
+
|
|
|
+ t.Run("engine restart shouldnt kill alive containers", func(t *testing.T) {
|
|
|
+ d, finishContainer, cID := run(t)
|
|
|
+
|
|
|
+ d.Restart(t, "--live-restore", "--iptables=false")
|
|
|
+
|
|
|
+ apiClient := d.NewClientT(t)
|
|
|
+ _, err := apiClient.ContainerInspect(ctx, cID)
|
|
|
+ assert.NilError(t, err, "Container shouldn't be removed after engine restart")
|
|
|
+
|
|
|
+ finishContainer()
|
|
|
+
|
|
|
+ poll.WaitOn(t, container.IsRemoved(ctx, apiClient, cID))
|
|
|
+ })
|
|
|
+ t.Run("engine restart should remove containers that exited", func(t *testing.T) {
|
|
|
+ d, finishContainer, cID := run(t)
|
|
|
+
|
|
|
+ d.Stop(t)
|
|
|
+
|
|
|
+ finishContainer()
|
|
|
+ time.Sleep(time.Millisecond * 200)
|
|
|
+
|
|
|
+ d.Start(t, "--live-restore", "--iptables=false")
|
|
|
+
|
|
|
+ poll.WaitOn(t, container.IsRemoved(ctx, d.NewClientT(t), cID))
|
|
|
+ })
|
|
|
}
|
|
|
|
|
|
func testLiveRestoreVolumeReferences(t *testing.T) {
|