diff --git a/integration-cli/docker_cli_create_test.go b/integration-cli/docker_cli_create_test.go index 6085ca1f11..4a0824d9c6 100644 --- a/integration-cli/docker_cli_create_test.go +++ b/integration-cli/docker_cli_create_test.go @@ -11,7 +11,6 @@ import ( "github.com/docker/docker/integration-cli/cli" "github.com/docker/docker/integration-cli/cli/build" - "github.com/docker/docker/pkg/stringid" "github.com/docker/docker/testutil/fakecontext" "github.com/docker/go-connections/nat" "gotest.tools/v3/assert" @@ -229,39 +228,6 @@ func (s *DockerCLICreateSuite) TestCreateModeIpcContainer(c *testing.T) { cli.DockerCmd(c, "create", fmt.Sprintf("--ipc=container:%s", id), "busybox") } -func (s *DockerCLICreateSuite) TestCreateByImageID(c *testing.T) { - imageName := "testcreatebyimageid" - buildImageSuccessfully(c, imageName, build.WithDockerfile(`FROM busybox - MAINTAINER dockerio`)) - imageID := getIDByName(c, imageName) - truncatedImageID := stringid.TruncateID(imageID) - - cli.DockerCmd(c, "create", imageID) - cli.DockerCmd(c, "create", truncatedImageID) - - // Ensure this fails - out, exit, _ := dockerCmdWithError("create", fmt.Sprintf("%s:%s", imageName, imageID)) - if exit == 0 { - c.Fatalf("expected non-zero exit code; received %d", exit) - } - - if expected := "invalid reference format"; !strings.Contains(out, expected) { - c.Fatalf(`Expected %q in output; got: %s`, expected, out) - } - - if i := strings.IndexRune(imageID, ':'); i >= 0 { - imageID = imageID[i+1:] - } - out, exit, _ = dockerCmdWithError("create", fmt.Sprintf("%s:%s", "wrongimage", imageID)) - if exit == 0 { - c.Fatalf("expected non-zero exit code; received %d", exit) - } - - if expected := "Unable to find image"; !strings.Contains(out, expected) { - c.Fatalf(`Expected %q in output; got: %s`, expected, out) - } -} - func (s *DockerCLICreateSuite) TestCreateStopSignal(c *testing.T) { const name = "test_create_stop_signal" cli.DockerCmd(c, "create", "--name", name, "--stop-signal", "9", "busybox") @@ -303,14 +269,6 @@ func (s *DockerCLICreateSuite) TestCreateWithInvalidLogOpts(c *testing.T) { assert.Assert(c, !strings.Contains(out, name)) } -// #20972 -func (s *DockerCLICreateSuite) TestCreate64ByteHexID(c *testing.T) { - out := inspectField(c, "busybox", "Id") - imageID := strings.TrimPrefix(strings.TrimSpace(out), "sha256:") - - cli.DockerCmd(c, "create", imageID) -} - // Test case for #23498 func (s *DockerCLICreateSuite) TestCreateUnsetEntrypoint(c *testing.T) { const name = "test-entrypoint" diff --git a/integration/container/create_test.go b/integration/container/create_test.go index c95fba125a..ced8bfbdd4 100644 --- a/integration/container/create_test.go +++ b/integration/container/create_test.go @@ -19,6 +19,7 @@ import ( ctr "github.com/docker/docker/integration/internal/container" net "github.com/docker/docker/integration/internal/network" "github.com/docker/docker/oci" + "github.com/docker/docker/pkg/stringid" "github.com/docker/docker/testutil" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "gotest.tools/v3/assert" @@ -70,6 +71,75 @@ func TestCreateFailsWhenIdentifierDoesNotExist(t *testing.T) { } } +func TestCreateByImageID(t *testing.T) { + ctx := setupTest(t) + apiClient := testEnv.APIClient() + + img, _, err := apiClient.ImageInspectWithRaw(ctx, "busybox") + assert.NilError(t, err) + + imgIDWithAlgorithm := img.ID + imgID, _ := strings.CutPrefix(imgIDWithAlgorithm, "sha256:") + imgShortID := stringid.TruncateID(imgID) + + testCases := []struct { + doc string + image string + expectedErrType func(error) bool + expectedErr string + }{ + { + doc: "image ID with algorithm", + image: imgIDWithAlgorithm, + }, + { + // test case for https://github.com/moby/moby/issues/20972 + doc: "image ID without algorithm", + image: imgID, + }, + { + doc: "image short-ID", + image: imgShortID, + }, + { + doc: "image with ID and algorithm as tag", + image: "busybox:" + imgIDWithAlgorithm, + expectedErrType: errdefs.IsInvalidParameter, + expectedErr: "Error response from daemon: invalid reference format", + }, + { + doc: "image with ID as tag", + image: "busybox:" + imgID, + expectedErrType: errdefs.IsNotFound, + expectedErr: "Error response from daemon: No such image: busybox:" + imgID, + }, + } + + for _, tc := range testCases { + t.Run(tc.doc, func(t *testing.T) { + t.Parallel() + ctx := testutil.StartSpan(ctx, t) + resp, err := apiClient.ContainerCreate(ctx, + &container.Config{Image: tc.image}, + &container.HostConfig{}, + &network.NetworkingConfig{}, + nil, + "", + ) + if tc.expectedErr != "" { + assert.Check(t, is.DeepEqual(resp, container.CreateResponse{})) + assert.Check(t, is.Error(err, tc.expectedErr)) + assert.Check(t, is.ErrorType(err, tc.expectedErrType)) + } else { + assert.Check(t, resp.ID != "") + assert.NilError(t, err) + } + // cleanup the container if one was created. + _ = apiClient.ContainerRemove(ctx, resp.ID, container.RemoveOptions{Force: true}) + }) + } +} + // TestCreateLinkToNonExistingContainer verifies that linking to a non-existing // container returns an "invalid parameter" (400) status, and not the underlying // "non exists" (404).