Files
kubevela/pkg/test/cli.go
2020-08-07 15:08:35 +08:00

124 lines
3.1 KiB
Go

package test
import (
"context"
"strings"
"testing"
"gotest.tools/assert"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
cmdutil "github.com/cloud-native-application/rudrx/pkg/cmd/util"
"github.com/spf13/cobra"
)
// CliTest test engine
type CliTest interface {
Run()
}
// InitResources resource to init before run testing
type InitResources struct {
Create []runtime.Object
Update []runtime.Object
}
// CliTestCase is testing case for cli
type CliTestCase struct {
// Resources to init
Resources InitResources
// ExpectedExistResources expected exist resources
ExpectedExistResources []runtime.Object
// ExpectedResources expected resources exist and equal
ExpectedResources []runtime.Object
// WantException expected exit with error
WantException bool
// ExpectedOutput output equal to
ExpectedOutput string
// ExpectedString output contains strings
ExpectedString string
Args []string
// Namespaces to run
Namespaces string
}
type clitestImpl struct {
cases map[string]*CliTestCase
t *testing.T
scheme *runtime.Scheme
command func(c client.Client, ioStreams cmdutil.IOStreams, args []string) *cobra.Command
}
// NewCliTest return cli testimpl
func NewCliTest(t *testing.T, scheme *runtime.Scheme,
command func(c client.Client, ioStreams cmdutil.IOStreams,
args []string) *cobra.Command, cases map[string]*CliTestCase) CliTest {
return &clitestImpl{
cases: cases,
t: t,
scheme: scheme,
command: command,
}
}
// Run testing
func (c *clitestImpl) Run() {
for name, tc := range c.cases {
c.t.Run(name, func(t *testing.T) {
fakeClient := fake.NewFakeClientWithScheme(c.scheme)
iostream, _, outPut, _ := cmdutil.NewTestIOStreams()
// init resources
if len(tc.Resources.Create) != 0 {
for _, resource := range tc.Resources.Create {
err := fakeClient.Create(context.TODO(), resource)
assert.NilError(t, err)
}
}
if len(tc.Resources.Update) != 0 {
for _, resource := range tc.Resources.Update {
err := fakeClient.Update(context.TODO(), resource)
assert.NilError(t, err)
}
}
// init command
runCmd := c.command(fakeClient, iostream, tc.Args)
runCmd.SetOutput(outPut)
err := runCmd.Execute()
// check expected resources
if len(tc.ExpectedExistResources) != 0 {
for _, expectedResource := range tc.ExpectedExistResources {
object, _ := expectedResource.(metav1.Object)
resource := expectedResource.DeepCopyObject()
err := fakeClient.Get(context.TODO(), client.ObjectKey{Namespace: object.GetNamespace(), Name: object.GetName()}, resource)
assert.NilError(t, err)
}
}
// check exit output
errTip := tc.ExpectedString
if tc.ExpectedOutput != "" {
errTip = tc.ExpectedOutput
}
if tc.WantException {
assert.ErrorContains(t, err, errTip)
return
}
// check output messages
if tc.ExpectedOutput != "" {
assert.Equal(t, tc.ExpectedOutput, outPut.String(), name)
return
}
assert.Equal(t, true, strings.Contains(outPut.String(), tc.ExpectedString))
})
}
}