diff --git a/integration/container/inspect_test.go b/integration/container/inspect_test.go index 1123684126..5ecd287bfe 100644 --- a/integration/container/inspect_test.go +++ b/integration/container/inspect_test.go @@ -6,9 +6,8 @@ import ( "testing" "time" - "github.com/docker/docker/api/types/container" - "github.com/docker/docker/api/types/network" "github.com/docker/docker/client" + "github.com/docker/docker/integration/internal/container" "github.com/docker/docker/integration/internal/request" "github.com/gotestyourself/gotestyourself/poll" "github.com/gotestyourself/gotestyourself/skip" @@ -25,10 +24,12 @@ func TestInspectCpusetInConfigPre120(t *testing.T) { name := "cpusetinconfig-pre120" // Create container with up to-date-API - runSimpleContainer(ctx, t, request.NewAPIClient(t), name, func(config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig) { - config.Cmd = []string{"true"} - hostConfig.Resources.CpusetCpus = "0" - }) + container.Run(t, ctx, request.NewAPIClient(t), container.WithName(name), + container.WithCmd("true"), + func(c *container.TestContainerConfig) { + c.HostConfig.Resources.CpusetCpus = "0" + }, + ) poll.WaitOn(t, containerIsInState(ctx, client, name, "exited"), poll.WithDelay(100*time.Millisecond)) _, body, err := client.ContainerInspectWithRaw(ctx, name, false) diff --git a/integration/container/kill_test.go b/integration/container/kill_test.go index caf2a55ab3..6efc5fc61d 100644 --- a/integration/container/kill_test.go +++ b/integration/container/kill_test.go @@ -5,11 +5,9 @@ import ( "testing" "time" - "github.com/docker/docker/api/types" - "github.com/docker/docker/api/types/container" - "github.com/docker/docker/api/types/network" - "github.com/docker/docker/api/types/strslice" + containertypes "github.com/docker/docker/api/types/container" "github.com/docker/docker/client" + "github.com/docker/docker/integration/internal/container" "github.com/docker/docker/integration/internal/request" "github.com/gotestyourself/gotestyourself/poll" "github.com/gotestyourself/gotestyourself/skip" @@ -20,25 +18,15 @@ func TestKillContainerInvalidSignal(t *testing.T) { defer setupTest(t)() client := request.NewAPIClient(t) ctx := context.Background() - c, err := client.ContainerCreate(ctx, - &container.Config{ - Image: "busybox", - Cmd: strslice.StrSlice([]string{"top"}), - }, - &container.HostConfig{}, - &network.NetworkingConfig{}, - "") - require.NoError(t, err) - err = client.ContainerStart(ctx, c.ID, types.ContainerStartOptions{}) - require.NoError(t, err) + id := container.Run(t, ctx, client) - err = client.ContainerKill(ctx, c.ID, "0") + err := client.ContainerKill(ctx, id, "0") require.EqualError(t, err, "Error response from daemon: Invalid signal: 0") - poll.WaitOn(t, containerIsInState(ctx, client, c.ID, "running"), poll.WithDelay(100*time.Millisecond)) + poll.WaitOn(t, containerIsInState(ctx, client, id, "running"), poll.WithDelay(100*time.Millisecond)) - err = client.ContainerKill(ctx, c.ID, "SIG42") + err = client.ContainerKill(ctx, id, "SIG42") require.EqualError(t, err, "Error response from daemon: Invalid signal: SIG42") - poll.WaitOn(t, containerIsInState(ctx, client, c.ID, "running"), poll.WithDelay(100*time.Millisecond)) + poll.WaitOn(t, containerIsInState(ctx, client, id, "running"), poll.WithDelay(100*time.Millisecond)) } func TestKillContainer(t *testing.T) { @@ -71,21 +59,11 @@ func TestKillContainer(t *testing.T) { tc := tc t.Run(tc.doc, func(t *testing.T) { ctx := context.Background() - c, err := client.ContainerCreate(ctx, - &container.Config{ - Image: "busybox", - Cmd: strslice.StrSlice([]string{"top"}), - }, - &container.HostConfig{}, - &network.NetworkingConfig{}, - "") - require.NoError(t, err) - err = client.ContainerStart(ctx, c.ID, types.ContainerStartOptions{}) - require.NoError(t, err) - err = client.ContainerKill(ctx, c.ID, tc.signal) + id := container.Run(t, ctx, client) + err := client.ContainerKill(ctx, id, tc.signal) require.NoError(t, err) - poll.WaitOn(t, containerIsInState(ctx, client, c.ID, tc.status), poll.WithDelay(100*time.Millisecond)) + poll.WaitOn(t, containerIsInState(ctx, client, id, tc.status), poll.WithDelay(100*time.Millisecond)) }) } } @@ -116,25 +94,16 @@ func TestKillWithStopSignalAndRestartPolicies(t *testing.T) { tc := tc t.Run(tc.doc, func(t *testing.T) { ctx := context.Background() - c, err := client.ContainerCreate(ctx, - &container.Config{ - Image: "busybox", - Cmd: strslice.StrSlice([]string{"top"}), - StopSignal: tc.stopsignal, - }, - &container.HostConfig{ - RestartPolicy: container.RestartPolicy{ - Name: "always", - }}, - &network.NetworkingConfig{}, - "") - require.NoError(t, err) - err = client.ContainerStart(ctx, c.ID, types.ContainerStartOptions{}) - require.NoError(t, err) - err = client.ContainerKill(ctx, c.ID, "TERM") + id := container.Run(t, ctx, client, func(c *container.TestContainerConfig) { + c.Config.StopSignal = tc.stopsignal + c.HostConfig.RestartPolicy = containertypes.RestartPolicy{ + Name: "always", + } + }) + err := client.ContainerKill(ctx, id, "TERM") require.NoError(t, err) - poll.WaitOn(t, containerIsInState(ctx, client, c.ID, tc.status), poll.WithDelay(100*time.Millisecond)) + poll.WaitOn(t, containerIsInState(ctx, client, id, tc.status), poll.WithDelay(100*time.Millisecond)) }) } } @@ -144,16 +113,8 @@ func TestKillStoppedContainer(t *testing.T) { defer setupTest(t)() ctx := context.Background() client := request.NewAPIClient(t) - c, err := client.ContainerCreate(ctx, - &container.Config{ - Image: "busybox", - Cmd: strslice.StrSlice([]string{"top"}), - }, - &container.HostConfig{}, - &network.NetworkingConfig{}, - "") - require.NoError(t, err) - err = client.ContainerKill(ctx, c.ID, "SIGKILL") + id := container.Create(t, ctx, client) + err := client.ContainerKill(ctx, id, "SIGKILL") require.Error(t, err) require.Contains(t, err.Error(), "is not running") } @@ -163,16 +124,8 @@ func TestKillStoppedContainerAPIPre120(t *testing.T) { defer setupTest(t)() ctx := context.Background() client := request.NewAPIClient(t, client.WithVersion("1.19")) - c, err := client.ContainerCreate(ctx, - &container.Config{ - Image: "busybox", - Cmd: strslice.StrSlice([]string{"top"}), - }, - &container.HostConfig{}, - &network.NetworkingConfig{}, - "") - require.NoError(t, err) - err = client.ContainerKill(ctx, c.ID, "SIGKILL") + id := container.Create(t, ctx, client) + err := client.ContainerKill(ctx, id, "SIGKILL") require.NoError(t, err) } @@ -184,12 +137,12 @@ func TestKillDifferentUserContainer(t *testing.T) { ctx := context.Background() client := request.NewAPIClient(t, client.WithVersion("1.19")) - cID := runSimpleContainer(ctx, t, client, "", func(config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig) { - config.User = "daemon" + id := container.Run(t, ctx, client, func(c *container.TestContainerConfig) { + c.Config.User = "daemon" }) - poll.WaitOn(t, containerIsInState(ctx, client, cID, "running"), poll.WithDelay(100*time.Millisecond)) + poll.WaitOn(t, containerIsInState(ctx, client, id, "running"), poll.WithDelay(100*time.Millisecond)) - err := client.ContainerKill(ctx, cID, "SIGKILL") + err := client.ContainerKill(ctx, id, "SIGKILL") require.NoError(t, err) - poll.WaitOn(t, containerIsInState(ctx, client, cID, "exited"), poll.WithDelay(100*time.Millisecond)) + poll.WaitOn(t, containerIsInState(ctx, client, id, "exited"), poll.WithDelay(100*time.Millisecond)) } diff --git a/integration/container/main_test.go b/integration/container/main_test.go index bc482ce92d..fb87fddcc2 100644 --- a/integration/container/main_test.go +++ b/integration/container/main_test.go @@ -1,17 +1,11 @@ package container // import "github.com/docker/docker/integration/container" import ( - "context" "fmt" "os" "testing" - "github.com/docker/docker/api/types" - "github.com/docker/docker/api/types/container" - "github.com/docker/docker/api/types/network" - "github.com/docker/docker/client" "github.com/docker/docker/internal/test/environment" - "github.com/stretchr/testify/require" ) var testEnv *environment.Execution @@ -37,32 +31,3 @@ func setupTest(t *testing.T) func() { environment.ProtectAll(t, testEnv) return func() { testEnv.Clean(t) } } - -type containerConstructor func(config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig) - -func createSimpleContainer(ctx context.Context, t *testing.T, client client.APIClient, name string, f ...containerConstructor) string { - config := &container.Config{ - Cmd: []string{"top"}, - Image: "busybox", - } - hostConfig := &container.HostConfig{} - networkingConfig := &network.NetworkingConfig{} - - for _, fn := range f { - fn(config, hostConfig, networkingConfig) - } - - c, err := client.ContainerCreate(ctx, config, hostConfig, networkingConfig, name) - require.NoError(t, err) - - return c.ID -} - -func runSimpleContainer(ctx context.Context, t *testing.T, client client.APIClient, name string, f ...containerConstructor) string { - cID := createSimpleContainer(ctx, t, client, name, f...) - - err := client.ContainerStart(ctx, cID, types.ContainerStartOptions{}) - require.NoError(t, err) - - return cID -} diff --git a/integration/container/rename_test.go b/integration/container/rename_test.go index e6af2ac9e9..da2bed17c7 100644 --- a/integration/container/rename_test.go +++ b/integration/container/rename_test.go @@ -6,8 +6,8 @@ import ( "time" "github.com/docker/docker/api/types" - "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/network" + "github.com/docker/docker/integration/internal/container" "github.com/docker/docker/integration/internal/request" "github.com/docker/docker/internal/testutil" "github.com/docker/docker/pkg/stringid" @@ -26,23 +26,18 @@ func TestRenameLinkedContainer(t *testing.T) { ctx := context.Background() client := request.NewAPIClient(t) - aID := runSimpleContainer(ctx, t, client, "a0") - - bID := runSimpleContainer(ctx, t, client, "b0", func(config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig) { - hostConfig.Links = []string{"a0"} - }) + aID := container.Run(t, ctx, client, container.WithName("a0")) + bID := container.Run(t, ctx, client, container.WithName("b0"), container.WithLinks("a0")) err := client.ContainerRename(ctx, aID, "a1") require.NoError(t, err) - runSimpleContainer(ctx, t, client, "a0") + container.Run(t, ctx, client, container.WithName("a0")) err = client.ContainerRemove(ctx, bID, types.ContainerRemoveOptions{Force: true}) require.NoError(t, err) - bID = runSimpleContainer(ctx, t, client, "b0", func(config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig) { - hostConfig.Links = []string{"a0"} - }) + bID = container.Run(t, ctx, client, container.WithName("b0"), container.WithLinks("a0")) inspect, err := client.ContainerInspect(ctx, bID) require.NoError(t, err) @@ -55,9 +50,7 @@ func TestRenameStoppedContainer(t *testing.T) { client := request.NewAPIClient(t) oldName := "first_name" - cID := runSimpleContainer(ctx, t, client, oldName, func(config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig) { - config.Cmd = []string{"sh"} - }) + cID := container.Run(t, ctx, client, container.WithName(oldName), container.WithCmd("sh")) poll.WaitOn(t, containerIsInState(ctx, client, cID, "exited"), poll.WithDelay(100*time.Millisecond)) inspect, err := client.ContainerInspect(ctx, cID) @@ -79,7 +72,7 @@ func TestRenameRunningContainerAndReuse(t *testing.T) { client := request.NewAPIClient(t) oldName := "first_name" - cID := runSimpleContainer(ctx, t, client, oldName) + cID := container.Run(t, ctx, client, container.WithName(oldName)) poll.WaitOn(t, containerIsInState(ctx, client, cID, "running"), poll.WithDelay(100*time.Millisecond)) newName := "new_name" + stringid.GenerateNonCryptoID() @@ -93,7 +86,7 @@ func TestRenameRunningContainerAndReuse(t *testing.T) { _, err = client.ContainerInspect(ctx, oldName) testutil.ErrorContains(t, err, "No such container: "+oldName) - cID = runSimpleContainer(ctx, t, client, oldName) + cID = container.Run(t, ctx, client, container.WithName(oldName)) poll.WaitOn(t, containerIsInState(ctx, client, cID, "running"), poll.WithDelay(100*time.Millisecond)) inspect, err = client.ContainerInspect(ctx, cID) @@ -107,7 +100,7 @@ func TestRenameInvalidName(t *testing.T) { client := request.NewAPIClient(t) oldName := "first_name" - cID := runSimpleContainer(ctx, t, client, oldName) + cID := container.Run(t, ctx, client, container.WithName(oldName)) poll.WaitOn(t, containerIsInState(ctx, client, cID, "running"), poll.WithDelay(100*time.Millisecond)) err := client.ContainerRename(ctx, oldName, "new:invalid") @@ -132,11 +125,11 @@ func TestRenameAnonymousContainer(t *testing.T) { _, err := client.NetworkCreate(ctx, "network1", types.NetworkCreate{}) require.NoError(t, err) - cID := createSimpleContainer(ctx, t, client, "", func(config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig) { - networkingConfig.EndpointsConfig = map[string]*network.EndpointSettings{ + cID := container.Run(t, ctx, client, func(c *container.TestContainerConfig) { + c.NetworkingConfig.EndpointsConfig = map[string]*network.EndpointSettings{ "network1": {}, } - hostConfig.NetworkMode = "network1" + c.HostConfig.NetworkMode = "network1" }) err = client.ContainerRename(ctx, cID, "container1") require.NoError(t, err) @@ -149,13 +142,12 @@ func TestRenameAnonymousContainer(t *testing.T) { if testEnv.OSType == "windows" { count = "-n" } - cID = runSimpleContainer(ctx, t, client, "", func(config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig) { - networkingConfig.EndpointsConfig = map[string]*network.EndpointSettings{ + cID = container.Run(t, ctx, client, func(c *container.TestContainerConfig) { + c.NetworkingConfig.EndpointsConfig = map[string]*network.EndpointSettings{ "network1": {}, } - hostConfig.NetworkMode = "network1" - config.Cmd = []string{"ping", count, "1", "container1"} - }) + c.HostConfig.NetworkMode = "network1" + }, container.WithCmd("ping", count, "1", "container1")) poll.WaitOn(t, containerIsInState(ctx, client, cID, "exited"), poll.WithDelay(100*time.Millisecond)) inspect, err := client.ContainerInspect(ctx, cID) @@ -169,7 +161,7 @@ func TestRenameContainerWithSameName(t *testing.T) { ctx := context.Background() client := request.NewAPIClient(t) - cID := runSimpleContainer(ctx, t, client, "old") + cID := container.Run(t, ctx, client, container.WithName("old")) poll.WaitOn(t, containerIsInState(ctx, client, cID, "running"), poll.WithDelay(100*time.Millisecond)) err := client.ContainerRename(ctx, "old", "old") testutil.ErrorContains(t, err, "Renaming a container with the same name") @@ -189,12 +181,10 @@ func TestRenameContainerWithLinkedContainer(t *testing.T) { ctx := context.Background() client := request.NewAPIClient(t) - db1ID := runSimpleContainer(ctx, t, client, "db1") + db1ID := container.Run(t, ctx, client, container.WithName("db1")) poll.WaitOn(t, containerIsInState(ctx, client, db1ID, "running"), poll.WithDelay(100*time.Millisecond)) - app1ID := runSimpleContainer(ctx, t, client, "app1", func(config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig) { - hostConfig.Links = []string{"db1:/mysql"} - }) + app1ID := container.Run(t, ctx, client, container.WithName("app1"), container.WithLinks("db1:/mysql")) poll.WaitOn(t, containerIsInState(ctx, client, app1ID, "running"), poll.WithDelay(100*time.Millisecond)) err := client.ContainerRename(ctx, "app1", "app2") diff --git a/integration/container/resize_test.go b/integration/container/resize_test.go index 887f1f6292..0ada5c32e4 100644 --- a/integration/container/resize_test.go +++ b/integration/container/resize_test.go @@ -7,9 +7,8 @@ import ( "time" "github.com/docker/docker/api/types" - "github.com/docker/docker/api/types/container" - "github.com/docker/docker/api/types/network" req "github.com/docker/docker/integration-cli/request" + "github.com/docker/docker/integration/internal/container" "github.com/docker/docker/integration/internal/request" "github.com/docker/docker/internal/testutil" "github.com/gotestyourself/gotestyourself/poll" @@ -22,7 +21,7 @@ func TestResize(t *testing.T) { client := request.NewAPIClient(t) ctx := context.Background() - cID := runSimpleContainer(ctx, t, client, "") + cID := container.Run(t, ctx, client) poll.WaitOn(t, containerIsInState(ctx, client, cID, "running"), poll.WithDelay(100*time.Millisecond)) @@ -38,7 +37,7 @@ func TestResizeWithInvalidSize(t *testing.T) { client := request.NewAPIClient(t) ctx := context.Background() - cID := runSimpleContainer(ctx, t, client, "") + cID := container.Run(t, ctx, client) poll.WaitOn(t, containerIsInState(ctx, client, cID, "running"), poll.WithDelay(100*time.Millisecond)) @@ -53,9 +52,7 @@ func TestResizeWhenContainerNotStarted(t *testing.T) { client := request.NewAPIClient(t) ctx := context.Background() - cID := runSimpleContainer(ctx, t, client, "", func(config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig) { - config.Cmd = []string{"echo"} - }) + cID := container.Run(t, ctx, client, container.WithCmd("echo")) poll.WaitOn(t, containerIsInState(ctx, client, cID, "exited"), poll.WithDelay(100*time.Millisecond)) diff --git a/integration/internal/container/container.go b/integration/internal/container/container.go new file mode 100644 index 0000000000..8d8fe28791 --- /dev/null +++ b/integration/internal/container/container.go @@ -0,0 +1,54 @@ +package container + +import ( + "context" + "testing" + + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" + "github.com/docker/docker/api/types/network" + "github.com/docker/docker/client" + "github.com/stretchr/testify/require" +) + +// TestContainerConfig holds container configuration struct that +// are used in api calls. +type TestContainerConfig struct { + Name string + Config *container.Config + HostConfig *container.HostConfig + NetworkingConfig *network.NetworkingConfig +} + +// Create creates a container with the specified options +func Create(t *testing.T, ctx context.Context, client client.APIClient, ops ...func(*TestContainerConfig)) string { // nolint: golint + t.Helper() + config := &TestContainerConfig{ + Config: &container.Config{ + Image: "busybox", + Cmd: []string{"top"}, + }, + HostConfig: &container.HostConfig{}, + NetworkingConfig: &network.NetworkingConfig{}, + } + + for _, op := range ops { + op(config) + } + + c, err := client.ContainerCreate(ctx, config.Config, config.HostConfig, config.NetworkingConfig, config.Name) + require.NoError(t, err) + + return c.ID +} + +// Run creates and start a container with the specified options +func Run(t *testing.T, ctx context.Context, client client.APIClient, ops ...func(*TestContainerConfig)) string { // nolint: golint + t.Helper() + id := Create(t, ctx, client, ops...) + + err := client.ContainerStart(ctx, id, types.ContainerStartOptions{}) + require.NoError(t, err) + + return id +} diff --git a/integration/internal/container/ops.go b/integration/internal/container/ops.go new file mode 100644 index 0000000000..940fd68923 --- /dev/null +++ b/integration/internal/container/ops.go @@ -0,0 +1,24 @@ +package container + +import "github.com/docker/docker/api/types/strslice" + +// WithName sets the name of the container +func WithName(name string) func(*TestContainerConfig) { + return func(c *TestContainerConfig) { + c.Name = name + } +} + +// WithLinks sets the links of the container +func WithLinks(links ...string) func(*TestContainerConfig) { + return func(c *TestContainerConfig) { + c.HostConfig.Links = links + } +} + +// WithCmd sets the comannds of the container +func WithCmd(cmds ...string) func(*TestContainerConfig) { + return func(c *TestContainerConfig) { + c.Config.Cmd = strslice.StrSlice(cmds) + } +}