diff --git a/controllers/sriovibnetwork_controller_test.go b/controllers/sriovibnetwork_controller_test.go index 6ba0d2bd80..9b2aef84e9 100644 --- a/controllers/sriovibnetwork_controller_test.go +++ b/controllers/sriovibnetwork_controller_test.go @@ -1,10 +1,11 @@ package controllers import ( - goctx "context" + "context" "fmt" "io" "strings" + "sync" "time" netattdefv1 "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1" @@ -21,7 +22,39 @@ import ( "github.com/k8snetworkplumbingwg/sriov-network-operator/test/util" ) -var _ = Describe("SriovIBNetwork Controller", func() { +var _ = Describe("SriovIBNetwork Controller", Ordered, func() { + var cancel context.CancelFunc + var ctx context.Context + + BeforeAll(func() { + By("Setup controller manager") + k8sManager, err := setupK8sManagerForTest() + Expect(err).ToNot(HaveOccurred()) + + err = (&SriovIBNetworkReconciler{ + Client: k8sManager.GetClient(), + Scheme: k8sManager.GetScheme(), + }).SetupWithManager(k8sManager) + Expect(err).ToNot(HaveOccurred()) + + ctx, cancel = context.WithCancel(context.Background()) + + wg := sync.WaitGroup{} + wg.Add(1) + go func() { + defer wg.Done() + defer GinkgoRecover() + By("Start controller manager") + err := k8sManager.Start(ctx) + Expect(err).ToNot(HaveOccurred()) + }() + + DeferCleanup(func() { + By("Shutdown controller manager") + cancel() + wg.Wait() + }) + }) Context("with SriovIBNetwork", func() { specs := map[string]sriovnetworkv1.SriovIBNetworkSpec{ @@ -52,7 +85,7 @@ var _ = Describe("SriovIBNetwork Controller", func() { By("Create the SriovIBNetwork Custom Resource") // get global framework variables - err = k8sClient.Create(goctx.TODO(), &cr) + err = k8sClient.Create(ctx, &cr) Expect(err).NotTo(HaveOccurred()) ns := testNamespace if cr.Spec.NetworkNamespace != "" { @@ -68,9 +101,9 @@ var _ = Describe("SriovIBNetwork Controller", func() { By("Delete the SriovIBNetwork Custom Resource") found := &sriovnetworkv1.SriovIBNetwork{} - err = k8sClient.Get(goctx.TODO(), types.NamespacedName{Namespace: cr.GetNamespace(), Name: cr.GetName()}, found) + err = k8sClient.Get(ctx, types.NamespacedName{Namespace: cr.GetNamespace(), Name: cr.GetName()}, found) Expect(err).NotTo(HaveOccurred()) - err = k8sClient.Delete(goctx.TODO(), found, []dynclient.DeleteOption{}...) + err = k8sClient.Delete(ctx, found, []dynclient.DeleteOption{}...) Expect(err).NotTo(HaveOccurred()) netAttDef = &netattdefv1.NetworkAttachmentDefinition{} @@ -98,11 +131,11 @@ var _ = Describe("SriovIBNetwork Controller", func() { DescribeTable("should be possible to update net-att-def", func(old, new sriovnetworkv1.SriovIBNetwork) { old.Name = new.GetName() - err := k8sClient.Create(goctx.TODO(), &old) + err := k8sClient.Create(ctx, &old) Expect(err).NotTo(HaveOccurred()) defer func() { // Cleanup the test resource - Expect(k8sClient.Delete(goctx.TODO(), &old)).To(Succeed()) + Expect(k8sClient.Delete(ctx, &old)).To(Succeed()) }() found := &sriovnetworkv1.SriovIBNetwork{} expect := generateExpectedIBNetConfig(&new) @@ -110,13 +143,13 @@ var _ = Describe("SriovIBNetwork Controller", func() { retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { // Retrieve the latest version of SriovIBNetwork before attempting update // RetryOnConflict uses exponential backoff to avoid exhausting the apiserver - getErr := k8sClient.Get(goctx.TODO(), types.NamespacedName{Namespace: old.GetNamespace(), Name: old.GetName()}, found) + getErr := k8sClient.Get(ctx, types.NamespacedName{Namespace: old.GetNamespace(), Name: old.GetName()}, found) if getErr != nil { io.WriteString(GinkgoWriter, fmt.Sprintf("Failed to get latest version of SriovIBNetwork: %v", getErr)) } found.Spec = new.Spec found.Annotations = new.Annotations - updateErr := k8sClient.Update(goctx.TODO(), found) + updateErr := k8sClient.Update(ctx, found) if getErr != nil { io.WriteString(GinkgoWriter, fmt.Sprintf("Failed to update latest version of SriovIBNetwork: %v", getErr)) } @@ -164,7 +197,7 @@ var _ = Describe("SriovIBNetwork Controller", func() { var err error expect := generateExpectedIBNetConfig(&cr) - err = k8sClient.Create(goctx.TODO(), &cr) + err = k8sClient.Create(ctx, &cr) Expect(err).NotTo(HaveOccurred()) ns := testNamespace if cr.Spec.NetworkNamespace != "" { @@ -174,7 +207,7 @@ var _ = Describe("SriovIBNetwork Controller", func() { err = util.WaitForNamespacedObject(netAttDef, k8sClient, ns, cr.GetName(), util.RetryInterval, util.Timeout) Expect(err).NotTo(HaveOccurred()) - err = k8sClient.Delete(goctx.TODO(), netAttDef) + err = k8sClient.Delete(ctx, netAttDef) Expect(err).NotTo(HaveOccurred()) time.Sleep(3 * time.Second) err = util.WaitForNamespacedObject(netAttDef, k8sClient, ns, cr.GetName(), util.RetryInterval, util.Timeout) @@ -184,9 +217,9 @@ var _ = Describe("SriovIBNetwork Controller", func() { Expect(strings.TrimSpace(netAttDef.Spec.Config)).To(Equal(expect)) found := &sriovnetworkv1.SriovIBNetwork{} - err = k8sClient.Get(goctx.TODO(), types.NamespacedName{Namespace: cr.GetNamespace(), Name: cr.GetName()}, found) + err = k8sClient.Get(ctx, types.NamespacedName{Namespace: cr.GetNamespace(), Name: cr.GetName()}, found) Expect(err).NotTo(HaveOccurred()) - err = k8sClient.Delete(goctx.TODO(), found, []dynclient.DeleteOption{}...) + err = k8sClient.Delete(ctx, found, []dynclient.DeleteOption{}...) Expect(err).NotTo(HaveOccurred()) }) }) @@ -207,11 +240,11 @@ var _ = Describe("SriovIBNetwork Controller", func() { var err error expect := generateExpectedIBNetConfig(&cr) - err = k8sClient.Create(goctx.TODO(), &cr) + err = k8sClient.Create(ctx, &cr) Expect(err).NotTo(HaveOccurred()) DeferCleanup(func() { - err = k8sClient.Delete(goctx.TODO(), &cr) + err = k8sClient.Delete(ctx, &cr) Expect(err).NotTo(HaveOccurred()) }) @@ -227,10 +260,10 @@ var _ = Describe("SriovIBNetwork Controller", func() { nsObj := &corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{Name: "ib-ns-xxx"}, } - err = k8sClient.Create(goctx.TODO(), nsObj) + err = k8sClient.Create(ctx, nsObj) Expect(err).NotTo(HaveOccurred()) DeferCleanup(func() { - err = k8sClient.Delete(goctx.TODO(), nsObj) + err = k8sClient.Delete(ctx, nsObj) Expect(err).NotTo(HaveOccurred()) }) diff --git a/controllers/sriovnetwork_controller_test.go b/controllers/sriovnetwork_controller_test.go index 9f2e5a6ae4..356b7d3cdb 100644 --- a/controllers/sriovnetwork_controller_test.go +++ b/controllers/sriovnetwork_controller_test.go @@ -1,10 +1,11 @@ package controllers import ( - goctx "context" + "context" "fmt" "io" "strings" + "sync" "time" netattdefv1 "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1" @@ -27,7 +28,39 @@ const ( emptyCurls = "{}" ) -var _ = Describe("SriovNetwork Controller", func() { +var _ = Describe("SriovNetwork Controller", Ordered, func() { + var cancel context.CancelFunc + var ctx context.Context + + BeforeAll(func() { + By("Setup controller manager") + k8sManager, err := setupK8sManagerForTest() + Expect(err).ToNot(HaveOccurred()) + + err = (&SriovNetworkReconciler{ + Client: k8sManager.GetClient(), + Scheme: k8sManager.GetScheme(), + }).SetupWithManager(k8sManager) + Expect(err).ToNot(HaveOccurred()) + + ctx, cancel = context.WithCancel(context.Background()) + + wg := sync.WaitGroup{} + wg.Add(1) + go func() { + defer wg.Done() + defer GinkgoRecover() + By("Start controller manager") + err := k8sManager.Start(ctx) + Expect(err).ToNot(HaveOccurred()) + }() + + DeferCleanup(func() { + By("Shutdown controller manager") + cancel() + wg.Wait() + }) + }) Context("with SriovNetwork", func() { specs := map[string]sriovnetworkv1.SriovNetworkSpec{ @@ -72,7 +105,7 @@ var _ = Describe("SriovNetwork Controller", func() { By("Create the SriovNetwork Custom Resource") // get global framework variables - err = k8sClient.Create(goctx.TODO(), &cr) + err = k8sClient.Create(ctx, &cr) Expect(err).NotTo(HaveOccurred()) ns := testNamespace if cr.Spec.NetworkNamespace != "" { @@ -88,9 +121,9 @@ var _ = Describe("SriovNetwork Controller", func() { By("Delete the SriovNetwork Custom Resource") found := &sriovnetworkv1.SriovNetwork{} - err = k8sClient.Get(goctx.TODO(), types.NamespacedName{Namespace: cr.GetNamespace(), Name: cr.GetName()}, found) + err = k8sClient.Get(ctx, types.NamespacedName{Namespace: cr.GetNamespace(), Name: cr.GetName()}, found) Expect(err).NotTo(HaveOccurred()) - err = k8sClient.Delete(goctx.TODO(), found, []dynclient.DeleteOption{}...) + err = k8sClient.Delete(ctx, found, []dynclient.DeleteOption{}...) Expect(err).NotTo(HaveOccurred()) netAttDef = &netattdefv1.NetworkAttachmentDefinition{} @@ -131,10 +164,10 @@ var _ = Describe("SriovNetwork Controller", func() { DescribeTable("should be possible to update net-att-def", func(old, new sriovnetworkv1.SriovNetwork) { old.Name = new.GetName() - err := k8sClient.Create(goctx.TODO(), &old) + err := k8sClient.Create(ctx, &old) defer func() { // Cleanup the test resource - Expect(k8sClient.Delete(goctx.TODO(), &old)).To(Succeed()) + Expect(k8sClient.Delete(ctx, &old)).To(Succeed()) }() Expect(err).NotTo(HaveOccurred()) found := &sriovnetworkv1.SriovNetwork{} @@ -143,13 +176,13 @@ var _ = Describe("SriovNetwork Controller", func() { retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { // Retrieve the latest version of SriovNetwork before attempting update // RetryOnConflict uses exponential backoff to avoid exhausting the apiserver - getErr := k8sClient.Get(goctx.TODO(), types.NamespacedName{Namespace: old.GetNamespace(), Name: old.GetName()}, found) + getErr := k8sClient.Get(ctx, types.NamespacedName{Namespace: old.GetNamespace(), Name: old.GetName()}, found) if getErr != nil { io.WriteString(GinkgoWriter, fmt.Sprintf("Failed to get latest version of SriovNetwork: %v", getErr)) } found.Spec = new.Spec found.Annotations = new.Annotations - updateErr := k8sClient.Update(goctx.TODO(), found) + updateErr := k8sClient.Update(ctx, found) if getErr != nil { io.WriteString(GinkgoWriter, fmt.Sprintf("Failed to update latest version of SriovNetwork: %v", getErr)) } @@ -200,7 +233,7 @@ var _ = Describe("SriovNetwork Controller", func() { var err error expect := generateExpectedNetConfig(&cr) - err = k8sClient.Create(goctx.TODO(), &cr) + err = k8sClient.Create(ctx, &cr) Expect(err).NotTo(HaveOccurred()) ns := testNamespace if cr.Spec.NetworkNamespace != "" { @@ -210,7 +243,7 @@ var _ = Describe("SriovNetwork Controller", func() { err = util.WaitForNamespacedObject(netAttDef, k8sClient, ns, cr.GetName(), util.RetryInterval, util.Timeout) Expect(err).NotTo(HaveOccurred()) - err = k8sClient.Delete(goctx.TODO(), netAttDef) + err = k8sClient.Delete(ctx, netAttDef) Expect(err).NotTo(HaveOccurred()) time.Sleep(3 * time.Second) err = util.WaitForNamespacedObject(netAttDef, k8sClient, ns, cr.GetName(), util.RetryInterval, util.Timeout) @@ -220,9 +253,9 @@ var _ = Describe("SriovNetwork Controller", func() { Expect(strings.TrimSpace(netAttDef.Spec.Config)).To(Equal(expect)) found := &sriovnetworkv1.SriovNetwork{} - err = k8sClient.Get(goctx.TODO(), types.NamespacedName{Namespace: cr.GetNamespace(), Name: cr.GetName()}, found) + err = k8sClient.Get(ctx, types.NamespacedName{Namespace: cr.GetNamespace(), Name: cr.GetName()}, found) Expect(err).NotTo(HaveOccurred()) - err = k8sClient.Delete(goctx.TODO(), found, []dynclient.DeleteOption{}...) + err = k8sClient.Delete(ctx, found, []dynclient.DeleteOption{}...) Expect(err).NotTo(HaveOccurred()) }) }) @@ -244,11 +277,11 @@ var _ = Describe("SriovNetwork Controller", func() { var err error expect := generateExpectedNetConfig(&cr) - err = k8sClient.Create(goctx.TODO(), &cr) + err = k8sClient.Create(ctx, &cr) Expect(err).NotTo(HaveOccurred()) DeferCleanup(func() { - err = k8sClient.Delete(goctx.TODO(), &cr) + err = k8sClient.Delete(ctx, &cr) Expect(err).NotTo(HaveOccurred()) }) @@ -264,10 +297,10 @@ var _ = Describe("SriovNetwork Controller", func() { nsObj := &corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{Name: "ns-xxx"}, } - err = k8sClient.Create(goctx.TODO(), nsObj) + err = k8sClient.Create(ctx, nsObj) Expect(err).NotTo(HaveOccurred()) DeferCleanup(func() { - err = k8sClient.Delete(goctx.TODO(), nsObj) + err = k8sClient.Delete(ctx, nsObj) Expect(err).NotTo(HaveOccurred()) }) diff --git a/controllers/sriovnetworkpoolconfig_controller_test.go b/controllers/sriovnetworkpoolconfig_controller_test.go index d0a7090c54..6659e256f1 100644 --- a/controllers/sriovnetworkpoolconfig_controller_test.go +++ b/controllers/sriovnetworkpoolconfig_controller_test.go @@ -1,12 +1,14 @@ package controllers import ( - goctx "context" + "context" + "sync" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" + "github.com/golang/mock/gomock" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -15,11 +17,65 @@ import ( sriovnetworkv1 "github.com/k8snetworkplumbingwg/sriov-network-operator/api/v1" "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/consts" constants "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/consts" + mock_platforms "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/platforms/mock" + "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/platforms/openshift" "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/vars" "github.com/k8snetworkplumbingwg/sriov-network-operator/test/util" ) -var _ = Describe("Operator", func() { +var _ = Describe("SriovNetworkPoolConfig controller", Ordered, func() { + var cancel context.CancelFunc + var ctx context.Context + + BeforeAll(func() { + By("Create default SriovNetworkPoolConfig k8s objs") + poolConfig := &sriovnetworkv1.SriovNetworkPoolConfig{} + poolConfig.SetNamespace(testNamespace) + poolConfig.SetName(constants.DefaultConfigName) + poolConfig.Spec = sriovnetworkv1.SriovNetworkPoolConfigSpec{} + Expect(k8sClient.Create(context.Background(), poolConfig)).Should(Succeed()) + DeferCleanup(func() { + err := k8sClient.Delete(context.Background(), poolConfig) + Expect(err).ToNot(HaveOccurred()) + }) + + By("Setup controller manager") + k8sManager, err := setupK8sManagerForTest() + Expect(err).ToNot(HaveOccurred()) + + t := GinkgoT() + mockCtrl := gomock.NewController(t) + platformHelper := mock_platforms.NewMockInterface(mockCtrl) + platformHelper.EXPECT().GetFlavor().Return(openshift.OpenshiftFlavorDefault).AnyTimes() + platformHelper.EXPECT().IsOpenshiftCluster().Return(false).AnyTimes() + platformHelper.EXPECT().IsHypershift().Return(false).AnyTimes() + + err = (&SriovNetworkPoolConfigReconciler{ + Client: k8sManager.GetClient(), + Scheme: k8sManager.GetScheme(), + PlatformHelper: platformHelper, + }).SetupWithManager(k8sManager) + Expect(err).ToNot(HaveOccurred()) + + ctx, cancel = context.WithCancel(context.Background()) + + wg := sync.WaitGroup{} + wg.Add(1) + go func() { + defer wg.Done() + defer GinkgoRecover() + By("Start controller manager") + err := k8sManager.Start(ctx) + Expect(err).ToNot(HaveOccurred()) + }() + + DeferCleanup(func() { + By("Shutdown controller manager") + cancel() + wg.Wait() + }) + }) + Context("When is up", func() { It("should be able to create machine config for MachineConfigPool specified in sriov pool config", func() { if vars.ClusterType != consts.ClusterTypeOpenshift { @@ -32,11 +88,11 @@ var _ = Describe("Operator", func() { mcpName := "worker" mc := &mcfgv1.MachineConfig{} mcName := "00-" + mcpName + "-" + constants.OVSHWOLMachineConfigNameSuffix - err := k8sClient.Get(goctx.TODO(), types.NamespacedName{Name: mcName, Namespace: testNamespace}, mc) + err := k8sClient.Get(ctx, types.NamespacedName{Name: mcName, Namespace: testNamespace}, mc) Expect(errors.IsNotFound(err)).Should(BeTrue()) mcp := &mcfgv1.MachineConfigPool{} - err = k8sClient.Get(goctx.TODO(), types.NamespacedName{Name: mcpName, Namespace: testNamespace}, mcp) + err = k8sClient.Get(ctx, types.NamespacedName{Name: mcpName, Namespace: testNamespace}, mcp) Expect(errors.IsNotFound(err)).Should(BeTrue()) mcp = &mcfgv1.MachineConfigPool{ @@ -51,26 +107,26 @@ var _ = Describe("Operator", func() { }, }, } - err = k8sClient.Create(goctx.TODO(), mcp) + err = k8sClient.Create(ctx, mcp) Expect(err).NotTo(HaveOccurred()) DeferCleanup(func() { - err = k8sClient.Delete(goctx.TODO(), mcp) + err = k8sClient.Delete(ctx, mcp) Expect(err).ToNot(HaveOccurred()) }) config.Spec.OvsHardwareOffloadConfig = sriovnetworkv1.OvsHardwareOffloadConfig{ Name: mcpName, } - err = k8sClient.Create(goctx.TODO(), config) + err = k8sClient.Create(ctx, config) Expect(err).NotTo(HaveOccurred()) DeferCleanup(func() { - err = k8sClient.Delete(goctx.TODO(), config) + err = k8sClient.Delete(ctx, config) Expect(err).ToNot(HaveOccurred()) }) Eventually(func() error { mc := &mcfgv1.MachineConfig{} - err := k8sClient.Get(goctx.TODO(), types.NamespacedName{Name: mcName, Namespace: testNamespace}, mc) + err := k8sClient.Get(ctx, types.NamespacedName{Name: mcName, Namespace: testNamespace}, mc) if err != nil { return err } diff --git a/controllers/sriovoperatorconfig_controller_test.go b/controllers/sriovoperatorconfig_controller_test.go index c2e779ee14..09c75c551a 100644 --- a/controllers/sriovoperatorconfig_controller_test.go +++ b/controllers/sriovoperatorconfig_controller_test.go @@ -1,20 +1,98 @@ package controllers import ( - goctx "context" + "context" + "sync" admv1 "k8s.io/api/admissionregistration/v1" appsv1 "k8s.io/api/apps/v1" "k8s.io/apimachinery/pkg/types" + "github.com/golang/mock/gomock" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" sriovnetworkv1 "github.com/k8snetworkplumbingwg/sriov-network-operator/api/v1" + constants "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/consts" + mock_platforms "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/platforms/mock" + "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/platforms/openshift" util "github.com/k8snetworkplumbingwg/sriov-network-operator/test/util" ) -var _ = Describe("Operator", func() { +var _ = Describe("SriovOperatorConfig controller", Ordered, func() { + var cancel context.CancelFunc + var ctx context.Context + + BeforeAll(func() { + By("Create SriovOperatorConfig controller k8s objs") + config := &sriovnetworkv1.SriovOperatorConfig{} + config.SetNamespace(testNamespace) + config.SetName(constants.DefaultConfigName) + config.Spec = sriovnetworkv1.SriovOperatorConfigSpec{ + EnableInjector: func() *bool { b := true; return &b }(), + EnableOperatorWebhook: func() *bool { b := true; return &b }(), + ConfigDaemonNodeSelector: map[string]string{}, + LogLevel: 2, + } + Expect(k8sClient.Create(context.Background(), config)).Should(Succeed()) + DeferCleanup(func() { + err := k8sClient.Delete(context.Background(), config) + Expect(err).ToNot(HaveOccurred()) + }) + + // Create default SriovNetworkNodePolicy + defaultPolicy := &sriovnetworkv1.SriovNetworkNodePolicy{} + defaultPolicy.SetNamespace(testNamespace) + defaultPolicy.SetName(constants.DefaultPolicyName) + defaultPolicy.Spec = sriovnetworkv1.SriovNetworkNodePolicySpec{ + NumVfs: 0, + NodeSelector: make(map[string]string), + NicSelector: sriovnetworkv1.SriovNetworkNicSelector{}, + } + Expect(k8sClient.Create(context.Background(), defaultPolicy)).Should(Succeed()) + DeferCleanup(func() { + err := k8sClient.Delete(context.Background(), defaultPolicy) + Expect(err).ToNot(HaveOccurred()) + }) + + // setup controller manager + By("Setup controller manager") + k8sManager, err := setupK8sManagerForTest() + Expect(err).ToNot(HaveOccurred()) + + t := GinkgoT() + mockCtrl := gomock.NewController(t) + platformHelper := mock_platforms.NewMockInterface(mockCtrl) + platformHelper.EXPECT().GetFlavor().Return(openshift.OpenshiftFlavorDefault).AnyTimes() + platformHelper.EXPECT().IsOpenshiftCluster().Return(false).AnyTimes() + platformHelper.EXPECT().IsHypershift().Return(false).AnyTimes() + + err = (&SriovOperatorConfigReconciler{ + Client: k8sManager.GetClient(), + Scheme: k8sManager.GetScheme(), + PlatformHelper: platformHelper, + }).SetupWithManager(k8sManager) + Expect(err).ToNot(HaveOccurred()) + + ctx, cancel = context.WithCancel(context.Background()) + + wg := sync.WaitGroup{} + wg.Add(1) + go func() { + defer wg.Done() + defer GinkgoRecover() + By("Start controller manager") + err := k8sManager.Start(ctx) + Expect(err).ToNot(HaveOccurred()) + }() + + DeferCleanup(func() { + By("Shut down manager") + cancel() + wg.Wait() + }) + }) + Context("When is up", func() { JustBeforeEach(func() { config := &sriovnetworkv1.SriovOperatorConfig{} @@ -26,7 +104,7 @@ var _ = Describe("Operator", func() { // ConfigDaemonNodeSelector: map[string]string{}, LogLevel: 2, } - err = k8sClient.Update(goctx.TODO(), config) + err = k8sClient.Update(ctx, config) Expect(err).NotTo(HaveOccurred()) }) @@ -59,7 +137,7 @@ var _ = Describe("Operator", func() { Expect(err).NotTo(HaveOccurred()) *config.Spec.EnableInjector = false - err = k8sClient.Update(goctx.TODO(), config) + err = k8sClient.Update(ctx, config) Expect(err).NotTo(HaveOccurred()) daemonSet := &appsv1.DaemonSet{} @@ -75,7 +153,7 @@ var _ = Describe("Operator", func() { Expect(err).NotTo(HaveOccurred()) *config.Spec.EnableInjector = true - err = k8sClient.Update(goctx.TODO(), config) + err = k8sClient.Update(ctx, config) Expect(err).NotTo(HaveOccurred()) daemonSet = &appsv1.DaemonSet{} @@ -95,7 +173,7 @@ var _ = Describe("Operator", func() { Expect(err).NotTo(HaveOccurred()) *config.Spec.EnableOperatorWebhook = false - err = k8sClient.Update(goctx.TODO(), config) + err = k8sClient.Update(ctx, config) Expect(err).NotTo(HaveOccurred()) daemonSet := &appsv1.DaemonSet{} @@ -115,7 +193,7 @@ var _ = Describe("Operator", func() { Expect(err).NotTo(HaveOccurred()) *config.Spec.EnableOperatorWebhook = true - err = k8sClient.Update(goctx.TODO(), config) + err = k8sClient.Update(ctx, config) Expect(err).NotTo(HaveOccurred()) daemonSet = &appsv1.DaemonSet{} @@ -137,13 +215,13 @@ var _ = Describe("Operator", func() { err := util.WaitForNamespacedObject(config, k8sClient, testNamespace, "default", util.RetryInterval, util.APITimeout) Expect(err).NotTo(HaveOccurred()) config.Spec.ConfigDaemonNodeSelector = map[string]string{"node-role.kubernetes.io/worker": ""} - err = k8sClient.Update(goctx.TODO(), config) + err = k8sClient.Update(ctx, config) Expect(err).NotTo(HaveOccurred()) daemonSet := &appsv1.DaemonSet{} Eventually(func() map[string]string { // By("wait for DaemonSet NodeSelector") - err := k8sClient.Get(goctx.TODO(), types.NamespacedName{Name: "sriov-network-config-daemon", Namespace: testNamespace}, daemonSet) + err := k8sClient.Get(ctx, types.NamespacedName{Name: "sriov-network-config-daemon", Namespace: testNamespace}, daemonSet) if err != nil { return nil } @@ -157,15 +235,15 @@ var _ = Describe("Operator", func() { err := util.WaitForNamespacedObject(config, k8sClient, testNamespace, "default", util.RetryInterval, util.APITimeout) Expect(err).NotTo(HaveOccurred()) config.Spec.ConfigDaemonNodeSelector = map[string]string{"labelA": "", "labelB": "", "labelC": ""} - err = k8sClient.Update(goctx.TODO(), config) + err = k8sClient.Update(ctx, config) Expect(err).NotTo(HaveOccurred()) config.Spec.ConfigDaemonNodeSelector = map[string]string{"labelA": "", "labelB": ""} - err = k8sClient.Update(goctx.TODO(), config) + err = k8sClient.Update(ctx, config) Expect(err).NotTo(HaveOccurred()) daemonSet := &appsv1.DaemonSet{} Eventually(func() map[string]string { - err := k8sClient.Get(goctx.TODO(), types.NamespacedName{Name: "sriov-network-config-daemon", Namespace: testNamespace}, daemonSet) + err := k8sClient.Get(ctx, types.NamespacedName{Name: "sriov-network-config-daemon", Namespace: testNamespace}, daemonSet) if err != nil { return nil } diff --git a/controllers/suite_test.go b/controllers/suite_test.go index 13505c1a2d..1b8b7dd8d7 100644 --- a/controllers/suite_test.go +++ b/controllers/suite_test.go @@ -23,7 +23,6 @@ import ( "testing" "time" - "github.com/golang/mock/gomock" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -31,11 +30,13 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/envtest" logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/log/zap" + "sigs.k8s.io/controller-runtime/pkg/manager" netattdefv1 "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1" openshiftconfigv1 "github.com/openshift/api/config/v1" @@ -43,9 +44,6 @@ import ( //+kubebuilder:scaffold:imports sriovnetworkv1 "github.com/k8snetworkplumbingwg/sriov-network-operator/api/v1" - constants "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/consts" - mock_platforms "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/platforms/mock" - "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/platforms/openshift" "github.com/k8snetworkplumbingwg/sriov-network-operator/test/util" ) @@ -55,15 +53,35 @@ import ( var ( k8sClient client.Client testEnv *envtest.Environment - - ctx context.Context - cancel context.CancelFunc + cfg *rest.Config ) // Define utility constants for object names and testing timeouts/durations and intervals. const testNamespace = "openshift-sriov-network-operator" +func setupK8sManagerForTest() (manager.Manager, error) { + k8sManager, err := ctrl.NewManager(cfg, ctrl.Options{ + Scheme: scheme.Scheme, + }) + + if err != nil { + return nil, err + } + + k8sManager.GetCache().IndexField(context.Background(), &sriovnetworkv1.SriovNetwork{}, "spec.networkNamespace", func(o client.Object) []string { + return []string{o.(*sriovnetworkv1.SriovNetwork).Spec.NetworkNamespace} + }) + + k8sManager.GetCache().IndexField(context.Background(), &sriovnetworkv1.SriovIBNetwork{}, "spec.networkNamespace", func(o client.Object) []string { + return []string{o.(*sriovnetworkv1.SriovIBNetwork).Spec.NetworkNamespace} + }) + + return k8sManager, nil +} + var _ = BeforeSuite(func() { + var err error + logf.SetLogger(zap.New( zap.WriteTo(GinkgoWriter), zap.UseDevMode(true), @@ -82,10 +100,11 @@ var _ = BeforeSuite(func() { testEnv.ControlPlane.GetAPIServer().Configure().Set("disable-admission-plugins", "MutatingAdmissionWebhook", "ValidatingAdmissionWebhook") - cfg, err := testEnv.Start() + cfg, err = testEnv.Start() Expect(err).NotTo(HaveOccurred()) Expect(cfg).NotTo(BeNil()) + By("registering schemes") err = sriovnetworkv1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) err = netattdefv1.AddToScheme(scheme.Scheme) @@ -95,60 +114,12 @@ var _ = BeforeSuite(func() { err = openshiftconfigv1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) - //+kubebuilder:scaffold:scheme - - // A client is created for our test CRUD operations. + By("creating K8s client") k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) Expect(err).NotTo(HaveOccurred()) Expect(k8sClient).NotTo(BeNil()) - // Start controllers - k8sManager, err := ctrl.NewManager(cfg, ctrl.Options{ - Scheme: scheme.Scheme, - }) - Expect(err).ToNot(HaveOccurred()) - - k8sManager.GetCache().IndexField(context.Background(), &sriovnetworkv1.SriovNetwork{}, "spec.networkNamespace", func(o client.Object) []string { - return []string{o.(*sriovnetworkv1.SriovNetwork).Spec.NetworkNamespace} - }) - - k8sManager.GetCache().IndexField(context.Background(), &sriovnetworkv1.SriovIBNetwork{}, "spec.networkNamespace", func(o client.Object) []string { - return []string{o.(*sriovnetworkv1.SriovIBNetwork).Spec.NetworkNamespace} - }) - - err = (&SriovNetworkReconciler{ - Client: k8sManager.GetClient(), - Scheme: k8sManager.GetScheme(), - }).SetupWithManager(k8sManager) - Expect(err).ToNot(HaveOccurred()) - - err = (&SriovIBNetworkReconciler{ - Client: k8sManager.GetClient(), - Scheme: k8sManager.GetScheme(), - }).SetupWithManager(k8sManager) - Expect(err).ToNot(HaveOccurred()) - - t := GinkgoT() - mockCtrl := gomock.NewController(t) - platformHelper := mock_platforms.NewMockInterface(mockCtrl) - platformHelper.EXPECT().GetFlavor().Return(openshift.OpenshiftFlavorDefault).AnyTimes() - platformHelper.EXPECT().IsOpenshiftCluster().Return(false).AnyTimes() - platformHelper.EXPECT().IsHypershift().Return(false).AnyTimes() - - err = (&SriovOperatorConfigReconciler{ - Client: k8sManager.GetClient(), - Scheme: k8sManager.GetScheme(), - PlatformHelper: platformHelper, - }).SetupWithManager(k8sManager) - Expect(err).ToNot(HaveOccurred()) - - err = (&SriovNetworkPoolConfigReconciler{ - Client: k8sManager.GetClient(), - Scheme: k8sManager.GetScheme(), - PlatformHelper: platformHelper, - }).SetupWithManager(k8sManager) - Expect(err).ToNot(HaveOccurred()) - + By("setting up env variables for tests") os.Setenv("RESOURCE_PREFIX", "openshift.io") os.Setenv("NAMESPACE", "openshift-sriov-network-operator") os.Setenv("ADMISSION_CONTROLLERS_ENABLED", "true") @@ -163,8 +134,7 @@ var _ = BeforeSuite(func() { os.Setenv("RELEASE_VERSION", "4.7.0") os.Setenv("OPERATOR_NAME", "sriov-network-operator") - ctx, cancel = context.WithCancel(ctrl.SetupSignalHandler()) - + By("creating default/common k8s objects for tests") // Create test namespace ns := &corev1.Namespace{ TypeMeta: metav1.TypeMeta{}, @@ -174,30 +144,7 @@ var _ = BeforeSuite(func() { Spec: corev1.NamespaceSpec{}, Status: corev1.NamespaceStatus{}, } - Expect(k8sClient.Create(context.TODO(), ns)).Should(Succeed()) - - // Create default SriovOperatorConfig - config := &sriovnetworkv1.SriovOperatorConfig{} - config.SetNamespace(testNamespace) - config.SetName(constants.DefaultConfigName) - config.Spec = sriovnetworkv1.SriovOperatorConfigSpec{ - EnableInjector: func() *bool { b := true; return &b }(), - EnableOperatorWebhook: func() *bool { b := true; return &b }(), - ConfigDaemonNodeSelector: map[string]string{}, - LogLevel: 2, - } - Expect(k8sClient.Create(context.TODO(), config)).Should(Succeed()) - - // Create default SriovNetworkNodePolicy - defaultPolicy := &sriovnetworkv1.SriovNetworkNodePolicy{} - defaultPolicy.SetNamespace(testNamespace) - defaultPolicy.SetName(constants.DefaultPolicyName) - defaultPolicy.Spec = sriovnetworkv1.SriovNetworkNodePolicySpec{ - NumVfs: 0, - NodeSelector: make(map[string]string), - NicSelector: sriovnetworkv1.SriovNetworkNicSelector{}, - } - Expect(k8sClient.Create(context.TODO(), defaultPolicy)).Should(Succeed()) + Expect(k8sClient.Create(context.Background(), ns)).Should(Succeed()) // Create openshift Infrastructure infra := &openshiftconfigv1.Infrastructure{ @@ -209,25 +156,11 @@ var _ = BeforeSuite(func() { ControlPlaneTopology: openshiftconfigv1.HighlyAvailableTopologyMode, }, } - Expect(k8sClient.Create(context.TODO(), infra)).Should(Succeed()) - - // Create default SriovNetworkPoolConfig - poolConfig := &sriovnetworkv1.SriovNetworkPoolConfig{} - poolConfig.SetNamespace(testNamespace) - poolConfig.SetName(constants.DefaultConfigName) - poolConfig.Spec = sriovnetworkv1.SriovNetworkPoolConfigSpec{} - Expect(k8sClient.Create(context.TODO(), poolConfig)).Should(Succeed()) - - go func() { - defer GinkgoRecover() - err = k8sManager.Start(ctx) - Expect(err).ToNot(HaveOccurred()) - }() + Expect(k8sClient.Create(context.Background(), infra)).Should(Succeed()) }) var _ = AfterSuite(func() { By("tearing down the test environment") - cancel() if testEnv != nil { Eventually(func() error { return testEnv.Stop()