forked from dragonflyoss/nydus
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
nydusify: add some unit tests for pkg/utils and cmd/nydusify
Signed-off-by: Qinqi Qu <[email protected]>
- Loading branch information
1 parent
c5fdfda
commit 35aa3a2
Showing
2 changed files
with
265 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// Copyright 2023 Alibaba Cloud. All rights reserved. | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package main | ||
|
||
import ( | ||
"encoding/json" | ||
"io/ioutil" | ||
"os" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestIsPossibleValue(t *testing.T) { | ||
value := "qwe" | ||
list := []string{"abc", "qwe", "xyz"} | ||
require.True(t, isPossibleValue(list, value)) | ||
|
||
// Failure situation | ||
value2 := "vdf" | ||
require.False(t, isPossibleValue(list, value2)) | ||
} | ||
|
||
func TestAddReferenceSuffix(t *testing.T) { | ||
source := "localhost:5000/nginx:latest" | ||
suffix := "-suffix" | ||
target, err := addReferenceSuffix(source, suffix) | ||
require.NoError(t, err) | ||
require.Equal(t, target, "localhost:5000/nginx:latest-suffix") | ||
|
||
// Failure situation | ||
source = "localhost:5000\nginx:latest" | ||
suffix = "-suffix" | ||
_, err = addReferenceSuffix(source, suffix) | ||
require.Error(t, err) | ||
require.Contains(t, err.Error(), "invalid source image reference") | ||
} | ||
|
||
func TestParseBackendConfig(t *testing.T) { | ||
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))) | ||
|
||
file, err := ioutil.TempFile("", "nydusify-backend-config-test.json") | ||
require.NoError(t, err) | ||
defer os.RemoveAll(file.Name()) | ||
|
||
_, err = file.WriteString(configJSON) | ||
require.NoError(t, err) | ||
file.Sync() | ||
|
||
resultJSON, err := parseBackendConfig("", file.Name()) | ||
require.NoError(t, err) | ||
require.True(t, json.Valid([]byte(resultJSON))) | ||
require.Equal(t, configJSON, resultJSON) | ||
|
||
// Failure situation | ||
_, err = parseBackendConfig(configJSON, file.Name()) | ||
require.Error(t, err) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,196 @@ | ||
// Copyright 2023 Alibaba Cloud. All rights reserved. | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
package utils | ||
|
||
import ( | ||
"archive/tar" | ||
"compress/gzip" | ||
"io" | ||
"os" | ||
"strings" | ||
"testing" | ||
|
||
"github.com/opencontainers/go-digest" | ||
ocispec "github.com/opencontainers/image-spec/specs-go/v1" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func makePlatform(osArch string, nydus bool) *ocispec.Platform { | ||
var platform *ocispec.Platform | ||
if osArch == "" { | ||
platform = &ocispec.Platform{ | ||
OS: "", | ||
Architecture: "", | ||
} | ||
} else { | ||
platform = &ocispec.Platform{ | ||
OS: strings.Split(osArch, "/")[0], | ||
Architecture: strings.Split(osArch, "/")[1], | ||
} | ||
} | ||
if nydus { | ||
platform.OSFeatures = []string{ManifestOSFeatureNydus} | ||
} | ||
return platform | ||
} | ||
|
||
func makeDesc(id string, platform *ocispec.Platform) ocispec.Descriptor { | ||
return ocispec.Descriptor{ | ||
MediaType: ocispec.MediaTypeImageManifest, | ||
Digest: digest.FromString("manifest-" + id), | ||
Size: 10, | ||
Platform: platform, | ||
} | ||
} | ||
|
||
func TestIsSupportedArch(t *testing.T) { | ||
var arch string | ||
arch = PlatformArchAMD64 | ||
require.Equal(t, IsSupportedArch(arch), true) | ||
arch = PlatformArchARM64 | ||
require.Equal(t, IsSupportedArch(arch), true) | ||
arch = "riscv64" | ||
require.Equal(t, IsSupportedArch(arch), false) | ||
arch = "unsupported" | ||
require.Equal(t, IsSupportedArch(arch), false) | ||
} | ||
|
||
func TestIsNydusPlatform(t *testing.T) { | ||
var platform *ocispec.Platform | ||
platform = makePlatform("linux/amd64", true) | ||
require.Equal(t, IsNydusPlatform(platform), true) | ||
platform = makePlatform("linux/arm64", true) | ||
require.Equal(t, IsNydusPlatform(platform), true) | ||
platform = makePlatform("linux/amd64", false) | ||
require.Equal(t, IsNydusPlatform(platform), false) | ||
platform = makePlatform("linux/arm64", false) | ||
require.Equal(t, IsNydusPlatform(platform), false) | ||
} | ||
|
||
func TestMatchNydusPlatform(t *testing.T) { | ||
var desc ocispec.Descriptor | ||
desc = makeDesc("nydus", makePlatform("linux/amd64", true)) | ||
require.Equal(t, MatchNydusPlatform(&desc, "linux", "arm64"), false) | ||
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("windows/arm64", true)) | ||
require.Equal(t, MatchNydusPlatform(&desc, "windows", "arm64"), true) | ||
require.Equal(t, MatchNydusPlatform(&desc, "windows", "amd64"), false) | ||
require.Equal(t, MatchNydusPlatform(&desc, "linux", "arm64"), false) | ||
require.Equal(t, MatchNydusPlatform(&desc, "linux", "amd64"), false) | ||
} | ||
|
||
func TestIsEmptyString(t *testing.T) { | ||
var str = "" | ||
require.Equal(t, IsEmptyString(str), true) | ||
str = "test" | ||
require.Equal(t, IsEmptyString(str), false) | ||
} | ||
|
||
func TestIsPathExists(t *testing.T) { | ||
var tempdir = "./test/" | ||
err := os.MkdirAll(tempdir, 0666) | ||
require.NoError(t, err) | ||
defer os.RemoveAll(tempdir) | ||
require.Equal(t, IsPathExists(tempdir), true) | ||
var path = "UnexistFolder" | ||
require.Equal(t, IsPathExists(path), false) | ||
} | ||
|
||
func createArchive(files []string, buf io.Writer) error { | ||
// Create new Writers for gzip and tar | ||
// These writers are chained. Writing to the tar writer will | ||
// write to the gzip writer which in turn will write to | ||
// the "buf" writer | ||
gw := gzip.NewWriter(buf) | ||
defer gw.Close() | ||
tw := tar.NewWriter(gw) | ||
defer tw.Close() | ||
// Iterate over files and add them to the tar archive | ||
for _, file := range files { | ||
err := addToArchive(tw, file) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func addToArchive(tw *tar.Writer, filename string) error { | ||
// Open the file which will be written into the archive | ||
file, err := os.Open(filename) | ||
if err != nil { | ||
return err | ||
} | ||
defer file.Close() | ||
// Get FileInfo about our file providing file size, mode, etc. | ||
info, err := file.Stat() | ||
if err != nil { | ||
return err | ||
} | ||
// Create a tar Header from the FileInfo data | ||
header, err := tar.FileInfoHeader(info, info.Name()) | ||
if err != nil { | ||
return err | ||
} | ||
// Use full path as name (FileInfoHeader only takes the basename) | ||
// If we don't do this the directory strucuture would | ||
// not be preserved | ||
// https://golang.org/src/archive/tar/common.go?#L626 | ||
header.Name = filename | ||
// Write file header to the tar archive | ||
err = tw.WriteHeader(header) | ||
if err != nil { | ||
return err | ||
} | ||
// Copy file content to tar archive | ||
_, err = io.Copy(tw, file) | ||
if err != nil { | ||
return err | ||
} | ||
return nil | ||
} | ||
|
||
func TestUnpackFile(t *testing.T) { | ||
fileName := "example.txt" | ||
dirName := "test" | ||
mockData := "this is a test data" | ||
// Create file1 | ||
file1, err := os.Create(fileName) | ||
require.NoError(t, err) | ||
defer file1.Close() | ||
defer os.RemoveAll(file1.Name()) | ||
_, err = io.WriteString(file1, mockData) | ||
require.NoError(t, err) | ||
// Create file2 | ||
err = os.MkdirAll(dirName, 0666) | ||
defer os.RemoveAll(dirName) | ||
require.NoError(t, err) | ||
file2, err := os.Create(dirName + fileName) | ||
require.NoError(t, err) | ||
defer file2.Close() | ||
defer os.RemoveAll(file2.Name()) | ||
_, err = io.WriteString(file2, mockData) | ||
require.NoError(t, err) | ||
// Files which to include in the tar.gz archive | ||
files := []string{file1.Name(), file2.Name()} | ||
// Create output file | ||
targzName := "output.tar.gz" | ||
out, err := os.Create(targzName) | ||
require.NoError(t, err) | ||
defer out.Close() | ||
defer os.Remove(targzName) | ||
// Create the archive and write the output to the "out" Writer | ||
err = createArchive(files, out) | ||
require.NoError(t, err) | ||
// Archive created successfully | ||
targzFile, err := os.Open(out.Name()) | ||
require.NoError(t, err) | ||
defer targzFile.Close() | ||
outputName := "output.txt" | ||
err = UnpackFile(targzFile, file1.Name(), outputName) | ||
require.NoError(t, err) | ||
defer os.Remove(outputName) | ||
} |