From 832590155c2bd6c4bfd42d73644c51c7e5a6be05 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Fri, 24 Oct 2025 12:54:41 +0200 Subject: [PATCH] client: ExecCreateResult: define local type with ID field The `ExecCreateResult` was embedding the `container.ExecCreateRespons`, which in itself was an alias for `common.IDResponse`. This type has a single field (`ID`) currently, but the embedding made it awkward to use, for example, when mocking a `ExecCreateResult` using struct-literals: func execCreateWithID(_ string, _ client.ExecCreateOptions) (client.ExecCreateResult, error) { return client.ExecCreateResult{ExecCreateResponse: container.ExecCreateResponse{ID: "execid"}}, nil } This patch defines it as a local type with the `ID` as field. Signed-off-by: Sebastiaan van Stijn --- client/container_exec.go | 4 ++-- client/container_exec_test.go | 4 ++-- integration-cli/docker_api_exec_test.go | 4 ++-- integration/container/exec_test.go | 16 ++++++++-------- integration/internal/container/exec.go | 4 ++-- integration/internal/swarm/service.go | 4 ++-- integration/system/event_test.go | 6 +++--- 7 files changed, 21 insertions(+), 21 deletions(-) diff --git a/client/container_exec.go b/client/container_exec.go index 3b23de487d..76e4d09871 100644 --- a/client/container_exec.go +++ b/client/container_exec.go @@ -26,7 +26,7 @@ type ExecCreateOptions struct { // ExecCreateResult holds the result of creating a container exec. type ExecCreateResult struct { - container.ExecCreateResponse + ID string } // ExecCreate creates a new exec configuration to run an exec process. @@ -58,7 +58,7 @@ func (cli *Client) ExecCreate(ctx context.Context, containerID string, options E var response container.ExecCreateResponse err = json.NewDecoder(resp.Body).Decode(&response) - return ExecCreateResult{ExecCreateResponse: response}, err + return ExecCreateResult{ID: response.ID}, err } type execStartAttachOptions struct { diff --git a/client/container_exec_test.go b/client/container_exec_test.go index cf2cc4192f..9c7ae4d424 100644 --- a/client/container_exec_test.go +++ b/client/container_exec_test.go @@ -68,11 +68,11 @@ func TestExecCreate(t *testing.T) { ) assert.NilError(t, err) - r, err := client.ExecCreate(context.Background(), "container_id", ExecCreateOptions{ + res, err := client.ExecCreate(context.Background(), "container_id", ExecCreateOptions{ User: "user", }) assert.NilError(t, err) - assert.Check(t, is.Equal(r.ID, "exec_id")) + assert.Check(t, is.Equal(res.ID, "exec_id")) } func TestExecStartError(t *testing.T) { diff --git a/integration-cli/docker_api_exec_test.go b/integration-cli/docker_api_exec_test.go index 8fe51a278a..86fffc0104 100644 --- a/integration-cli/docker_api_exec_test.go +++ b/integration-cli/docker_api_exec_test.go @@ -128,13 +128,13 @@ func (s *DockerAPISuite) TestExecAPIStartWithDetach(c *testing.T) { assert.NilError(c, err) defer apiClient.Close() - createResp, err := apiClient.ExecCreate(ctx, name, client.ExecCreateOptions{ + res, err := apiClient.ExecCreate(ctx, name, client.ExecCreateOptions{ Cmd: []string{"true"}, AttachStderr: true, }) assert.NilError(c, err) - _, body, err := request.Post(ctx, fmt.Sprintf("/exec/%s/start", createResp.ID), request.RawString(`{"Detach": true}`), request.JSON) + _, body, err := request.Post(ctx, fmt.Sprintf("/exec/%s/start", res.ID), request.RawString(`{"Detach": true}`), request.JSON) assert.NilError(c, err) b, err := request.ReadBody(body) diff --git a/integration/container/exec_test.go b/integration/container/exec_test.go index 0611838bb1..3ec2bc6f54 100644 --- a/integration/container/exec_test.go +++ b/integration/container/exec_test.go @@ -33,14 +33,14 @@ func TestExecWithCloseStdin(t *testing.T) { cID := container.Run(ctx, t, apiClient) const expected = "closeIO" - execResp, err := apiClient.ExecCreate(ctx, cID, client.ExecCreateOptions{ + res, err := apiClient.ExecCreate(ctx, cID, client.ExecCreateOptions{ AttachStdin: true, AttachStdout: true, Cmd: []string{"sh", "-c", "cat && echo " + expected}, }) assert.NilError(t, err) - resp, err := apiClient.ExecAttach(ctx, execResp.ID, client.ExecAttachOptions{}) + resp, err := apiClient.ExecAttach(ctx, res.ID, client.ExecAttachOptions{}) assert.NilError(t, err) defer resp.Close() @@ -88,7 +88,7 @@ func TestExec(t *testing.T) { cID := container.Run(ctx, t, apiClient, container.WithTty(true), container.WithWorkingDir("/root")) - id, err := apiClient.ExecCreate(ctx, cID, client.ExecCreateOptions{ + res, err := apiClient.ExecCreate(ctx, cID, client.ExecCreateOptions{ WorkingDir: "/tmp", Env: []string{"FOO=BAR"}, AttachStdout: true, @@ -96,11 +96,11 @@ func TestExec(t *testing.T) { }) assert.NilError(t, err) - inspect, err := apiClient.ExecInspect(ctx, id.ID, client.ExecInspectOptions{}) + inspect, err := apiClient.ExecInspect(ctx, res.ID, client.ExecInspectOptions{}) assert.NilError(t, err) - assert.Check(t, is.Equal(inspect.ExecID, id.ID)) + assert.Check(t, is.Equal(inspect.ExecID, res.ID)) - resp, err := apiClient.ExecAttach(ctx, id.ID, client.ExecAttachOptions{}) + resp, err := apiClient.ExecAttach(ctx, res.ID, client.ExecAttachOptions{}) assert.NilError(t, err) defer resp.Close() r, err := io.ReadAll(resp.Reader) @@ -126,12 +126,12 @@ func TestExecResize(t *testing.T) { if runtime.GOOS == "windows" { cmd = []string{"sleep", "240"} } - resp, err := apiClient.ExecCreate(ctx, cID, client.ExecCreateOptions{ + res, err := apiClient.ExecCreate(ctx, cID, client.ExecCreateOptions{ Tty: true, // Windows requires a TTY for the resize to work, otherwise fails with "is not a tty: failed precondition", see https://github.com/moby/moby/pull/48665#issuecomment-2412530345 Cmd: cmd, }) assert.NilError(t, err) - execID := resp.ID + execID := res.ID assert.NilError(t, err) _, err = apiClient.ExecStart(ctx, execID, client.ExecStartOptions{ Detach: true, diff --git a/integration/internal/container/exec.go b/integration/internal/container/exec.go index 263ade1990..5748e7915b 100644 --- a/integration/internal/container/exec.go +++ b/integration/internal/container/exec.go @@ -58,11 +58,11 @@ func Exec(ctx context.Context, apiClient client.APIClient, id string, cmd []stri op(&execOptions) } - cresp, err := apiClient.ExecCreate(ctx, id, execOptions) + res, err := apiClient.ExecCreate(ctx, id, execOptions) if err != nil { return ExecResult{}, err } - execID := cresp.ID + execID := res.ID // run it, with stdout/stderr attached aresp, err := apiClient.ExecAttach(ctx, execID, client.ExecAttachOptions{}) diff --git a/integration/internal/swarm/service.go b/integration/internal/swarm/service.go index 3c472d1c83..2254d0ee75 100644 --- a/integration/internal/swarm/service.go +++ b/integration/internal/swarm/service.go @@ -237,10 +237,10 @@ func ExecTask(ctx context.Context, t *testing.T, d *daemon.Daemon, task swarmtyp apiClient := d.NewClientT(t) defer apiClient.Close() - resp, err := apiClient.ExecCreate(ctx, task.Status.ContainerStatus.ContainerID, options) + res, err := apiClient.ExecCreate(ctx, task.Status.ContainerStatus.ContainerID, options) assert.NilError(t, err, "error creating exec") - attach, err := apiClient.ExecAttach(ctx, resp.ID, client.ExecAttachOptions{}) + attach, err := apiClient.ExecAttach(ctx, res.ID, client.ExecAttachOptions{}) assert.NilError(t, err, "error attaching to exec") return attach.HijackedResponse } diff --git a/integration/system/event_test.go b/integration/system/event_test.go index 6ebc53650d..f8d9e80c83 100644 --- a/integration/system/event_test.go +++ b/integration/system/event_test.go @@ -25,7 +25,7 @@ func TestEventsExecDie(t *testing.T) { cID := container.Run(ctx, t, apiClient) - id, err := apiClient.ExecCreate(ctx, cID, client.ExecCreateOptions{ + res, err := apiClient.ExecCreate(ctx, cID, client.ExecCreateOptions{ Cmd: []string{"echo", "hello"}, }) assert.NilError(t, err) @@ -34,7 +34,7 @@ func TestEventsExecDie(t *testing.T) { Filters: make(client.Filters).Add("container", cID).Add("event", string(events.ActionExecDie)), }) - _, err = apiClient.ExecStart(ctx, id.ID, client.ExecStartOptions{ + _, err = apiClient.ExecStart(ctx, res.ID, client.ExecStartOptions{ Detach: true, Tty: false, }) @@ -45,7 +45,7 @@ func TestEventsExecDie(t *testing.T) { assert.Equal(t, m.Type, events.ContainerEventType) assert.Equal(t, m.Actor.ID, cID) assert.Equal(t, m.Action, events.ActionExecDie) - assert.Equal(t, m.Actor.Attributes["execID"], id.ID) + assert.Equal(t, m.Actor.Attributes["execID"], res.ID) assert.Equal(t, m.Actor.Attributes["exitCode"], "0") case err = <-errs: assert.NilError(t, err)