mirror of
https://github.com/moby/moby.git
synced 2026-01-11 18:51:37 +00:00
Move testutils image load to integration internal
The image load is only used by integration tests but the specialimage testutils package used by many different tests. The image load relies on the client which creates a transitive client dependency from the daemon packages. Signed-off-by: Derek McGowan <derek@mcg.dev>
This commit is contained in:
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
})
|
||||
|
||||
@@ -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")},
|
||||
})
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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,
|
||||
{
|
||||
|
||||
@@ -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"})
|
||||
|
||||
|
||||
68
integration/internal/image/load.go
Normal file
68
integration/internal/image/load.go
Normal file
@@ -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 ""
|
||||
}
|
||||
@@ -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 ""
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user