diff --git a/contrib/nydusify/cmd/nydusify_test.go b/contrib/nydusify/cmd/nydusify_test.go index 019be92fa2c..5abea7e729c 100644 --- a/contrib/nydusify/cmd/nydusify_test.go +++ b/contrib/nydusify/cmd/nydusify_test.go @@ -6,10 +6,12 @@ package main import ( "encoding/json" + "flag" "os" "testing" "github.com/stretchr/testify/require" + "github.com/urfave/cli/v2" ) func TestIsPossibleValue(t *testing.T) { @@ -35,6 +37,12 @@ func TestAddReferenceSuffix(t *testing.T) { _, err = addReferenceSuffix(source, suffix) require.Error(t, err) require.Contains(t, err.Error(), "invalid source image reference") + + source = "localhost:5000/nginx:latest@sha256:757574c5a2102627de54971a0083d4ecd24eb48fdf06b234d063f19f7bbc22fb" + suffix = "-suffix" + _, err = addReferenceSuffix(source, suffix) + require.Error(t, err) + require.Contains(t, err.Error(), "unsupported digested image reference") } func TestParseBackendConfig(t *testing.T) { @@ -65,4 +73,249 @@ func TestParseBackendConfig(t *testing.T) { // Failure situation _, err = parseBackendConfig(configJSON, file.Name()) require.Error(t, err) + + _, err = parseBackendConfig("", "non-existent.json") + require.Error(t, err) +} + +func TestGetBackendConfig(t *testing.T) { + app := &cli.App{ + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "prefixbackend-type", + Value: "", + }, + &cli.StringFlag{ + Name: "prefixbackend-config", + Value: "", + }, + &cli.StringFlag{ + Name: "prefixbackend-config-file", + Value: "", + }, + }, + } + ctx := cli.NewContext(app, nil, nil) + + backendType, backendConfig, err := getBackendConfig(ctx, "prefix", false) + require.NoError(t, err) + require.Empty(t, backendType) + require.Empty(t, backendConfig) + + backendType, backendConfig, err = getBackendConfig(ctx, "prefix", true) + require.Error(t, err) + require.Contains(t, err.Error(), "backend type is empty, please specify option") + require.Empty(t, backendType) + require.Empty(t, backendConfig) + + flagSet := flag.NewFlagSet("test1", flag.PanicOnError) + flagSet.String("prefixbackend-type", "errType", "") + ctx = cli.NewContext(app, flagSet, nil) + backendType, backendConfig, err = getBackendConfig(ctx, "prefix", true) + require.Error(t, err) + require.Contains(t, err.Error(), "backend-type should be one of") + require.Empty(t, backendType) + require.Empty(t, backendConfig) + + flagSet = flag.NewFlagSet("test2", flag.PanicOnError) + flagSet.String("prefixbackend-type", "oss", "") + ctx = cli.NewContext(app, flagSet, nil) + backendType, backendConfig, err = getBackendConfig(ctx, "prefix", true) + require.Error(t, err) + require.Contains(t, err.Error(), "backend configuration is empty, please specify option") + require.Empty(t, backendType) + require.Empty(t, backendConfig) + + configJSON := ` + { + "bucket_name": "test", + "endpoint": "region.oss.com", + "access_key_id": "testAK", + "access_key_secret": "testSK", + "meta_prefix": "meta", + "blob_prefix": "blob" + }` + require.True(t, json.Valid([]byte(configJSON))) + + flagSet = flag.NewFlagSet("test3", flag.PanicOnError) + flagSet.String("prefixbackend-type", "oss", "") + flagSet.String("prefixbackend-config", configJSON, "") + ctx = cli.NewContext(app, flagSet, nil) + backendType, backendConfig, err = getBackendConfig(ctx, "prefix", true) + require.NoError(t, err) + require.Equal(t, "oss", backendType) + require.Equal(t, configJSON, backendConfig) + + file, err := os.CreateTemp("", "nydusify-backend-config-test.json") + require.NoError(t, err) + defer os.RemoveAll(file.Name()) + + _, err = file.WriteString(configJSON) + require.NoError(t, err) + file.Sync() + + flagSet = flag.NewFlagSet("test4", flag.PanicOnError) + flagSet.String("prefixbackend-type", "oss", "") + flagSet.String("prefixbackend-config-file", file.Name(), "") + ctx = cli.NewContext(app, flagSet, nil) + backendType, backendConfig, err = getBackendConfig(ctx, "prefix", true) + require.NoError(t, err) + require.Equal(t, "oss", backendType) + require.Equal(t, configJSON, backendConfig) + + flagSet = flag.NewFlagSet("test5", flag.PanicOnError) + flagSet.String("prefixbackend-type", "oss", "") + flagSet.String("prefixbackend-config", configJSON, "") + flagSet.String("prefixbackend-config-file", file.Name(), "") + ctx = cli.NewContext(app, flagSet, nil) + backendType, backendConfig, err = getBackendConfig(ctx, "prefix", true) + require.Error(t, err) + require.Contains(t, err.Error(), "--backend-config conflicts with --backend-config-file") + require.Empty(t, backendType) + require.Empty(t, backendConfig) +} + +func TestGetTargetReference(t *testing.T) { + app := &cli.App{ + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "target", + Value: "", + }, + &cli.StringFlag{ + Name: "target-suffix", + Value: "", + }, + &cli.StringFlag{ + Name: "source", + Value: "", + }, + }, + } + ctx := cli.NewContext(app, nil, nil) + + target, err := getTargetReference(ctx) + require.Error(t, err) + require.Contains(t, err.Error(), "--target or --target-suffix is required") + require.Empty(t, target) + + flagSet := flag.NewFlagSet("test1", flag.PanicOnError) + flagSet.String("target", "testTarget", "") + flagSet.String("target-suffix", "testSuffix", "") + ctx = cli.NewContext(app, flagSet, nil) + target, err = getTargetReference(ctx) + require.Error(t, err) + require.Contains(t, err.Error(), "-target conflicts with --target-suffix") + require.Empty(t, target) + + flagSet = flag.NewFlagSet("test2", flag.PanicOnError) + flagSet.String("target-suffix", "-nydus", "") + flagSet.String("source", "localhost:5000/nginx:latest", "") + ctx = cli.NewContext(app, flagSet, nil) + target, err = getTargetReference(ctx) + require.NoError(t, err) + require.Equal(t, "localhost:5000/nginx:latest-nydus", target) + + flagSet = flag.NewFlagSet("test3", flag.PanicOnError) + flagSet.String("target-suffix", "-nydus", "") + flagSet.String("source", "localhost:5000\nginx:latest", "") + ctx = cli.NewContext(app, flagSet, nil) + target, err = getTargetReference(ctx) + require.Error(t, err) + require.Contains(t, err.Error(), "invalid source image reference") + require.Empty(t, target) + + flagSet = flag.NewFlagSet("test4", flag.PanicOnError) + flagSet.String("target", "testTarget", "") + ctx = cli.NewContext(app, flagSet, nil) + target, err = getTargetReference(ctx) + require.NoError(t, err) + require.Equal(t, "testTarget", target) +} + +func TestGetCacheReferencet(t *testing.T) { + app := &cli.App{ + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "build-cache", + Value: "", + }, + &cli.StringFlag{ + Name: "build-cache-tag", + Value: "", + }, + }, + } + ctx := cli.NewContext(app, nil, nil) + + cache, err := getCacheReference(ctx, "") + require.NoError(t, err) + require.Empty(t, cache) + + flagSet := flag.NewFlagSet("test1", flag.PanicOnError) + flagSet.String("build-cache", "cache", "") + flagSet.String("build-cache-tag", "cacheTag", "") + ctx = cli.NewContext(app, flagSet, nil) + cache, err = getCacheReference(ctx, "") + require.Error(t, err) + require.Contains(t, err.Error(), "--build-cache conflicts with --build-cache-tag") + require.Empty(t, cache) + + flagSet = flag.NewFlagSet("test2", flag.PanicOnError) + flagSet.String("build-cache-tag", "cacheTag", "errTarget") + ctx = cli.NewContext(app, flagSet, nil) + cache, err = getCacheReference(ctx, "") + require.Error(t, err) + require.Contains(t, err.Error(), "invalid target image reference: invalid reference format") + require.Empty(t, cache) + + flagSet = flag.NewFlagSet("test2", flag.PanicOnError) + flagSet.String("build-cache-tag", "latest-cache", "") + ctx = cli.NewContext(app, flagSet, nil) + cache, err = getCacheReference(ctx, "localhost:5000/nginx:latest") + require.NoError(t, err) + require.Equal(t, "localhost:5000/nginx:latest-cache", cache) +} + +func TestGetPrefetchPatterns(t *testing.T) { + app := &cli.App{ + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "prefetch-dir", + Value: "", + }, + &cli.BoolFlag{ + Name: "prefetch-patterns", + Value: false, + }, + }, + } + ctx := cli.NewContext(app, nil, nil) + + patterns, err := getPrefetchPatterns(ctx) + require.NoError(t, err) + require.Equal(t, "/", patterns) + + flagSet := flag.NewFlagSet("test1", flag.PanicOnError) + flagSet.String("prefetch-dir", "/etc/passwd", "") + ctx = cli.NewContext(app, flagSet, nil) + patterns, err = getPrefetchPatterns(ctx) + require.NoError(t, err) + require.Equal(t, "/etc/passwd", patterns) + + flagSet = flag.NewFlagSet("test2", flag.PanicOnError) + flagSet.String("prefetch-dir", "/etc/passwd", "") + flagSet.Bool("prefetch-patterns", true, "") + ctx = cli.NewContext(app, flagSet, nil) + patterns, err = getPrefetchPatterns(ctx) + require.Error(t, err) + require.Contains(t, err.Error(), "--prefetch-dir conflicts with --prefetch-patterns") + require.Empty(t, patterns) + + flagSet = flag.NewFlagSet("test3", flag.PanicOnError) + flagSet.Bool("prefetch-patterns", true, "") + ctx = cli.NewContext(app, flagSet, nil) + patterns, err = getPrefetchPatterns(ctx) + require.NoError(t, err) + require.Equal(t, "/", patterns) } diff --git a/contrib/nydusify/pkg/backend/backend_test.go b/contrib/nydusify/pkg/backend/backend_test.go new file mode 100644 index 00000000000..0fc5223408e --- /dev/null +++ b/contrib/nydusify/pkg/backend/backend_test.go @@ -0,0 +1,62 @@ +package backend + +import ( + "encoding/json" + "testing" + + "github.com/dragonflyoss/nydus/contrib/nydusify/pkg/provider" + "github.com/dragonflyoss/nydus/contrib/nydusify/pkg/utils" + "github.com/stretchr/testify/require" +) + +func TestBlobDesc(t *testing.T) { + desc := blobDesc(123456, "205eed24cbec29ad9cb4593a73168ef1803402370a82f7d51ce25646fc2f943a") + require.Equal(t, int64(123456), desc.Size) + require.Equal(t, "sha256:205eed24cbec29ad9cb4593a73168ef1803402370a82f7d51ce25646fc2f943a", desc.Digest.String()) + require.Equal(t, utils.MediaTypeNydusBlob, desc.MediaType) + require.Equal(t, map[string]string{ + utils.LayerAnnotationUncompressed: "sha256:205eed24cbec29ad9cb4593a73168ef1803402370a82f7d51ce25646fc2f943a", + utils.LayerAnnotationNydusBlob: "true", + }, desc.Annotations) +} + +func TestNewBackend(t *testing.T) { + ossConfigJSON := ` + { + "bucket_name": "test", + "endpoint": "region.oss.com", + "access_key_id": "testAK", + "access_key_secret": "testSK", + "object_prefix": "blob" + }` + require.True(t, json.Valid([]byte(ossConfigJSON))) + backend, err := NewBackend("oss", []byte(ossConfigJSON), nil) + require.NoError(t, err) + require.Equal(t, OssBackend, backend.Type()) + + s3ConfigJSON := ` + { + "bucket_name": "test", + "endpoint": "s3.amazonaws.com", + "access_key_id": "testAK", + "access_key_secret": "testSK", + "object_prefix": "blob", + "scheme": "https", + "region": "region1" + }` + require.True(t, json.Valid([]byte(s3ConfigJSON))) + backend, err = NewBackend("s3", []byte(s3ConfigJSON), nil) + require.NoError(t, err) + require.Equal(t, S3backend, backend.Type()) + + testRegistryRemote, err := provider.DefaultRemote("test", false) + require.NoError(t, err) + backend, err = NewBackend("registry", nil, testRegistryRemote) + require.NoError(t, err) + require.Equal(t, RegistryBackend, backend.Type()) + + backend, err = NewBackend("errBackend", nil, testRegistryRemote) + require.Error(t, err) + require.Contains(t, err.Error(), "unsupported backend type") + require.Nil(t, backend) +} diff --git a/contrib/nydusify/pkg/backend/oss_test.go b/contrib/nydusify/pkg/backend/oss_test.go new file mode 100644 index 00000000000..3fb58c84ef7 --- /dev/null +++ b/contrib/nydusify/pkg/backend/oss_test.go @@ -0,0 +1,133 @@ +package backend + +import ( + "encoding/json" + "hash/crc64" + "os" + "testing" + + "github.com/stretchr/testify/require" +) + +func tempOSSBackend() *OSSBackend { + ossConfigJSON := ` + { + "bucket_name": "test", + "endpoint": "region.oss.com", + "access_key_id": "testAK", + "access_key_secret": "testSK", + "object_prefix": "blob" + }` + backend, _ := newOSSBackend([]byte(ossConfigJSON)) + return backend +} + +func TestCalcCrc64ECMA(t *testing.T) { + blobCrc64, err := calcCrc64ECMA("nil") + require.Error(t, err) + require.Contains(t, err.Error(), "calc md5sum") + require.Zero(t, blobCrc64) + + file, err := os.CreateTemp("", "temp") + require.NoError(t, err) + defer os.RemoveAll(file.Name()) + + _, err = file.WriteString("123") + require.NoError(t, err) + file.Sync() + + blobCrc64, err = calcCrc64ECMA(file.Name()) + require.NoError(t, err) + require.Equal(t, crc64.Checksum([]byte("123"), crc64.MakeTable(crc64.ECMA)), blobCrc64) +} + +func TestOSSRemoteID(t *testing.T) { + ossBackend := tempOSSBackend() + id := ossBackend.remoteID("111") + require.Equal(t, "oss://test/blob111", id) +} + +func TestNewOSSBackend(t *testing.T) { + ossConfigJSON1 := ` + { + "bucket_name": "test", + "endpoint": "region.oss.com", + "access_key_id": "testAK", + "access_key_secret": "testSK", + "object_prefix": "blob" + }` + require.True(t, json.Valid([]byte(ossConfigJSON1))) + backend, err := newOSSBackend([]byte(ossConfigJSON1)) + require.NoError(t, err) + require.Equal(t, "test", backend.bucket.BucketName) + require.Equal(t, "blob", backend.objectPrefix) + + ossConfigJSON2 := ` + { + "bucket_name": "test", + "access_key_id": "testAK", + "access_key_secret": "testSK", + "object_prefix": "blob" + }` + require.True(t, json.Valid([]byte(ossConfigJSON2))) + backend, err = newOSSBackend([]byte(ossConfigJSON2)) + require.Error(t, err) + require.Contains(t, err.Error(), "invalid OSS configuration: missing 'endpoint' or 'bucket'") + require.Nil(t, backend) + + ossConfigJSON3 := ` + { + "bucket_name": "test", + "access_key_id": "testAK", + "access_key_secret": "testSK", + "object_prefix": "blob" + }` + require.True(t, json.Valid([]byte(ossConfigJSON3))) + backend, err = newOSSBackend([]byte(ossConfigJSON3)) + require.Error(t, err) + require.Contains(t, err.Error(), "invalid OSS configuration: missing 'endpoint' or 'bucket'") + require.Nil(t, backend) + + ossConfigJSON4 := ` + { + "bucket_name": "t", + "endpoint": "region.oss.com", + "access_key_id": "testAK", + "access_key_secret": "testSK", + "object_prefix": "blob" + }` + require.True(t, json.Valid([]byte(ossConfigJSON4))) + backend, err = newOSSBackend([]byte(ossConfigJSON4)) + require.Error(t, err) + require.Contains(t, err.Error(), "Create bucket") + require.Contains(t, err.Error(), "len is between [3-63],now is") + require.Nil(t, backend) + + ossConfigJSON5 := ` + { + "bucket_name": "AAA", + "endpoint": "region.oss.com", + "access_key_id": "testAK", + "access_key_secret": "testSK", + "object_prefix": "blob" + }` + require.True(t, json.Valid([]byte(ossConfigJSON5))) + backend, err = newOSSBackend([]byte(ossConfigJSON5)) + require.Error(t, err) + require.Contains(t, err.Error(), "Create bucket") + require.Contains(t, err.Error(), "can only include lowercase letters, numbers, and -") + require.Nil(t, backend) + + ossConfigJSON6 := ` + { + "bucket_name": "AAA", + "endpoint": "region.oss.com", + "access_key_id": "testAK", + "access_key_secret": "testSK", + "object_prefix": "blob", + }` + backend, err = newOSSBackend([]byte(ossConfigJSON6)) + require.Error(t, err) + require.Contains(t, err.Error(), "Parse OSS storage backend configuration") + require.Nil(t, backend) +} diff --git a/contrib/nydusify/pkg/backend/s3_test.go b/contrib/nydusify/pkg/backend/s3_test.go new file mode 100644 index 00000000000..be29e433b3b --- /dev/null +++ b/contrib/nydusify/pkg/backend/s3_test.go @@ -0,0 +1,115 @@ +package backend + +import ( + "context" + "encoding/json" + "testing" + + "github.com/aws/aws-sdk-go-v2/credentials" + "github.com/stretchr/testify/require" +) + +func tempS3Backend() *S3Backend { + s3ConfigJSON := ` + { + "bucket_name": "test", + "endpoint": "s3.amazonaws.com", + "access_key_id": "testAK", + "access_key_secret": "testSK", + "object_prefix": "blob", + "scheme": "https", + "region": "region1" + }` + backend, _ := newS3Backend([]byte(s3ConfigJSON)) + return backend +} + +func TestS3RemoteID(t *testing.T) { + s3Backend := tempS3Backend() + id := s3Backend.remoteID("111") + require.Equal(t, "https://s3.amazonaws.com/test/111", id) +} + +func TestBlobObjectKey(t *testing.T) { + s3Backend := tempS3Backend() + blobObjectKey := s3Backend.blobObjectKey("111") + require.Equal(t, "blob111", blobObjectKey) +} + +func TestNewS3Backend(t *testing.T) { + s3ConfigJSON1 := ` + { + "bucket_name": "test", + "endpoint": "s3.amazonaws.com", + "access_key_id": "testAK", + "access_key_secret": "testSK", + "object_prefix": "blob", + "scheme": "https", + "region": "region1" + }` + require.True(t, json.Valid([]byte(s3ConfigJSON1))) + backend, err := newS3Backend([]byte(s3ConfigJSON1)) + require.NoError(t, err) + require.Equal(t, "blob", backend.objectPrefix) + require.Equal(t, "test", backend.bucketName) + require.Equal(t, "https://s3.amazonaws.com", backend.endpointWithScheme) + require.Equal(t, "https://s3.amazonaws.com", *backend.client.Options().BaseEndpoint) + testCredentials, err := backend.client.Options().Credentials.Retrieve(context.Background()) + require.NoError(t, err) + realCredentials, err := credentials.NewStaticCredentialsProvider("testAK", "testSK", "").Retrieve(context.Background()) + require.NoError(t, err) + require.Equal(t, testCredentials, realCredentials) + + s3ConfigJSON2 := ` + { + "bucket_name": "test", + "endpoint": "s3.amazonaws.com", + "access_key_id": "testAK", + "access_key_secret": "testSK", + "object_prefix": "blob", + "scheme": "https", + "region": "region1", + }` + backend, err = newS3Backend([]byte(s3ConfigJSON2)) + require.Error(t, err) + require.Contains(t, err.Error(), "parse S3 storage backend configuration") + require.Nil(t, backend) + + s3ConfigJSON3 := ` + { + "bucket_name": "test", + "endpoint": "", + "access_key_id": "testAK", + "access_key_secret": "testSK", + "object_prefix": "blob", + "scheme": "", + "region": "region1" + }` + require.True(t, json.Valid([]byte(s3ConfigJSON3))) + backend, err = newS3Backend([]byte(s3ConfigJSON3)) + require.NoError(t, err) + require.Equal(t, "blob", backend.objectPrefix) + require.Equal(t, "test", backend.bucketName) + require.Equal(t, "https://s3.amazonaws.com", backend.endpointWithScheme) + testCredentials, err = backend.client.Options().Credentials.Retrieve(context.Background()) + require.NoError(t, err) + realCredentials, err = credentials.NewStaticCredentialsProvider("testAK", "testSK", "").Retrieve(context.Background()) + require.NoError(t, err) + require.Equal(t, testCredentials, realCredentials) + + s3ConfigJSON4 := ` + { + "bucket_name": "", + "endpoint": "s3.amazonaws.com", + "access_key_id": "testAK", + "access_key_secret": "testSK", + "object_prefix": "blob", + "scheme": "https", + "region": "" + }` + require.True(t, json.Valid([]byte(s3ConfigJSON4))) + backend, err = newS3Backend([]byte(s3ConfigJSON4)) + require.Error(t, err) + require.Contains(t, err.Error(), "invalid S3 configuration: missing 'bucket_name' or 'region'") + require.Nil(t, backend) +} diff --git a/contrib/nydusify/pkg/packer/artifact.go b/contrib/nydusify/pkg/packer/artifact.go index 53f266348ce..13ec4274270 100644 --- a/contrib/nydusify/pkg/packer/artifact.go +++ b/contrib/nydusify/pkg/packer/artifact.go @@ -32,9 +32,8 @@ func (a Artifact) blobFilePath(imageName string, isDigest bool) string { return filepath.Join(a.OutputDir, imageName) } else if suffix := filepath.Ext(imageName); suffix != "" { return filepath.Join(a.OutputDir, strings.TrimSuffix(imageName, suffix)+".blob") - } else { - return filepath.Join(a.OutputDir, imageName+".blob") } + return filepath.Join(a.OutputDir, imageName+".blob") } func (a Artifact) outputJSONPath() string { diff --git a/contrib/nydusify/pkg/utils/archive_test.go b/contrib/nydusify/pkg/utils/archive_test.go index 992babe4c7a..da9139ad794 100644 --- a/contrib/nydusify/pkg/utils/archive_test.go +++ b/contrib/nydusify/pkg/utils/archive_test.go @@ -5,10 +5,16 @@ package utils import ( + "archive/tar" + "bytes" + "compress/gzip" + "context" + "io" "os" "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestPackTargzInfo(t *testing.T) { @@ -25,3 +31,35 @@ func TestPackTargzInfo(t *testing.T) { assert.Equal(t, "sha256:6cdd1b26d54d5852fbea95a81cbb25383975b70b4ffad9f9b6d25c7a434a51eb", digest.String()) assert.Equal(t, size, int64(315)) } + +func TestUnpackTargz(t *testing.T) { + tarBuffer := new(bytes.Buffer) + tarWriter := tar.NewWriter(tarBuffer) + fileContent := []byte("Hello, this is an example file.") + tarHeader := &tar.Header{ + Name: "example_file.txt", + Mode: 0644, + Size: int64(len(fileContent)), + } + err := tarWriter.WriteHeader(tarHeader) + require.NoError(t, err) + _, err = tarWriter.Write(fileContent) + require.NoError(t, err) + err = tarWriter.Close() + require.NoError(t, err) + gzipBuffer := new(bytes.Buffer) + gzipWriter := gzip.NewWriter(gzipBuffer) + _, err = io.Copy(gzipWriter, tarBuffer) + require.NoError(t, err) + err = gzipWriter.Close() + require.NoError(t, err) + tarGzReader := bytes.NewReader(gzipBuffer.Bytes()) + + err = UnpackTargz(context.Background(), "temp", tarGzReader, false) + defer os.RemoveAll("temp") + require.NoError(t, err) + + bytes, err := os.ReadFile("temp/example_file.txt") + require.NoError(t, err) + require.Equal(t, bytes, fileContent) +} diff --git a/contrib/nydusify/pkg/utils/utils_test.go b/contrib/nydusify/pkg/utils/utils_test.go index 19179d53774..d8b1b8bf539 100644 --- a/contrib/nydusify/pkg/utils/utils_test.go +++ b/contrib/nydusify/pkg/utils/utils_test.go @@ -6,11 +6,14 @@ package utils import ( "archive/tar" "compress/gzip" + "fmt" "io" + "net/http" "os" "strings" "testing" + "github.com/goharbor/acceleration-service/pkg/driver/nydus/utils" "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "github.com/stretchr/testify/require" @@ -31,6 +34,8 @@ func makePlatform(osArch string, nydus bool) *ocispec.Platform { } if nydus { platform.OSFeatures = []string{ManifestOSFeatureNydus} + } else { + platform.OSFeatures = nil } return platform } @@ -75,6 +80,11 @@ func TestMatchNydusPlatform(t *testing.T) { require.Equal(t, MatchNydusPlatform(&desc, "linux", "amd64"), true) require.Equal(t, MatchNydusPlatform(&desc, "windows", "amd64"), false) require.Equal(t, MatchNydusPlatform(&desc, "windows", "arm64"), false) + desc = makeDesc("nydus", makePlatform("linux/amd64", false)) + require.Equal(t, MatchNydusPlatform(&desc, "linux", "arm64"), false) + require.Equal(t, MatchNydusPlatform(&desc, "linux", "amd64"), false) + require.Equal(t, MatchNydusPlatform(&desc, "windows", "amd64"), false) + require.Equal(t, MatchNydusPlatform(&desc, "windows", "arm64"), false) desc = makeDesc("nydus", makePlatform("windows/arm64", true)) require.Equal(t, MatchNydusPlatform(&desc, "windows", "arm64"), true) require.Equal(t, MatchNydusPlatform(&desc, "windows", "amd64"), false) @@ -194,3 +204,67 @@ func TestUnpackFile(t *testing.T) { require.NoError(t, err) defer os.Remove(outputName) } + +func TestHashFile(t *testing.T) { + file, err := os.CreateTemp("", "tempFile") + require.NoError(t, err) + defer os.RemoveAll(file.Name()) + + _, err = file.WriteString("123456") + require.NoError(t, err) + file.Sync() + + hashSum, err := HashFile(file.Name()) + require.NoError(t, err) + require.Len(t, hashSum, 32) +} + +func TestMarshalToDesc(t *testing.T) { + config := ocispec.Image{ + Config: ocispec.ImageConfig{}, + RootFS: ocispec.RootFS{ + Type: "layers", + // Layers from manifest must be match image config. + DiffIDs: []digest.Digest{}, + }, + } + configDesc, configBytes, err := utils.MarshalToDesc(config, ocispec.MediaTypeImageConfig) + require.NoError(t, err) + require.Equal(t, "application/vnd.oci.image.config.v1+json", configDesc.MediaType) + require.Equal(t, "sha256:92ceafbaf24c322b45bfeed6e98e25f735c723ae470442c647569086f74cc032", configDesc.Digest.String()) + require.Equal(t, int64(len(configBytes)), configDesc.Size) +} + +func TestWithRetry(t *testing.T) { + err := WithRetry(func() error { + _, err := http.Get("http://localhost:5000") + return err + }) + require.Contains(t, err.Error(), "connect: connection refused") +} + +func TestRetryWithHTTP(t *testing.T) { + require.True(t, RetryWithHTTP(fmt.Errorf("server gave HTTP response to HTTPS client"))) + require.False(t, RetryWithHTTP(nil)) +} + +func TestGetNydusFsVersionOrDefault(t *testing.T) { + testAnnotations := make(map[string]string) + fsVersion := GetNydusFsVersionOrDefault(testAnnotations, V5) + require.Equal(t, fsVersion, V5) + + fsVersion = GetNydusFsVersionOrDefault(nil, V6) + require.Equal(t, fsVersion, V6) + + testAnnotations[LayerAnnotationNydusFsVersion] = "5" + fsVersion = GetNydusFsVersionOrDefault(testAnnotations, V6) + require.Equal(t, fsVersion, V5) + + testAnnotations[LayerAnnotationNydusFsVersion] = "6" + fsVersion = GetNydusFsVersionOrDefault(testAnnotations, V5) + require.Equal(t, fsVersion, V6) + + testAnnotations[LayerAnnotationNydusFsVersion] = "7" + fsVersion = GetNydusFsVersionOrDefault(testAnnotations, V5) + require.Equal(t, fsVersion, V5) +}