diff --git a/integration/image/inspect_test.go b/integration/image/inspect_test.go index a0a700c36f..f5c5e21499 100644 --- a/integration/image/inspect_test.go +++ b/integration/image/inspect_test.go @@ -7,6 +7,7 @@ import ( "github.com/docker/docker/api/types/image" "github.com/docker/docker/client" + iimage "github.com/docker/docker/integration/internal/image" "github.com/docker/docker/internal/testutils/specialimage" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "gotest.tools/v3/assert" @@ -21,7 +22,7 @@ func TestImageInspectEmptyTagsAndDigests(t *testing.T) { apiClient := testEnv.APIClient() - danglingID := specialimage.Load(ctx, t, apiClient, specialimage.Dangling) + danglingID := iimage.Load(ctx, t, apiClient, specialimage.Dangling) var raw bytes.Buffer inspect, err := apiClient.ImageInspect(ctx, danglingID, client.ImageInspectWithRawResponse(&raw)) @@ -103,7 +104,7 @@ func TestImageInspectWithPlatform(t *testing.T) { Architecture: "amd64", } - imageID := specialimage.Load(ctx, t, apiClient, func(dir string) (*ocispec.Index, error) { + imageID := iimage.Load(ctx, t, apiClient, func(dir string) (*ocispec.Index, error) { i, descs, err := specialimage.MultiPlatform(dir, "multiplatform:latest", []ocispec.Platform{nativePlatform, differentPlatform}) assert.NilError(t, err) diff --git a/integration/image/list_test.go b/integration/image/list_test.go index 35622aed61..38c8e5f904 100644 --- a/integration/image/list_test.go +++ b/integration/image/list_test.go @@ -14,6 +14,7 @@ import ( "github.com/docker/docker/api/types/versions" "github.com/docker/docker/client" "github.com/docker/docker/integration/internal/container" + iimage "github.com/docker/docker/integration/internal/image" "github.com/docker/docker/internal/testutils/specialimage" "github.com/docker/docker/testutil" "github.com/docker/docker/testutil/daemon" @@ -213,14 +214,14 @@ func TestAPIImagesListSizeShared(t *testing.T) { client := daemon.NewClientT(t) - specialimage.Load(ctx, t, client, func(dir string) (*ocispec.Index, error) { + iimage.Load(ctx, t, client, func(dir string) (*ocispec.Index, error) { return specialimage.MultiLayerCustom(dir, "multilayer:latest", []specialimage.SingleFileLayer{ {Name: "bar", Content: []byte("2")}, {Name: "foo", Content: []byte("1")}, }) }) - specialimage.Load(ctx, t, client, func(dir string) (*ocispec.Index, error) { + iimage.Load(ctx, t, client, func(dir string) (*ocispec.Index, error) { return specialimage.MultiLayerCustom(dir, "multilayer2:latest", []specialimage.SingleFileLayer{ {Name: "asdf", Content: []byte("3")}, {Name: "foo", Content: []byte("1")}, @@ -249,7 +250,7 @@ func TestAPIImagesListManifests(t *testing.T) { {OS: "linux", Architecture: "arm", Variant: "v7"}, {OS: "darwin", Architecture: "arm64"}, } - specialimage.Load(ctx, t, apiClient, func(dir string) (*ocispec.Index, error) { + iimage.Load(ctx, t, apiClient, func(dir string) (*ocispec.Index, error) { idx, _, err := specialimage.MultiPlatform(dir, "multiplatform:latest", testPlatforms) return idx, err }) diff --git a/integration/image/load_test.go b/integration/image/load_test.go index 589a1c04b1..29a593a34d 100644 --- a/integration/image/load_test.go +++ b/integration/image/load_test.go @@ -6,6 +6,7 @@ import ( cerrdefs "github.com/containerd/errdefs" "github.com/docker/docker/api/types/image" + iimage "github.com/docker/docker/integration/internal/image" "github.com/docker/docker/internal/testutils/specialimage" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "gotest.tools/v3/assert" @@ -20,7 +21,7 @@ func TestLoadDanglingImages(t *testing.T) { client := testEnv.APIClient() - specialimage.Load(ctx, t, client, func(dir string) (*ocispec.Index, error) { + iimage.Load(ctx, t, client, func(dir string) (*ocispec.Index, error) { return specialimage.MultiLayerCustom(dir, "namedimage:latest", []specialimage.SingleFileLayer{ {Name: "bar", Content: []byte("1")}, }) @@ -44,7 +45,7 @@ func TestLoadDanglingImages(t *testing.T) { assert.NilError(t, err) // Retain a copy of the old image and then replace it with a new one. - specialimage.Load(ctx, t, client, func(dir string) (*ocispec.Index, error) { + iimage.Load(ctx, t, client, func(dir string) (*ocispec.Index, error) { return specialimage.MultiLayerCustom(dir, "namedimage:latest", []specialimage.SingleFileLayer{ {Name: "bar", Content: []byte("2")}, }) diff --git a/integration/image/prune_test.go b/integration/image/prune_test.go index dd6d58158f..76c6f440c0 100644 --- a/integration/image/prune_test.go +++ b/integration/image/prune_test.go @@ -9,6 +9,7 @@ import ( "github.com/docker/docker/api/types/image" "github.com/docker/docker/client" "github.com/docker/docker/integration/internal/container" + iimage "github.com/docker/docker/integration/internal/image" "github.com/docker/docker/internal/testutils/specialimage" "github.com/docker/docker/testutil" "github.com/docker/docker/testutil/daemon" @@ -31,7 +32,7 @@ func TestPruneDontDeleteUsedDangling(t *testing.T) { apiClient := d.NewClientT(t) defer apiClient.Close() - danglingID := specialimage.Load(ctx, t, apiClient, specialimage.Dangling) + danglingID := iimage.Load(ctx, t, apiClient, specialimage.Dangling) _, err := apiClient.ImageInspect(ctx, danglingID) assert.NilError(t, err, "Test dangling image doesn't exist") diff --git a/integration/image/remove_test.go b/integration/image/remove_test.go index ca383f172b..bc0076db0d 100644 --- a/integration/image/remove_test.go +++ b/integration/image/remove_test.go @@ -10,6 +10,7 @@ import ( containertypes "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/image" "github.com/docker/docker/integration/internal/container" + iimage "github.com/docker/docker/integration/internal/image" "github.com/docker/docker/internal/testutils/specialimage" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "gotest.tools/v3/assert" @@ -115,7 +116,7 @@ func TestRemoveWithPlatform(t *testing.T) { var imageIdx *ocispec.Index var descs []ocispec.Descriptor - specialimage.Load(ctx, t, apiClient, func(dir string) (*ocispec.Index, error) { + iimage.Load(ctx, t, apiClient, func(dir string) (*ocispec.Index, error) { idx, d, err := specialimage.MultiPlatform(dir, imgName, []ocispec.Platform{ platformHost, { diff --git a/integration/image/save_test.go b/integration/image/save_test.go index 084056cde8..8696f25df6 100644 --- a/integration/image/save_test.go +++ b/integration/image/save_test.go @@ -20,6 +20,7 @@ import ( "github.com/docker/docker/client" "github.com/docker/docker/integration/internal/build" "github.com/docker/docker/integration/internal/container" + iimage "github.com/docker/docker/integration/internal/image" "github.com/docker/docker/internal/testutils" "github.com/docker/docker/internal/testutils/specialimage" "github.com/docker/docker/testutil/fakecontext" @@ -116,7 +117,7 @@ func TestSaveOCI(t *testing.T) { } if testEnv.DaemonInfo.OSType != "windows" { - multiLayerImage := specialimage.Load(ctx, t, client, specialimage.MultiLayer) + multiLayerImage := iimage.Load(ctx, t, client, specialimage.MultiLayer) // Multi-layer image testCases = append(testCases, testCase{image: multiLayerImage, expectedContainerdRef: "docker.io/library/multilayer:latest", expectedOCIRef: "latest"}) diff --git a/integration/internal/image/load.go b/integration/internal/image/load.go new file mode 100644 index 0000000000..dc0339e6b9 --- /dev/null +++ b/integration/internal/image/load.go @@ -0,0 +1,68 @@ +package image + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "io" + "strings" + "testing" + + "github.com/docker/docker/client" + "github.com/docker/docker/internal/testutils/specialimage" + "github.com/docker/docker/pkg/jsonmessage" + "github.com/moby/go-archive" + "gotest.tools/v3/assert" +) + +func Load(ctx context.Context, t *testing.T, apiClient client.APIClient, imageFunc specialimage.SpecialImageFunc) string { + tempDir := t.TempDir() + + _, err := imageFunc(tempDir) + assert.NilError(t, err) + + rc, err := archive.TarWithOptions(tempDir, &archive.TarOptions{}) + assert.NilError(t, err) + + defer rc.Close() + + resp, err := apiClient.ImageLoad(ctx, rc, client.ImageLoadWithQuiet(true)) + assert.NilError(t, err, "Failed to load dangling image") + + defer resp.Body.Close() + + if !assert.Check(t, err) { + respBody, err := io.ReadAll(resp.Body) + if err != nil { + t.Fatalf("Failed to read response body: %v", err) + return "" + } + t.Fatalf("Failed load: %s", string(respBody)) + } + + all, err := io.ReadAll(resp.Body) + assert.NilError(t, err) + + decoder := json.NewDecoder(bytes.NewReader(all)) + for { + var msg jsonmessage.JSONMessage + err := decoder.Decode(&msg) + if errors.Is(err, io.EOF) { + break + } + assert.NilError(t, err) + + msg.Stream = strings.TrimSpace(msg.Stream) + + if _, imageID, hasID := strings.Cut(msg.Stream, "Loaded image ID: "); hasID { + return imageID + } + if _, imageRef, hasRef := strings.Cut(msg.Stream, "Loaded image: "); hasRef { + return imageRef + } + } + + t.Fatalf("failed to read image ID\n%s", string(all)) + return "" +} diff --git a/internal/testutils/specialimage/load.go b/internal/testutils/specialimage/load.go index 2d2b9d7c09..dab8d1e89c 100644 --- a/internal/testutils/specialimage/load.go +++ b/internal/testutils/specialimage/load.go @@ -1,70 +1,7 @@ package specialimage import ( - "bytes" - "context" - "encoding/json" - "errors" - "io" - "strings" - "testing" - - "github.com/docker/docker/client" - "github.com/docker/docker/pkg/jsonmessage" - "github.com/moby/go-archive" ocispec "github.com/opencontainers/image-spec/specs-go/v1" - "gotest.tools/v3/assert" ) type SpecialImageFunc func(string) (*ocispec.Index, error) - -func Load(ctx context.Context, t *testing.T, apiClient client.APIClient, imageFunc SpecialImageFunc) string { - tempDir := t.TempDir() - - _, err := imageFunc(tempDir) - assert.NilError(t, err) - - rc, err := archive.TarWithOptions(tempDir, &archive.TarOptions{}) - assert.NilError(t, err) - - defer rc.Close() - - resp, err := apiClient.ImageLoad(ctx, rc, client.ImageLoadWithQuiet(true)) - assert.NilError(t, err, "Failed to load dangling image") - - defer resp.Body.Close() - - if !assert.Check(t, err) { - respBody, err := io.ReadAll(resp.Body) - if err != nil { - t.Fatalf("Failed to read response body: %v", err) - return "" - } - t.Fatalf("Failed load: %s", string(respBody)) - } - - all, err := io.ReadAll(resp.Body) - assert.NilError(t, err) - - decoder := json.NewDecoder(bytes.NewReader(all)) - for { - var msg jsonmessage.JSONMessage - err := decoder.Decode(&msg) - if errors.Is(err, io.EOF) { - break - } - assert.NilError(t, err) - - msg.Stream = strings.TrimSpace(msg.Stream) - - if _, imageID, hasID := strings.Cut(msg.Stream, "Loaded image ID: "); hasID { - return imageID - } - if _, imageRef, hasRef := strings.Cut(msg.Stream, "Loaded image: "); hasRef { - return imageRef - } - } - - t.Fatalf("failed to read image ID\n%s", string(all)) - return "" -}