diff --git a/pkg/controller/serviceaccount/serviceaccount_controller_suite_test.go b/pkg/controller/serviceaccount/serviceaccount_controller_suite_test.go deleted file mode 100644 index 174a96d7ab05eb54d1e18a3e983114e55f28cc68..0000000000000000000000000000000000000000 --- a/pkg/controller/serviceaccount/serviceaccount_controller_suite_test.go +++ /dev/null @@ -1,101 +0,0 @@ -/* -Copyright 2019 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 serviceaccount - -import ( - "os" - "path/filepath" - "testing" - "time" - - "github.com/onsi/gomega/gexec" - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/klog/klogr" - "kubesphere.io/kubesphere/pkg/apis" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - logf "sigs.k8s.io/controller-runtime/pkg/log" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - "sigs.k8s.io/controller-runtime/pkg/envtest" - "sigs.k8s.io/controller-runtime/pkg/envtest/printer" -) - -// These tests use Ginkgo (BDD-style Go testing framework). Refer to -// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. - -var k8sClient client.Client -var k8sManager ctrl.Manager -var testEnv *envtest.Environment - -func TestServiceAccountController(t *testing.T) { - RegisterFailHandler(Fail) - RunSpecsWithDefaultAndCustomReporters(t, - "ServiceAccount Controller Test Suite", - []Reporter{printer.NewlineReporter{}}) -} - -var _ = BeforeSuite(func(done Done) { - logf.SetLogger(klogr.New()) - - By("bootstrapping test environment") - t := true - if os.Getenv("TEST_USE_EXISTING_CLUSTER") == "true" { - testEnv = &envtest.Environment{ - UseExistingCluster: &t, - } - } else { - testEnv = &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crds")}, - AttachControlPlaneOutput: false, - } - } - - cfg, err := testEnv.Start() - Expect(err).ToNot(HaveOccurred()) - Expect(cfg).ToNot(BeNil()) - - err = apis.AddToScheme(scheme.Scheme) - Expect(err).NotTo(HaveOccurred()) - - k8sManager, err = ctrl.NewManager(cfg, ctrl.Options{ - Scheme: scheme.Scheme, - MetricsBindAddress: "0", - }) - Expect(err).ToNot(HaveOccurred()) - - err = (&Reconciler{}).SetupWithManager(k8sManager) - Expect(err).ToNot(HaveOccurred()) - - go func() { - err = k8sManager.Start(ctrl.SetupSignalHandler()) - Expect(err).ToNot(HaveOccurred()) - }() - - k8sClient = k8sManager.GetClient() - Expect(k8sClient).ToNot(BeNil()) - - close(done) -}, 160) - -var _ = AfterSuite(func() { - By("tearing down the test environment") - gexec.KillAndWait(5 * time.Second) - err := testEnv.Stop() - Expect(err).ToNot(HaveOccurred()) -}) diff --git a/pkg/controller/serviceaccount/serviceaccount_controller_test.go b/pkg/controller/serviceaccount/serviceaccount_controller_test.go index 2d65ca3d726a3d0392b50fcced6b01a0ed534ec2..fccdd3762a3c18bbf21099b2027cb850a2d6bb3f 100644 --- a/pkg/controller/serviceaccount/serviceaccount_controller_test.go +++ b/pkg/controller/serviceaccount/serviceaccount_controller_test.go @@ -18,35 +18,60 @@ package serviceaccount import ( "context" - "time" + "testing" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/tools/record" iamv1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2" + "kubesphere.io/kubesphere/pkg/utils/k8sutil" + ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/client/fake" ) +func TestServiceAccountController(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "KubeSphere e2e suite") +} + var _ = Describe("ServiceAccount", func() { const ( saName = "test-serviceaccount" saNamespace = "default" saRole = "test-role" - timeout = time.Second * 30 - interval = time.Second * 1 ) - role := &rbacv1.Role{ - ObjectMeta: metav1.ObjectMeta{ - Name: saRole, - Namespace: saNamespace, - }, - } + var role *rbacv1.Role + var sa *corev1.ServiceAccount + var req ctrl.Request + BeforeEach(func() { - // Create workspace - Expect(k8sClient.Create(context.Background(), role)).Should(Succeed()) + role = &rbacv1.Role{ + ObjectMeta: metav1.ObjectMeta{ + Name: saRole, + Namespace: saNamespace, + }, + } + + sa = &corev1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{ + Name: saName, + Namespace: saNamespace, + Annotations: map[string]string{iamv1alpha2.RoleAnnotation: saRole}, + }, + } + req = ctrl.Request{ + NamespacedName: types.NamespacedName{ + Namespace: saNamespace, + Name: saName, + }, + } }) // Add Tests for OpenAPI validation (or additonal CRD features) specified in @@ -54,30 +79,43 @@ var _ = Describe("ServiceAccount", func() { // Avoid adding tests for vanilla CRUD operations because they would // test Kubernetes API server, which isn't the goal here. Context("ServiceAccount Controller", func() { - It("Should create successfully", func() { + It("Should create ServiceAccount successfully and create a rolebinding", func() { ctx := context.Background() - sa := &corev1.ServiceAccount{ - ObjectMeta: metav1.ObjectMeta{ - Name: saName, - Namespace: saNamespace, - Annotations: map[string]string{iamv1alpha2.RoleAnnotation: saRole}, - }, + + reconciler := &Reconciler{ + Client: fake.NewFakeClientWithScheme(scheme.Scheme), + logger: ctrl.Log.WithName("controllers").WithName("acrpullbinding-controller"), + scheme: scheme.Scheme, + recorder: record.NewFakeRecorder(5), } - By("Expecting to create serviceaccount successfully") - Expect(k8sClient.Create(ctx, sa)).Should(Succeed()) - expectedSa := &corev1.ServiceAccount{} - Eventually(func() bool { - k8sClient.Get(ctx, types.NamespacedName{Name: sa.Name, Namespace: sa.Namespace}, expectedSa) - return !expectedSa.CreationTimestamp.IsZero() - }, timeout, interval).Should(BeTrue()) + Expect(reconciler.Create(ctx, sa)).Should(Succeed()) + Expect(reconciler.Create(ctx, role)).Should(Succeed()) + + _, err := reconciler.Reconcile(req) + Expect(err).To(BeNil()) By("Expecting to bind role successfully") rolebindings := &rbacv1.RoleBindingList{} - Eventually(func() bool { - k8sClient.List(ctx, rolebindings, client.InNamespace(sa.Namespace), client.MatchingLabels{iamv1alpha2.ServiceAccountReferenceLabel: sa.Name}) - return len(rolebindings.Items) == 1 - }, timeout, interval).Should(BeTrue()) + Expect(func() bool { + reconciler.List(ctx, rolebindings, client.InNamespace(sa.Namespace), client.MatchingLabels{iamv1alpha2.ServiceAccountReferenceLabel: sa.Name}) + return len(rolebindings.Items) == 1 && k8sutil.IsControlledBy(rolebindings.Items[0].OwnerReferences, "ServiceAccount", saName) + }()).Should(BeTrue()) + }) + + It("Should report NotFound error when role doesn't exist", func() { + ctx := context.Background() + + reconciler := &Reconciler{ + Client: fake.NewFakeClientWithScheme(scheme.Scheme), + logger: ctrl.Log.WithName("controllers").WithName("acrpullbinding-controller"), + scheme: scheme.Scheme, + recorder: record.NewFakeRecorder(5), + } + + Expect(reconciler.Create(ctx, sa)).Should(Succeed()) + _, err := reconciler.Reconcile(req) + Expect(apierrors.IsNotFound(err)).To(BeTrue()) }) }) })