From fb5518b62357be9ed6236b16362d64c10df2e2ed Mon Sep 17 00:00:00 2001 From: Ali Ok Date: Mon, 27 Apr 2020 02:34:13 +0300 Subject: [PATCH 1/4] Channel conformance tests for spec.subscriber --- test/conformance/channel_spec_test.go | 30 ++++ .../helpers/channel_spec_test_helper.go | 132 ++++++++++++++++++ 2 files changed, 162 insertions(+) create mode 100644 test/conformance/channel_spec_test.go create mode 100644 test/conformance/helpers/channel_spec_test_helper.go diff --git a/test/conformance/channel_spec_test.go b/test/conformance/channel_spec_test.go new file mode 100644 index 00000000000..ec137d2a93b --- /dev/null +++ b/test/conformance/channel_spec_test.go @@ -0,0 +1,30 @@ +// +build e2e + +/* +Copyright 2020 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 conformance + +import ( + "testing" + + "knative.dev/eventing/test/conformance/helpers" + "knative.dev/eventing/test/lib" +) + +func TestChannelSpec(t *testing.T) { + helpers.ChannelSpecTestHelperWithChannelTestRunner(t, channelTestRunner, lib.SetupClientOptionNoop) +} diff --git a/test/conformance/helpers/channel_spec_test_helper.go b/test/conformance/helpers/channel_spec_test_helper.go new file mode 100644 index 00000000000..506358fd67e --- /dev/null +++ b/test/conformance/helpers/channel_spec_test_helper.go @@ -0,0 +1,132 @@ +/* +Copyright 2020 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 helpers + +import ( + "testing" + + "encoding/json" + + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apiserver/pkg/storage/names" + + eventingduckv1alpha1 "knative.dev/eventing/pkg/apis/duck/v1alpha1" + eventingduckv1beta1 "knative.dev/eventing/pkg/apis/duck/v1beta1" + "knative.dev/eventing/test/lib" + "knative.dev/pkg/apis" +) + +func ChannelSpecTestHelperWithChannelTestRunner( + t *testing.T, + channelTestRunner lib.ChannelTestRunner, + options ...lib.SetupClientOption, +) { + + channelTestRunner.RunTests(t, lib.FeatureBasic, func(st *testing.T, channel metav1.TypeMeta) { + client := lib.Setup(st, true, options...) + defer lib.TearDown(client) + + t.Run("Channel spec allows subscribers", func(t *testing.T) { + channelSpecAllowsRequiredFields(st, client, channel) + }) + }) +} + +func channelSpecAllowsRequiredFields(st *testing.T, client *lib.Client, channel metav1.TypeMeta, options ...lib.SetupClientOption) { + st.Logf("Running channel spec conformance test with channel %q", channel) + + dtsv, err := getChannelDuckTypeSupportVersionFromTypeMeta(client, channel) + if err != nil { + st.Fatalf("Unable to check Channel duck type support version for %q: %q", channel, err) + } + + channelName := names.SimpleNameGenerator.GenerateName("channel-spec-req-fields-") + client.T.Logf("Creating channel %+v-%s", channel, channelName) + client.CreateChannelOrFail(channelName, &channel) + client.WaitForResourceReadyOrFail(channelName, &channel) + + sampleUrl, _ := apis.ParseURL("http://example.com") + gvr, _ := meta.UnsafeGuessKindToResource(channel.GroupVersionKind()) + + var ch interface{} + + if dtsv == "" || dtsv == "v1alpha1" { + // treat missing annotation value as v1alpha1, as written in the spec + channelable, err := getChannelAsV1Alpha1Channelable(channelName, client, channel) + if err != nil { + st.Fatalf("Unable to get channel %q to v1alpha1 duck type: %q", channel, err) + } + + // SPEC: each channel CRD MUST contain an array of subscribers: spec.subscribable.subscribers + channelable.Spec.Subscribable = &eventingduckv1alpha1.Subscribable{ + Subscribers: []eventingduckv1alpha1.SubscriberSpec{ + { + UID: "1234", + ReplyURI: sampleUrl, + }, + }, + } + + ch = channelable + + } else if dtsv == "v1beta1" { + channelable, err := getChannelAsV1Beta1Channelable(channelName, client, channel) + if err != nil { + st.Fatalf("Unable to get channel %q to v1beta1 duck type: %q", channel, err) + } + + // SPEC: each channel CRD MUST contain an array of subscribers: spec.subscribers + channelable.Spec.Subscribers = []eventingduckv1beta1.SubscriberSpec{ + { + UID: "1234", + ReplyURI: sampleUrl, + }, + } + + ch = channelable + } else { + st.Fatalf("Channel doesn't support v1alpha1 nor v1beta1 Channel duck types: %q", channel) + } + + raw, err := json.Marshal(ch) + if err != nil { + st.Fatalf("Error marshaling %q: %q", channel, err) + } + u := &unstructured.Unstructured{} + err = json.Unmarshal(raw, u) + if err != nil { + st.Fatalf("Error unmarshaling %q: %q", u, err) + } + + _, err = client.Dynamic.Resource(gvr).Namespace(client.Namespace).Update(u, metav1.UpdateOptions{}) + if err != nil { + st.Fatalf("Error updating %q with subscribers in spec: %q", channel, err) + } +} + +func getChannelDuckTypeSupportVersionFromTypeMeta(client *lib.Client, channel metav1.TypeMeta) (string, error) { + // the only way is to create one and see + channelName := names.SimpleNameGenerator.GenerateName("channel-tmp-") + + client.T.Logf("Creating channel %+v-%s", channel, channelName) + client.CreateChannelOrFail(channelName, &channel) + client.WaitForResourceReadyOrFail(channelName, &channel) + + return getChannelDuckTypeSupportVersion(channelName, client, &channel) +} From 28b90a976355567a107668a4aacd9d6f302b0c98 Mon Sep 17 00:00:00 2001 From: Ali Ok Date: Thu, 14 May 2020 10:15:06 +0300 Subject: [PATCH 2/4] Skip channel conformance tests for spec.subscriber for generic `Channel` --- test/conformance/helpers/channel.go | 12 ++++++++++++ test/conformance/helpers/channel_spec_test_helper.go | 9 ++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/test/conformance/helpers/channel.go b/test/conformance/helpers/channel.go index 097ea75da78..e1742688061 100644 --- a/test/conformance/helpers/channel.go +++ b/test/conformance/helpers/channel.go @@ -31,6 +31,18 @@ const ( SubscribableAnnotationKey = "messaging.knative.dev/subscribable" ) +var ( + channelv1alpha1 = metav1.TypeMeta{ + Kind: "Channel", + APIVersion: "messaging.knative.dev/v1alpha1", + } + + channelv1beta1 = metav1.TypeMeta{ + Kind: "Channel", + APIVersion: "messaging.knative.dev/v1beta1", + } +) + func getChannelDuckTypeSupportVersion(channelName string, client *lib.Client, channel *metav1.TypeMeta) (string, error) { metaResource := resources.NewMetaResource(channelName, client.Namespace, channel) obj, err := duck.GetGenericObject(client.Dynamic, metaResource, &eventingduckv1beta1.Channelable{}) diff --git a/test/conformance/helpers/channel_spec_test_helper.go b/test/conformance/helpers/channel_spec_test_helper.go index 506358fd67e..f46e9cbbf11 100644 --- a/test/conformance/helpers/channel_spec_test_helper.go +++ b/test/conformance/helpers/channel_spec_test_helper.go @@ -43,12 +43,15 @@ func ChannelSpecTestHelperWithChannelTestRunner( defer lib.TearDown(client) t.Run("Channel spec allows subscribers", func(t *testing.T) { - channelSpecAllowsRequiredFields(st, client, channel) + if channel == channelv1alpha1 || channel == channelv1beta1 { + t.Skip("Not running spec.subscribers array test for generic Channel") + } + channelSpecAllowsSubscribersArray(st, client, channel) }) }) } -func channelSpecAllowsRequiredFields(st *testing.T, client *lib.Client, channel metav1.TypeMeta, options ...lib.SetupClientOption) { +func channelSpecAllowsSubscribersArray(st *testing.T, client *lib.Client, channel metav1.TypeMeta, options ...lib.SetupClientOption) { st.Logf("Running channel spec conformance test with channel %q", channel) dtsv, err := getChannelDuckTypeSupportVersionFromTypeMeta(client, channel) @@ -56,7 +59,7 @@ func channelSpecAllowsRequiredFields(st *testing.T, client *lib.Client, channel st.Fatalf("Unable to check Channel duck type support version for %q: %q", channel, err) } - channelName := names.SimpleNameGenerator.GenerateName("channel-spec-req-fields-") + channelName := names.SimpleNameGenerator.GenerateName("channel-spec-subscribers-") client.T.Logf("Creating channel %+v-%s", channel, channelName) client.CreateChannelOrFail(channelName, &channel) client.WaitForResourceReadyOrFail(channelName, &channel) From c1f2ea6a214d6b9fad4920db923d331de97f6941 Mon Sep 17 00:00:00 2001 From: Ali Ok Date: Fri, 15 May 2020 09:54:55 +0300 Subject: [PATCH 3/4] Get rid of hardcoded `Channel` GVK strings --- test/conformance/helpers/channel.go | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/test/conformance/helpers/channel.go b/test/conformance/helpers/channel.go index e1742688061..a574ef4dd53 100644 --- a/test/conformance/helpers/channel.go +++ b/test/conformance/helpers/channel.go @@ -25,6 +25,9 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" eventingduckv1alpha1 "knative.dev/eventing/pkg/apis/duck/v1alpha1" eventingduckv1beta1 "knative.dev/eventing/pkg/apis/duck/v1beta1" + + messagingv1alpha1 "knative.dev/eventing/pkg/apis/messaging/v1alpha1" + messagingv1beta1 "knative.dev/eventing/pkg/apis/messaging/v1beta1" ) const ( @@ -32,14 +35,17 @@ const ( ) var ( + channelv1alpha1GVK = (&messagingv1alpha1.Channel{}).GetGroupVersionKind() + channelv1beta1GVK = (&messagingv1beta1.Channel{}).GetGroupVersionKind() + channelv1alpha1 = metav1.TypeMeta{ - Kind: "Channel", - APIVersion: "messaging.knative.dev/v1alpha1", + Kind: channelv1alpha1GVK.Kind, + APIVersion: channelv1alpha1GVK.GroupVersion().String(), } channelv1beta1 = metav1.TypeMeta{ - Kind: "Channel", - APIVersion: "messaging.knative.dev/v1beta1", + Kind: channelv1beta1GVK.Kind, + APIVersion: channelv1beta1GVK.GroupVersion().String(), } ) From 87ccd27349854263db71b3cbc06e71b0e2cfd4b3 Mon Sep 17 00:00:00 2001 From: Ali Ok Date: Fri, 15 May 2020 10:06:55 +0300 Subject: [PATCH 4/4] Change %q with %s --- .../helpers/channel_spec_test_helper.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/conformance/helpers/channel_spec_test_helper.go b/test/conformance/helpers/channel_spec_test_helper.go index f46e9cbbf11..191714cb872 100644 --- a/test/conformance/helpers/channel_spec_test_helper.go +++ b/test/conformance/helpers/channel_spec_test_helper.go @@ -52,11 +52,11 @@ func ChannelSpecTestHelperWithChannelTestRunner( } func channelSpecAllowsSubscribersArray(st *testing.T, client *lib.Client, channel metav1.TypeMeta, options ...lib.SetupClientOption) { - st.Logf("Running channel spec conformance test with channel %q", channel) + st.Logf("Running channel spec conformance test with channel %s", channel) dtsv, err := getChannelDuckTypeSupportVersionFromTypeMeta(client, channel) if err != nil { - st.Fatalf("Unable to check Channel duck type support version for %q: %q", channel, err) + st.Fatalf("Unable to check Channel duck type support version for %s: %s", channel, err) } channelName := names.SimpleNameGenerator.GenerateName("channel-spec-subscribers-") @@ -73,7 +73,7 @@ func channelSpecAllowsSubscribersArray(st *testing.T, client *lib.Client, channe // treat missing annotation value as v1alpha1, as written in the spec channelable, err := getChannelAsV1Alpha1Channelable(channelName, client, channel) if err != nil { - st.Fatalf("Unable to get channel %q to v1alpha1 duck type: %q", channel, err) + st.Fatalf("Unable to get channel %s to v1alpha1 duck type: %s", channel, err) } // SPEC: each channel CRD MUST contain an array of subscribers: spec.subscribable.subscribers @@ -91,7 +91,7 @@ func channelSpecAllowsSubscribersArray(st *testing.T, client *lib.Client, channe } else if dtsv == "v1beta1" { channelable, err := getChannelAsV1Beta1Channelable(channelName, client, channel) if err != nil { - st.Fatalf("Unable to get channel %q to v1beta1 duck type: %q", channel, err) + st.Fatalf("Unable to get channel %s to v1beta1 duck type: %s", channel, err) } // SPEC: each channel CRD MUST contain an array of subscribers: spec.subscribers @@ -104,22 +104,22 @@ func channelSpecAllowsSubscribersArray(st *testing.T, client *lib.Client, channe ch = channelable } else { - st.Fatalf("Channel doesn't support v1alpha1 nor v1beta1 Channel duck types: %q", channel) + st.Fatalf("Channel doesn't support v1alpha1 nor v1beta1 Channel duck types: %s", channel) } raw, err := json.Marshal(ch) if err != nil { - st.Fatalf("Error marshaling %q: %q", channel, err) + st.Fatalf("Error marshaling %s: %s", channel, err) } u := &unstructured.Unstructured{} err = json.Unmarshal(raw, u) if err != nil { - st.Fatalf("Error unmarshaling %q: %q", u, err) + st.Fatalf("Error unmarshaling %s: %s", u, err) } _, err = client.Dynamic.Resource(gvr).Namespace(client.Namespace).Update(u, metav1.UpdateOptions{}) if err != nil { - st.Fatalf("Error updating %q with subscribers in spec: %q", channel, err) + st.Fatalf("Error updating %s with subscribers in spec: %s", channel, err) } }