提交 4be7fbaf 编写于 作者: D DCCooper

tests: add more go tests for the project

Signed-off-by: NDCCooper <1866858@gmail.com>
上级 6b90e6de
......@@ -15,6 +15,7 @@ package main
import (
"context"
"errors"
"io/ioutil"
"os"
"path/filepath"
......@@ -54,6 +55,8 @@ type mockDaemon struct {
statusReq *pb.StatusRequest
removeReq *pb.RemoveRequest
loadReq *pb.LoadRequest
loginReq *pb.LoginRequest
logoutReq *pb.LogoutRequest
}
func newMockDaemon() *mockDaemon {
......@@ -85,6 +88,28 @@ func (f *mockDaemon) remove(_ context.Context, in *pb.RemoveRequest, opts ...grp
return &mockRemoveClient{}, nil
}
func (f *mockDaemon) login(_ context.Context, in *pb.LoginRequest, opts ...grpc.CallOption) (*pb.LoginResponse, error) {
f.loginReq = in
serverLen := len(f.loginReq.Server)
if serverLen == 0 || serverLen > 128 {
return &pb.LoginResponse{
Content: "Login Failed",
}, errors.New("empty server address")
}
return &pb.LoginResponse{Content: "Success"}, nil
}
func (f *mockDaemon) logout(_ context.Context, in *pb.LogoutRequest, opts ...grpc.CallOption) (*pb.LogoutResponse, error) {
f.logoutReq = in
serverLen := len(f.logoutReq.Server)
if serverLen == 0 || serverLen > 128 {
return &pb.LogoutResponse{Result: "Logout Failed"}, errors.New("empty server address")
}
return &pb.LogoutResponse{Result: "Success"}, nil
}
func TestRunBuildWithLocalDockerfile(t *testing.T) {
dockerfile := `
FROM alpine:latest
......
......@@ -103,8 +103,11 @@ func getStartTimeout(timeout string) (time.Duration, error) {
return defaultStartTimeout, nil
}
timeParse, err := time.ParseDuration(timeout)
if err != nil || timeParse < minStartTimeout || timeParse > maxStartTimeout {
return -1, errors.Wrapf(err, "invalid timeout value: %s, supported range [%s, %s]", timeout, minStartTimeout, maxStartTimeout)
if err != nil {
return -1, err
}
if timeParse < minStartTimeout || timeParse > maxStartTimeout {
return -1, errors.Errorf("invalid timeout value: %s, supported range [%s, %s]", timeout, minStartTimeout, maxStartTimeout)
}
return timeParse, nil
}
......
......@@ -16,6 +16,8 @@ package main
import (
"context"
"io"
"testing"
"time"
types "github.com/gogo/protobuf/types"
"google.golang.org/grpc"
......@@ -98,10 +100,10 @@ func (gcli *mockGrpcClient) Login(ctx context.Context, in *pb.LoginRequest, opts
}
func (gcli *mockGrpcClient) Logout(ctx context.Context, in *pb.LogoutRequest, opts ...grpc.CallOption) (*pb.LogoutResponse, error) {
if gcli.loginFunc != nil {
if gcli.logoutFunc != nil {
return gcli.logoutFunc(ctx, in, opts...)
}
return nil, nil
return &pb.LogoutResponse{Result: "Success Logout"}, nil
}
func (gcli *mockGrpcClient) Load(ctx context.Context, in *pb.LoadRequest, opts ...grpc.CallOption) (*pb.LoadResponse, error) {
......@@ -148,3 +150,58 @@ func (rcli *mockRemoveClient) Recv() (*pb.RemoveResponse, error) {
}
return resp, io.EOF
}
func TestGetStartTimeout(t *testing.T) {
type args struct {
timeout string
}
tests := []struct {
name string
args args
want time.Duration
wantErr bool
}{
{
name: "TC1 - normal case",
args: args{timeout: "1s"},
want: time.Second,
wantErr: false,
},
{
name: "TC2 - normal case with empty timeout input",
args: args{timeout: ""},
want: defaultStartTimeout,
wantErr: false,
},
{
name: "TC3 - abnormal case with larger than max start timeout",
args: args{timeout: "21s"},
want: -1,
wantErr: true,
},
{
name: "TC4 - abnormal case with less than min start timeout",
args: args{timeout: "19ms"},
want: -1,
wantErr: true,
},
{
name: "TC5 - abnormal case with invalid timeout format",
args: args{timeout: "abc"},
want: -1,
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := getStartTimeout(tt.args.timeout)
if (err != nil) != tt.wantErr {
t.Errorf("getStartTimeout() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("getStartTimeout() got = %v, want %v", got, tt.want)
}
})
}
}
......@@ -18,6 +18,7 @@ import (
"context"
"crypto/sha256"
"fmt"
"io"
"os"
"strings"
......@@ -45,6 +46,7 @@ var (
errEmptyRegistry = errors.New("empty registry found, please input one registry")
errTooManyArgs = errors.New("too many arguments, login only accepts 1 argument")
errLackOfFlags = errors.New("must provides --password-stdin with --username")
loginOpts loginOptions
)
type loginOptions struct {
......@@ -55,7 +57,7 @@ type loginOptions struct {
stdinPass bool
}
var loginOpts loginOptions
type passReader func() ([]byte, error)
// NewLoginCmd returns login command
func NewLoginCmd() *cobra.Command {
......@@ -170,20 +172,23 @@ func getPassword(c *cobra.Command) error {
}
if loginOpts.stdinPass {
if err := getPassFromStdin(); err != nil {
if err := getPassFromStdin(os.Stdin); err != nil {
return err
}
} else {
if err := getPassFromInput(); err != nil {
r := func() ([]byte, error) {
return terminal.ReadPassword(0)
}
if err := getPassFromInput(r); err != nil {
return err
}
}
return nil
}
func getPassFromInput() error {
func getPassFromInput(f passReader) error {
fmt.Print("Password: ")
termPass, err := terminal.ReadPassword(0)
termPass, err := f()
if err != nil {
return errReadPassFromTerm
}
......@@ -196,9 +201,9 @@ func getPassFromInput() error {
return nil
}
func getPassFromStdin() error {
func getPassFromStdin(r io.Reader) error {
var buf strings.Builder
passScanner := bufio.NewScanner(os.Stdin)
passScanner := bufio.NewScanner(r)
for passScanner.Scan() {
if _, err := fmt.Fprint(&buf, passScanner.Text()); err != nil {
return err
......
// 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: Xiang Li
// Create: 2020-07-20
// Description: This file is used for testing command login
package main
import (
"bytes"
"context"
"errors"
"fmt"
"io"
"strings"
"testing"
"github.com/spf13/cobra"
"gotest.tools/assert"
)
func TestNewLoginCmd(t *testing.T) {
loginCmd := NewLoginCmd()
loginCmd.SetArgs(strings.Split("test.org --username testuser --password-stdin", " "))
err := loginCmd.Execute()
args := []string{"test.org"}
err = loginCommand(loginCmd, args)
if err != nil {
assert.ErrorContains(t, err, "auth info can not be empty")
}
}
func TestGetPassFromInput(t *testing.T) {
type args struct {
f passReader
}
tests := []struct {
name string
args args
wantErr bool
}{
{
name: "TC1 - normal input",
args: args{f: func() ([]byte, error) {
return []byte("aaa"), nil
}},
wantErr: false,
},
{
name: "TC2 - abnormal input with error",
args: args{f: func() ([]byte, error) {
return nil, errors.New("error read password")
}},
wantErr: true,
},
{
name: "TC3 - abnormal input with length more than 128",
args: args{func() ([]byte, error) {
return bytes.Repeat([]byte("a"), 129), nil
}},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := getPassFromInput(tt.args.f); (err != nil) != tt.wantErr {
t.Errorf("getPassFromInput() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
func TestGetPassFromStdin(t *testing.T) {
type args struct {
r io.Reader
}
tests := []struct {
name string
args args
wantErr bool
}{
{
name: "TC1 - normal input",
args: args{r: strings.NewReader("aaa")},
wantErr: false,
},
{
name: "TC2 - empty input",
args: args{r: strings.NewReader("")},
wantErr: true,
},
{
name: "TC2 - abnormal input length",
args: args{r: strings.NewReader(string(bytes.Repeat([]byte("a"), 129)))},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := getPassFromStdin(tt.args.r); (err != nil) != tt.wantErr {
t.Errorf("getPassFromStdin() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
func TestEncryptOpts(t *testing.T) {
err := encryptOpts()
assert.NilError(t, err)
}
func TestRunLogin(t *testing.T) {
type testcase struct {
name string
server string
errString string
wantErr bool
}
var testcases = []testcase{
{
name: "TC1 - normal case",
server: "test.org",
wantErr: false,
},
{
name: "TC2 - abnormal case with empty server",
server: "",
wantErr: true,
errString: "empty server address",
},
}
for _, tc := range testcases {
ctx := context.Background()
mockD := newMockDaemon()
cli := newMockClient(&mockGrpcClient{loginFunc: mockD.login})
loginOpts.server = tc.server
_, err := runLogin(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)
}
}
}
func TestNewLoginOptions(t *testing.T) {
type args struct {
c *cobra.Command
args []string
}
type flags struct {
username string
passStdin bool
}
tests := []struct {
name string
args args
flags flags
errString string
}{
{
name: "TC1 - normal case",
args: args{
c: NewLoginCmd(),
args: []string{"test.org -u testuser"},
},
flags: flags{
username: "aaa",
passStdin: true,
},
errString: "auth info can not be empty",
},
{
name: "TC2 - abnormal case with out username flag",
args: args{
c: NewLoginCmd(),
args: []string{"test.org"},
},
flags: flags{
passStdin: true,
},
errString: "",
},
{
name: "TC3 - abnormal case with invalid args",
args: args{
c: NewLoginCmd(),
args: []string{"a", "b"},
},
errString: "too many arguments, login only accepts 1 argument",
},
{
name: "TC4 - abnormal case with empty args",
args: args{
c: NewLoginCmd(),
args: []string{},
},
errString: "empty registry found",
},
{
name: "TC5 - abnormal case with empty args",
args: args{
c: NewLoginCmd(),
args: []string{"/aaaa"},
},
errString: "invalid registry address",
},
{
name: "TC6 - abnormal case with long username",
args: args{
c: NewLoginCmd(),
args: []string{"test.org"},
},
flags: flags{
username: strings.Repeat("a", 129),
passStdin: true,
},
errString: "length of input exceeded",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.flags.passStdin {
tt.args.c.Flag("password-stdin").Changed = true
tt.args.c.Flag("password-stdin").Value.Set(fmt.Sprintf("%v", tt.flags.passStdin))
}
if tt.flags.username != "" {
tt.args.c.Flag("username").Changed = true
tt.args.c.Flag("username").Value.Set(tt.flags.username)
}
tt.args.c.ParseFlags(tt.args.args)
err := newLoginOptions(tt.args.c, tt.args.args)
if err != nil {
assert.ErrorContains(t, err, tt.errString)
}
})
}
}
// 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: Xiang Li
// Create: 2020-07-20
// Description: This file is used for testing command logout
package main
import (
"context"
"strings"
"testing"
"github.com/spf13/cobra"
"gotest.tools/assert"
)
func TestRunLogout(t *testing.T) {
type testcase struct {
name string
all bool
server string
errString string
wantErr bool
}
var testcases = []testcase{
{
name: "TC1 - normal case",
all: false,
server: "test.org",
wantErr: false,
},
{
name: "TC2 - normal case with -a flag",
all: true,
server: "test.org",
wantErr: false,
},
{
name: "TC3 - abnormal case with empty server name",
all: false,
server: "",
wantErr: true,
},
{
name: "TC4 - abnormal case with empty server name and -a flag",
all: true,
server: "",
wantErr: true,
},
{
name: "TC5 - abnormal case with server name larger than 128",
all: true,
server: strings.Repeat("a", 129),
wantErr: true,
},
}
for _, tc := range testcases {
ctx := context.Background()
mockD := newMockDaemon()
cli := newMockClient(&mockGrpcClient{logoutFunc: mockD.logout})
logoutOpts.all = tc.all
logoutOpts.server = tc.server
_, err := runLogout(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)
}
}
}
func TestNewLogoutOptions(t *testing.T) {
type args struct {
c *cobra.Command
args []string
}
tests := []struct {
name string
args args
flag string
wantErr bool
}{
{
name: "TC1 - normal case",
args: args{
c: NewLogoutCmd(),
args: []string{"test.org"},
},
flag: "--all",
wantErr: false,
},
{
name: "TC2 - abnormal case with empty server",
args: args{
c: NewLogoutCmd(),
args: []string{},
},
wantErr: true,
},
{
name: "TC3 - abnormal case with more than one args",
args: args{
c: NewLogoutCmd(),
args: []string{"a", "b"},
},
wantErr: true,
},
{
name: "TC4 - abnormal case with invalid server address",
args: args{
c: NewLogoutCmd(),
args: []string{"/aaaaaa"},
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.flag != "" {
tt.args.c.Flag("all").Changed = true
}
if err := newLogoutOptions(tt.args.c, tt.args.args); (err != nil) != tt.wantErr {
t.Errorf("newLogoutOptions() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
func TestNewLogoutCmd(t *testing.T) {
tests := []struct {
name string
args string
errString string
}{
{
name: "TC1 - normal case",
args: "test.org",
errString: "isula_build.sock",
},
{
name: "TC2 - abnormal case with invalid args",
args: "test.org a b",
errString: "too many arguments",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cmd := NewLogoutCmd()
cmd.SetArgs(strings.Split(tt.args, " "))
err := cmd.Execute()
if err != nil {
}
assert.ErrorContains(t, err, tt.errString)
})
}
}
// Copyright (c) Huawei Technologies Co., Ltd. 2020. All rights reserved.
// iSula-Kits 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: Xiang Li
// Create: 2020-07-20
// Description: This file is used for testing port setting
package util
import (
"testing"
)
func TestPortSet(t *testing.T) {
type args struct {
rawPort string
}
tests := []struct {
name string
args args
want string
wantErr bool
}{
{
name: "TC1 - normal case",
args: args{rawPort: "8080"},
want: "8080/tcp",
wantErr: false,
},
{
name: "TC2 - normal case",
args: args{rawPort: "8080/"},
want: "8080/tcp",
wantErr: false,
},
{
name: "TC3 - abnormal case with invalid port format",
args: args{rawPort: "aaa"},
want: "",
wantErr: true,
},
{
name: "TC4 - normal case with port range",
args: args{rawPort: "3000-5000/udp"},
want: "3000-5000/udp",
wantErr: false,
},
{
name: "TC5 - abnormal case with invalid port range",
args: args{rawPort: "3000-500/udp"},
want: "",
wantErr: true,
},
{
name: "TC6 - abnormal case with invalid port range number",
args: args{rawPort: "a-b/udp"},
want: "",
wantErr: true,
},
{
name: "TC7 - abnormal case with invalid port range numbers",
args: args{rawPort: "3000-5000-8000/udp"},
want: "",
wantErr: true,
},
{
name: "TC8 - abnormal case with empty port",
args: args{rawPort: ""},
want: "",
wantErr: true,
},
{
name: "TC9 - abnormal case with invalid protocol",
args: args{rawPort: "80/abc"},
want: "",
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := PortSet(tt.args.rawPort)
if (err != nil) != tt.wantErr {
t.Errorf("PortSet() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("PortSet() got = %v, want %v", got, tt.want)
}
})
}
}
......@@ -233,3 +233,58 @@ func TestCopyXattrs(t *testing.T) {
}
}
func TestValidateSignal(t *testing.T) {
type args struct {
sigStr string
}
tests := []struct {
name string
args args
want syscall.Signal
wantErr bool
}{
{
name: "TC1 - normal case with integer",
args: args{sigStr: "9"},
want: syscall.Signal(9),
wantErr: false,
},
{
name: "TC2 - normal case with signal name",
args: args{sigStr: "SIGKILL"},
want: syscall.Signal(9),
wantErr: false,
},
{
name: "TC3 - abnormal case with invalid signal name",
args: args{sigStr: "aaa"},
want: -1,
wantErr: true,
},
{
name: "TC4 - abnormal case with invalid signal value",
args: args{sigStr: "65"},
want: -1,
wantErr: true,
},
{
name: "TC5 - abnormal case with invalid signal value",
args: args{sigStr: "0"},
want: -1,
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := ValidateSignal(tt.args.sigStr)
if (err != nil) != tt.wantErr {
t.Errorf("ValidateSignal() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("ValidateSignal() got = %v, want %v", got, tt.want)
}
})
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册