automation-tests/common/libimage/push_test.go

193 lines
6.3 KiB
Go

//go:build !remote
package libimage
import (
"context"
"os"
"path/filepath"
"testing"
"github.com/containers/common/pkg/config"
"github.com/containers/image/v5/pkg/compression"
"github.com/containers/image/v5/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestPush(t *testing.T) {
runtime := testNewRuntime(t)
ctx := context.Background()
// Prefetch alpine.
pullOptions := &PullOptions{}
pullOptions.Writer = os.Stdout
_, err := runtime.Pull(ctx, "quay.io/libpod/alpine:latest", config.PullPolicyAlways, pullOptions)
require.NoError(t, err)
pushOptions := &PushOptions{}
pushOptions.Writer = os.Stdout
workdir := t.TempDir()
for _, test := range []struct {
source string
destination string
expectError bool
}{
{"alpine", "dir:" + workdir + "/dir", false},
{"alpine", "oci:" + workdir + "/oci", false},
{"alpine", "oci-archive:" + workdir + "/oci-archive", false},
{"alpine", "docker-archive:" + workdir + "/docker-archive", false},
{"alpine", "containers-storage:localhost/another:alpine", false},
} {
_, err := runtime.Push(ctx, test.source, test.destination, pushOptions)
if test.expectError {
require.Error(t, err, "%v", test)
continue
}
require.NoError(t, err, "%v", test)
pulledImages, err := runtime.Pull(ctx, test.destination, config.PullPolicyAlways, pullOptions)
require.NoError(t, err, "%v", test)
require.Len(t, pulledImages, 1, "%v", test)
}
// Now there should only be two images: alpine in Docker format and
// alpine in OCI format.
listOptions := ListImagesOptions{SetListData: true}
listedImages, err := runtime.ListImages(ctx, &listOptions)
require.NoError(t, err, "error listing images")
require.Len(t, listedImages, 2, "there should only be two images (alpine in Docke/OCI)")
for _, image := range listedImages {
require.NotNil(t, image.ListData.IsDangling, "IsDangling should be set")
}
// And now remove all of them.
rmReports, rmErrors := runtime.RemoveImages(ctx, nil, nil)
require.Len(t, rmErrors, 0)
require.Len(t, rmReports, 2)
for i, image := range listedImages {
require.Equal(t, image.ID(), rmReports[i].ID)
require.True(t, rmReports[i].Removed)
}
}
func TestPushOtherPlatform(t *testing.T) {
runtime := testNewRuntime(t)
ctx := context.Background()
// Prefetch alpine.
pullOptions := &PullOptions{}
pullOptions.Writer = os.Stdout
pullOptions.Architecture = "arm64"
pulledImages, err := runtime.Pull(ctx, "quay.io/libpod/alpine:latest", config.PullPolicyAlways, pullOptions)
require.NoError(t, err)
require.Len(t, pulledImages, 1)
data, err := pulledImages[0].Inspect(ctx, nil)
require.NoError(t, err)
require.Equal(t, "arm64", data.Architecture)
pushOptions := &PushOptions{}
pushOptions.Writer = os.Stdout
tmp, err := os.CreateTemp(t.TempDir(), "")
require.NoError(t, err)
tmp.Close()
_, err = runtime.Push(ctx, "quay.io/libpod/alpine:latest", "docker-archive:"+tmp.Name(), pushOptions)
require.NoError(t, err)
}
func TestPushWithForceCompression(t *testing.T) {
runtime := testNewRuntime(t)
ctx := context.Background()
// Prefetch alpine.
pullOptions := &PullOptions{}
pullOptions.Writer = os.Stdout
pullOptions.Architecture = "arm64"
pulledImages, err := runtime.Pull(ctx, "quay.io/libpod/alpine:latest", config.PullPolicyAlways, pullOptions)
require.NoError(t, err)
require.Len(t, pulledImages, 1)
data, err := pulledImages[0].Inspect(ctx, nil)
require.NoError(t, err)
require.Equal(t, "arm64", data.Architecture)
// Push newly pulled alpine to directory with uncompressed blobs
pushOptions := &PushOptions{}
pushOptions.SystemContext = &types.SystemContext{}
pushOptions.SystemContext.DirForceDecompress = true
pushOptions.Writer = os.Stdout
dirDest := t.TempDir()
_, err = runtime.Push(ctx, "quay.io/libpod/alpine:latest", "dir:"+dirDest, pushOptions)
require.NoError(t, err)
// Pull uncompressed alpine from `dir:dirDest` as source.
pullOptions = &PullOptions{}
pullOptions.Writer = os.Stdout
pullOptions.Architecture = "arm64"
pulledImages, err = runtime.Pull(ctx, "dir:"+dirDest, config.PullPolicyAlways, pullOptions)
require.NoError(t, err)
require.Len(t, pulledImages, 1)
// create `oci` image from uncompressed alpine.
pushOptions = &PushOptions{}
pushOptions.OciAcceptUncompressedLayers = true
pushOptions.Writer = os.Stdout
ociDest := t.TempDir()
_, err = runtime.Push(ctx, "quay.io/libpod/alpine:latest", "oci:"+ociDest, pushOptions)
require.NoError(t, err)
// blobs from first push
entries, err := os.ReadDir(filepath.Join(ociDest, "blobs", "sha256"))
require.NoError(t, err)
blobsFirstPush := []string{}
for _, e := range entries {
blobsFirstPush = append(blobsFirstPush, e.Name())
}
// Note: Compression is changed from `uncompressed` to `Gzip` but blobs
// should still be same since `ForceCompressionFormat` is `false`.
pushOptions = &PushOptions{}
pushOptions.Writer = os.Stdout
pushOptions.CompressionFormat = &compression.Gzip
pushOptions.ForceCompressionFormat = false
_, err = runtime.Push(ctx, "quay.io/libpod/alpine:latest", "oci:"+ociDest, pushOptions)
require.NoError(t, err)
// blobs from second push
entries, err = os.ReadDir(filepath.Join(ociDest, "blobs", "sha256"))
require.NoError(t, err)
blobsSecondPush := []string{}
for _, e := range entries {
blobsSecondPush = append(blobsSecondPush, e.Name())
}
// All blobs of first push should be equivalent to blobs of
// second push since same compression was used
assert.Equal(t, blobsSecondPush, blobsFirstPush)
// Note: Compression is changed from `uncompressed` to `Gzip` but blobs
// should still be same since `ForceCompressionFormat` is `false`.
pushOptions = &PushOptions{}
pushOptions.Writer = os.Stdout
pushOptions.CompressionFormat = &compression.Gzip
pushOptions.ForceCompressionFormat = true
_, err = runtime.Push(ctx, "quay.io/libpod/alpine:latest", "oci:"+ociDest, pushOptions)
require.NoError(t, err)
// collect blobs from third push
entries, err = os.ReadDir(filepath.Join(ociDest, "blobs", "sha256"))
require.NoError(t, err)
blobsThirdPush := []string{}
for _, e := range entries {
blobsThirdPush = append(blobsThirdPush, e.Name())
}
// All blobs of third push should not be equivalent to blobs of
// first push since new compression was used and `ForceCompressionFormat`
// was `true`.
assert.NotEqual(t, blobsThirdPush, blobsFirstPush)
}