diff --git a/backend/src/cmd/ml/cmd/client_factory.go b/backend/src/cmd/ml/cmd/client_factory.go index 09fc209a479..b1251137700 100644 --- a/backend/src/cmd/ml/cmd/client_factory.go +++ b/backend/src/cmd/ml/cmd/client_factory.go @@ -1,6 +1,7 @@ package cmd import ( + "bytes" "io" "os" @@ -20,10 +21,12 @@ type ClientFactoryInterface interface { client.RunInterface, error) Time() util.TimeInterface Writer() io.Writer + Result() string } type ClientFactory struct { time util.TimeInterface + buffer *bytes.Buffer writer io.Writer } @@ -34,6 +37,15 @@ func NewClientFactory() *ClientFactory { } } +func NewClientFactoryWithByteBuffer() *ClientFactory { + buffer := new(bytes.Buffer) + return &ClientFactory{ + time: util.NewRealTime(), + buffer: buffer, + writer: buffer, + } +} + func (f *ClientFactory) CreatePipelineUploadClient(config clientcmd.ClientConfig, debug bool) ( client.PipelineUploadInterface, error) { return client.NewPipelineUploadClient(config, debug) @@ -61,3 +73,10 @@ func (f *ClientFactory) Time() util.TimeInterface { func (f *ClientFactory) Writer() io.Writer { return f.writer } + +func (f *ClientFactory) Result() string { + if f.buffer == nil { + return "The writer is set to 'os.Stdout'. The result is not recorded." + } + return (*f.buffer).String() +} diff --git a/backend/src/cmd/ml/cmd/client_factory_fake.go b/backend/src/cmd/ml/cmd/client_factory_fake.go index f19d7d18a4f..55607cba56f 100644 --- a/backend/src/cmd/ml/cmd/client_factory_fake.go +++ b/backend/src/cmd/ml/cmd/client_factory_fake.go @@ -56,7 +56,7 @@ func (f *ClientFactoryFake) Result() string { return (*f.buffer).String() } -func getFakeRootCommand() (*RootCommand, *ClientFactoryFake) { +func GetFakeRootCommand() (*RootCommand, *ClientFactoryFake) { factory := NewClientFactoryFake() rootCmd := NewRootCmd(factory) rootCmd = CreateSubCommands(rootCmd, 10) diff --git a/backend/src/cmd/ml/cmd/job.go b/backend/src/cmd/ml/cmd/job.go index d2c50a40f42..ea70d8c96f3 100644 --- a/backend/src/cmd/ml/cmd/job.go +++ b/backend/src/cmd/ml/cmd/job.go @@ -117,7 +117,7 @@ func NewJobCreateCmd(root *RootCommand) *cobra.Command { if err != nil { return util.ExtractErrorForCLI(err, root.Debug()) } - PrettyPrintResult(root.Writer(), root.NoColor(), root.OutputFormat(), job) + PrettyPrintResult(root.Writer(), root.OutputFormat(), job) return nil }, } @@ -223,7 +223,7 @@ func NewJobGetCmd(root *RootCommand) *cobra.Command { if err != nil { return util.ExtractErrorForCLI(err, root.Debug()) } - PrettyPrintResult(root.Writer(), root.NoColor(), root.OutputFormat(), pkg) + PrettyPrintResult(root.Writer(), root.OutputFormat(), pkg) return nil }, } @@ -259,7 +259,7 @@ func NewJobListCmd(root *RootCommand, pageSize int32) *cobra.Command { if err != nil { return util.ExtractErrorForCLI(err, root.Debug()) } - PrettyPrintResult(root.Writer(), root.NoColor(), root.OutputFormat(), results) + PrettyPrintResult(root.Writer(), root.OutputFormat(), results) return nil }, } @@ -292,7 +292,7 @@ func NewJobEnableCmd(root *RootCommand) *cobra.Command { if err != nil { return util.ExtractErrorForCLI(err, root.Debug()) } - PrettyPrintResult(root.Writer(), root.NoColor(), root.OutputFormat(), "") + PrettyPrintResult(root.Writer(), root.OutputFormat(), "") return nil }, } @@ -323,7 +323,7 @@ func NewJobDisableCmd(root *RootCommand) *cobra.Command { if err != nil { return util.ExtractErrorForCLI(err, root.Debug()) } - PrettyPrintResult(root.Writer(), root.NoColor(), root.OutputFormat(), "") + PrettyPrintResult(root.Writer(), root.OutputFormat(), "") return nil }, } @@ -354,7 +354,7 @@ func NewJobDeleteCmd(root *RootCommand) *cobra.Command { if err != nil { return util.ExtractErrorForCLI(err, root.Debug()) } - PrettyPrintResult(root.Writer(), root.NoColor(), root.OutputFormat(), "") + PrettyPrintResult(root.Writer(), root.OutputFormat(), "") return nil }, } diff --git a/backend/src/cmd/ml/cmd/job_test.go b/backend/src/cmd/ml/cmd/job_test.go index b447c188726..89d8792364b 100644 --- a/backend/src/cmd/ml/cmd/job_test.go +++ b/backend/src/cmd/ml/cmd/job_test.go @@ -9,14 +9,13 @@ import ( ) func TestCreateJob(t *testing.T) { - rootCmd, factory := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"job", "create", "--no-color", + rootCmd, factory := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"job", "create", client.JobForDefaultTest, "--pipeline-id", "5"}) _, err := rootCmd.Command().ExecuteC() assert.Nil(t, err) expected := ` -SUCCESS created_at: "1970-01-01T00:00:00.000Z" description: JOB_DESCRIPTION id: "500" @@ -29,8 +28,8 @@ updated_at: "0001-01-01T00:00:00.000Z" } func TestCreateJobClientError(t *testing.T) { - rootCmd, _ := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"job", "create", "--no-color", + rootCmd, _ := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"job", "create", client.JobForClientErrorTest, "--pipeline-id", "5"}) _, err := rootCmd.Command().ExecuteC() assert.NotNil(t, err) @@ -38,16 +37,16 @@ func TestCreateJobClientError(t *testing.T) { } func TestCreateJobInvalidArgumentCount(t *testing.T) { - rootCmd, _ := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"job", "--no-color", "--pipeline-id", "5", "create"}) + rootCmd, _ := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"job", "--pipeline-id", "5", "create"}) _, err := rootCmd.Command().ExecuteC() assert.NotNil(t, err) assert.Contains(t, err.Error(), "Missing 'NAME' argument") } func TestCreateJobInvalidMaxConcurrency(t *testing.T) { - rootCmd, _ := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"job", "create", "--no-color", + rootCmd, _ := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"job", "create", client.JobForDefaultTest, "--pipeline-id", "5", "--max-concurrency", "0"}) _, err := rootCmd.Command().ExecuteC() assert.NotNil(t, err) @@ -55,8 +54,8 @@ func TestCreateJobInvalidMaxConcurrency(t *testing.T) { } func TestCreateJobInvalidStartTime(t *testing.T) { - rootCmd, _ := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"job", "create", "--no-color", + rootCmd, _ := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"job", "create", client.JobForDefaultTest, "--pipeline-id", "5", "--start-time", "INVALID_TIME"}) _, err := rootCmd.Command().ExecuteC() assert.NotNil(t, err) @@ -65,8 +64,8 @@ func TestCreateJobInvalidStartTime(t *testing.T) { } func TestCreateJobInvalidEndTime(t *testing.T) { - rootCmd, _ := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"job", "create", "--no-color", + rootCmd, _ := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"job", "create", client.JobForDefaultTest, "--pipeline-id", "5", "--end-time", "INVALID_TIME"}) _, err := rootCmd.Command().ExecuteC() assert.NotNil(t, err) @@ -75,8 +74,8 @@ func TestCreateJobInvalidEndTime(t *testing.T) { } func TestCreateJobInvalidCron(t *testing.T) { - rootCmd, _ := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"job", "create", "--no-color", + rootCmd, _ := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"job", "create", client.JobForDefaultTest, "--pipeline-id", "5", "--cron", "INVALID_CRON"}) _, err := rootCmd.Command().ExecuteC() assert.NotNil(t, err) @@ -85,8 +84,8 @@ func TestCreateJobInvalidCron(t *testing.T) { } func TestCreateJobInvalidInterval(t *testing.T) { - rootCmd, _ := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"job", "create", "--no-color", + rootCmd, _ := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"job", "create", client.JobForDefaultTest, "--pipeline-id", "5", "--period", "INVALID_PERIOD"}) _, err := rootCmd.Command().ExecuteC() assert.NotNil(t, err) @@ -95,8 +94,8 @@ func TestCreateJobInvalidInterval(t *testing.T) { } func TestCreateJobInvalidParameter(t *testing.T) { - rootCmd, _ := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"job", "create", "--no-color", + rootCmd, _ := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"job", "create", client.JobForDefaultTest, "--pipeline-id", "5", "-p", "WRONG_PARAMETER"}) _, err := rootCmd.Command().ExecuteC() assert.NotNil(t, err) @@ -105,8 +104,8 @@ func TestCreateJobInvalidParameter(t *testing.T) { } func TestCreateJobBothCronAndInterval(t *testing.T) { - rootCmd, _ := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"job", "create", "--no-color", + rootCmd, _ := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"job", "create", client.JobForDefaultTest, "--pipeline-id", "5", "--cron", "0 30 * * * *", "--period", "10s"}) _, err := rootCmd.Command().ExecuteC() @@ -116,14 +115,13 @@ func TestCreateJobBothCronAndInterval(t *testing.T) { } func TestGetJob(t *testing.T) { - rootCmd, factory := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"job", "get", "--no-color", + rootCmd, factory := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"job", "get", client.JobForDefaultTest}) _, err := rootCmd.Command().ExecuteC() assert.Nil(t, err) expected := ` -SUCCESS created_at: "1970-01-01T00:00:00.000Z" description: JOB_DESCRIPTION id: JOB_DEFAULT @@ -136,8 +134,8 @@ updated_at: "0001-01-01T00:00:00.000Z" } func TestGetJobClientError(t *testing.T) { - rootCmd, _ := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"job", "get", "--no-color", + rootCmd, _ := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"job", "get", client.JobForClientErrorTest}) _, err := rootCmd.Command().ExecuteC() assert.NotNil(t, err) @@ -145,21 +143,20 @@ func TestGetJobClientError(t *testing.T) { } func TestGetJobInvalidArgumentCount(t *testing.T) { - rootCmd, _ := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"job", "get", "--no-color"}) + rootCmd, _ := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"job", "get"}) _, err := rootCmd.Command().ExecuteC() assert.NotNil(t, err) assert.Contains(t, err.Error(), "Missing 'ID' argument") } func TestListJob(t *testing.T) { - rootCmd, factory := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"job", "list", "--no-color"}) + rootCmd, factory := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"job", "list"}) _, err := rootCmd.Command().ExecuteC() assert.Nil(t, err) expected := ` -SUCCESS - created_at: "1970-01-01T00:00:00.000Z" description: JOB_DESCRIPTION id: "100" @@ -184,14 +181,13 @@ SUCCESS } func TestListJobMaxItems(t *testing.T) { - rootCmd, factory := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"job", "list", "--no-color", + rootCmd, factory := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"job", "list", "--max-items", "1"}) _, err := rootCmd.Command().ExecuteC() assert.Nil(t, err) expected := ` -SUCCESS - created_at: "1970-01-01T00:00:00.000Z" description: JOB_DESCRIPTION id: "100" @@ -204,8 +200,8 @@ SUCCESS } func TestListJobInvalidMaxItems(t *testing.T) { - rootCmd, _ := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"job", "list", "--no-color", + rootCmd, _ := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"job", "list", "--max-items", "INVALID_MAX_ITEMS"}) _, err := rootCmd.Command().ExecuteC() assert.NotNil(t, err) @@ -213,30 +209,28 @@ func TestListJobInvalidMaxItems(t *testing.T) { } func TestListJobInvalidArgumentCount(t *testing.T) { - rootCmd, _ := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"job", "list", "--no-color", "EXTRA_ARGUMENT"}) + rootCmd, _ := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"job", "list", "EXTRA_ARGUMENT"}) _, err := rootCmd.Command().ExecuteC() assert.NotNil(t, err) assert.Contains(t, err.Error(), "Expected 0 arguments") } func TestEnableJob(t *testing.T) { - rootCmd, factory := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"job", "enable", "--no-color", + rootCmd, factory := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"job", "enable", client.JobForDefaultTest}) _, err := rootCmd.Command().ExecuteC() assert.Nil(t, err) - expected := ` -SUCCESS -` + expected := "" assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(factory.Result())) //To print the actual output, use: fmt.Println(factory.Result()) } func TestEnableJobClientError(t *testing.T) { - rootCmd, _ := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"job", "enable", "--no-color", + rootCmd, _ := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"job", "enable", client.JobForClientErrorTest}) _, err := rootCmd.Command().ExecuteC() assert.NotNil(t, err) @@ -244,30 +238,28 @@ func TestEnableJobClientError(t *testing.T) { } func TestEnableJobInvalidArgumentCount(t *testing.T) { - rootCmd, _ := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"job", "enable", "--no-color"}) + rootCmd, _ := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"job", "enable"}) _, err := rootCmd.Command().ExecuteC() assert.NotNil(t, err) assert.Contains(t, err.Error(), "Missing 'ID' argument") } func TestDisableJob(t *testing.T) { - rootCmd, factory := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"job", "disable", "--no-color", + rootCmd, factory := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"job", "disable", client.JobForDefaultTest}) _, err := rootCmd.Command().ExecuteC() assert.Nil(t, err) - expected := ` -SUCCESS -` + expected := "" assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(factory.Result())) //To print the actual output, use: fmt.Println(factory.Result()) } func TestDisableJobClientError(t *testing.T) { - rootCmd, _ := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"job", "disable", "--no-color", + rootCmd, _ := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"job", "disable", client.JobForClientErrorTest}) _, err := rootCmd.Command().ExecuteC() assert.NotNil(t, err) @@ -275,30 +267,28 @@ func TestDisableJobClientError(t *testing.T) { } func TestDisableJobInvalidArgumentCount(t *testing.T) { - rootCmd, _ := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"job", "disable", "--no-color"}) + rootCmd, _ := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"job", "disable"}) _, err := rootCmd.Command().ExecuteC() assert.NotNil(t, err) assert.Contains(t, err.Error(), "Missing 'ID' argument") } func TestDeleteJob(t *testing.T) { - rootCmd, factory := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"job", "delete", "--no-color", + rootCmd, factory := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"job", "delete", client.JobForDefaultTest}) _, err := rootCmd.Command().ExecuteC() assert.Nil(t, err) - expected := ` -SUCCESS -` + expected := "" assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(factory.Result())) //To print the actual output, use: fmt.Println(factory.Result()) } func TestDeleteJobClientError(t *testing.T) { - rootCmd, _ := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"job", "delete", "--no-color", + rootCmd, _ := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"job", "delete", client.JobForClientErrorTest}) _, err := rootCmd.Command().ExecuteC() assert.NotNil(t, err) @@ -306,8 +296,8 @@ func TestDeleteJobClientError(t *testing.T) { } func TestDeleteJobInvalidArgumentCount(t *testing.T) { - rootCmd, _ := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"job", "delete", "--no-color"}) + rootCmd, _ := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"job", "delete"}) _, err := rootCmd.Command().ExecuteC() assert.NotNil(t, err) assert.Contains(t, err.Error(), "Missing 'ID' argument") diff --git a/backend/src/cmd/ml/cmd/pipeline.go b/backend/src/cmd/ml/cmd/pipeline.go index 8e55f531f72..4beb4af3216 100644 --- a/backend/src/cmd/ml/cmd/pipeline.go +++ b/backend/src/cmd/ml/cmd/pipeline.go @@ -42,12 +42,12 @@ func NewPipelineUploadCmd(root *RootCommand) *cobra.Command { if name != "" { params.Name = &name } - _, err := root.PipelineUploadClient().UploadFile(filename, params) + pipeline, err := root.PipelineUploadClient().UploadFile(filename, params) if err != nil { return util.ExtractErrorForCLI(err, root.Debug()) } - PrettyPrintResult(root.Writer(), root.NoColor(), root.OutputFormat(), "") + PrettyPrintResult(root.Writer(), root.OutputFormat(), pipeline) return nil }, } @@ -91,7 +91,7 @@ func NewPipelineCreateCmd(root *RootCommand) *cobra.Command { return util.ExtractErrorForCLI(err, root.Debug()) } - PrettyPrintResult(root.Writer(), root.NoColor(), root.OutputFormat(), pkg) + PrettyPrintResult(root.Writer(), root.OutputFormat(), pkg) return nil }, } @@ -122,7 +122,7 @@ func NewPipelineGetCmd(root *RootCommand) *cobra.Command { if err != nil { return util.ExtractErrorForCLI(err, root.Debug()) } - PrettyPrintResult(root.Writer(), root.NoColor(), root.OutputFormat(), pkg) + PrettyPrintResult(root.Writer(), root.OutputFormat(), pkg) return nil }, } @@ -158,7 +158,7 @@ func NewPipelineListCmd(root *RootCommand, pageSize int32) *cobra.Command { if err != nil { return util.ExtractErrorForCLI(err, root.Debug()) } - PrettyPrintResult(root.Writer(), root.NoColor(), root.OutputFormat(), results) + PrettyPrintResult(root.Writer(), root.OutputFormat(), results) return nil }, } @@ -191,7 +191,7 @@ func NewPipelineDeleteCmd(root *RootCommand) *cobra.Command { if err != nil { return util.ExtractErrorForCLI(err, root.Debug()) } - PrettyPrintResult(root.Writer(), root.NoColor(), root.OutputFormat(), "") + PrettyPrintResult(root.Writer(), root.OutputFormat(), "") return nil }, } @@ -222,7 +222,7 @@ func NewPipelineGetTemplateCmd(root *RootCommand) *cobra.Command { if err != nil { return util.ExtractErrorForCLI(err, root.Debug()) } - PrettyPrintResult(root.Writer(), root.NoColor(), root.OutputFormat(), workflow) + PrettyPrintResult(root.Writer(), root.OutputFormat(), workflow) return nil }, } diff --git a/backend/src/cmd/ml/cmd/pipeline_test.go b/backend/src/cmd/ml/cmd/pipeline_test.go index dfe68be45b5..8f7c32d41e4 100644 --- a/backend/src/cmd/ml/cmd/pipeline_test.go +++ b/backend/src/cmd/ml/cmd/pipeline_test.go @@ -10,14 +10,13 @@ import ( ) func TestGetPipeline(t *testing.T) { - rootCmd, factory := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"pipeline", "get", "--no-color", + rootCmd, factory := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"pipeline", "get", fmt.Sprintf("%v", client.PipelineForDefaultTest)}) _, err := rootCmd.Command().ExecuteC() assert.Nil(t, err) expected := ` -SUCCESS created_at: "1970-01-01T00:00:00.000Z" description: PIPELINE_DESCRIPTION id: PIPELINE_ID_10 @@ -31,14 +30,13 @@ parameters: } func TestGetPipelineJson(t *testing.T) { - rootCmd, factory := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"pipeline", "get", "--no-color", "-o", "json", + rootCmd, factory := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"pipeline", "get", "-o", "json", fmt.Sprintf("%v", client.PipelineForDefaultTest)}) _, err := rootCmd.Command().ExecuteC() assert.Nil(t, err) expected := ` -SUCCESS { "created_at": "1970-01-01T00:00:00.000Z", "description": "PIPELINE_DESCRIPTION", @@ -57,8 +55,8 @@ SUCCESS } func TestGetPipelineClientError(t *testing.T) { - rootCmd, _ := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"pipeline", "get", "--no-color", + rootCmd, _ := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"pipeline", "get", fmt.Sprintf("%v", client.PipelineForClientErrorTest)}) _, err := rootCmd.Command().ExecuteC() assert.NotNil(t, err) @@ -66,21 +64,20 @@ func TestGetPipelineClientError(t *testing.T) { } func TestGetPipelineInvalidArgumentCount(t *testing.T) { - rootCmd, _ := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"pipeline", "get", "--no-color"}) + rootCmd, _ := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"pipeline", "get"}) _, err := rootCmd.Command().ExecuteC() assert.NotNil(t, err) assert.Contains(t, err.Error(), "Missing 'ID' argument") } func TestListPipeline(t *testing.T) { - rootCmd, factory := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"pipeline", "list", "--no-color"}) + rootCmd, factory := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"pipeline", "list"}) _, err := rootCmd.Command().ExecuteC() assert.Nil(t, err) expected := ` -SUCCESS - created_at: "1970-01-01T00:00:00.000Z" description: PIPELINE_DESCRIPTION id: PIPELINE_ID_100 @@ -108,14 +105,13 @@ SUCCESS } func TestListPipelineMaxItems(t *testing.T) { - rootCmd, factory := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"pipeline", "list", "--no-color", + rootCmd, factory := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"pipeline", "list", "--max-items", "1"}) _, err := rootCmd.Command().ExecuteC() assert.Nil(t, err) expected := ` -SUCCESS - created_at: "1970-01-01T00:00:00.000Z" description: PIPELINE_DESCRIPTION id: PIPELINE_ID_100 @@ -129,8 +125,8 @@ SUCCESS } func TestListPipelineInvalidMaxItems(t *testing.T) { - rootCmd, _ := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"pipeline", "list", "--no-color", + rootCmd, _ := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"pipeline", "list", "--max-items", "INVALID_MAX_ITEMS"}) _, err := rootCmd.Command().ExecuteC() assert.NotNil(t, err) @@ -138,30 +134,28 @@ func TestListPipelineInvalidMaxItems(t *testing.T) { } func TestListPipelineInvalidArgumentCount(t *testing.T) { - rootCmd, _ := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"pipeline", "list", "--no-color", "INVALID_ARGUMENT"}) + rootCmd, _ := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"pipeline", "list", "INVALID_ARGUMENT"}) _, err := rootCmd.Command().ExecuteC() assert.NotNil(t, err) assert.Contains(t, err.Error(), "Expected 0 arguments") } func TestDeletePipeline(t *testing.T) { - rootCmd, factory := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"pipeline", "delete", "--no-color", + rootCmd, factory := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"pipeline", "delete", fmt.Sprintf("%v", client.PipelineForDefaultTest)}) _, err := rootCmd.Command().ExecuteC() assert.Nil(t, err) - expected := ` -SUCCESS -` + expected := "" assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(factory.Result())) //To print the actual output, use: fmt.Println(factory.Result()) } func TestDeletePipelineClientError(t *testing.T) { - rootCmd, _ := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"pipeline", "delete", "--no-color", + rootCmd, _ := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"pipeline", "delete", fmt.Sprintf("%v", client.PipelineForClientErrorTest)}) _, err := rootCmd.Command().ExecuteC() assert.NotNil(t, err) @@ -169,22 +163,21 @@ func TestDeletePipelineClientError(t *testing.T) { } func TestDeletePipelineInvalidArgumentCount(t *testing.T) { - rootCmd, _ := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"pipeline", "delete", "--no-color"}) + rootCmd, _ := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"pipeline", "delete"}) _, err := rootCmd.Command().ExecuteC() assert.NotNil(t, err) assert.Contains(t, err.Error(), "Missing 'ID' argument") } func TestGetTemplate(t *testing.T) { - rootCmd, factory := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"pipeline", "get-manifest", "--no-color", + rootCmd, factory := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"pipeline", "get-manifest", fmt.Sprintf("%v", client.PipelineForDefaultTest)}) _, err := rootCmd.Command().ExecuteC() assert.Nil(t, err) expected := ` -SUCCESS metadata: creationTimestamp: null name: MY_NAME @@ -202,8 +195,8 @@ status: } func TestGetTemplateClientError(t *testing.T) { - rootCmd, _ := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"pipeline", "get-manifest", "--no-color", + rootCmd, _ := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"pipeline", "get-manifest", fmt.Sprintf("%v", client.PipelineForClientErrorTest)}) _, err := rootCmd.Command().ExecuteC() assert.NotNil(t, err) @@ -211,22 +204,21 @@ func TestGetTemplateClientError(t *testing.T) { } func TestGetTemplateInvalidArgumentCount(t *testing.T) { - rootCmd, _ := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"pipeline", "get-manifest", "--no-color"}) + rootCmd, _ := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"pipeline", "get-manifest"}) _, err := rootCmd.Command().ExecuteC() assert.NotNil(t, err) assert.Contains(t, err.Error(), "Missing 'ID' argument") } func TestCreatePipeline(t *testing.T) { - rootCmd, factory := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"pipeline", "create", "--no-color", + rootCmd, factory := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"pipeline", "create", client.PipelineValidURL}) _, err := rootCmd.Command().ExecuteC() assert.Nil(t, err) expected := ` -SUCCESS created_at: "1970-01-01T00:00:00.000Z" description: PIPELINE_DESCRIPTION id: foo.yaml @@ -239,8 +231,8 @@ parameters: } func TestCreatePipelineInvalidUrlFormat(t *testing.T) { - rootCmd, _ := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"pipeline", "create", "--no-color", + rootCmd, _ := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"pipeline", "create", client.PipelineInvalidURL}) _, err := rootCmd.Command().ExecuteC() assert.NotNil(t, err) @@ -248,8 +240,8 @@ func TestCreatePipelineInvalidUrlFormat(t *testing.T) { } func TestCreatePipelineInvalidArgumentCount(t *testing.T) { - rootCmd, _ := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"pipeline", "create", "--no-color"}) + rootCmd, _ := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"pipeline", "create"}) _, err := rootCmd.Command().ExecuteC() assert.NotNil(t, err) assert.Contains(t, err.Error(), "Missing 'url' argument") diff --git a/backend/src/cmd/ml/cmd/pipeline_upload_test.go b/backend/src/cmd/ml/cmd/pipeline_upload_test.go index 933fa6482d1..0d1217a4dd3 100644 --- a/backend/src/cmd/ml/cmd/pipeline_upload_test.go +++ b/backend/src/cmd/ml/cmd/pipeline_upload_test.go @@ -10,49 +10,53 @@ import ( ) func TestPipelineUpload(t *testing.T) { - rootCmd, factory := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"pipeline", "upload", "--no-color", + rootCmd, factory := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"pipeline", "upload", client.FileForDefaultTest}) _, err := rootCmd.Command().ExecuteC() assert.Nil(t, err) expected := ` -SUCCESS +created_at: "1970-01-01T00:00:00.000Z" +description: PIPELINE_DESCRIPTION +id: "500" +name: PIPELINE_NAME +parameters: +- name: PARAM_NAME + value: PARAM_VALUE ` assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(factory.Result())) fmt.Println(factory.Result()) } func TestPipelineUploadJson(t *testing.T) { - rootCmd, factory := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"pipeline", "upload", "--no-color", "-o", "json", + rootCmd, factory := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"pipeline", "upload", "-o", "json", client.FileForDefaultTest}) _, err := rootCmd.Command().ExecuteC() assert.Nil(t, err) expected := ` -SUCCESS -` - assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(factory.Result())) - fmt.Println(factory.Result()) +{ + "created_at": "1970-01-01T00:00:00.000Z", + "description": "PIPELINE_DESCRIPTION", + "id": "500", + "name": "PIPELINE_NAME", + "parameters": [ + { + "name": "PARAM_NAME", + "value": "PARAM_VALUE" + } + ] } - -func TestPipelineUploadColor(t *testing.T) { - rootCmd, factory := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"pipeline", "upload", client.FileForDefaultTest}) - _, err := rootCmd.Command().ExecuteC() - assert.Nil(t, err) - - expected := fmt.Sprintf(` -%s[32mSUCCESS%s[0m -`, Escape, Escape) +` assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(factory.Result())) fmt.Println(factory.Result()) } func TestPipelineUploadNoFile(t *testing.T) { - rootCmd, factory := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"pipeline", "upload", "--no-color"}) + rootCmd, factory := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"pipeline", "upload"}) _, err := rootCmd.Command().ExecuteC() assert.NotNil(t, err) assert.Contains(t, err.Error(), "Missing 'FILE' argument") @@ -60,8 +64,8 @@ func TestPipelineUploadNoFile(t *testing.T) { } func TestPipelineUploadClientError(t *testing.T) { - rootCmd, factory := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"pipeline", "upload", "--no-color", + rootCmd, factory := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"pipeline", "upload", client.FileForClientErrorTest}) _, err := rootCmd.Command().ExecuteC() assert.NotNil(t, err) diff --git a/backend/src/cmd/ml/cmd/root.go b/backend/src/cmd/ml/cmd/root.go index 0b0a963b670..5305f0c77aa 100644 --- a/backend/src/cmd/ml/cmd/root.go +++ b/backend/src/cmd/ml/cmd/root.go @@ -15,7 +15,6 @@ type RootCommand struct { command *cobra.Command outputFormat string debug bool - noColor bool clientConfig clientcmd.ClientConfig pipelineUploadClient client.PipelineUploadInterface pipelineClient client.PipelineInterface @@ -64,17 +63,16 @@ func NewRootCmd(factory ClientFactoryInterface) *RootCommand { root.command = command root.command.SilenceErrors = true root.command.SilenceUsage = true - addStandardFlagsToCmd(command, &root.outputFormat, &root.debug, &root.noColor) + addStandardFlagsToCmd(command, &root.outputFormat, &root.debug) root.clientConfig = addKubectlFlagsToCmd(command) return root } -func addStandardFlagsToCmd(cmd *cobra.Command, outputFormat *string, debug *bool, noColor *bool) { +func addStandardFlagsToCmd(cmd *cobra.Command, outputFormat *string, debug *bool) { cmd.PersistentFlags().StringVarP(outputFormat, "output", "o", "yaml", "Output format. One of: json|yaml|go") cmd.PersistentFlags().BoolVarP(debug, "debug", "d", false, "Enable debug mode") - cmd.PersistentFlags().BoolVar(noColor, "no-color", false, "Disable colorized output") } func addKubectlFlagsToCmd(cmd *cobra.Command) clientcmd.ClientConfig { @@ -111,10 +109,6 @@ func (r *RootCommand) Debug() bool { return r.debug } -func (r *RootCommand) NoColor() bool { - return r.noColor -} - func (r *RootCommand) ClientConfig() clientcmd.ClientConfig { return r.clientConfig } diff --git a/backend/src/cmd/ml/cmd/run.go b/backend/src/cmd/ml/cmd/run.go index cf64a24839c..0eaaf0a1e1a 100644 --- a/backend/src/cmd/ml/cmd/run.go +++ b/backend/src/cmd/ml/cmd/run.go @@ -46,7 +46,7 @@ func NewRunGetCmd(root *RootCommand) *cobra.Command { return util.ExtractErrorForCLI(err, root.Debug()) } pkg.PipelineRuntime.WorkflowManifest = "" - PrettyPrintResult(root.Writer(), root.NoColor(), root.OutputFormat(), pkg, + PrettyPrintResult(root.Writer(), root.OutputFormat(), pkg, &WorkflowForDisplay{Workflow: workflow}) return nil }, @@ -83,7 +83,7 @@ func NewRunListCmd(root *RootCommand, pageSize int32) *cobra.Command { if err != nil { return util.ExtractErrorForCLI(err, root.Debug()) } - PrettyPrintResult(root.Writer(), root.NoColor(), root.OutputFormat(), results) + PrettyPrintResult(root.Writer(), root.OutputFormat(), results) return nil }, } diff --git a/backend/src/cmd/ml/cmd/run_test.go b/backend/src/cmd/ml/cmd/run_test.go index ea9c37dab15..d2044e6a8d9 100644 --- a/backend/src/cmd/ml/cmd/run_test.go +++ b/backend/src/cmd/ml/cmd/run_test.go @@ -10,14 +10,13 @@ import ( ) func TestGetRun(t *testing.T) { - rootCmd, factory := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"run", "get", "--no-color", + rootCmd, factory := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"run", "get", fmt.Sprintf("%v", client.RunForDefaultTest)}) _, err := rootCmd.Command().ExecuteC() assert.Nil(t, err) expected := ` -SUCCESS pipeline_runtime: {} run: created_at: "1970-01-01T00:00:00.000Z" @@ -45,8 +44,8 @@ workflow: } func TestGetRunClientError(t *testing.T) { - rootCmd, _ := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"run", "get", "--no-color", + rootCmd, _ := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"run", "get", fmt.Sprintf("%v", client.RunForClientErrorTest)}) _, err := rootCmd.Command().ExecuteC() assert.NotNil(t, err) @@ -54,21 +53,20 @@ func TestGetRunClientError(t *testing.T) { } func TestGetRunInvalidArgumentCount(t *testing.T) { - rootCmd, _ := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"run", "get", "--no-color"}) + rootCmd, _ := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"run", "get"}) _, err := rootCmd.Command().ExecuteC() assert.NotNil(t, err) assert.Contains(t, err.Error(), "Missing 'ID' argument") } func TestListRun(t *testing.T) { - rootCmd, factory := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"run", "list", "--no-color"}) + rootCmd, factory := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"run", "list"}) _, err := rootCmd.Command().ExecuteC() assert.Nil(t, err) expected := ` -SUCCESS - created_at: "1970-01-01T00:00:00.000Z" id: "100" metrics: [] @@ -93,14 +91,13 @@ SUCCESS } func TestListRunMaxItems(t *testing.T) { - rootCmd, factory := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"run", "list", "--no-color", + rootCmd, factory := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"run", "list", "--max-items", "1"}) _, err := rootCmd.Command().ExecuteC() assert.Nil(t, err) expected := ` -SUCCESS - created_at: "1970-01-01T00:00:00.000Z" id: "100" metrics: [] @@ -113,8 +110,8 @@ SUCCESS } func TestListRunInvalidMaxItems(t *testing.T) { - rootCmd, _ := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"run", "list", "--no-color", + rootCmd, _ := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"run", "list", "--max-items", "INVALID_MAX_ITEMS"}) _, err := rootCmd.Command().ExecuteC() assert.NotNil(t, err) @@ -122,8 +119,8 @@ func TestListRunInvalidMaxItems(t *testing.T) { } func TestListRunInvalidArgumentCount(t *testing.T) { - rootCmd, _ := getFakeRootCommand() - rootCmd.Command().SetArgs([]string{"run", "list", "--no-color", "EXTRA_ARGUMENT"}) + rootCmd, _ := GetFakeRootCommand() + rootCmd.Command().SetArgs([]string{"run", "list", "EXTRA_ARGUMENT"}) _, err := rootCmd.Command().ExecuteC() assert.NotNil(t, err) assert.Contains(t, err.Error(), "Expected 0 arguments") diff --git a/backend/src/cmd/ml/cmd/util.go b/backend/src/cmd/ml/cmd/util.go index 5599085eb34..a059bd04f22 100644 --- a/backend/src/cmd/ml/cmd/util.go +++ b/backend/src/cmd/ml/cmd/util.go @@ -5,8 +5,6 @@ import ( "fmt" "io" "math" - "os" - "strconv" "strings" "time" @@ -28,8 +26,7 @@ const ( endOfTime = math.MaxInt32 * 100 ) -func PrettyPrintResult(writer io.Writer, noColor bool, outputFormat string, vs ...interface{}) { - PrettyPrintSuccess(writer, noColor) +func PrettyPrintResult(writer io.Writer, outputFormat string, vs ...interface{}) { for _, v := range vs { if v != "" { PrettyPrint(writer, v, OutputFormat(outputFormat)) @@ -37,10 +34,6 @@ func PrettyPrintResult(writer io.Writer, noColor bool, outputFormat string, vs . } } -func PrettyPrintSuccess(writer io.Writer, noColor bool) { - fmt.Fprintln(writer, ansiFormat(noColor, "SUCCESS", FgGreen)) -} - func PrettyPrintGo(writer io.Writer, v interface{}) { fmt.Fprintf(writer, "%+v\n", v) } @@ -76,34 +69,6 @@ func PrettyPrint(writer io.Writer, v interface{}, format OutputFormat) { } } -// ANSI escape codes -const ( - Escape = "\x1b" - noFormat = 0 - Bold = 1 - FgBlack = 30 - FgRed = 31 - FgGreen = 32 - FgYellow = 33 - FgBlue = 34 - FgMagenta = 35 - FgCyan = 36 - FgWhite = 37 - FgDefault = 39 -) - -func ansiFormat(noColor bool, s string, codes ...int) string { - if noColor || os.Getenv("TERM") == "dumb" || len(codes) == 0 { - return s - } - codeStrs := make([]string, len(codes)) - for i, code := range codes { - codeStrs[i] = strconv.Itoa(code) - } - sequence := strings.Join(codeStrs, ";") - return fmt.Sprintf("%s[%sm%s%s[%dm", Escape, sequence, s, Escape, noFormat) -} - func ValidateSingleString(args []string, argumentName string) (string, error) { if len(args) < 1 { return "", fmt.Errorf("Missing '%s' argument", argumentName) @@ -121,45 +86,6 @@ func ValidateArgumentCount(args []string, expectedCount int) ([]string, error) { return args, nil } -func ValidateSingleInt32(args []string, argumentName string) (int32, error) { - if len(args) < 1 { - return 0, fmt.Errorf("Missing '%s' argument\n", argumentName) - } - if len(args) > 1 { - return 0, fmt.Errorf("Too many arguments") - } - - result, err := strconv.ParseInt(args[0], 10, 32) - if err != nil { - return 0, fmt.Errorf("Cannot convert '%s' into an int32: %s\n", args[0], err.Error()) - } - - return int32(result), nil -} - -func ValidateSingleInt64(args []string, argumentName string) (int64, error) { - if len(args) < 1 { - return 0, fmt.Errorf("Missing '%s' argument\n", argumentName) - } - if len(args) > 1 { - return 0, fmt.Errorf("Too many arguments") - } - - result, err := strconv.ParseInt(args[0], 10, 64) - if err != nil { - return 0, fmt.Errorf("Cannot convert '%s' into an int64: %s\n", args[0], err.Error()) - } - - return result, nil -} - -func ValidateInt32Min(value int32, minValue int32, flagName string) (int32, error) { - if value < minValue { - return 0, fmt.Errorf("Flag '%s' must be at least %d", flagName, minValue) - } - return value, nil -} - func ValidateInt64Min(value int64, minValue int64, flagName string) (int64, error) { if value < minValue { return 0, fmt.Errorf("Flag '%s' must be at least %d", flagName, minValue) diff --git a/backend/src/common/client/api_server/job_client_fake.go b/backend/src/common/client/api_server/job_client_fake.go index d9c5cdc769a..a88087587cb 100644 --- a/backend/src/common/client/api_server/job_client_fake.go +++ b/backend/src/common/client/api_server/job_client_fake.go @@ -33,10 +33,8 @@ func (c *JobClientFake) Create(params *jobparams.CreateJobParams) ( switch params.Body.Name { case JobForClientErrorTest: return nil, fmt.Errorf(ClientErrorString) - case JobForDefaultTest: - return getDefaultJob("500", params.Body.Name), nil default: - return nil, fmt.Errorf(InvalidFakeRequest) + return getDefaultJob("500", params.Body.Name), nil } } @@ -45,10 +43,8 @@ func (c *JobClientFake) Get(params *jobparams.GetJobParams) ( switch params.ID { case JobForClientErrorTest: return nil, fmt.Errorf(ClientErrorString) - case JobForDefaultTest: - return getDefaultJob(params.ID, "JOB_NAME"), nil default: - return nil, fmt.Errorf(InvalidFakeRequest) + return getDefaultJob(params.ID, "JOB_NAME"), nil } } @@ -56,10 +52,8 @@ func (c *JobClientFake) Delete(params *jobparams.DeleteJobParams) error { switch params.ID { case JobForClientErrorTest: return fmt.Errorf(ClientErrorString) - case JobForDefaultTest: - return nil default: - return fmt.Errorf(InvalidFakeRequest) + return nil } } @@ -67,10 +61,8 @@ func (c *JobClientFake) Enable(params *jobparams.EnableJobParams) error { switch params.ID { case JobForClientErrorTest: return fmt.Errorf(ClientErrorString) - case JobForDefaultTest: - return nil default: - return fmt.Errorf(InvalidFakeRequest) + return nil } } @@ -78,10 +70,8 @@ func (c *JobClientFake) Disable(params *jobparams.DisableJobParams) error { switch params.ID { case JobForClientErrorTest: return fmt.Errorf(ClientErrorString) - case JobForDefaultTest: - return nil default: - return fmt.Errorf(InvalidFakeRequest) + return nil } } @@ -109,7 +99,7 @@ func (c *JobClientFake) List(params *jobparams.ListJobsParams) ( getDefaultJob("102", "MY_THIRD_JOB"), }, FinalToken, nil default: - return nil, "", fmt.Errorf(InvalidFakeRequest) + return nil, "", fmt.Errorf(InvalidFakeRequest, token) } } diff --git a/backend/src/common/client/api_server/pipeline_client_fake.go b/backend/src/common/client/api_server/pipeline_client_fake.go index 45d61125fd6..deae203d340 100644 --- a/backend/src/common/client/api_server/pipeline_client_fake.go +++ b/backend/src/common/client/api_server/pipeline_client_fake.go @@ -61,10 +61,8 @@ func (c *PipelineClientFake) Create(params *pipelineparams.CreatePipelineParams) switch params.Body.PipelineURL { case PipelineInvalidURL: return nil, fmt.Errorf(ClientErrorString) - case PipelineValidURL: - return getDefaultPipeline(path.Base(params.Body.PipelineURL)), nil default: - return nil, fmt.Errorf(InvalidFakeRequest) + return getDefaultPipeline(path.Base(params.Body.PipelineURL)), nil } } @@ -73,10 +71,8 @@ func (c *PipelineClientFake) Get(params *pipelineparams.GetPipelineParams) ( switch params.ID { case PipelineForClientErrorTest: return nil, fmt.Errorf(ClientErrorString) - case PipelineForDefaultTest: - return getDefaultPipeline(params.ID), nil default: - return nil, fmt.Errorf(InvalidFakeRequest) + return getDefaultPipeline(params.ID), nil } } @@ -84,10 +80,8 @@ func (c *PipelineClientFake) Delete(params *pipelineparams.DeletePipelineParams) switch params.ID { case PipelineForClientErrorTest: return fmt.Errorf(ClientErrorString) - case PipelineForDefaultTest: - return nil default: - return fmt.Errorf(InvalidFakeRequest) + return nil } } @@ -96,10 +90,8 @@ func (c *PipelineClientFake) GetTemplate(params *pipelineparams.GetTemplateParam switch params.ID { case PipelineForClientErrorTest: return nil, fmt.Errorf(ClientErrorString) - case PipelineForDefaultTest: - return getDefaultWorkflow(), nil default: - return nil, fmt.Errorf(InvalidFakeRequest) + return getDefaultWorkflow(), nil } } @@ -128,7 +120,7 @@ func (c *PipelineClientFake) List(params *pipelineparams.ListPipelinesParams) ( getDefaultPipeline("PIPELINE_ID_102"), }, FinalToken, nil default: - return nil, "", fmt.Errorf(InvalidFakeRequest) + return nil, "", fmt.Errorf(InvalidFakeRequest, token) } } diff --git a/backend/src/common/client/api_server/pipeline_upload_client_fake.go b/backend/src/common/client/api_server/pipeline_upload_client_fake.go index 21de0c03439..fd9e0230a26 100644 --- a/backend/src/common/client/api_server/pipeline_upload_client_fake.go +++ b/backend/src/common/client/api_server/pipeline_upload_client_fake.go @@ -13,7 +13,7 @@ const ( FileForClientErrorTest = "./samples/hello-world.yaml" ClientErrorString = "Error with client" - InvalidFakeRequest = "Invalid fake request" + InvalidFakeRequest = "Invalid fake request, don't know how to handle '%s' in the fake client." ) func getDefaultUploadedPipeline() *model.APIPipeline { @@ -40,9 +40,7 @@ func (c *PipelineUploadClientFake) UploadFile(filePath string, switch filePath { case FileForClientErrorTest: return nil, fmt.Errorf(ClientErrorString) - case FileForDefaultTest: - return getDefaultUploadedPipeline(), nil default: - return nil, fmt.Errorf(InvalidFakeRequest) + return getDefaultUploadedPipeline(), nil } } diff --git a/backend/src/common/client/api_server/run_client_fake.go b/backend/src/common/client/api_server/run_client_fake.go index f38d1675f8a..11292bccbdf 100644 --- a/backend/src/common/client/api_server/run_client_fake.go +++ b/backend/src/common/client/api_server/run_client_fake.go @@ -37,10 +37,8 @@ func (c *RunClientFake) Get(params *runparams.GetRunParams) (*runmodel.APIRunDet switch params.RunID { case RunForClientErrorTest: return nil, nil, fmt.Errorf(ClientErrorString) - case RunForDefaultTest: - return getDefaultRun(params.RunID, "RUN_NAME"), getDefaultWorkflow(), nil default: - return nil, nil, fmt.Errorf(InvalidFakeRequest) + return getDefaultRun(params.RunID, "RUN_NAME"), getDefaultWorkflow(), nil } } @@ -68,7 +66,7 @@ func (c *RunClientFake) List(params *runparams.ListRunsParams) ( getDefaultRun("102", "MY_THIRD_RUN").Run, }, FinalToken, nil default: - return nil, "", fmt.Errorf(InvalidFakeRequest) + return nil, "", fmt.Errorf(InvalidFakeRequest, token) } } diff --git a/backend/test/cli_test.go b/backend/test/cli_test.go index 61d72ae7e15..281544625f3 100644 --- a/backend/test/cli_test.go +++ b/backend/test/cli_test.go @@ -3,21 +3,34 @@ package test import ( "testing" + "encoding/json" + "github.com/golang/glog" + "github.com/kubeflow/pipelines/backend/api/go_http_client/pipeline_model" "github.com/kubeflow/pipelines/backend/src/cmd/ml/cmd" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" ) const ( - defaultPageSize = int32(10) + defaultPageSize = int32(10) + myUploadedPipeline = "my-uploaded-pipeline" + // If true, run as a unit test using a fake client. + // If false, run as an integration test calling the service. + // This is useful to test locally before running an e2e test (which takes a while). + // IMPORTANT: This should always be set to FALSE in the checked-in code. + runAsUnitTest = false ) -func GetRealRootCommand() (*cmd.RootCommand, *cmd.ClientFactory) { - clientFactory := cmd.NewClientFactory() - rootCmd := cmd.NewRootCmd(clientFactory) - rootCmd = cmd.CreateSubCommands(rootCmd, defaultPageSize) - return rootCmd, clientFactory +func GetRealRootCommand() (*cmd.RootCommand, cmd.ClientFactoryInterface) { + if runAsUnitTest { + return cmd.GetFakeRootCommand() + } else { + clientFactory := cmd.NewClientFactoryWithByteBuffer() + rootCmd := cmd.NewRootCmd(clientFactory) + rootCmd = cmd.CreateSubCommands(rootCmd, defaultPageSize) + return rootCmd, clientFactory + } } type CLIIntegrationTest struct { @@ -29,26 +42,47 @@ type CLIIntegrationTest struct { func (c *CLIIntegrationTest) SetupTest() { c.namespace = *namespace - // Wait for the system to be ready. - err := waitForReady(c.namespace, *initializeTimeout) - if err != nil { - glog.Exitf("Cluster namespace '%s' is still not ready after timeout. Error: %s", c.namespace, - err.Error()) + if !runAsUnitTest { + // Wait for the system to be ready. + err := waitForReady(c.namespace, *initializeTimeout) + if err != nil { + glog.Exitf("Cluster namespace '%s' is still not ready after timeout. Error: %s", c.namespace, + err.Error()) + } } } func (c *CLIIntegrationTest) TearDownTest() { - // Nothing to do. + err := c.deletePipelines() + if err != nil { + glog.Exitf("Failed to delete pipelines: %v", err) + } } func (c *CLIIntegrationTest) TestPipelineListSuccess() { t := c.T() + + // Create pipelines rootCmd, _ := GetRealRootCommand() - args := []string{"pipeline", "list"} + args := []string{"pipeline", "create", + "https://storage.googleapis.com/ml-pipeline-dataset/sequential.yaml"} args = addCommonArgs(args, c.namespace) rootCmd.Command().SetArgs(args) _, err := rootCmd.Command().ExecuteC() assert.Nil(t, err) + + // List pipeline + rootCmd, factory := GetRealRootCommand() + args = []string{"pipeline", "list"} + args = addCommonArgs(args, c.namespace) + rootCmd.Command().SetArgs(args) + _, err = rootCmd.Command().ExecuteC() + assert.Nil(t, err) + + // Convert and assert result + pipelines, err := toPipelines(factory.Result()) + assert.Nil(t, err) + assert.True(t, len(pipelines) >= 1) } func (c *CLIIntegrationTest) TestPipelineListFailureInvalidArgument() { @@ -61,11 +95,113 @@ func (c *CLIIntegrationTest) TestPipelineListFailureInvalidArgument() { assert.NotNil(t, err) } +func (c *CLIIntegrationTest) TestPipelineUploadSuccess() { + t := c.T() + rootCmd, _ := GetRealRootCommand() + args := []string{"pipeline", "upload", "--name", myUploadedPipeline, + "./resources/hello-world.yaml"} + args = addCommonArgs(args, c.namespace) + rootCmd.Command().SetArgs(args) + _, err := rootCmd.Command().ExecuteC() + assert.Nil(t, err) +} + +func (c *CLIIntegrationTest) TestPipelineCreateGetDeleteSuccess() { + t := c.T() + rootCmd, factory := GetRealRootCommand() + + // Create pipeline + args := []string{"pipeline", "create", + "https://storage.googleapis.com/ml-pipeline-dataset/sequential.yaml"} + args = addCommonArgs(args, c.namespace) + rootCmd.Command().SetArgs(args) + _, err := rootCmd.Command().ExecuteC() + assert.Nil(t, err) + + // Get ID + pipelineID, err := toPipelineID(factory.Result()) + assert.Nil(t, err) + + // Get pipeline + args = []string{"pipeline", "get", pipelineID} + args = addCommonArgs(args, c.namespace) + rootCmd.Command().SetArgs(args) + _, err = rootCmd.Command().ExecuteC() + assert.Nil(t, err) + + // Get manifest + args = []string{"pipeline", "get-manifest", pipelineID} + args = addCommonArgs(args, c.namespace) + rootCmd.Command().SetArgs(args) + _, err = rootCmd.Command().ExecuteC() + assert.Nil(t, err) + + // Delete pipeline + args = []string{"pipeline", "delete", pipelineID} + args = addCommonArgs(args, c.namespace) + rootCmd.Command().SetArgs(args) + _, err = rootCmd.Command().ExecuteC() + assert.Nil(t, err) +} + func TestPipelineAPI(t *testing.T) { suite.Run(t, new(CLIIntegrationTest)) } func addCommonArgs(args []string, namespace string) []string { - args = append(args, "--debug", "--namespace", namespace) + args = append(args, "--debug", "--namespace", namespace, "-o", "json") return args } + +func toPipelineID(jsonPipeline string) (string, error) { + var pipeline pipeline_model.APIPipeline + err := json.Unmarshal([]byte(jsonPipeline), &pipeline) + if err != nil { + return "", err + } + return pipeline.ID, nil +} + +func toPipelines(jsonPipelines string) ([]pipeline_model.APIPipeline, error) { + var pipelines []pipeline_model.APIPipeline + err := json.Unmarshal([]byte(jsonPipelines), &pipelines) + if err != nil { + return nil, err + } + return pipelines, nil +} + +func (c *CLIIntegrationTest) deletePipelines() error { + pipelines, err := c.listPipelines() + if err != nil { + return err + } + for _, pipeline := range pipelines { + err = c.deletePipeline(pipeline) + if err != nil { + return err + } + } + return nil +} + +func (c *CLIIntegrationTest) deletePipeline(pipeline pipeline_model.APIPipeline) error { + rootCmd, _ := GetRealRootCommand() + args := []string{"pipeline", "delete", pipeline.ID} + args = addCommonArgs(args, c.namespace) + rootCmd.Command().SetArgs(args) + _, err := rootCmd.Command().ExecuteC() + return err +} + +func (c *CLIIntegrationTest) listPipelines() ([]pipeline_model.APIPipeline, error) { + rootCmd, factory := GetRealRootCommand() + args := []string{"pipeline", "list"} + args = addCommonArgs(args, c.namespace) + rootCmd.Command().SetArgs(args) + _, err := rootCmd.Command().ExecuteC() + if err != nil { + return nil, err + } + return toPipelines(factory.Result()) +}