constellation/cli/cmd/verify_test.go
2022-05-04 08:07:14 +02:00

190 lines
5.5 KiB
Go

package cmd
import (
"bytes"
"context"
"encoding/base64"
"errors"
"testing"
"github.com/edgelesssys/constellation/cli/cloudprovider"
"github.com/edgelesssys/constellation/cli/file"
"github.com/spf13/afero"
"github.com/spf13/cobra"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"google.golang.org/grpc/codes"
rpcStatus "google.golang.org/grpc/status"
)
func TestVerifyCmdArgumentValidation(t *testing.T) {
testCases := map[string]struct {
args []string
wantErr bool
}{
"no args": {[]string{}, true},
"valid azure": {[]string{"azure", "192.0.2.1", "1234"}, false},
"valid gcp": {[]string{"gcp", "192.0.2.1", "1234"}, false},
"invalid provider": {[]string{"invalid", "192.0.2.1", "1234"}, true},
"invalid ip": {[]string{"gcp", "invalid", "1234"}, true},
"invalid port": {[]string{"gcp", "192.0.2.1", "invalid"}, true},
"invalid port 2": {[]string{"gcp", "192.0.2.1", "65536"}, true},
"not enough arguments": {[]string{"gcp", "192.0.2.1"}, true},
"too many arguments": {[]string{"gcp", "192.0.2.1", "1234", "5678"}, true},
}
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
assert := assert.New(t)
cmd := newVerifyCmd()
err := cmd.ValidateArgs(tc.args)
if tc.wantErr {
assert.Error(err)
} else {
assert.NoError(err)
}
})
}
}
func TestVerify(t *testing.T) {
zeroBase64 := base64.StdEncoding.EncodeToString([]byte("00000000000000000000000000000000"))
someErr := errors.New("failed")
testCases := map[string]struct {
setupFs func(*require.Assertions) afero.Fs
provider cloudprovider.Provider
protoClient protoClient
devConfigFlag string
ownerIDFlag string
clusterIDFlag string
wantErr bool
}{
"gcp": {
setupFs: func(require *require.Assertions) afero.Fs { return afero.NewMemMapFs() },
provider: cloudprovider.GCP,
ownerIDFlag: zeroBase64,
protoClient: &stubProtoClient{},
},
"azure": {
setupFs: func(require *require.Assertions) afero.Fs { return afero.NewMemMapFs() },
provider: cloudprovider.Azure,
ownerIDFlag: zeroBase64,
protoClient: &stubProtoClient{},
},
"neither owner id nor cluster id set": {
setupFs: func(require *require.Assertions) afero.Fs { return afero.NewMemMapFs() },
provider: cloudprovider.GCP,
wantErr: true,
},
"dev config file not existing": {
setupFs: func(require *require.Assertions) afero.Fs { return afero.NewMemMapFs() },
provider: cloudprovider.GCP,
ownerIDFlag: zeroBase64,
devConfigFlag: "./file",
wantErr: true,
},
"error protoClient Connect": {
setupFs: func(require *require.Assertions) afero.Fs { return afero.NewMemMapFs() },
provider: cloudprovider.Azure,
ownerIDFlag: zeroBase64,
protoClient: &stubProtoClient{connectErr: someErr},
wantErr: true,
},
"error protoClient GetState": {
setupFs: func(require *require.Assertions) afero.Fs { return afero.NewMemMapFs() },
provider: cloudprovider.Azure,
ownerIDFlag: zeroBase64,
protoClient: &stubProtoClient{getStateErr: rpcStatus.Error(codes.Internal, "failed")},
wantErr: true,
},
"error protoClient GetState not rpc": {
setupFs: func(require *require.Assertions) afero.Fs { return afero.NewMemMapFs() },
provider: cloudprovider.Azure,
ownerIDFlag: zeroBase64,
protoClient: &stubProtoClient{getStateErr: someErr},
wantErr: true,
},
}
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
assert := assert.New(t)
require := require.New(t)
cmd := newVerifyCmd()
cmd.Flags().String("dev-config", "", "") // register persisten flag manually
out := &bytes.Buffer{}
cmd.SetOut(out)
cmd.SetErr(&bytes.Buffer{})
if tc.devConfigFlag != "" {
require.NoError(cmd.Flags().Set("dev-config", tc.devConfigFlag))
}
if tc.ownerIDFlag != "" {
require.NoError(cmd.Flags().Set("owner-id", tc.ownerIDFlag))
}
if tc.clusterIDFlag != "" {
require.NoError(cmd.Flags().Set("cluster-id", tc.clusterIDFlag))
}
fileHandler := file.NewHandler(tc.setupFs(require))
ctx := context.Background()
err := verify(ctx, cmd, tc.provider, "192.0.2.1", "1234", fileHandler, tc.protoClient)
if tc.wantErr {
assert.Error(err)
} else {
assert.NoError(err)
assert.Contains(out.String(), "OK")
}
})
}
}
func TestVerifyCompletion(t *testing.T) {
testCases := map[string]struct {
args []string
toComplete string
wantResult []string
wantShellCD cobra.ShellCompDirective
}{
"first arg": {
args: []string{},
toComplete: "az",
wantResult: []string{"gcp", "azure"},
wantShellCD: cobra.ShellCompDirectiveNoFileComp,
},
"second arg": {
args: []string{"gcp"},
toComplete: "192.0.2.1",
wantResult: []string{},
wantShellCD: cobra.ShellCompDirectiveNoFileComp,
},
"third arg": {
args: []string{"gcp", "192.0.2.1"},
toComplete: "443",
wantResult: []string{},
wantShellCD: cobra.ShellCompDirectiveNoFileComp,
},
"additional arg": {
args: []string{"gcp", "192.0.2.1", "443"},
toComplete: "./file",
wantResult: []string{},
wantShellCD: cobra.ShellCompDirectiveError,
},
}
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
assert := assert.New(t)
cmd := &cobra.Command{}
result, shellCD := verifyCompletion(cmd, tc.args, tc.toComplete)
assert.Equal(tc.wantResult, result)
assert.Equal(tc.wantShellCD, shellCD)
})
}
}