From 563f1d9294838e1cfbf2d402e977de750405439c Mon Sep 17 00:00:00 2001 From: Yevhen Vydolob Date: Tue, 13 Apr 2021 17:53:00 +0300 Subject: [PATCH] Fix service/revision list output with '-o' param (#1276) * Fix service/revision list output with '-o' param Signed-off-by: Yevhen Vydolob * Update CHANGELOG Signed-off-by: Yevhen Vydolob * Simplify output flag check Signed-off-by: Yevhen Vydolob * Respect '-o' in all list commands Signed-off-by: Yevhen Vydolob * Fix imports Signed-off-by: Yevhen Vydolob * Fix e2e test Signed-off-by: Yevhen Vydolob * Fix e2e test Signed-off-by: Yevhen Vydolob * Remove unnecessary import Signed-off-by: Yevhen Vydolob * Fix import Signed-off-by: Yevhen Vydolob * Fix tests Signed-off-by: Yevhen Vydolob --- CHANGELOG.adoc | 10 ++++++++ pkg/kn/commands/broker/list.go | 2 +- pkg/kn/commands/broker/list_test.go | 14 +++++++++++ pkg/kn/commands/channel/list.go | 14 +++++++++-- pkg/kn/commands/channel/list_test.go | 25 +++++++++++++++++++ pkg/kn/commands/channel/list_types.go | 10 +++++++- pkg/kn/commands/channel/list_types_test.go | 9 +++++++ pkg/kn/commands/revision/list.go | 2 +- pkg/kn/commands/revision/list_test.go | 11 ++++++++ pkg/kn/commands/route/list.go | 2 +- pkg/kn/commands/route/list_test.go | 13 ++++++++++ pkg/kn/commands/service/list.go | 4 ++- pkg/kn/commands/service/list_test.go | 12 +++++++++ pkg/kn/commands/source/apiserver/list.go | 2 +- pkg/kn/commands/source/apiserver/list_test.go | 17 +++++++++++++ pkg/kn/commands/source/binding/list.go | 2 +- pkg/kn/commands/source/binding/list_test.go | 17 +++++++++++++ pkg/kn/commands/source/container/list.go | 2 +- pkg/kn/commands/source/container/list_test.go | 17 +++++++++++++ pkg/kn/commands/source/list.go | 18 +++++++++++-- pkg/kn/commands/source/list_test.go | 21 ++++++++++++++++ pkg/kn/commands/source/list_types.go | 11 +++++++- pkg/kn/commands/source/ping/list.go | 2 +- pkg/kn/commands/source/ping/list_test.go | 17 +++++++++++++ pkg/kn/commands/subscription/list.go | 13 +++++++++- pkg/kn/commands/subscription/list_test.go | 14 +++++++++++ pkg/kn/commands/trigger/list.go | 2 +- pkg/kn/commands/trigger/list_test.go | 15 +++++++++++ test/e2e/source_list_test.go | 2 +- 29 files changed, 283 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 82dbd12f8b..aee97ec65c 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -12,6 +12,16 @@ | https://github.com/knative/client/pull/[#] //// +## (Unreleased) +[cols="1,10,3", options="header", width="100%"] +|=== +| | Description | PR + +|🐛 +| Respect `-o` in `list` commands in case if no data present +| https://github.com/knative/client/pull/1276[#1276] +|=== + ## v0.22.0 (2021-04-06) [cols="1,10,3", options="header", width="100%"] |=== diff --git a/pkg/kn/commands/broker/list.go b/pkg/kn/commands/broker/list.go index c1fcf54869..e8867521ae 100644 --- a/pkg/kn/commands/broker/list.go +++ b/pkg/kn/commands/broker/list.go @@ -61,7 +61,7 @@ func NewBrokerListCommand(p *commands.KnParams) *cobra.Command { if err != nil { return err } - if len(brokerList.Items) == 0 { + if !brokerListFlags.GenericPrintFlags.OutputFlagSpecified() && len(brokerList.Items) == 0 { fmt.Fprintf(cmd.OutOrStdout(), "No brokers found.\n") return nil } diff --git a/pkg/kn/commands/broker/list_test.go b/pkg/kn/commands/broker/list_test.go index 73622e91bf..ad23aabfca 100644 --- a/pkg/kn/commands/broker/list_test.go +++ b/pkg/kn/commands/broker/list_test.go @@ -61,6 +61,20 @@ func TestBrokerListEmpty(t *testing.T) { eventingRecorder.Validate() } +func TestBrokerListEmptyWithJSON(t *testing.T) { + eventingClient := clienteventingv1.NewMockKnEventingClient(t) + eventingRecorder := eventingClient.Recorder() + brokerList := &v1beta1.BrokerList{} + brokerList.APIVersion = "eventing.knative.dev/v1beta1" + brokerList.Kind = "BrokerList" + eventingRecorder.ListBrokers(brokerList, nil) + output, err := executeBrokerCommand(eventingClient, "list", "-o", "json") + assert.NilError(t, err) + assert.Assert(t, util.ContainsAll(output, "\"apiVersion\": \"eventing.knative.dev/v1beta1\"", "\"items\": [],", "\"kind\": \"BrokerList\"")) + + eventingRecorder.Validate() +} + func TestTriggerListAllNamespace(t *testing.T) { eventingClient := clienteventingv1.NewMockKnEventingClient(t) eventingRecorder := eventingClient.Recorder() diff --git a/pkg/kn/commands/channel/list.go b/pkg/kn/commands/channel/list.go index 0146c3bf8a..ab81371791 100644 --- a/pkg/kn/commands/channel/list.go +++ b/pkg/kn/commands/channel/list.go @@ -17,10 +17,13 @@ package channel import ( "fmt" - "github.com/spf13/cobra" + "knative.dev/client/pkg/util" + messagingv1 "knative.dev/eventing/pkg/apis/messaging/v1" + "github.com/spf13/cobra" "knative.dev/client/pkg/kn/commands" "knative.dev/client/pkg/kn/commands/flags" + "knative.dev/eventing/pkg/client/clientset/versioned/scheme" ) // NewChannelListCommand is for listing channel objects @@ -51,7 +54,14 @@ func NewChannelListCommand(p *commands.KnParams) *cobra.Command { return err } - if channelList == nil || len(channelList.Items) == 0 { + if channelList == nil { + channelList = &messagingv1.ChannelList{} + err := util.UpdateGroupVersionKindWithScheme(channelList, messagingv1.SchemeGroupVersion, scheme.Scheme) + if err != nil { + return err + } + } + if !listFlags.GenericPrintFlags.OutputFlagSpecified() && len(channelList.Items) == 0 { fmt.Fprintf(cmd.OutOrStdout(), "No channels found.\n") return nil } diff --git a/pkg/kn/commands/channel/list_test.go b/pkg/kn/commands/channel/list_test.go index 5e392876a4..cf6c0d3119 100644 --- a/pkg/kn/commands/channel/list_test.go +++ b/pkg/kn/commands/channel/list_test.go @@ -17,6 +17,8 @@ package channel import ( "testing" + "knative.dev/eventing/pkg/client/clientset/versioned/scheme" + "gotest.tools/v3/assert" "k8s.io/apimachinery/pkg/runtime/schema" @@ -36,6 +38,29 @@ func TestChannelListNoChannelsFound(t *testing.T) { cRecorder.Validate() } +func TestChannelListNoChannelsFoundWithOutputSet(t *testing.T) { + cClient := clientmessagingv1.NewMockKnChannelsClient(t) + cRecorder := cClient.Recorder() + cRecorder.ListChannel(nil, nil) + out, err := executeChannelCommand(cClient, "list", "-o", "json") + assert.NilError(t, err) + assert.Check(t, util.ContainsAll(out, "\"apiVersion\": \"messaging.knative.dev/v1\"", "\"kind\": \"ChannelList\"", "\"items\": []")) + cRecorder.Validate() +} + +func TestChannelListEmptyWithOutputSet(t *testing.T) { + cClient := clientmessagingv1.NewMockKnChannelsClient(t) + cRecorder := cClient.Recorder() + channelList := &messagingv1.ChannelList{} + err := util.UpdateGroupVersionKindWithScheme(channelList, messagingv1.SchemeGroupVersion, scheme.Scheme) + assert.NilError(t, err) + cRecorder.ListChannel(channelList, nil) + out, err := executeChannelCommand(cClient, "list", "-o", "json") + assert.NilError(t, err) + assert.Check(t, util.ContainsAll(out, "\"apiVersion\": \"messaging.knative.dev/v1\"", "\"kind\": \"ChannelList\"", "\"items\": []")) + cRecorder.Validate() +} + func TestChannelList(t *testing.T) { cClient := clientmessagingv1.NewMockKnChannelsClient(t) cRecorder := cClient.Recorder() diff --git a/pkg/kn/commands/channel/list_types.go b/pkg/kn/commands/channel/list_types.go index 830cfd50b3..aa75f9ff59 100644 --- a/pkg/kn/commands/channel/list_types.go +++ b/pkg/kn/commands/channel/list_types.go @@ -62,10 +62,18 @@ func NewChannelListTypesCommand(p *commands.KnParams) *cobra.Command { return knerrors.GetError(err) } - if channelListTypes == nil || len(channelListTypes.Items) == 0 { + if channelListTypes == nil { + channelListTypes = &unstructured.UnstructuredList{} + } + if !listTypesFlags.GenericPrintFlags.OutputFlagSpecified() && len(channelListTypes.Items) == 0 { return fmt.Errorf("no channels found on the backend, please verify the installation") } + if channelListTypes.GroupVersionKind().Empty() { + channelListTypes.SetAPIVersion("apiextensions.k8s.io/v1") + channelListTypes.SetKind("CustomResourceDefinitionList") + } + printer, err := listTypesFlags.ToPrinter() if err != nil { return nil diff --git a/pkg/kn/commands/channel/list_types_test.go b/pkg/kn/commands/channel/list_types_test.go index cdb8041235..8f6e60ab51 100644 --- a/pkg/kn/commands/channel/list_types_test.go +++ b/pkg/kn/commands/channel/list_types_test.go @@ -71,6 +71,15 @@ func TestChannelListTypesNoChannelInstalled(t *testing.T) { assert.Check(t, util.ContainsAll(err.Error(), "no channels found on the backend, please verify the installation")) } +func TestChannelListTypesNoChannelWithJsonOutput(t *testing.T) { + dynamicClient := dynamicfakeClient.CreateFakeKnDynamicClient(testNamespace) + assert.Equal(t, dynamicClient.Namespace(), testNamespace) + + output, err := channelFakeCmd([]string{"channel", "list-types", "-o", "json"}, dynamicClient) + assert.NilError(t, err) + assert.Check(t, util.ContainsAll(strings.Join(output[:], "\n"), "\"apiVersion\": \"apiextensions.k8s.io/v1\"", "\"items\": []", "\"kind\": \"CustomResourceDefinitionList\"")) +} + func TestChannelListTypesErrorDynamicClient(t *testing.T) { dynamicClient := dynamicfakeClient.CreateFakeKnDynamicClient("") assert.Check(t, dynamicClient.Namespace() != testNamespace) diff --git a/pkg/kn/commands/revision/list.go b/pkg/kn/commands/revision/list.go index 9bdbe41795..2f818b73f4 100644 --- a/pkg/kn/commands/revision/list.go +++ b/pkg/kn/commands/revision/list.go @@ -83,7 +83,7 @@ func NewRevisionListCommand(p *commands.KnParams) *cobra.Command { } // Stop if nothing found - if len(revisionList.Items) == 0 { + if !revisionListFlags.GenericPrintFlags.OutputFlagSpecified() && len(revisionList.Items) == 0 { fmt.Fprintf(cmd.OutOrStdout(), "No revisions found.\n") return nil } diff --git a/pkg/kn/commands/revision/list_test.go b/pkg/kn/commands/revision/list_test.go index 11d290f51b..647baec9f5 100644 --- a/pkg/kn/commands/revision/list_test.go +++ b/pkg/kn/commands/revision/list_test.go @@ -60,6 +60,17 @@ func TestRevisionListEmpty(t *testing.T) { } } +func TestRevisionListEmptyWithJSON(t *testing.T) { + action, output, err := fakeRevisionList([]string{"revision", "list", "-o", "json"}, &servingv1.RevisionList{}) + assert.NilError(t, err) + if action == nil { + t.Errorf("No action") + } else if !action.Matches("list", "revisions") { + t.Errorf("Bad action %v", action) + } + assert.Assert(t, util.ContainsAll(strings.Join(output[:], "\n"), "\"apiVersion\": \"serving.knative.dev/v1\"", "\"items\": [],", "\"kind\": \"RevisionList\"")) +} + func TestRevisionListEmptyByName(t *testing.T) { action, _, err := fakeRevisionList([]string{"revision", "list", "name"}, &servingv1.RevisionList{}) assert.NilError(t, err) diff --git a/pkg/kn/commands/route/list.go b/pkg/kn/commands/route/list.go index 12710420b7..2e40896341 100644 --- a/pkg/kn/commands/route/list.go +++ b/pkg/kn/commands/route/list.go @@ -66,7 +66,7 @@ func NewRouteListCommand(p *commands.KnParams) *cobra.Command { if err != nil { return err } - if len(routeList.Items) == 0 { + if !routeListFlags.GenericPrintFlags.OutputFlagSpecified() && len(routeList.Items) == 0 { fmt.Fprintf(cmd.OutOrStdout(), "No routes found.\n") return nil } diff --git a/pkg/kn/commands/route/list_test.go b/pkg/kn/commands/route/list_test.go index a72f0195d6..db8b10e86a 100644 --- a/pkg/kn/commands/route/list_test.go +++ b/pkg/kn/commands/route/list_test.go @@ -57,6 +57,19 @@ func TestListEmpty(t *testing.T) { } } +func TestListEmptyWithJsonOutput(t *testing.T) { + action, output, err := fakeRouteList([]string{"route", "list", "-o", "json"}, &servingv1.RouteList{}) + assert.NilError(t, err) + if action == nil { + t.Errorf("No action") + } else if !action.Matches("list", "routes") { + t.Errorf("Bad action %v", action) + } + + outputJson := strings.Join(output[:], "\n") + assert.Assert(t, util.ContainsAll(outputJson, "\"apiVersion\": \"serving.knative.dev/v1\"", "\"items\": [],", "\"kind\": \"RouteList\"")) +} + func TestRouteListDefaultOutput(t *testing.T) { route1 := createMockRouteSingleTarget("foo", "foo-01234", 100) route2 := createMockRouteSingleTarget("bar", "bar-98765", 100) diff --git a/pkg/kn/commands/service/list.go b/pkg/kn/commands/service/list.go index 32a28caf28..30e3a58b81 100644 --- a/pkg/kn/commands/service/list.go +++ b/pkg/kn/commands/service/list.go @@ -64,7 +64,9 @@ func NewServiceListCommand(p *commands.KnParams) *cobra.Command { if err != nil { return err } - if len(serviceList.Items) == 0 { + + // Stop if nothing found + if !serviceListFlags.GenericPrintFlags.OutputFlagSpecified() && len(serviceList.Items) == 0 { fmt.Fprintf(cmd.OutOrStdout(), "No services found.\n") return nil } diff --git a/pkg/kn/commands/service/list_test.go b/pkg/kn/commands/service/list_test.go index 18038ef6fd..ce2ecc0b6b 100644 --- a/pkg/kn/commands/service/list_test.go +++ b/pkg/kn/commands/service/list_test.go @@ -58,6 +58,18 @@ func TestListEmpty(t *testing.T) { } } +func TestListEmptyWithJSON(t *testing.T) { + action, output, err := fakeServiceList([]string{"service", "list", "-o", "json"}, &servingv1.ServiceList{}) + assert.NilError(t, err) + if action == nil { + t.Errorf("No action") + } else if !action.Matches("list", "services") { + t.Errorf("Bad action %v", action) + } + + assert.Assert(t, util.ContainsAll(strings.Join(output[:], "\n"), "\"apiVersion\": \"serving.knative.dev/v1\"", "\"items\": [],", "\"kind\": \"ServiceList\"")) +} + func TestGetEmpty(t *testing.T) { action, _, err := fakeServiceList([]string{"service", "list", "name"}, &servingv1.ServiceList{}) assert.NilError(t, err) diff --git a/pkg/kn/commands/source/apiserver/list.go b/pkg/kn/commands/source/apiserver/list.go index b4ff177519..edf701e7d8 100644 --- a/pkg/kn/commands/source/apiserver/list.go +++ b/pkg/kn/commands/source/apiserver/list.go @@ -50,7 +50,7 @@ func NewAPIServerListCommand(p *commands.KnParams) *cobra.Command { return err } - if len(sourceList.Items) == 0 { + if !listFlags.GenericPrintFlags.OutputFlagSpecified() && len(sourceList.Items) == 0 { fmt.Fprintf(cmd.OutOrStdout(), "No ApiServer source found.\n") return nil } diff --git a/pkg/kn/commands/source/apiserver/list_test.go b/pkg/kn/commands/source/apiserver/list_test.go index 22da4e6b51..0a4164c2a6 100644 --- a/pkg/kn/commands/source/apiserver/list_test.go +++ b/pkg/kn/commands/source/apiserver/list_test.go @@ -17,6 +17,8 @@ package apiserver import ( "testing" + "knative.dev/eventing/pkg/client/clientset/versioned/scheme" + "gotest.tools/v3/assert" v1alpha2 "knative.dev/eventing/pkg/apis/sources/v1alpha2" @@ -58,3 +60,18 @@ func TestListAPIServerSourceEmpty(t *testing.T) { apiServerRecorder.Validate() } + +func TestListAPIServerSourceEmptyWithJsonOutput(t *testing.T) { + apiServerClient := v1alpha22.NewMockKnAPIServerSourceClient(t) + + apiServerRecorder := apiServerClient.Recorder() + sampleSourceList := v1alpha2.ApiServerSourceList{} + _ = util.UpdateGroupVersionKindWithScheme(&sampleSourceList, v1alpha2.SchemeGroupVersion, scheme.Scheme) + apiServerRecorder.ListAPIServerSource(&sampleSourceList, nil) + + out, err := executeAPIServerSourceCommand(apiServerClient, nil, "list", "-o", "json") + assert.NilError(t, err, "Sources should be listed") + assert.Assert(t, util.ContainsAll(out, "\"apiVersion\": \"sources.knative.dev/v1alpha2\"", "\"items\": []", "\"kind\": \"ApiServerSourceList\"")) + + apiServerRecorder.Validate() +} diff --git a/pkg/kn/commands/source/binding/list.go b/pkg/kn/commands/source/binding/list.go index 63c9713668..cf8bb0234e 100644 --- a/pkg/kn/commands/source/binding/list.go +++ b/pkg/kn/commands/source/binding/list.go @@ -49,7 +49,7 @@ func NewBindingListCommand(p *commands.KnParams) *cobra.Command { return err } - if len(sourceList.Items) == 0 { + if !listFlags.GenericPrintFlags.OutputFlagSpecified() && len(sourceList.Items) == 0 { fmt.Fprintf(cmd.OutOrStdout(), "No sink binding found.\n") return nil } diff --git a/pkg/kn/commands/source/binding/list_test.go b/pkg/kn/commands/source/binding/list_test.go index 2b2454b56e..00b7663d77 100644 --- a/pkg/kn/commands/source/binding/list_test.go +++ b/pkg/kn/commands/source/binding/list_test.go @@ -17,6 +17,8 @@ package binding import ( "testing" + "knative.dev/eventing/pkg/client/clientset/versioned/scheme" + "gotest.tools/v3/assert" v1alpha2 "knative.dev/eventing/pkg/apis/sources/v1alpha2" @@ -58,3 +60,18 @@ func TestListBindingEmpty(t *testing.T) { bindingRecorder.Validate() } + +func TestListBindingEmptyWithJsonOutput(t *testing.T) { + bindingClient := clientv1alpha2.NewMockKnSinkBindingClient(t) + + bindingRecorder := bindingClient.Recorder() + bindingList := v1alpha2.SinkBindingList{} + _ = util.UpdateGroupVersionKindWithScheme(&bindingList, v1alpha2.SchemeGroupVersion, scheme.Scheme) + bindingRecorder.ListSinkBindings(&bindingList, nil) + + out, err := executeSinkBindingCommand(bindingClient, nil, "list", "-o", "json") + assert.NilError(t, err, "Sources should be listed") + assert.Assert(t, util.ContainsAll(out, "\"apiVersion\": \"sources.knative.dev/v1alpha2\"", "\"items\": []", "\"kind\": \"SinkBindingList\"")) + + bindingRecorder.Validate() +} diff --git a/pkg/kn/commands/source/container/list.go b/pkg/kn/commands/source/container/list.go index f61be2e658..a28a1d52dd 100644 --- a/pkg/kn/commands/source/container/list.go +++ b/pkg/kn/commands/source/container/list.go @@ -50,7 +50,7 @@ func NewContainerListCommand(p *commands.KnParams) *cobra.Command { return err } - if len(sourceList.Items) == 0 { + if !listFlags.GenericPrintFlags.OutputFlagSpecified() && len(sourceList.Items) == 0 { fmt.Fprintf(cmd.OutOrStdout(), "No Container source found.\n") return nil } diff --git a/pkg/kn/commands/source/container/list_test.go b/pkg/kn/commands/source/container/list_test.go index 651b1807a3..d947431aba 100644 --- a/pkg/kn/commands/source/container/list_test.go +++ b/pkg/kn/commands/source/container/list_test.go @@ -19,6 +19,8 @@ package container import ( "testing" + "knative.dev/eventing/pkg/client/clientset/versioned/scheme" + "gotest.tools/v3/assert" v1alpha22 "knative.dev/client/pkg/sources/v1alpha2" "knative.dev/client/pkg/util" @@ -58,3 +60,18 @@ func TestListContainerSourceEmpty(t *testing.T) { containerRecorder.Validate() } + +func TestListContainerSourceEmptyWithJsonOutput(t *testing.T) { + containerClient := v1alpha22.NewMockKnContainerSourceClient(t) + + containerRecorder := containerClient.Recorder() + sampleSourceList := v1alpha2.ContainerSourceList{} + _ = util.UpdateGroupVersionKindWithScheme(&sampleSourceList, v1alpha2.SchemeGroupVersion, scheme.Scheme) + containerRecorder.ListContainerSources(&sampleSourceList, nil) + + out, err := executeContainerSourceCommand(containerClient, nil, "list", "-o", "json") + assert.NilError(t, err, "Sources should be listed") + assert.Assert(t, util.ContainsAll(out, "\"apiVersion\": \"sources.knative.dev/v1alpha2\"", "\"items\": []", "\"kind\": \"ContainerSourceList\"")) + + containerRecorder.Validate() +} diff --git a/pkg/kn/commands/source/list.go b/pkg/kn/commands/source/list.go index 53e53ed76a..1b12805792 100644 --- a/pkg/kn/commands/source/list.go +++ b/pkg/kn/commands/source/list.go @@ -18,7 +18,8 @@ import ( "fmt" "github.com/spf13/cobra" - + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" "knative.dev/client/pkg/dynamic" knerrors "knative.dev/client/pkg/errors" "knative.dev/client/pkg/kn/commands" @@ -27,6 +28,12 @@ import ( sourcesv1alpha2 "knative.dev/client/pkg/sources/v1alpha2" ) +const ( + sourceListGroup = "client.knative.dev" + sourceListVersion = "v1alpha1" + sourceListKind = "SourceList" +) + var listExample = ` # List available eventing sources kn source list @@ -73,10 +80,17 @@ func NewListCommand(p *commands.KnParams) *cobra.Command { return knerrors.GetError(err) } - if sourceList == nil || len(sourceList.Items) == 0 { + if sourceList == nil { + sourceList = &unstructured.UnstructuredList{} + } + if !listFlags.GenericPrintFlags.OutputFlagSpecified() && len(sourceList.Items) == 0 { fmt.Fprintf(cmd.OutOrStdout(), "No sources found.\n") return nil } + + if sourceList.GroupVersionKind().Empty() { + sourceList.SetGroupVersionKind(schema.GroupVersionKind{Group: sourceListGroup, Version: sourceListVersion, Kind: sourceListKind}) + } // empty namespace indicates all namespaces flag is specified if namespace == "" { listFlags.EnsureWithNamespace() diff --git a/pkg/kn/commands/source/list_test.go b/pkg/kn/commands/source/list_test.go index 1b0291f148..26d86c8465 100644 --- a/pkg/kn/commands/source/list_test.go +++ b/pkg/kn/commands/source/list_test.go @@ -59,6 +59,18 @@ func TestSourceListTypesNoSourcesInstalled(t *testing.T) { assert.Check(t, util.ContainsAll(err.Error(), "no sources", "found", "backend", "verify", "installation")) } +func TestSourceListTypesNoSourcesWithJsonOutput(t *testing.T) { + output, err := sourceFakeCmd([]string{"source", "list-types", "-o", "json"}, + &unstructured.Unstructured{ + Object: map[string]interface{}{ + "apiVersion": "apiextensions.k8s.io/v1", + "kind": "CustomResourceDefinitionList", + }, + }) + assert.NilError(t, err) + assert.Check(t, util.ContainsAll(strings.Join(output[:], "\n"), "\"apiVersion\": \"apiextensions.k8s.io/v1\"", "\"items\": []", "\"kind\": \"CustomResourceDefinitionList\"")) +} + func TestSourceListTypes(t *testing.T) { output, err := sourceFakeCmd([]string{"source", "list-types"}, newSourceCRDObjWithSpec("pingsources", "sources.knative.dev", "v1alpha1", "PingSource"), @@ -95,6 +107,15 @@ func TestSourceListNoSourcesInstalled(t *testing.T) { assert.Check(t, util.ContainsAll(err.Error(), "no sources", "found", "backend", "verify", "installation")) } +func TestSourceListEmpty(t *testing.T) { + output, err := sourceFakeCmd([]string{"source", "list", "-o", "json"}, + newSourceCRDObjWithSpec("pingsources", "sources.knative.dev", "v1alpha1", "PingSource"), + ) + assert.NilError(t, err) + outputJson := strings.Join(output[:], "\n") + assert.Assert(t, util.ContainsAll(outputJson, "\"apiVersion\": \"client.knative.dev/v1alpha1\"", "\"items\": [],", "\"kind\": \"SourceList\"")) +} + func TestSourceList(t *testing.T) { output, err := sourceFakeCmd([]string{"source", "list"}, newSourceCRDObjWithSpec("pingsources", "sources.knative.dev", "v1alpha1", "PingSource"), diff --git a/pkg/kn/commands/source/list_types.go b/pkg/kn/commands/source/list_types.go index cca0cf4262..34d1089db6 100644 --- a/pkg/kn/commands/source/list_types.go +++ b/pkg/kn/commands/source/list_types.go @@ -62,10 +62,19 @@ func NewListTypesCommand(p *commands.KnParams) *cobra.Command { return knerrors.GetError(err) } - if sourceListTypes == nil || len(sourceListTypes.Items) == 0 { + if sourceListTypes == nil { + sourceListTypes = &unstructured.UnstructuredList{} + } + + if !listTypesFlags.GenericPrintFlags.OutputFlagSpecified() && len(sourceListTypes.Items) == 0 { return fmt.Errorf("no sources found on the backend, please verify the installation") } + if sourceListTypes.GroupVersionKind().Empty() { + sourceListTypes.SetAPIVersion("apiextensions.k8s.io/v1") + sourceListTypes.SetKind("CustomResourceDefinitionList") + } + printer, err := listTypesFlags.ToPrinter() if err != nil { return nil diff --git a/pkg/kn/commands/source/ping/list.go b/pkg/kn/commands/source/ping/list.go index e8edeaa0e3..9e2118af13 100644 --- a/pkg/kn/commands/source/ping/list.go +++ b/pkg/kn/commands/source/ping/list.go @@ -50,7 +50,7 @@ func NewPingListCommand(p *commands.KnParams) *cobra.Command { return err } - if len(sourceList.Items) == 0 { + if !listFlags.GenericPrintFlags.OutputFlagSpecified() && len(sourceList.Items) == 0 { fmt.Fprintf(cmd.OutOrStdout(), "No Ping source found.\n") return nil } diff --git a/pkg/kn/commands/source/ping/list_test.go b/pkg/kn/commands/source/ping/list_test.go index 157cb04dc8..27bf8aeb18 100644 --- a/pkg/kn/commands/source/ping/list_test.go +++ b/pkg/kn/commands/source/ping/list_test.go @@ -17,6 +17,8 @@ package ping import ( "testing" + "knative.dev/eventing/pkg/client/clientset/versioned/scheme" + "gotest.tools/v3/assert" v1alpha2 "knative.dev/eventing/pkg/apis/sources/v1alpha2" @@ -58,3 +60,18 @@ func TestListPingJobSourceEmpty(t *testing.T) { pingRecorder.Validate() } + +func TestListPingJobSourceEmptyWithJsonOutput(t *testing.T) { + pingClient := clientv1alpha2.NewMockKnPingSourceClient(t) + + pingRecorder := pingClient.Recorder() + cJSourceList := v1alpha2.PingSourceList{} + _ = util.UpdateGroupVersionKindWithScheme(&cJSourceList, v1alpha2.SchemeGroupVersion, scheme.Scheme) + pingRecorder.ListPingSource(&cJSourceList, nil) + + out, err := executePingSourceCommand(pingClient, nil, "list", "-o", "json") + assert.NilError(t, err, "Sources should be listed") + assert.Assert(t, util.ContainsAll(out, "\"apiVersion\": \"sources.knative.dev/v1alpha2\"", "\"items\": []", "\"kind\": \"PingSourceList\"")) + + pingRecorder.Validate() +} diff --git a/pkg/kn/commands/subscription/list.go b/pkg/kn/commands/subscription/list.go index 8a8101bc2e..d77da3741d 100644 --- a/pkg/kn/commands/subscription/list.go +++ b/pkg/kn/commands/subscription/list.go @@ -19,6 +19,10 @@ package subscription import ( "fmt" + "knative.dev/client/pkg/util" + messagingv1 "knative.dev/eventing/pkg/apis/messaging/v1" + "knative.dev/eventing/pkg/client/clientset/versioned/scheme" + "github.com/spf13/cobra" "knative.dev/client/pkg/kn/commands" @@ -52,7 +56,14 @@ func NewSubscriptionListCommand(p *commands.KnParams) *cobra.Command { return err } - if subscriptionList == nil || len(subscriptionList.Items) == 0 { + if subscriptionList == nil { + subscriptionList = &messagingv1.SubscriptionList{} + err := util.UpdateGroupVersionKindWithScheme(subscriptionList, messagingv1.SchemeGroupVersion, scheme.Scheme) + if err != nil { + return err + } + } + if !listFlags.GenericPrintFlags.OutputFlagSpecified() && len(subscriptionList.Items) == 0 { fmt.Fprintf(cmd.OutOrStdout(), "No subscriptions found.\n") return nil } diff --git a/pkg/kn/commands/subscription/list_test.go b/pkg/kn/commands/subscription/list_test.go index f8ebd162b2..fb2034a1ce 100644 --- a/pkg/kn/commands/subscription/list_test.go +++ b/pkg/kn/commands/subscription/list_test.go @@ -20,6 +20,8 @@ import ( "strings" "testing" + "knative.dev/eventing/pkg/client/clientset/versioned/scheme" + "gotest.tools/v3/assert" messagingv1 "knative.dev/eventing/pkg/apis/messaging/v1" @@ -37,6 +39,18 @@ func TestSubscriptionListNoSubscriptionsFound(t *testing.T) { cRecorder.Validate() } +func TestSubscriptionListNoSubscriptionsWithJsonOutput(t *testing.T) { + cClient := v1beta1.NewMockKnSubscriptionsClient(t) + cRecorder := cClient.Recorder() + clist := &messagingv1.SubscriptionList{} + _ = util.UpdateGroupVersionKindWithScheme(clist, messagingv1.SchemeGroupVersion, scheme.Scheme) + cRecorder.ListSubscription(clist, nil) + out, err := executeSubscriptionCommand(cClient, nil, "list", "-o", "json") + assert.NilError(t, err) + assert.Check(t, util.ContainsAll(out, "\"apiVersion\": \"messaging.knative.dev/v1\"", "\"items\": []", "\"kind\": \"SubscriptionList\"")) + cRecorder.Validate() +} + func TestSubscriptionList(t *testing.T) { cClient := v1beta1.NewMockKnSubscriptionsClient(t) cRecorder := cClient.Recorder() diff --git a/pkg/kn/commands/trigger/list.go b/pkg/kn/commands/trigger/list.go index ad751a9463..7c952a2bab 100644 --- a/pkg/kn/commands/trigger/list.go +++ b/pkg/kn/commands/trigger/list.go @@ -50,7 +50,7 @@ func NewTriggerListCommand(p *commands.KnParams) *cobra.Command { if err != nil { return err } - if len(triggerList.Items) == 0 { + if !triggerListFlags.GenericPrintFlags.OutputFlagSpecified() && len(triggerList.Items) == 0 { fmt.Fprintf(cmd.OutOrStdout(), "No triggers found.\n") return nil } diff --git a/pkg/kn/commands/trigger/list_test.go b/pkg/kn/commands/trigger/list_test.go index 0896e18883..df33b61026 100644 --- a/pkg/kn/commands/trigger/list_test.go +++ b/pkg/kn/commands/trigger/list_test.go @@ -18,6 +18,8 @@ import ( "strings" "testing" + "knative.dev/eventing/pkg/client/clientset/versioned/scheme" + "gotest.tools/v3/assert" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" eventingv1 "knative.dev/eventing/pkg/apis/eventing/v1" @@ -69,6 +71,19 @@ func TestTriggerListEmpty(t *testing.T) { eventingRecorder.Validate() } +func TestTriggerListEmptyWithJsonOutput(t *testing.T) { + eventingClient := clienteventingv1.NewMockKnEventingClient(t) + eventingRecorder := eventingClient.Recorder() + triggerList := &eventingv1.TriggerList{} + util.UpdateGroupVersionKindWithScheme(triggerList, eventingv1.SchemeGroupVersion, scheme.Scheme) + eventingRecorder.ListTriggers(triggerList, nil) + output, err := executeTriggerCommand(eventingClient, nil, "list", "-o", "json") + assert.NilError(t, err) + assert.Assert(t, util.ContainsAll(output, " \"apiVersion\": \"eventing.knative.dev/v1\"", "\"kind\": \"TriggerList\"", "\"items\": [],")) + + eventingRecorder.Validate() +} + func TestTriggerListAllNamespace(t *testing.T) { servingClient := clientservingv1.NewMockKnServiceClient(t) servingRecorder := servingClient.Recorder() diff --git a/test/e2e/source_list_test.go b/test/e2e/source_list_test.go index 94473351fe..69bd8ad6c6 100644 --- a/test/e2e/source_list_test.go +++ b/test/e2e/source_list_test.go @@ -88,7 +88,7 @@ func TestSourceList(t *testing.T) { output = sourceList(r, "--type", "testapisource0") assert.Check(t, util.ContainsAll(output, "No", "sources", "found.")) output = sourceList(r, "--type", "TestSource", "-oyaml") - assert.Check(t, util.ContainsAll(output, "No", "sources", "found.")) + assert.Check(t, util.ContainsAll(output, "apiVersion", "client.knative.dev/v1alpha1", "items", "[]", "kind", "SourceList")) t.Log("List available source in YAML format") output = sourceList(r, "--type", "PingSource,ApiServerSource", "-oyaml")