diff --git a/pkg/controller/notification/notification_controller_suite_test.go b/pkg/controller/notification/notification_controller_suite_test.go deleted file mode 100644 index eb214c14c..000000000 --- a/pkg/controller/notification/notification_controller_suite_test.go +++ /dev/null @@ -1,63 +0,0 @@ -/* -Copyright 2020 The KubeSphere 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 notification - -import ( - "path/filepath" - "testing" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" - "sigs.k8s.io/controller-runtime/pkg/envtest" - "sigs.k8s.io/controller-runtime/pkg/envtest/printer" - - "kubesphere.io/api/notification/v2beta1" - - "kubesphere.io/kubesphere/pkg/apis" -) - -func TestSource(t *testing.T) { - RegisterFailHandler(Fail) - suiteName := "Cache Suite" - RunSpecsWithDefaultAndCustomReporters(t, suiteName, []Reporter{printer.NewlineReporter{}, printer.NewProwReporter(suiteName)}) -} - -var testenv *envtest.Environment -var cfg *rest.Config - -var _ = BeforeSuite(func(done Done) { - - testenv = &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crds")}, - } - - var err error - cfg, err = testenv.Start() - Expect(err).NotTo(HaveOccurred()) - Expect(cfg).ToNot(BeNil()) - - Expect(v2beta1.AddToScheme(scheme.Scheme)).NotTo(HaveOccurred()) - Expect(apis.AddToScheme(scheme.Scheme)).NotTo(HaveOccurred()) - - close(done) -}, 60) - -var _ = AfterSuite(func() { - Expect(testenv.Stop()).To(Succeed()) -}) diff --git a/pkg/controller/notification/notification_controller_test.go b/pkg/controller/notification/notification_controller_test.go index 76b82a65e..3ae7cc82c 100644 --- a/pkg/controller/notification/notification_controller_test.go +++ b/pkg/controller/notification/notification_controller_test.go @@ -18,36 +18,47 @@ package notification import ( "context" + "testing" "time" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/kubernetes" fakek8s "k8s.io/client-go/kubernetes/fake" "sigs.k8s.io/controller-runtime/pkg/cache" "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/client/fake" + "sigs.k8s.io/controller-runtime/pkg/envtest/printer" "kubesphere.io/api/cluster/v1alpha1" "kubesphere.io/api/notification/v2beta1" "kubesphere.io/api/types/v1beta1" + k8sinformers "k8s.io/client-go/informers" + "k8s.io/client-go/kubernetes/scheme" + + "kubesphere.io/kubesphere/pkg/apis" "kubesphere.io/kubesphere/pkg/constants" ) +func TestSource(t *testing.T) { + RegisterFailHandler(Fail) + suiteName := "Cache Suite" + RunSpecsWithDefaultAndCustomReporters(t, suiteName, []Reporter{printer.NewlineReporter{}, printer.NewProwReporter(suiteName)}) +} + var ( _ = Describe("Secret", func() { + v2beta1.AddToScheme(scheme.Scheme) + apis.AddToScheme(scheme.Scheme) const timeout = time.Second * 30 const interval = time.Second * 1 - namespace := &corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: constants.NotificationSecretNamespace, - }, - } - secret := &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "foo", @@ -83,39 +94,19 @@ var ( } var ( - cl client.Client - ksCache cache.Cache - informerCacheCtx context.Context - informerCacheCancel context.CancelFunc + cl client.Client + ksCache cache.Cache + k8sClient kubernetes.Interface + informerCacheCtx context.Context ) - BeforeEach(func() { - var err error - cl, err = client.New(cfg, client.Options{}) - Expect(err).NotTo(HaveOccurred()) - - ksCache, err = cache.New(cfg, cache.Options{}) - Expect(err).NotTo(HaveOccurred()) - - informerCacheCtx, informerCacheCancel = context.WithCancel(context.Background()) - go func(ctx context.Context) { - defer GinkgoRecover() - Expect(ksCache.Start(ctx.Done())).To(Succeed()) - }(informerCacheCtx) - Expect(ksCache.WaitForCacheSync(informerCacheCtx.Done())).To(BeTrue()) - - Eventually(func() bool { - err = cl.Create(informerCacheCtx, namespace) - if err == nil || errors.IsAlreadyExists(err) { - return true - } - return false - }, timeout, interval).Should(BeTrue()) - }) - - AfterEach(func() { - By("cleaning up") - informerCacheCancel() + k8sClient = fakek8s.NewSimpleClientset() + cl = fake.NewFakeClientWithScheme(scheme.Scheme) + informerCacheCtx = context.TODO() + ksCache = &fakeCache{ + k8sClient, + cl, + } }) // Add Tests for OpenAPI validation (or additional CRD features) specified in @@ -125,7 +116,7 @@ var ( Context("Notification Controller", func() { It("Should create successfully", func() { - r, err := NewController(fakek8s.NewSimpleClientset(), cl, ksCache) + r, err := NewController(k8sClient, cl, ksCache) Expect(err).ToNot(HaveOccurred()) // Create a secret @@ -134,11 +125,10 @@ var ( fedSecret := &v1beta1.FederatedSecret{} By("Expecting to create federated secret successfully") - Eventually(func() bool { - err := ksCache.Get(context.Background(), client.ObjectKey{Name: secret.Name, Namespace: constants.NotificationSecretNamespace}, fedSecret) - Expect(err).Should(Succeed()) - return !fedSecret.CreationTimestamp.IsZero() - }, timeout, interval).Should(BeTrue()) + + err = ksCache.Get(context.Background(), client.ObjectKey{Name: secret.Name, Namespace: constants.NotificationSecretNamespace}, fedSecret) + Expect(err).Should(Succeed()) + Expect(fedSecret.Name).Should(Equal(secret.Name)) // Update a secret err = ksCache.Get(context.Background(), client.ObjectKey{Name: secret.Name, Namespace: constants.NotificationSecretNamespace}, secret) @@ -148,11 +138,10 @@ var ( Expect(r.reconcile(secret)).Should(Succeed()) By("Expecting to update federated secret successfully") - Eventually(func() bool { - err := ksCache.Get(context.Background(), client.ObjectKey{Name: secret.Name, Namespace: constants.NotificationSecretNamespace}, fedSecret) - Expect(err).Should(Succeed()) - return string(fedSecret.Spec.Template.Data["foo"]) == "bar" - }, timeout, interval).Should(BeTrue()) + + err = ksCache.Get(context.Background(), client.ObjectKey{Name: secret.Name, Namespace: constants.NotificationSecretNamespace}, fedSecret) + Expect(err).Should(Succeed()) + Expect(fedSecret.Spec.Template.StringData["foo"]).Should(Equal("bar")) // Create a Config Expect(cl.Create(context.Background(), config)).Should(Succeed()) @@ -160,11 +149,9 @@ var ( fedConfig := &v1beta1.FederatedNotificationConfig{} By("Expecting to create federated object successfully") - Eventually(func() bool { - err := ksCache.Get(context.Background(), client.ObjectKey{Name: config.Name}, fedConfig) - Expect(err).Should(Succeed()) - return !fedConfig.CreationTimestamp.IsZero() - }, timeout, interval).Should(BeTrue()) + err = ksCache.Get(context.Background(), client.ObjectKey{Name: config.Name}, fedConfig) + Expect(err).Should(Succeed()) + Expect(fedConfig.Name).Should(Equal(config.Name)) // Update a config err = ksCache.Get(context.Background(), client.ObjectKey{Name: config.Name}, config) @@ -174,11 +161,9 @@ var ( Expect(r.reconcile(config)).Should(Succeed()) By("Expecting to update federated object successfully") - Eventually(func() bool { - err := ksCache.Get(context.Background(), client.ObjectKey{Name: config.Name}, fedConfig) - Expect(err).Should(Succeed()) - return fedConfig.Spec.Template.Labels["foo"] == "bar" - }, timeout, interval).Should(BeTrue()) + err = ksCache.Get(context.Background(), client.ObjectKey{Name: config.Name}, fedConfig) + Expect(err).Should(Succeed()) + Expect(fedConfig.Spec.Template.Labels["foo"]).Should(Equal("bar")) // Create a receiver Expect(cl.Create(context.Background(), receiver)).Should(Succeed()) @@ -186,11 +171,9 @@ var ( fedReceiver := &v1beta1.FederatedNotificationReceiver{} By("Expecting to create federated object successfully") - Eventually(func() bool { - err := ksCache.Get(context.Background(), client.ObjectKey{Name: receiver.Name}, fedReceiver) - Expect(err).Should(Succeed()) - return !fedReceiver.CreationTimestamp.IsZero() - }, timeout, interval).Should(BeTrue()) + err = ksCache.Get(context.Background(), client.ObjectKey{Name: receiver.Name}, fedReceiver) + Expect(err).Should(Succeed()) + Expect(fedReceiver.Name).Should(Equal(receiver.Name)) // Update a receiver err = ksCache.Get(context.Background(), client.ObjectKey{Name: receiver.Name}, receiver) @@ -200,47 +183,64 @@ var ( Expect(r.reconcile(receiver)).Should(Succeed()) By("Expecting to update federated object successfully") - Eventually(func() bool { - err := ksCache.Get(context.Background(), client.ObjectKey{Name: receiver.Name}, fedReceiver) - Expect(err).Should(Succeed()) - return fedReceiver.Spec.Template.Labels["foo"] == "bar" - }, timeout, interval).Should(BeTrue()) + + err = ksCache.Get(context.Background(), client.ObjectKey{Name: receiver.Name}, fedReceiver) + Expect(err).Should(Succeed()) + Expect(fedReceiver.Spec.Template.Labels["foo"]).Should(Equal("bar")) // Add a cluster Expect(cl.Create(informerCacheCtx, host)).Should(Succeed()) Expect(r.reconcile(secret)).Should(Succeed()) By("Expecting to update federated secret successfully") - Eventually(func() bool { - err := ksCache.Get(context.Background(), client.ObjectKey{Name: secret.Name, Namespace: constants.NotificationSecretNamespace}, fedSecret) - Expect(err).Should(Succeed()) - if fedSecret.Spec.Overrides == nil || - len(fedSecret.Spec.Overrides) != 1 || - fedSecret.Spec.Overrides[0].ClusterName != "host" { - return false - } + err = ksCache.Get(context.Background(), client.ObjectKey{Name: secret.Name, Namespace: constants.NotificationSecretNamespace}, fedSecret) + Expect(err).Should(Succeed()) - return true - }, timeout, interval).Should(BeTrue()) + Expect(fedSecret.Spec.Overrides[0].ClusterName).Should(Equal("host")) // Delete a cluster Expect(cl.Delete(informerCacheCtx, host)).Should(Succeed()) Expect(r.reconcile(secret)).Should(Succeed()) By("Expecting to update federated secret successfully") - Eventually(func() bool { - err := ksCache.Get(context.Background(), client.ObjectKey{Name: secret.Name, Namespace: constants.NotificationSecretNamespace}, fedSecret) - Expect(err).Should(Succeed()) - if fedSecret.Spec.Overrides != nil || - len(fedSecret.Spec.Overrides) != 0 { - return false - } + fedSecret = &v1beta1.FederatedSecret{} + err = ksCache.Get(context.Background(), client.ObjectKey{Name: secret.Name, Namespace: constants.NotificationSecretNamespace}, fedSecret) + Expect(err).Should(Succeed()) + Expect(fedSecret.Spec.Overrides).Should(BeNil()) - return true - }, timeout, interval).Should(BeTrue()) }) }) }) ) + +const defaultResync = 600 * time.Second + +type fakeCache struct { + K8sClient kubernetes.Interface + client.Reader +} + +// GetInformerForKind returns the informer for the GroupVersionKind +func (f *fakeCache) GetInformerForKind(ctx context.Context, gvk schema.GroupVersionKind) (cache.Informer, error) { + return nil, nil +} + +// GetInformer returns the informer for the obj +func (f *fakeCache) GetInformer(ctx context.Context, obj runtime.Object) (cache.Informer, error) { + fakeInformerFactory := k8sinformers.NewSharedInformerFactory(f.K8sClient, defaultResync) + return fakeInformerFactory.Core().V1().Namespaces().Informer(), nil +} + +func (f *fakeCache) IndexField(ctx context.Context, obj runtime.Object, field string, extractValue client.IndexerFunc) error { + return nil +} + +func (f *fakeCache) Start(stopCh <-chan struct{}) error { + return nil +} + +func (f *fakeCache) WaitForCacheSync(stop <-chan struct{}) bool { + return true +}