249 lines
7.2 KiB
Diff
249 lines
7.2 KiB
Diff
|
|
From 374c6ece3d911d8b5bc72f4e04c4483061624e5a Mon Sep 17 00:00:00 2001
|
||
|
|
From: daisicheng <daisicheng@huawei.com>
|
||
|
|
Date: Thu, 20 Oct 2022 14:51:49 +0800
|
||
|
|
Subject: [PATCH] add import_test.go for import.go and add TestCleanContainers
|
||
|
|
function for store.go
|
||
|
|
|
||
|
|
---
|
||
|
|
cmd/cli/import_test.go | 134 +++++++++++++++++++++++++++++++++++++++++
|
||
|
|
cmd/cli/mock.go | 19 +++++-
|
||
|
|
store/store_test.go | 27 +++++++++
|
||
|
|
3 files changed, 178 insertions(+), 2 deletions(-)
|
||
|
|
create mode 100644 cmd/cli/import_test.go
|
||
|
|
|
||
|
|
diff --git a/cmd/cli/import_test.go b/cmd/cli/import_test.go
|
||
|
|
new file mode 100644
|
||
|
|
index 0000000..057bf17
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/cmd/cli/import_test.go
|
||
|
|
@@ -0,0 +1,134 @@
|
||
|
|
+// Copyright (c) Huawei Technologies Co., Ltd. 2020. All rights reserved.
|
||
|
|
+// isula-build licensed under the Mulan PSL v2.
|
||
|
|
+// You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||
|
|
+// You may obtain a copy of Mulan PSL v2 at:
|
||
|
|
+// http://license.coscl.org.cn/MulanPSL2
|
||
|
|
+// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||
|
|
+// IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||
|
|
+// PURPOSE.
|
||
|
|
+// See the Mulan PSL v2 for more details.
|
||
|
|
+// Author: daisicheng
|
||
|
|
+// Create: 2022-10-20
|
||
|
|
+// Description: This file is for image import test.
|
||
|
|
+
|
||
|
|
+// Description: This file is is used for testing import command.
|
||
|
|
+package main
|
||
|
|
+
|
||
|
|
+import (
|
||
|
|
+ "context"
|
||
|
|
+ "io/ioutil"
|
||
|
|
+ "os"
|
||
|
|
+ "path/filepath"
|
||
|
|
+ "testing"
|
||
|
|
+
|
||
|
|
+ "gotest.tools/v3/assert"
|
||
|
|
+ "gotest.tools/v3/fs"
|
||
|
|
+
|
||
|
|
+ constant "isula.org/isula-build"
|
||
|
|
+)
|
||
|
|
+
|
||
|
|
+const ExceededImportFileSize = 2048 * 1024 * 1024
|
||
|
|
+
|
||
|
|
+func TestImportCommand(t *testing.T) {
|
||
|
|
+ tmpFile := fs.NewFile(t, t.Name())
|
||
|
|
+ exceededFile := fs.NewFile(t, t.Name())
|
||
|
|
+ err := ioutil.WriteFile(tmpFile.Path(), []byte("This is test file"), constant.DefaultSharedFileMode)
|
||
|
|
+ assert.NilError(t, err)
|
||
|
|
+ err = ioutil.WriteFile(exceededFile.Path(), []byte("This is exceeded test file"), constant.DefaultSharedFileMode)
|
||
|
|
+ assert.NilError(t, err)
|
||
|
|
+ err = os.Truncate(exceededFile.Path(), ExceededImportFileSize)
|
||
|
|
+ assert.NilError(t, err)
|
||
|
|
+ defer tmpFile.Remove()
|
||
|
|
+ defer exceededFile.Remove()
|
||
|
|
+
|
||
|
|
+ type testcase struct {
|
||
|
|
+ name string
|
||
|
|
+ errString string
|
||
|
|
+ args []string
|
||
|
|
+ wantErr bool
|
||
|
|
+ }
|
||
|
|
+ var testcases = []testcase{
|
||
|
|
+ {
|
||
|
|
+ name: "TC1 - abnormal case with no args",
|
||
|
|
+ errString: "requires at least one argument",
|
||
|
|
+ wantErr: true,
|
||
|
|
+ },
|
||
|
|
+ {
|
||
|
|
+ name: "TC2 - abnormal case with exceeded limit input",
|
||
|
|
+ args: []string{exceededFile.Path()},
|
||
|
|
+ errString: "exceeds limit 1073741824",
|
||
|
|
+ wantErr: true,
|
||
|
|
+ },
|
||
|
|
+ {
|
||
|
|
+ name: "TC3 - normal case",
|
||
|
|
+ args: []string{tmpFile.Path()},
|
||
|
|
+ errString: "isula_build.sock",
|
||
|
|
+ wantErr: true,
|
||
|
|
+ },
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ for _, tc := range testcases {
|
||
|
|
+ t.Run(tc.name, func(t *testing.T) {
|
||
|
|
+ importCmd := NewImportCmd()
|
||
|
|
+ err = importCommand(importCmd, tc.args)
|
||
|
|
+ if tc.wantErr {
|
||
|
|
+ assert.ErrorContains(t, err, tc.errString)
|
||
|
|
+ }
|
||
|
|
+ if !tc.wantErr {
|
||
|
|
+ assert.NilError(t, err)
|
||
|
|
+ }
|
||
|
|
+ })
|
||
|
|
+ }
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+func TestRunImport(t *testing.T) {
|
||
|
|
+ ctx := context.Background()
|
||
|
|
+ mockImport := newMockDaemon()
|
||
|
|
+ cli := newMockClient(&mockGrpcClient{importFunc: mockImport.importImage})
|
||
|
|
+ fileEmpty := "empty.tar"
|
||
|
|
+ fileNormal := "test.tar"
|
||
|
|
+ exceededFile := fs.NewFile(t, t.Name())
|
||
|
|
+ err := ioutil.WriteFile(exceededFile.Path(), []byte("This is exceeded test file"), constant.DefaultSharedFileMode)
|
||
|
|
+ assert.NilError(t, err)
|
||
|
|
+ err = os.Truncate(exceededFile.Path(), ExceededImportFileSize)
|
||
|
|
+ assert.NilError(t, err)
|
||
|
|
+ ctxDir := fs.NewDir(t, "import", fs.WithFile(fileEmpty, ""), fs.WithFile(fileNormal, "test"))
|
||
|
|
+ defer ctxDir.Remove()
|
||
|
|
+ defer exceededFile.Remove()
|
||
|
|
+
|
||
|
|
+ type testcase struct {
|
||
|
|
+ name string
|
||
|
|
+ source string
|
||
|
|
+ wantErr bool
|
||
|
|
+ errString string
|
||
|
|
+ }
|
||
|
|
+ var testcases = []testcase{
|
||
|
|
+ {
|
||
|
|
+ name: "TC1 - abnormal case with empty file",
|
||
|
|
+ source: filepath.Join(ctxDir.Path(), fileEmpty),
|
||
|
|
+ wantErr: true,
|
||
|
|
+ errString: "empty",
|
||
|
|
+ },
|
||
|
|
+ {
|
||
|
|
+ name: "TC2 - abnormal case with exceeded limit file",
|
||
|
|
+ source: exceededFile.Path(),
|
||
|
|
+ wantErr: true,
|
||
|
|
+ errString: "limit",
|
||
|
|
+ },
|
||
|
|
+ {
|
||
|
|
+ name: "TC3 - normal case",
|
||
|
|
+ source: filepath.Join(ctxDir.Path(), fileNormal),
|
||
|
|
+ wantErr: false,
|
||
|
|
+ },
|
||
|
|
+ }
|
||
|
|
+ for _, tc := range testcases {
|
||
|
|
+ t.Run(tc.name, func(t *testing.T) {
|
||
|
|
+ importOpts.source = tc.source
|
||
|
|
+ err := runImport(ctx, &cli)
|
||
|
|
+ assert.Equal(t, err != nil, tc.wantErr, "Failed at [%s], err: %v", tc.name, err)
|
||
|
|
+ if err != nil {
|
||
|
|
+ assert.ErrorContains(t, err, tc.errString)
|
||
|
|
+ }
|
||
|
|
+ })
|
||
|
|
+ }
|
||
|
|
+}
|
||
|
|
diff --git a/cmd/cli/mock.go b/cmd/cli/mock.go
|
||
|
|
index 23a8a03..d201fe0 100644
|
||
|
|
--- a/cmd/cli/mock.go
|
||
|
|
+++ b/cmd/cli/mock.go
|
||
|
|
@@ -17,12 +17,14 @@ import (
|
||
|
|
"context"
|
||
|
|
"io"
|
||
|
|
"os"
|
||
|
|
+ "path/filepath"
|
||
|
|
"testing"
|
||
|
|
|
||
|
|
"github.com/gogo/protobuf/types"
|
||
|
|
"github.com/pkg/errors"
|
||
|
|
"google.golang.org/grpc"
|
||
|
|
|
||
|
|
+ constant "isula.org/isula-build"
|
||
|
|
pb "isula.org/isula-build/api/services"
|
||
|
|
)
|
||
|
|
|
||
|
|
@@ -261,7 +263,7 @@ func (icli *mockImportClient) Recv() (*pb.ImportResponse, error) {
|
||
|
|
resp := &pb.ImportResponse{
|
||
|
|
Log: "Import success with image id: " + imageID,
|
||
|
|
}
|
||
|
|
- return resp, nil
|
||
|
|
+ return resp, io.EOF
|
||
|
|
}
|
||
|
|
|
||
|
|
func (icli *mockImportClient) Send(*pb.ImportRequest) error {
|
||
|
|
@@ -313,7 +315,20 @@ func (cli *mockClient) Close() error {
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
-func (f *mockDaemon) importImage(_ context.Context, opts ...grpc.CallOption) (pb.Control_ImportClient, error) {
|
||
|
|
+func (f *mockDaemon) importImage(_ context.Context, in *pb.ImportRequest, opts ...grpc.CallOption) (pb.Control_ImportClient, error) {
|
||
|
|
+ f.importReq = in
|
||
|
|
+ source := f.importReq.Source
|
||
|
|
+ file, err := os.Stat(filepath.Clean(source))
|
||
|
|
+ if err != nil {
|
||
|
|
+ return &mockImportClient{}, err
|
||
|
|
+ }
|
||
|
|
+ if file.Size() == 0 {
|
||
|
|
+ return &mockImportClient{}, errors.Errorf("file %s is empty", file.Name())
|
||
|
|
+ }
|
||
|
|
+ if file.Size() > constant.MaxImportFileSize {
|
||
|
|
+ return &mockImportClient{}, errors.Errorf("file %s size is: %d, exceeds limit", file.Name(), file.Size())
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
return &mockImportClient{}, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
diff --git a/store/store_test.go b/store/store_test.go
|
||
|
|
index d99d871..77a9353 100644
|
||
|
|
--- a/store/store_test.go
|
||
|
|
+++ b/store/store_test.go
|
||
|
|
@@ -36,6 +36,11 @@ func TestGetDefaultStoreOptions(t *testing.T) {
|
||
|
|
assert.NilError(t, err)
|
||
|
|
}
|
||
|
|
|
||
|
|
+func TestGetStorageConfigFileOptions(t *testing.T) {
|
||
|
|
+ _, err := GetStorageConfigFileOptions()
|
||
|
|
+ assert.NilError(t, err)
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
func TestGetStore(t *testing.T) {
|
||
|
|
dataDir := "/tmp/lib"
|
||
|
|
runDir := "/tmp/run"
|
||
|
|
@@ -53,3 +58,25 @@ func TestGetStore(t *testing.T) {
|
||
|
|
assert.Equal(t, s.RunRoot(), storeOpts.RunRoot)
|
||
|
|
assert.Equal(t, s.GraphRoot(), storeOpts.DataRoot)
|
||
|
|
}
|
||
|
|
+
|
||
|
|
+func TestCleanContainers(t *testing.T) {
|
||
|
|
+ dataDir := "/tmp/lib"
|
||
|
|
+ runDir := "/tmp/run"
|
||
|
|
+ storeOpts.DataRoot = filepath.Join(dataDir, "containers/storage")
|
||
|
|
+ storeOpts.RunRoot = filepath.Join(runDir, "containers/storage")
|
||
|
|
+
|
||
|
|
+ s, err := GetStore()
|
||
|
|
+ assert.NilError(t, err)
|
||
|
|
+ s.CreateContainer("", []string{""}, "", "", "", nil)
|
||
|
|
+ s.CleanContainers()
|
||
|
|
+ containers, _ := s.Containers()
|
||
|
|
+ if len(containers) > 0 {
|
||
|
|
+ t.Errorf("Failed to clean containers")
|
||
|
|
+ }
|
||
|
|
+ defer func() {
|
||
|
|
+ unix.Unmount(filepath.Join(storeOpts.DataRoot, "overlay"), 0)
|
||
|
|
+ unix.Unmount(filepath.Join(storeOpts.RunRoot, "overlay"), 0)
|
||
|
|
+ os.RemoveAll(dataDir)
|
||
|
|
+ os.RemoveAll(runDir)
|
||
|
|
+ }()
|
||
|
|
+}
|
||
|
|
--
|
||
|
|
2.33.0
|
||
|
|
|