From 5977d835bd62c994b61c6880abeb565c627bc12f Mon Sep 17 00:00:00 2001 From: Navid Shaikh Date: Tue, 25 Jun 2019 16:02:43 +0530 Subject: [PATCH 1/9] Adds kn revision delete command --- docs/cmd/kn_revision.md | 1 + docs/cmd/kn_revision_delete.md | 38 ++++++++++++++++++ pkg/kn/commands/revision/delete.go | 60 ++++++++++++++++++++++++++++ pkg/kn/commands/revision/revision.go | 1 + 4 files changed, 100 insertions(+) create mode 100644 docs/cmd/kn_revision_delete.md create mode 100644 pkg/kn/commands/revision/delete.go diff --git a/docs/cmd/kn_revision.md b/docs/cmd/kn_revision.md index 1453bc048f..01f393e23d 100644 --- a/docs/cmd/kn_revision.md +++ b/docs/cmd/kn_revision.md @@ -22,6 +22,7 @@ Revision command group ### SEE ALSO * [kn](kn.md) - Knative client +* [kn revision delete](kn_revision_delete.md) - Delete a revision. * [kn revision describe](kn_revision_describe.md) - Describe revisions. * [kn revision list](kn_revision_list.md) - List available revisions. diff --git a/docs/cmd/kn_revision_delete.md b/docs/cmd/kn_revision_delete.md new file mode 100644 index 0000000000..e333fb2639 --- /dev/null +++ b/docs/cmd/kn_revision_delete.md @@ -0,0 +1,38 @@ +## kn revision delete + +Delete a revision. + +### Synopsis + +Delete a revision. + +``` +kn revision delete NAME [flags] +``` + +### Examples + +``` + + # Delete a revision 'svc1-abcde' in default namespace + kn revision delete svc1-abcde +``` + +### Options + +``` + -h, --help help for delete + -n, --namespace string List the requested object(s) in given namespace. +``` + +### Options inherited from parent commands + +``` + --config string config file (default is $HOME/.kn/config.yaml) + --kubeconfig string kubectl config file (default is $HOME/.kube/config) +``` + +### SEE ALSO + +* [kn revision](kn_revision.md) - Revision command group + diff --git a/pkg/kn/commands/revision/delete.go b/pkg/kn/commands/revision/delete.go new file mode 100644 index 0000000000..ce0806a7d5 --- /dev/null +++ b/pkg/kn/commands/revision/delete.go @@ -0,0 +1,60 @@ +// Copyright © 2019 The Knative Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package revision + +import ( + "errors" + "fmt" + + "github.com/knative/client/pkg/kn/commands" + "github.com/spf13/cobra" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// NewRevisionDeleteCommand represent 'revision delete' command +func NewRevisionDeleteCommand(p *commands.KnParams) *cobra.Command { + RevisionDeleteCommand := &cobra.Command{ + Use: "delete NAME", + Short: "Delete a revision.", + Example: ` + # Delete a revision 'svc1-abcde' in default namespace + kn revision delete svc1-abcde`, + RunE: func(cmd *cobra.Command, args []string) error { + if len(args) != 1 { + return errors.New("requires the revision name.") + } + client, err := p.ServingFactory() + if err != nil { + return err + } + namespace, err := p.GetNamespace(cmd) + if err != nil { + return err + } + + err = client.Revisions(namespace).Delete( + args[0], + &v1.DeleteOptions{}, + ) + if err != nil { + return err + } + fmt.Fprintf(cmd.OutOrStdout(), "Revision '%s' successfully deleted in namespace '%s'.\n", args[0], namespace) + return nil + }, + } + commands.AddNamespaceFlags(RevisionDeleteCommand.Flags(), false) + return RevisionDeleteCommand +} diff --git a/pkg/kn/commands/revision/revision.go b/pkg/kn/commands/revision/revision.go index 24519bfbe9..087f6c8927 100644 --- a/pkg/kn/commands/revision/revision.go +++ b/pkg/kn/commands/revision/revision.go @@ -26,5 +26,6 @@ func NewRevisionCommand(p *commands.KnParams) *cobra.Command { } revisionCmd.AddCommand(NewRevisionListCommand(p)) revisionCmd.AddCommand(NewRevisionDescribeCommand(p)) + revisionCmd.AddCommand(NewRevisionDeleteCommand(p)) return revisionCmd } From 2b70903423a04cf1646e5b9ad3f5e3ec6ee19025 Mon Sep 17 00:00:00 2001 From: Navid Shaikh Date: Wed, 26 Jun 2019 16:06:08 +0530 Subject: [PATCH 2/9] Adds unit tests for revision delete command --- pkg/kn/commands/revision/delete_test.go | 66 +++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 pkg/kn/commands/revision/delete_test.go diff --git a/pkg/kn/commands/revision/delete_test.go b/pkg/kn/commands/revision/delete_test.go new file mode 100644 index 0000000000..f6f7237758 --- /dev/null +++ b/pkg/kn/commands/revision/delete_test.go @@ -0,0 +1,66 @@ +// Copyright © 2019 The Knative Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package revision + +import ( + "fmt" + "strings" + "testing" + + "github.com/knative/client/pkg/kn/commands" + "k8s.io/apimachinery/pkg/runtime" + client_testing "k8s.io/client-go/testing" +) + +func fakeRevisionDelete(args []string) (action client_testing.Action, name string, output []string, err error) { + knParams := &commands.KnParams{} + cmd, fakeServing, buf := commands.CreateTestKnCommand(NewRevisionCommand(knParams), knParams) + fakeServing.AddReactor("delete", "*", + func(a client_testing.Action) (bool, runtime.Object, error) { + deleteAction, ok := a.(client_testing.DeleteAction) + action = deleteAction + if !ok { + return true, nil, fmt.Errorf("wrong kind of action %v", action) + } + name = deleteAction.GetName() + return true, nil, nil + }) + cmd.SetArgs(args) + err = cmd.Execute() + if err != nil { + return + } + output = strings.Split(buf.String(), "\n") + return +} + +func TestRevisionDelete(t *testing.T) { + revName := "foo-12345" + action, name, output, err := fakeRevisionDelete([]string{"revision", "delete", revName}) + if err != nil { + t.Error(err) + return + } + expectedOutput := fmt.Sprintf("Revision '%s' successfully deleted in namespace '%s'.", revName, commands.FakeNamespace) + if action == nil { + t.Errorf("No action") + } else if !action.Matches("delete", "revisions") { + t.Errorf("Bad action %v", action) + } else if output[0] != expectedOutput { + t.Errorf("Bad output %s\nExpected output %s", output[0], expectedOutput) + } else if name != revName { + t.Errorf("Bad revision name returned after delete.") + } +} From c2d9b969eef32a61e848d7727856fc0d1e0b14af Mon Sep 17 00:00:00 2001 From: Navid Shaikh Date: Wed, 26 Jun 2019 16:06:24 +0530 Subject: [PATCH 3/9] Adds integration tests for revision delete command Added revision delete command tests in new workflow namely TestRevisionWorkflow. --- test/e2e/revision_workflow_test.go | 46 ++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 test/e2e/revision_workflow_test.go diff --git a/test/e2e/revision_workflow_test.go b/test/e2e/revision_workflow_test.go new file mode 100644 index 0000000000..de24fbd275 --- /dev/null +++ b/test/e2e/revision_workflow_test.go @@ -0,0 +1,46 @@ +// Copyright 2019 The Knative Authors + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or im +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build e2e + +package e2e + +import ( + "fmt" + "testing" +) + +func TestRevisionWorkflow(t *testing.T) { + teardown := Setup(t) + defer teardown(t) + + testServiceCreate(t, k, "hello") + testDeleteRevision(t, k, "hello") + testServiceDelete(t, k, "hello") +} + +func testDeleteRevision(t *testing.T, k kn, serviceName string) { + revName, err := k.RunWithOpts([]string{"revision", "list", "-o=jsonpath={.items[0].metadata.name}"}, runOpts{}) + if err != nil { + t.Errorf("Error executing 'revision list -o' command. Error: %s", err.Error()) + } + out, err := k.RunWithOpts([]string{"revision", "delete", revName}, runOpts{}) + if err != nil { + t.Errorf("Error executing 'revision delete %s' command. Error: %s", revName, err.Error()) + } + expectedOutput := fmt.Sprintf("Revision '%s' successfully deleted in namespace '%s'.\n", revName, defaultKnE2ENamespace) + if out != expectedOutput { + t.Errorf("Wrong output from 'revision delete %s' command. Actual output:\n%s\nExpected output:\n%s\n", revName, out, expectedOutput) + } +} From 9805bb3df88362bee280a361e3dbb713426b61c5 Mon Sep 17 00:00:00 2001 From: Navid Shaikh Date: Wed, 26 Jun 2019 16:12:15 +0530 Subject: [PATCH 4/9] Removes extra line and renames an import alias --- pkg/kn/commands/revision/delete.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pkg/kn/commands/revision/delete.go b/pkg/kn/commands/revision/delete.go index ce0806a7d5..c887eca7a7 100644 --- a/pkg/kn/commands/revision/delete.go +++ b/pkg/kn/commands/revision/delete.go @@ -20,7 +20,7 @@ import ( "github.com/knative/client/pkg/kn/commands" "github.com/spf13/cobra" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) // NewRevisionDeleteCommand represent 'revision delete' command @@ -43,10 +43,9 @@ func NewRevisionDeleteCommand(p *commands.KnParams) *cobra.Command { if err != nil { return err } - err = client.Revisions(namespace).Delete( args[0], - &v1.DeleteOptions{}, + &metav1.DeleteOptions{}, ) if err != nil { return err From 2debc55bb31a8ccba9fa46b53b3c43b66a2fcf15 Mon Sep 17 00:00:00 2001 From: Navid Shaikh Date: Wed, 26 Jun 2019 17:00:45 +0530 Subject: [PATCH 5/9] Adds 10 seconds sleep between service create and revision delete Also adds check for 'No resources found' while grabbing revision name. --- test/e2e/revision_workflow_test.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/e2e/revision_workflow_test.go b/test/e2e/revision_workflow_test.go index de24fbd275..9633fb973f 100644 --- a/test/e2e/revision_workflow_test.go +++ b/test/e2e/revision_workflow_test.go @@ -18,7 +18,9 @@ package e2e import ( "fmt" + "strings" "testing" + "time" ) func TestRevisionWorkflow(t *testing.T) { @@ -26,6 +28,8 @@ func TestRevisionWorkflow(t *testing.T) { defer teardown(t) testServiceCreate(t, k, "hello") + // TODO: remove this when https://github.com/knative/client/pull/156 is merged + time.Sleep(10 * time.Second) testDeleteRevision(t, k, "hello") testServiceDelete(t, k, "hello") } @@ -35,6 +39,9 @@ func testDeleteRevision(t *testing.T, k kn, serviceName string) { if err != nil { t.Errorf("Error executing 'revision list -o' command. Error: %s", err.Error()) } + if strings.Contains(revName, "No resources found.") { + t.Errorf("Could not find revision name.") + } out, err := k.RunWithOpts([]string{"revision", "delete", revName}, runOpts{}) if err != nil { t.Errorf("Error executing 'revision delete %s' command. Error: %s", revName, err.Error()) From 8c8703ec7849405ed59a9780b16e4a1c7d6306df Mon Sep 17 00:00:00 2001 From: Navid Shaikh Date: Fri, 28 Jun 2019 19:59:45 +0530 Subject: [PATCH 6/9] Clean up imports --- pkg/kn/commands/service/service_create.go | 5 +++-- pkg/kn/commands/service/wait_args.go | 1 + pkg/kn/commands/wait_flags.go | 1 + pkg/kn/commands/wait_flags_test.go | 3 ++- pkg/wait/wait_for_ready.go | 5 +++-- 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/pkg/kn/commands/service/service_create.go b/pkg/kn/commands/service/service_create.go index 19984766ec..2f7731e36a 100644 --- a/pkg/kn/commands/service/service_create.go +++ b/pkg/kn/commands/service/service_create.go @@ -17,12 +17,13 @@ package service import ( "errors" "fmt" + "io" + "time" + "github.com/knative/client/pkg/kn/commands" serving_v1alpha1_api "github.com/knative/serving/pkg/apis/serving/v1alpha1" serving_v1alpha1_client "github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1" "github.com/spf13/cobra" - "io" - "time" corev1 "k8s.io/api/core/v1" api_errors "k8s.io/apimachinery/pkg/api/errors" diff --git a/pkg/kn/commands/service/wait_args.go b/pkg/kn/commands/service/wait_args.go index bad5a50ef5..8d985c26b6 100644 --- a/pkg/kn/commands/service/wait_args.go +++ b/pkg/kn/commands/service/wait_args.go @@ -16,6 +16,7 @@ package service import ( "fmt" + "github.com/knative/client/pkg/wait" "github.com/knative/pkg/apis" serving_v1alpha1_api "github.com/knative/serving/pkg/apis/serving/v1alpha1" diff --git a/pkg/kn/commands/wait_flags.go b/pkg/kn/commands/wait_flags.go index d10534f381..ecbf7cee92 100644 --- a/pkg/kn/commands/wait_flags.go +++ b/pkg/kn/commands/wait_flags.go @@ -16,6 +16,7 @@ package commands import ( "fmt" + "github.com/spf13/cobra" ) diff --git a/pkg/kn/commands/wait_flags_test.go b/pkg/kn/commands/wait_flags_test.go index 9156b4f2e2..e72d8924ef 100644 --- a/pkg/kn/commands/wait_flags_test.go +++ b/pkg/kn/commands/wait_flags_test.go @@ -15,9 +15,10 @@ package commands import ( - "github.com/spf13/cobra" "strings" "testing" + + "github.com/spf13/cobra" ) type waitTestCase struct { diff --git a/pkg/wait/wait_for_ready.go b/pkg/wait/wait_for_ready.go index be43157197..7baf6b2e64 100644 --- a/pkg/wait/wait_for_ready.go +++ b/pkg/wait/wait_for_ready.go @@ -16,14 +16,15 @@ package wait import ( "fmt" - "github.com/knative/pkg/apis" "io" + "time" + + "github.com/knative/pkg/apis" corev1 "k8s.io/api/core/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/watch" - "time" ) // Callbacks and configuration used while waiting From ac846114c9e20d9d9224245b23ccc1549ade4663 Mon Sep 17 00:00:00 2001 From: Navid Shaikh Date: Fri, 28 Jun 2019 20:03:34 +0530 Subject: [PATCH 7/9] Removes the pause after service create --- test/e2e/revision_workflow_test.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/e2e/revision_workflow_test.go b/test/e2e/revision_workflow_test.go index 9633fb973f..5143f7e261 100644 --- a/test/e2e/revision_workflow_test.go +++ b/test/e2e/revision_workflow_test.go @@ -20,7 +20,6 @@ import ( "fmt" "strings" "testing" - "time" ) func TestRevisionWorkflow(t *testing.T) { @@ -28,8 +27,6 @@ func TestRevisionWorkflow(t *testing.T) { defer teardown(t) testServiceCreate(t, k, "hello") - // TODO: remove this when https://github.com/knative/client/pull/156 is merged - time.Sleep(10 * time.Second) testDeleteRevision(t, k, "hello") testServiceDelete(t, k, "hello") } From 74d8c060ae8dfa39d68b31b58db2bd110188e167 Mon Sep 17 00:00:00 2001 From: Navid Shaikh Date: Fri, 28 Jun 2019 21:47:48 +0530 Subject: [PATCH 8/9] Updates testing output strings in unit and e2e --- pkg/kn/commands/revision/delete.go | 2 +- pkg/kn/commands/revision/delete_test.go | 17 +++++------------ pkg/kn/commands/test_helper.go | 12 ++++++++++++ test/e2e/revision_workflow_test.go | 7 +++---- 4 files changed, 21 insertions(+), 17 deletions(-) diff --git a/pkg/kn/commands/revision/delete.go b/pkg/kn/commands/revision/delete.go index c887eca7a7..9742f41f2d 100644 --- a/pkg/kn/commands/revision/delete.go +++ b/pkg/kn/commands/revision/delete.go @@ -33,7 +33,7 @@ func NewRevisionDeleteCommand(p *commands.KnParams) *cobra.Command { kn revision delete svc1-abcde`, RunE: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { - return errors.New("requires the revision name.") + return errors.New("'revision delete' requires the revision name given as single argument") } client, err := p.ServingFactory() if err != nil { diff --git a/pkg/kn/commands/revision/delete_test.go b/pkg/kn/commands/revision/delete_test.go index f6f7237758..080eb71b4c 100644 --- a/pkg/kn/commands/revision/delete_test.go +++ b/pkg/kn/commands/revision/delete_test.go @@ -15,8 +15,6 @@ package revision import ( - "fmt" - "strings" "testing" "github.com/knative/client/pkg/kn/commands" @@ -24,16 +22,13 @@ import ( client_testing "k8s.io/client-go/testing" ) -func fakeRevisionDelete(args []string) (action client_testing.Action, name string, output []string, err error) { +func fakeRevisionDelete(args []string) (action client_testing.Action, name string, output string, err error) { knParams := &commands.KnParams{} cmd, fakeServing, buf := commands.CreateTestKnCommand(NewRevisionCommand(knParams), knParams) - fakeServing.AddReactor("delete", "*", + fakeServing.AddReactor("delete", "revisions", func(a client_testing.Action) (bool, runtime.Object, error) { - deleteAction, ok := a.(client_testing.DeleteAction) + deleteAction, _ := a.(client_testing.DeleteAction) action = deleteAction - if !ok { - return true, nil, fmt.Errorf("wrong kind of action %v", action) - } name = deleteAction.GetName() return true, nil, nil }) @@ -42,7 +37,7 @@ func fakeRevisionDelete(args []string) (action client_testing.Action, name strin if err != nil { return } - output = strings.Split(buf.String(), "\n") + output = buf.String() return } @@ -53,14 +48,12 @@ func TestRevisionDelete(t *testing.T) { t.Error(err) return } - expectedOutput := fmt.Sprintf("Revision '%s' successfully deleted in namespace '%s'.", revName, commands.FakeNamespace) if action == nil { t.Errorf("No action") } else if !action.Matches("delete", "revisions") { t.Errorf("Bad action %v", action) - } else if output[0] != expectedOutput { - t.Errorf("Bad output %s\nExpected output %s", output[0], expectedOutput) } else if name != revName { t.Errorf("Bad revision name returned after delete.") } + commands.TestContains(t, output, []string{"Revision", revName, "deleted", "namespace", commands.FakeNamespace}, "word in output") } diff --git a/pkg/kn/commands/test_helper.go b/pkg/kn/commands/test_helper.go index a0ec06c7dd..a294cd2289 100644 --- a/pkg/kn/commands/test_helper.go +++ b/pkg/kn/commands/test_helper.go @@ -17,6 +17,8 @@ package commands import ( "bytes" "flag" + "strings" + "testing" serving "github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1" "github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/fake" @@ -67,3 +69,13 @@ Eventing: Manage event subscriptions and channels. Connect up event sources.`, flag.CommandLine.Parse([]string{}) return rootCmd } + +// TestContains is a test helper function, checking if a substring is present in given +// output string +func TestContains(t *testing.T, output string, sub []string, element string) { + for _, each := range sub { + if !strings.Contains(output, each) { + t.Errorf("Missing %s: %s", element, each) + } + } +} diff --git a/test/e2e/revision_workflow_test.go b/test/e2e/revision_workflow_test.go index 5143f7e261..31283e819d 100644 --- a/test/e2e/revision_workflow_test.go +++ b/test/e2e/revision_workflow_test.go @@ -20,6 +20,8 @@ import ( "fmt" "strings" "testing" + + "github.com/knative/client/pkg/kn/commands" ) func TestRevisionWorkflow(t *testing.T) { @@ -43,8 +45,5 @@ func testDeleteRevision(t *testing.T, k kn, serviceName string) { if err != nil { t.Errorf("Error executing 'revision delete %s' command. Error: %s", revName, err.Error()) } - expectedOutput := fmt.Sprintf("Revision '%s' successfully deleted in namespace '%s'.\n", revName, defaultKnE2ENamespace) - if out != expectedOutput { - t.Errorf("Wrong output from 'revision delete %s' command. Actual output:\n%s\nExpected output:\n%s\n", revName, out, expectedOutput) - } + commands.TestContains(t, out, []string{"Revision", revName, "deleted", "namespace", k.namespace}, "word in output") } From adc2704a60250a24ba0415ccf72e158ff94d30a3 Mon Sep 17 00:00:00 2001 From: Navid Shaikh Date: Fri, 28 Jun 2019 22:09:44 +0530 Subject: [PATCH 9/9] Updates post goimports on hack and test dirs --- hack/generate-docs.go | 4 ++-- test/e2e/revision_workflow_test.go | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/hack/generate-docs.go b/hack/generate-docs.go index 10b9642d8a..d1f7c11148 100644 --- a/hack/generate-docs.go +++ b/hack/generate-docs.go @@ -29,9 +29,9 @@ func main() { if len(os.Args) > 1 { dir = os.Args[1] } - err := doc.GenMarkdownTree(rootCmd, dir + "/docs/cmd/") + err := doc.GenMarkdownTree(rootCmd, dir+"/docs/cmd/") if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } -} \ No newline at end of file +} diff --git a/test/e2e/revision_workflow_test.go b/test/e2e/revision_workflow_test.go index 31283e819d..861319a812 100644 --- a/test/e2e/revision_workflow_test.go +++ b/test/e2e/revision_workflow_test.go @@ -17,7 +17,6 @@ package e2e import ( - "fmt" "strings" "testing"