From 11fbc841b5af5ff4dd5ac228c033a49cac742aad Mon Sep 17 00:00:00 2001 From: daisicheng Date: Fri, 25 Nov 2022 17:40:33 +0800 Subject: [PATCH] add login_test, logout_test, remove_test and import_test in daemon --- cmd/cli/build_test.go | 40 ++++++++++++++++ daemon/import_test.go | 87 +++++++++++++++++++++++++++++++++++ daemon/login_test.go | 103 ++++++++++++++++++++++++++++++++++++++++++ daemon/logout_test.go | 75 ++++++++++++++++++++++++++++++ daemon/pull_test.go | 7 ++- daemon/remove_test.go | 101 +++++++++++++++++++++++++++++++++++++++++ daemon/tag_test.go | 73 ++++++++++++++++++++++++++++++ 7 files changed, 485 insertions(+), 1 deletion(-) create mode 100644 daemon/import_test.go create mode 100644 daemon/login_test.go create mode 100644 daemon/logout_test.go create mode 100644 daemon/remove_test.go create mode 100644 daemon/tag_test.go diff --git a/cmd/cli/build_test.go b/cmd/cli/build_test.go index d446801..41cabbe 100644 --- a/cmd/cli/build_test.go +++ b/cmd/cli/build_test.go @@ -29,6 +29,46 @@ import ( "isula.org/isula-build/util" ) +func TestBuildCommand(t *testing.T) { + dockerfile := `` + filename := "Dockerfile" + tmpDir := fs.NewDir(t, t.Name(), fs.WithFile(filename, dockerfile)) + defer tmpDir.Remove() + + type testcase struct { + name string + file string + args []string + wanterr bool + errString string + } + var testcases = []testcase{ + { + name: "TC1 - normal case", + file: tmpDir.Path(), + args: []string{tmpDir.Path()}, + wanterr: true, + errString: "isula_build.sock", + }, + } + + for _, tc := range testcases { + t.Run(tc.name, func(t *testing.T) { + buildCmd := NewBuildCmd() + err := buildCmd.Execute() + assert.Equal(t, err != nil, true) + + err = buildCommand(buildCmd, tc.args) + if tc.wanterr { + assert.ErrorContains(t, err, tc.errString) + } + if !tc.wanterr { + assert.NilError(t, err) + } + }) + } +} + func TestRunBuildWithLocalDockerfile(t *testing.T) { dockerfile := ` FROM alpine:latest diff --git a/daemon/import_test.go b/daemon/import_test.go new file mode 100644 index 0000000..1a24eb4 --- /dev/null +++ b/daemon/import_test.go @@ -0,0 +1,87 @@ +// 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-12-01 +// Description: This file tests import interface. + +package daemon + +import ( + "context" + "io/ioutil" + "testing" + + "github.com/pkg/errors" + "google.golang.org/grpc" + "gotest.tools/v3/assert" + "gotest.tools/v3/fs" + + constant "isula.org/isula-build" + pb "isula.org/isula-build/api/services" + "isula.org/isula-build/util" +) + +type controlImportServer struct { + grpc.ServerStream +} + +func (c *controlImportServer) Send(response *pb.ImportResponse) error { + if response.Log == "error" { + return errors.New("error happened") + } + return nil +} + +func (c *controlImportServer) Context() context.Context { + return context.Background() +} + +func TestImport(t *testing.T) { + d := prepare(t) + defer tmpClean(d) + + tmpFile := fs.NewFile(t, t.Name()) + defer tmpFile.Remove() + err := ioutil.WriteFile(tmpFile.Path(), []byte("This is test file"), constant.DefaultSharedFileMode) + assert.NilError(t, err) + importID := util.GenerateNonCryptoID()[:constant.DefaultIDLen] + + testcases := []struct { + name string + req *pb.ImportRequest + wantErr bool + errString string + }{ + { + name: "TC1 - normal case", + req: &pb.ImportRequest{ + ImportID: importID, + Source: tmpFile.Path(), + Reference: "test:image", + }, + wantErr: true, + errString: "Error processing tar file", + }, + } + + for _, tc := range testcases { + t.Run(tc.name, func(t *testing.T) { + stream := &controlImportServer{} + err := d.Daemon.backend.Import(tc.req, stream) + if tc.wantErr == true { + assert.ErrorContains(t, err, tc.errString) + } + if tc.wantErr == false { + assert.NilError(t, err) + } + }) + } + +} diff --git a/daemon/login_test.go b/daemon/login_test.go new file mode 100644 index 0000000..b8ae002 --- /dev/null +++ b/daemon/login_test.go @@ -0,0 +1,103 @@ +// 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-12-01 +// Description: This file tests login interface. + +package daemon + +import ( + "context" + "crypto/sha512" + "testing" + + "gotest.tools/v3/assert" + + pb "isula.org/isula-build/api/services" + "isula.org/isula-build/util" +) + +func TestLogin(t *testing.T) { + d := prepare(t) + defer tmpClean(d) + + encryptKey, err := util.EncryptRSA("testpassword", d.Daemon.backend.daemon.key.PublicKey, sha512.New()) + assert.NilError(t, err) + testcases := []struct { + name string + req *pb.LoginRequest + wantErr bool + errString string + }{ + { + name: "TC1 - normal case with abnormal password", + req: &pb.LoginRequest{ + Server: "testcase.org", + Username: "testuser", + Password: "decfabdc", + }, + wantErr: true, + errString: "decryption failed", + }, + { + name: "TC2 - normal case with abnormal registry", + req: &pb.LoginRequest{ + Server: "testcase.org", + Username: "testuser", + Password: encryptKey, + }, + wantErr: true, + errString: "no route to host", + }, + { + name: "TC3 - abnormal case with empty server", + req: &pb.LoginRequest{ + Server: "", + Username: "testuser", + Password: "testpassword", + }, + wantErr: true, + errString: "empty server address", + }, + { + name: "TC4 - abnormal case with empty password", + req: &pb.LoginRequest{ + Server: "test.org", + Username: "testuser", + Password: "", + }, + wantErr: true, + errString: "empty auth info", + }, + { + name: "TC5 - abnormal case with empty password and username", + req: &pb.LoginRequest{ + Server: "test.org", + Username: "", + Password: "", + }, + wantErr: true, + errString: "failed to read auth file", + }, + } + + for _, tc := range testcases { + t.Run(tc.name, func(t *testing.T) { + ctx := context.TODO() + _, err := d.Daemon.backend.Login(ctx, tc.req) + if tc.wantErr == true { + assert.ErrorContains(t, err, tc.errString) + } + if tc.wantErr == false { + assert.NilError(t, err) + } + }) + } +} diff --git a/daemon/logout_test.go b/daemon/logout_test.go new file mode 100644 index 0000000..58f00b3 --- /dev/null +++ b/daemon/logout_test.go @@ -0,0 +1,75 @@ +// 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-11-29 +// Description: This file tests logout interface. + +package daemon + +import ( + "context" + "testing" + + "gotest.tools/v3/assert" + + pb "isula.org/isula-build/api/services" +) + +func TestLogout(t *testing.T) { + d := prepare(t) + defer tmpClean(d) + + testcases := []struct { + name string + req *pb.LogoutRequest + wantErr bool + errString string + }{ + { + name: "TC1 - normal case", + req: &pb.LogoutRequest{ + Server: "test.org", + All: true, + }, + wantErr: false, + }, + { + name: "TC2 - abnormal case with empty server", + req: &pb.LogoutRequest{ + Server: "", + All: false, + }, + wantErr: true, + errString: "empty server address", + }, + { + name: "TC3 - abnormal case with no logined registry", + req: &pb.LogoutRequest{ + Server: "test.org", + All: false, + }, + wantErr: true, + errString: "not logged in", + }, + } + + for _, tc := range testcases { + t.Run(tc.name, func(t *testing.T) { + ctx := context.TODO() + _, err := d.Daemon.backend.Logout(ctx, tc.req) + if tc.wantErr == true { + assert.ErrorContains(t, err, tc.errString) + } + if tc.wantErr == false { + assert.NilError(t, err) + } + }) + } +} diff --git a/daemon/pull_test.go b/daemon/pull_test.go index 27a4d6e..b296bfd 100644 --- a/daemon/pull_test.go +++ b/daemon/pull_test.go @@ -34,6 +34,7 @@ import ( _ "isula.org/isula-build/exporter/docker" "isula.org/isula-build/pkg/logger" "isula.org/isula-build/store" + "isula.org/isula-build/util" ) type daemonTestOptions struct { @@ -75,10 +76,14 @@ func prepare(t *testing.T) daemonTestOptions { DataRoot: dOpt.RootDir + "/data", RunRoot: dOpt.RootDir + "/run", }) - localStore, _ := store.GetStore() + localStore, err := store.GetStore() + assert.NilError(t, err) + localKey, err := util.GenerateRSAKey(util.DefaultRSAKeySize) + assert.NilError(t, err) dOpt.Daemon = &Daemon{ opts: opt, localStore: &localStore, + key: localKey, } dOpt.Daemon.NewBackend() return dOpt diff --git a/daemon/remove_test.go b/daemon/remove_test.go new file mode 100644 index 0000000..fc0f007 --- /dev/null +++ b/daemon/remove_test.go @@ -0,0 +1,101 @@ +// 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-12-02 +// Description: This file tests remove interface. + +package daemon + +import ( + "context" + "testing" + + "github.com/containers/storage" + "github.com/containers/storage/pkg/stringid" + "github.com/pkg/errors" + "google.golang.org/grpc" + "gotest.tools/v3/assert" + + pb "isula.org/isula-build/api/services" +) + +type controlRemoveServer struct { + grpc.ServerStream +} + +func (c *controlRemoveServer) Send(response *pb.RemoveResponse) error { + if response.LayerMessage == "error" { + return errors.New("error happened") + } + return nil +} + +func (c *controlRemoveServer) Context() context.Context { + return context.Background() +} + +func TestRemove(t *testing.T) { + d := prepare(t) + defer tmpClean(d) + + options := &storage.ImageOptions{} + testImg := make([]string, 0) + testImg1, err := d.Daemon.localStore.CreateImage(stringid.GenerateRandomID(), []string{"test:image1"}, "", "", options) + if err != nil { + t.Fatalf("create image with error: %v", err) + } + d.Daemon.localStore.SetNames(testImg1.ID, append(testImg1.Names, "test:image1-backup")) + testImg = append(testImg, testImg1.ID) + testImg2, err := d.Daemon.localStore.CreateImage(stringid.GenerateRandomID(), []string{"test:image2"}, "", "", options) + if err != nil { + t.Fatalf("create image with error: %v", err) + } + testImg = append(testImg, testImg2.ID) + + testcases := []struct { + name string + req *pb.RemoveRequest + wantErr bool + errString string + }{ + { + name: "TC1 - normal case", + req: &pb.RemoveRequest{ + ImageID: testImg, + All: true, + Prune: false, + }, + wantErr: false, + }, + { + name: "TC2 - abnormal case with no images", + req: &pb.RemoveRequest{ + ImageID: []string{""}, + All: false, + Prune: false, + }, + wantErr: true, + errString: "remove one or more images failed", + }, + } + + for _, tc := range testcases { + t.Run(tc.name, func(t *testing.T) { + stream := &controlRemoveServer{} + err := d.Daemon.backend.Remove(tc.req, stream) + if tc.wantErr == true { + assert.ErrorContains(t, err, tc.errString) + } + if tc.wantErr == false { + assert.NilError(t, err) + } + }) + } +} diff --git a/daemon/tag_test.go b/daemon/tag_test.go new file mode 100644 index 0000000..07ad9ee --- /dev/null +++ b/daemon/tag_test.go @@ -0,0 +1,73 @@ +// 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-12-04 +// Description: This file tests tag interface. + +package daemon + +import ( + "context" + "testing" + + "github.com/containers/storage" + "github.com/containers/storage/pkg/stringid" + "gotest.tools/v3/assert" + + pb "isula.org/isula-build/api/services" +) + +func TestTag(t *testing.T) { + d := prepare(t) + defer tmpClean(d) + + options := &storage.ImageOptions{} + _, err := d.Daemon.localStore.CreateImage(stringid.GenerateRandomID(), []string{"test:image"}, "", "", options) + if err != nil { + t.Fatalf("create image with error: %v", err) + } + testcases := []struct { + name string + req *pb.TagRequest + wantErr bool + errString string + }{ + { + name: "TC1 - normal case", + req: &pb.TagRequest{ + Image: "test:image", + Tag: "image-backup", + }, + wantErr: false, + }, + { + name: "TC2 - abnormal case with no existed images", + req: &pb.TagRequest{ + Image: "", + Tag: "image-backup", + }, + wantErr: true, + errString: "repository name must have at least one component", + }, + } + + for _, tc := range testcases { + t.Run(tc.name, func(t *testing.T) { + ctx := context.TODO() + _, err := d.Daemon.backend.Tag(ctx, tc.req) + if tc.wantErr == true { + assert.ErrorContains(t, err, tc.errString) + } + if tc.wantErr == false { + assert.NilError(t, err) + } + }) + } +} -- 2.33.0