From 00266693f55bd870476062d503ebb00529d18c0e Mon Sep 17 00:00:00 2001 From: Balazs Gibizer Date: Thu, 14 Sep 2023 10:53:56 +0200 Subject: [PATCH 1/8] [envtest]Assert all conditions initialized --- .../functional/placementapi_controller_test.go | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/tests/functional/placementapi_controller_test.go b/tests/functional/placementapi_controller_test.go index 918e0412..05d8d09f 100644 --- a/tests/functional/placementapi_controller_test.go +++ b/tests/functional/placementapi_controller_test.go @@ -98,15 +98,25 @@ var _ = Describe("PlacementAPI controller", func() { condition.InputReadyCondition, corev1.ConditionFalse, ) - - for _, cond := range []condition.Type{ - condition.ServiceConfigReadyCondition, + unknownConditions := []condition.Type{ condition.DBReadyCondition, condition.DBSyncReadyCondition, condition.ExposeServiceReadyCondition, + condition.ServiceConfigReadyCondition, condition.DeploymentReadyCondition, + condition.KeystoneServiceReadyCondition, + condition.KeystoneEndpointReadyCondition, condition.NetworkAttachmentsReadyCondition, - } { + condition.ServiceAccountReadyCondition, + condition.RoleReadyCondition, + condition.RoleBindingReadyCondition, + } + + placement := GetPlacementAPI(placementApiName) + // +2 as InputReady and Ready is False asserted above + Expect(placement.Status.Conditions).To(HaveLen(len(unknownConditions) + 2)) + + for _, cond := range unknownConditions { th.ExpectCondition( placementApiName, ConditionGetterFunc(PlacementConditionGetter), From 36351d1adcdde06b05f334f3f558ae12455aeaa6 Mon Sep 17 00:00:00 2001 From: Balazs Gibizer Date: Thu, 14 Sep 2023 14:43:04 +0200 Subject: [PATCH 2/8] [envtest]Show that secret fields are not checked This adds a test case to show that placement-operator does not ensure that the expected fields are in the provided secret so it can generate wrong dbsync job configuration. --- .../placementapi_controller_test.go | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/functional/placementapi_controller_test.go b/tests/functional/placementapi_controller_test.go index 05d8d09f..b5e3e3dd 100644 --- a/tests/functional/placementapi_controller_test.go +++ b/tests/functional/placementapi_controller_test.go @@ -127,6 +127,29 @@ var _ = Describe("PlacementAPI controller", func() { }) }) + When("a secret is provided with missing fields", func() { + BeforeEach(func() { + DeferCleanup(th.DeleteInstance, CreatePlacementAPI(placementApiName, GetDefaultPlacementAPISpec())) + DeferCleanup( + k8sClient.Delete, ctx, + th.CreateSecret( + types.NamespacedName{Namespace: namespace, Name: SecretName}, + map[string][]byte{}), + ) + }) + It("reports that input is not ready", func() { + // FIXME(gibi): This is a bug as placement controller does not + // check the content of the Secret so eventually a dbsync job is + // created with incorrect config + th.ExpectCondition( + placementApiName, + ConditionGetterFunc(PlacementConditionGetter), + condition.InputReadyCondition, + corev1.ConditionTrue, + ) + }) + }) + When("the proper secret is provided", func() { BeforeEach(func() { DeferCleanup(th.DeleteInstance, CreatePlacementAPI(placementApiName, GetDefaultPlacementAPISpec())) From 4b7806658e7ef35b4204c1d69fde0e4d2accb0fc Mon Sep 17 00:00:00 2001 From: Balazs Gibizer Date: Thu, 14 Sep 2023 14:44:08 +0200 Subject: [PATCH 3/8] [envtest]Add coverage for the happy deployment path This increased or coverage from 38 to 70 percent --- .../placementapi_controller_test.go | 230 +++++++++++++++++- 1 file changed, 229 insertions(+), 1 deletion(-) diff --git a/tests/functional/placementapi_controller_test.go b/tests/functional/placementapi_controller_test.go index b5e3e3dd..0fbab3c4 100644 --- a/tests/functional/placementapi_controller_test.go +++ b/tests/functional/placementapi_controller_test.go @@ -35,6 +35,13 @@ var _ = Describe("PlacementAPI controller", func() { var placementApiName types.NamespacedName var placementApiConfigMapName types.NamespacedName var keystoneAPI *keystonev1.KeystoneAPI + var dbSyncJobName types.NamespacedName + var mariaDBDatabaseName types.NamespacedName + var deploymentName types.NamespacedName + var publicServiceName types.NamespacedName + var internalServiceName types.NamespacedName + var keystoneServiceName types.NamespacedName + var keystoneEndpointName types.NamespacedName BeforeEach(func() { placementApiName = types.NamespacedName{ @@ -45,6 +52,13 @@ var _ = Describe("PlacementAPI controller", func() { Namespace: namespace, Name: placementApiName.Name + "-config-data", } + dbSyncJobName = types.NamespacedName{Namespace: namespace, Name: "placement-db-sync"} + mariaDBDatabaseName = types.NamespacedName{Namespace: namespace, Name: "placement"} + deploymentName = types.NamespacedName{Namespace: namespace, Name: "placement"} + publicServiceName = types.NamespacedName{Namespace: namespace, Name: "placement-public"} + internalServiceName = types.NamespacedName{Namespace: namespace, Name: "placement-internal"} + keystoneServiceName = types.NamespacedName{Namespace: namespace, Name: "placement"} + keystoneEndpointName = types.NamespacedName{Namespace: namespace, Name: "placement"} // lib-common uses OPERATOR_TEMPLATES env var to locate the "templates" // directory of the operator. We need to set them othervise lib-common @@ -187,7 +201,7 @@ var _ = Describe("PlacementAPI controller", func() { DeferCleanup(th.DeleteKeystoneAPI, keystoneAPIName) }) - It("should have input ready", func() { + It("should have config ready", func() { th.ExpectCondition( placementApiName, ConditionGetterFunc(PlacementConditionGetter), @@ -202,6 +216,220 @@ var _ = Describe("PlacementAPI controller", func() { ContainSubstring("auth_url = %s", keystoneAPI.Status.APIEndpoints["internal"])) Expect(cm.Data["placement.conf"]).Should( ContainSubstring("www_authenticate_uri = %s", keystoneAPI.Status.APIEndpoints["public"])) + Expect(cm.Data["placement.conf"]).Should( + ContainSubstring("username = placement")) + }) + + It("creates MariaDB database", func() { + th.ExpectCondition( + placementApiName, + ConditionGetterFunc(PlacementConditionGetter), + condition.DBReadyCondition, + corev1.ConditionFalse, + ) + + serviceSpec := corev1.ServiceSpec{Ports: []corev1.ServicePort{{Port: 3306}}} + DeferCleanup( + th.DeleteDBService, + th.CreateDBService(namespace, "openstack", serviceSpec), + ) + db := th.GetMariaDBDatabase(mariaDBDatabaseName) + Expect(db.Spec.Name).To(Equal("placement")) + Expect(db.Spec.Secret).To(Equal(SecretName)) + + th.SimulateMariaDBDatabaseCompleted(mariaDBDatabaseName) + + th.ExpectCondition( + placementApiName, + ConditionGetterFunc(PlacementConditionGetter), + condition.DBReadyCondition, + corev1.ConditionTrue, + ) + }) + It("creates keystone service", func() { + th.ExpectCondition( + placementApiName, + ConditionGetterFunc(PlacementConditionGetter), + condition.KeystoneServiceReadyCondition, + corev1.ConditionUnknown, + ) + + serviceSpec := corev1.ServiceSpec{Ports: []corev1.ServicePort{{Port: 3306}}} + DeferCleanup( + th.DeleteDBService, + th.CreateDBService(namespace, "openstack", serviceSpec), + ) + th.SimulateMariaDBDatabaseCompleted(mariaDBDatabaseName) + + th.SimulateKeystoneServiceReady(keystoneServiceName) + + th.ExpectCondition( + placementApiName, + ConditionGetterFunc(PlacementConditionGetter), + condition.KeystoneServiceReadyCondition, + corev1.ConditionTrue, + ) + }) + It("creates keystone endpoint", func() { + th.ExpectCondition( + placementApiName, + ConditionGetterFunc(PlacementConditionGetter), + condition.KeystoneEndpointReadyCondition, + corev1.ConditionUnknown, + ) + + serviceSpec := corev1.ServiceSpec{Ports: []corev1.ServicePort{{Port: 3306}}} + DeferCleanup( + th.DeleteDBService, + th.CreateDBService(namespace, "openstack", serviceSpec), + ) + th.SimulateMariaDBDatabaseCompleted(mariaDBDatabaseName) + + th.SimulateKeystoneEndpointReady(keystoneEndpointName) + + th.ExpectCondition( + placementApiName, + ConditionGetterFunc(PlacementConditionGetter), + condition.KeystoneEndpointReadyCondition, + corev1.ConditionTrue, + ) + }) + It("runs db sync", func() { + serviceSpec := corev1.ServiceSpec{Ports: []corev1.ServicePort{{Port: 3306}}} + DeferCleanup( + th.DeleteDBService, + th.CreateDBService(namespace, "openstack", serviceSpec), + ) + th.SimulateMariaDBDatabaseCompleted(mariaDBDatabaseName) + + th.ExpectCondition( + placementApiName, + ConditionGetterFunc(PlacementConditionGetter), + condition.DBSyncReadyCondition, + corev1.ConditionFalse, + ) + + job := th.GetJob(dbSyncJobName) + Expect(job.Spec.Template.Spec.Volumes).To(HaveLen(3)) + Expect(job.Spec.Template.Spec.InitContainers).To(HaveLen(1)) + Expect(job.Spec.Template.Spec.Containers).To(HaveLen(1)) + + init := job.Spec.Template.Spec.InitContainers[0] + Expect(init.VolumeMounts).To(HaveLen(3)) + Expect(init.Args[1]).To(ContainSubstring("init.sh")) + Expect(init.Image).To(Equal("quay.io/podified-antelope-centos9/openstack-placement-api:current-podified")) + env := &corev1.EnvVar{} + Expect(init.Env).To(ContainElement(HaveField("Name", "DatabaseHost"), env)) + Expect(env.Value).To(Equal("hostname-for-openstack")) + Expect(init.Env).To(ContainElement(HaveField("Name", "DatabaseUser"), env)) + Expect(env.Value).To(Equal("placement")) + Expect(init.Env).To(ContainElement(HaveField("Name", "DatabaseName"), env)) + Expect(env.Value).To(Equal("placement")) + Expect(init.Env).To(ContainElement(HaveField("Name", "DatabasePassword"), env)) + Expect(env.ValueFrom.SecretKeyRef.LocalObjectReference.Name).To(Equal(SecretName)) + Expect(env.ValueFrom.SecretKeyRef.Key).To(Equal("PlacementDatabasePassword")) + Expect(init.Env).To(ContainElement(HaveField("Name", "PlacementPassword"), env)) + Expect(env.ValueFrom.SecretKeyRef.LocalObjectReference.Name).To(Equal(SecretName)) + Expect(env.ValueFrom.SecretKeyRef.Key).To(Equal("PlacementPassword")) + + container := job.Spec.Template.Spec.Containers[0] + Expect(container.VolumeMounts).To(HaveLen(3)) + Expect(container.Args[1]).To(ContainSubstring("placement-manage db sync")) + Expect(container.Image).To(Equal("quay.io/podified-antelope-centos9/openstack-placement-api:current-podified")) + + th.SimulateJobSuccess(dbSyncJobName) + + th.ExpectCondition( + placementApiName, + ConditionGetterFunc(PlacementConditionGetter), + condition.DBSyncReadyCondition, + corev1.ConditionTrue, + ) + }) + It("creates deployment", func() { + serviceSpec := corev1.ServiceSpec{Ports: []corev1.ServicePort{{Port: 3306}}} + DeferCleanup( + th.DeleteDBService, + th.CreateDBService(namespace, "openstack", serviceSpec), + ) + th.SimulateMariaDBDatabaseCompleted(mariaDBDatabaseName) + th.SimulateJobSuccess(dbSyncJobName) + + th.ExpectCondition( + placementApiName, + ConditionGetterFunc(PlacementConditionGetter), + condition.DeploymentReadyCondition, + corev1.ConditionUnknown, + ) + + deployment := th.GetDeployment(deploymentName) + Expect(int(*deployment.Spec.Replicas)).To(Equal(1)) + Expect(deployment.Spec.Selector.MatchLabels).To(Equal(map[string]string{"service": "placement"})) + + th.SimulateDeploymentReplicaReady(deploymentName) + + th.ExpectCondition( + placementApiName, + ConditionGetterFunc(PlacementConditionGetter), + condition.DeploymentReadyCondition, + corev1.ConditionTrue, + ) + }) + It("exposes the service", func() { + th.ExpectCondition( + placementApiName, + ConditionGetterFunc(PlacementConditionGetter), + condition.ExposeServiceReadyCondition, + corev1.ConditionUnknown, + ) + + serviceSpec := corev1.ServiceSpec{Ports: []corev1.ServicePort{{Port: 3306}}} + DeferCleanup( + th.DeleteDBService, + th.CreateDBService(namespace, "openstack", serviceSpec), + ) + th.SimulateMariaDBDatabaseCompleted(mariaDBDatabaseName) + th.SimulateJobSuccess(dbSyncJobName) + th.SimulateDeploymentReplicaReady(deploymentName) + + public := th.GetService(publicServiceName) + Expect(public.Labels["service"]).To(Equal("placement")) + internal := th.GetService(internalServiceName) + Expect(internal.Labels["service"]).To(Equal("placement")) + + th.ExpectCondition( + placementApiName, + ConditionGetterFunc(PlacementConditionGetter), + condition.ExposeServiceReadyCondition, + corev1.ConditionTrue, + ) + }) + + It("reports ready when successfully deployed", func() { + th.ExpectCondition( + placementApiName, + ConditionGetterFunc(PlacementConditionGetter), + condition.ReadyCondition, + corev1.ConditionFalse, + ) + + serviceSpec := corev1.ServiceSpec{Ports: []corev1.ServicePort{{Port: 3306}}} + DeferCleanup( + th.DeleteDBService, + th.CreateDBService(namespace, "openstack", serviceSpec), + ) + th.SimulateMariaDBDatabaseCompleted(mariaDBDatabaseName) + th.SimulateKeystoneServiceReady(keystoneServiceName) + th.SimulateKeystoneEndpointReady(keystoneEndpointName) + th.SimulateJobSuccess(dbSyncJobName) + th.SimulateDeploymentReplicaReady(deploymentName) + + th.ExpectCondition( + placementApiName, + ConditionGetterFunc(PlacementConditionGetter), + condition.ReadyCondition, + corev1.ConditionTrue, + ) }) }) From 4c090527c1314f3d91b3faf296b04f05f7cb123c Mon Sep 17 00:00:00 2001 From: Balazs Gibizer Date: Thu, 14 Sep 2023 15:18:27 +0200 Subject: [PATCH 4/8] [envtest]Cover ServiceAccount, Role and RoleBinding creation --- .../placementapi_controller_test.go | 40 ++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/tests/functional/placementapi_controller_test.go b/tests/functional/placementapi_controller_test.go index 0fbab3c4..2ccf59e4 100644 --- a/tests/functional/placementapi_controller_test.go +++ b/tests/functional/placementapi_controller_test.go @@ -42,6 +42,9 @@ var _ = Describe("PlacementAPI controller", func() { var internalServiceName types.NamespacedName var keystoneServiceName types.NamespacedName var keystoneEndpointName types.NamespacedName + var serviceAccountName types.NamespacedName + var roleName types.NamespacedName + var roleBindingName types.NamespacedName BeforeEach(func() { placementApiName = types.NamespacedName{ @@ -59,6 +62,9 @@ var _ = Describe("PlacementAPI controller", func() { internalServiceName = types.NamespacedName{Namespace: namespace, Name: "placement-internal"} keystoneServiceName = types.NamespacedName{Namespace: namespace, Name: "placement"} keystoneEndpointName = types.NamespacedName{Namespace: namespace, Name: "placement"} + serviceAccountName = types.NamespacedName{Namespace: namespace, Name: "placement-placement"} + roleName = types.NamespacedName{Namespace: namespace, Name: "placement-placement-role"} + roleBindingName = types.NamespacedName{Namespace: namespace, Name: "placement-placement-rolebinding"} // lib-common uses OPERATOR_TEMPLATES env var to locate the "templates" // directory of the operator. We need to set them othervise lib-common @@ -220,6 +226,38 @@ var _ = Describe("PlacementAPI controller", func() { ContainSubstring("username = placement")) }) + It("creates service account, role and rolebindig", func() { + th.ExpectCondition( + placementApiName, + ConditionGetterFunc(PlacementConditionGetter), + condition.ServiceAccountReadyCondition, + corev1.ConditionTrue, + ) + sa := th.GetServiceAccount(serviceAccountName) + + th.ExpectCondition( + placementApiName, + ConditionGetterFunc(PlacementConditionGetter), + condition.RoleReadyCondition, + corev1.ConditionTrue, + ) + role := th.GetRole(roleName) + Expect(role.Rules).To(HaveLen(2)) + Expect(role.Rules[0].Resources).To(Equal([]string{"securitycontextconstraints"})) + Expect(role.Rules[1].Resources).To(Equal([]string{"pods"})) + + th.ExpectCondition( + placementApiName, + ConditionGetterFunc(PlacementConditionGetter), + condition.RoleBindingReadyCondition, + corev1.ConditionTrue, + ) + binding := th.GetRoleBinding(roleBindingName) + Expect(binding.RoleRef.Name).To(Equal(role.Name)) + Expect(binding.Subjects).To(HaveLen(1)) + Expect(binding.Subjects[0].Name).To(Equal(sa.Name)) + }) + It("creates MariaDB database", func() { th.ExpectCondition( placementApiName, @@ -365,7 +403,7 @@ var _ = Describe("PlacementAPI controller", func() { deployment := th.GetDeployment(deploymentName) Expect(int(*deployment.Spec.Replicas)).To(Equal(1)) Expect(deployment.Spec.Selector.MatchLabels).To(Equal(map[string]string{"service": "placement"})) - + Expect(deployment.Spec.Template.Spec.ServiceAccountName).To(Equal(serviceAccountName.Name)) th.SimulateDeploymentReplicaReady(deploymentName) th.ExpectCondition( From 607881e811c49965d90467d63324942d347e027f Mon Sep 17 00:00:00 2001 From: Balazs Gibizer Date: Thu, 14 Sep 2023 16:01:26 +0200 Subject: [PATCH 5/8] [envtest][refactor]Pull out name handling This is needed as we want to switch from the hardcoded "placement" PlacementAPI name to a generated one --- tests/functional/base_test.go | 56 +++++ .../placementapi_controller_test.go | 228 ++++++++---------- tests/functional/suite_test.go | 10 + 3 files changed, 165 insertions(+), 129 deletions(-) diff --git a/tests/functional/base_test.go b/tests/functional/base_test.go index 78e55f3a..d8236f96 100644 --- a/tests/functional/base_test.go +++ b/tests/functional/base_test.go @@ -27,6 +27,62 @@ import ( placementv1 "github.com/openstack-k8s-operators/placement-operator/api/v1beta1" ) +type Names struct { + Namespace string + PlacementAPIName types.NamespacedName + ConfigMapName types.NamespacedName + DBSyncJobName types.NamespacedName + MariaDBDatabaseName types.NamespacedName + DeploymentName types.NamespacedName + PublicServiceName types.NamespacedName + InternalServiceName types.NamespacedName + KeystoneServiceName types.NamespacedName + KeystoneEndpointName types.NamespacedName + ServiceAccountName types.NamespacedName + RoleName types.NamespacedName + RoleBindingName types.NamespacedName +} + +func CreateNames(placementAPIName types.NamespacedName) Names { + return Names{ + Namespace: placementAPIName.Namespace, + PlacementAPIName: placementAPIName, + ConfigMapName: types.NamespacedName{ + Namespace: placementAPIName.Namespace, + Name: placementAPIName.Name + "-config-data"}, + DBSyncJobName: types.NamespacedName{ + Namespace: placementAPIName.Namespace, + Name: placementAPIName.Name + "-db-sync"}, + MariaDBDatabaseName: types.NamespacedName{ + Namespace: placementAPIName.Namespace, + Name: "placement"}, + DeploymentName: types.NamespacedName{ + Namespace: placementAPIName.Namespace, + Name: "placement"}, + PublicServiceName: types.NamespacedName{ + Namespace: placementAPIName.Namespace, + Name: "placement-public"}, + InternalServiceName: types.NamespacedName{ + Namespace: placementAPIName.Namespace, + Name: "placement-internal"}, + KeystoneServiceName: types.NamespacedName{ + Namespace: placementAPIName.Namespace, + Name: "placement"}, + KeystoneEndpointName: types.NamespacedName{ + Namespace: placementAPIName.Namespace, + Name: "placement"}, + ServiceAccountName: types.NamespacedName{ + Namespace: placementAPIName.Namespace, + Name: "placement-" + placementAPIName.Name}, + RoleName: types.NamespacedName{ + Namespace: placementAPIName.Namespace, + Name: "placement-" + placementAPIName.Name + "-role"}, + RoleBindingName: types.NamespacedName{ + Namespace: placementAPIName.Namespace, + Name: "placement-" + placementAPIName.Name + "-rolebinding"}, + } +} + func GetDefaultPlacementAPISpec() map[string]interface{} { return map[string]interface{}{ "databaseInstance": "openstack", diff --git a/tests/functional/placementapi_controller_test.go b/tests/functional/placementapi_controller_test.go index 2ccf59e4..5e5651bb 100644 --- a/tests/functional/placementapi_controller_test.go +++ b/tests/functional/placementapi_controller_test.go @@ -17,7 +17,6 @@ limitations under the License. package functional_test import ( - "fmt" "os" . "github.com/onsi/ginkgo/v2" @@ -31,41 +30,7 @@ import ( ) var _ = Describe("PlacementAPI controller", func() { - - var placementApiName types.NamespacedName - var placementApiConfigMapName types.NamespacedName - var keystoneAPI *keystonev1.KeystoneAPI - var dbSyncJobName types.NamespacedName - var mariaDBDatabaseName types.NamespacedName - var deploymentName types.NamespacedName - var publicServiceName types.NamespacedName - var internalServiceName types.NamespacedName - var keystoneServiceName types.NamespacedName - var keystoneEndpointName types.NamespacedName - var serviceAccountName types.NamespacedName - var roleName types.NamespacedName - var roleBindingName types.NamespacedName - BeforeEach(func() { - placementApiName = types.NamespacedName{ - Name: "placement", - Namespace: namespace, - } - placementApiConfigMapName = types.NamespacedName{ - Namespace: namespace, - Name: placementApiName.Name + "-config-data", - } - dbSyncJobName = types.NamespacedName{Namespace: namespace, Name: "placement-db-sync"} - mariaDBDatabaseName = types.NamespacedName{Namespace: namespace, Name: "placement"} - deploymentName = types.NamespacedName{Namespace: namespace, Name: "placement"} - publicServiceName = types.NamespacedName{Namespace: namespace, Name: "placement-public"} - internalServiceName = types.NamespacedName{Namespace: namespace, Name: "placement-internal"} - keystoneServiceName = types.NamespacedName{Namespace: namespace, Name: "placement"} - keystoneEndpointName = types.NamespacedName{Namespace: namespace, Name: "placement"} - serviceAccountName = types.NamespacedName{Namespace: namespace, Name: "placement-placement"} - roleName = types.NamespacedName{Namespace: namespace, Name: "placement-placement-role"} - roleBindingName = types.NamespacedName{Namespace: namespace, Name: "placement-placement-rolebinding"} - // lib-common uses OPERATOR_TEMPLATES env var to locate the "templates" // directory of the operator. We need to set them othervise lib-common // will fail to generate the ConfigMap as it does not find common.sh @@ -75,11 +40,14 @@ var _ = Describe("PlacementAPI controller", func() { When("A PlacementAPI instance is created", func() { BeforeEach(func() { - DeferCleanup(th.DeleteInstance, CreatePlacementAPI(placementApiName, GetDefaultPlacementAPISpec())) + DeferCleanup( + th.DeleteInstance, + CreatePlacementAPI(names.PlacementAPIName, GetDefaultPlacementAPISpec()), + ) }) It("should have the Spec fields defaulted", func() { - Placement := GetPlacementAPI(placementApiName) + Placement := GetPlacementAPI(names.PlacementAPIName) Expect(Placement.Spec.DatabaseInstance).Should(Equal("openstack")) Expect(Placement.Spec.DatabaseUser).Should(Equal("placement")) Expect(Placement.Spec.ServiceUser).Should(Equal("placement")) @@ -87,7 +55,7 @@ var _ = Describe("PlacementAPI controller", func() { }) It("should have the Status fields initialized", func() { - Placement := GetPlacementAPI(placementApiName) + Placement := GetPlacementAPI(names.PlacementAPIName) Expect(Placement.Status.Hash).To(BeEmpty()) Expect(Placement.Status.DatabaseHostname).To(Equal("")) Expect(Placement.Status.ReadyCount).To(Equal(int32(0))) @@ -97,23 +65,23 @@ var _ = Describe("PlacementAPI controller", func() { // the reconciler loop adds the finalizer so we have to wait for // it to run Eventually(func() []string { - return GetPlacementAPI(placementApiName).Finalizers + return GetPlacementAPI(names.PlacementAPIName).Finalizers }, timeout, interval).Should(ContainElement("PlacementAPI")) }) It("should not create a config map", func() { - th.AssertConfigMapDoesNotExist(placementApiConfigMapName) + th.AssertConfigMapDoesNotExist(names.ConfigMapName) }) It("should have input not ready and unknown Conditions initialized", func() { th.ExpectCondition( - placementApiName, + names.PlacementAPIName, ConditionGetterFunc(PlacementConditionGetter), condition.ReadyCondition, corev1.ConditionFalse, ) th.ExpectCondition( - placementApiName, + names.PlacementAPIName, ConditionGetterFunc(PlacementConditionGetter), condition.InputReadyCondition, corev1.ConditionFalse, @@ -132,13 +100,13 @@ var _ = Describe("PlacementAPI controller", func() { condition.RoleBindingReadyCondition, } - placement := GetPlacementAPI(placementApiName) + placement := GetPlacementAPI(names.PlacementAPIName) // +2 as InputReady and Ready is False asserted above Expect(placement.Status.Conditions).To(HaveLen(len(unknownConditions) + 2)) for _, cond := range unknownConditions { th.ExpectCondition( - placementApiName, + names.PlacementAPIName, ConditionGetterFunc(PlacementConditionGetter), cond, corev1.ConditionUnknown, @@ -149,7 +117,10 @@ var _ = Describe("PlacementAPI controller", func() { When("a secret is provided with missing fields", func() { BeforeEach(func() { - DeferCleanup(th.DeleteInstance, CreatePlacementAPI(placementApiName, GetDefaultPlacementAPISpec())) + DeferCleanup( + th.DeleteInstance, + CreatePlacementAPI(names.PlacementAPIName, GetDefaultPlacementAPISpec()), + ) DeferCleanup( k8sClient.Delete, ctx, th.CreateSecret( @@ -162,7 +133,7 @@ var _ = Describe("PlacementAPI controller", func() { // check the content of the Secret so eventually a dbsync job is // created with incorrect config th.ExpectCondition( - placementApiName, + names.PlacementAPIName, ConditionGetterFunc(PlacementConditionGetter), condition.InputReadyCondition, corev1.ConditionTrue, @@ -172,20 +143,23 @@ var _ = Describe("PlacementAPI controller", func() { When("the proper secret is provided", func() { BeforeEach(func() { - DeferCleanup(th.DeleteInstance, CreatePlacementAPI(placementApiName, GetDefaultPlacementAPISpec())) + DeferCleanup( + th.DeleteInstance, + CreatePlacementAPI(names.PlacementAPIName, GetDefaultPlacementAPISpec()), + ) DeferCleanup( k8sClient.Delete, ctx, CreatePlacementAPISecret(namespace, SecretName)) }) It("should have input ready", func() { th.ExpectCondition( - placementApiName, + names.PlacementAPIName, ConditionGetterFunc(PlacementConditionGetter), condition.InputReadyCondition, corev1.ConditionTrue, ) th.ExpectCondition( - placementApiName, + names.PlacementAPIName, ConditionGetterFunc(PlacementConditionGetter), condition.ServiceConfigReadyCondition, corev1.ConditionFalse, @@ -193,13 +167,15 @@ var _ = Describe("PlacementAPI controller", func() { }) It("should not create a config map", func() { - th.AssertConfigMapDoesNotExist(placementApiConfigMapName) + th.AssertConfigMapDoesNotExist(names.ConfigMapName) }) }) When("keystoneAPI instance is available", func() { + var keystoneAPI *keystonev1.KeystoneAPI + BeforeEach(func() { - DeferCleanup(th.DeleteInstance, CreatePlacementAPI(placementApiName, GetDefaultPlacementAPISpec())) + DeferCleanup(th.DeleteInstance, CreatePlacementAPI(names.PlacementAPIName, GetDefaultPlacementAPISpec())) DeferCleanup( k8sClient.Delete, ctx, CreatePlacementAPISecret(namespace, SecretName)) keystoneAPIName := th.CreateKeystoneAPI(namespace) @@ -209,14 +185,14 @@ var _ = Describe("PlacementAPI controller", func() { It("should have config ready", func() { th.ExpectCondition( - placementApiName, + names.PlacementAPIName, ConditionGetterFunc(PlacementConditionGetter), condition.ServiceConfigReadyCondition, corev1.ConditionTrue, ) }) It("should create a ConfigMap for placement.conf", func() { - cm := th.GetConfigMap(placementApiConfigMapName) + cm := th.GetConfigMap(names.ConfigMapName) Expect(cm.Data["placement.conf"]).Should( ContainSubstring("auth_url = %s", keystoneAPI.Status.APIEndpoints["internal"])) @@ -228,31 +204,31 @@ var _ = Describe("PlacementAPI controller", func() { It("creates service account, role and rolebindig", func() { th.ExpectCondition( - placementApiName, + names.PlacementAPIName, ConditionGetterFunc(PlacementConditionGetter), condition.ServiceAccountReadyCondition, corev1.ConditionTrue, ) - sa := th.GetServiceAccount(serviceAccountName) + sa := th.GetServiceAccount(names.ServiceAccountName) th.ExpectCondition( - placementApiName, + names.PlacementAPIName, ConditionGetterFunc(PlacementConditionGetter), condition.RoleReadyCondition, corev1.ConditionTrue, ) - role := th.GetRole(roleName) + role := th.GetRole(names.RoleName) Expect(role.Rules).To(HaveLen(2)) Expect(role.Rules[0].Resources).To(Equal([]string{"securitycontextconstraints"})) Expect(role.Rules[1].Resources).To(Equal([]string{"pods"})) th.ExpectCondition( - placementApiName, + names.PlacementAPIName, ConditionGetterFunc(PlacementConditionGetter), condition.RoleBindingReadyCondition, corev1.ConditionTrue, ) - binding := th.GetRoleBinding(roleBindingName) + binding := th.GetRoleBinding(names.RoleBindingName) Expect(binding.RoleRef.Name).To(Equal(role.Name)) Expect(binding.Subjects).To(HaveLen(1)) Expect(binding.Subjects[0].Name).To(Equal(sa.Name)) @@ -260,7 +236,7 @@ var _ = Describe("PlacementAPI controller", func() { It("creates MariaDB database", func() { th.ExpectCondition( - placementApiName, + names.PlacementAPIName, ConditionGetterFunc(PlacementConditionGetter), condition.DBReadyCondition, corev1.ConditionFalse, @@ -271,14 +247,14 @@ var _ = Describe("PlacementAPI controller", func() { th.DeleteDBService, th.CreateDBService(namespace, "openstack", serviceSpec), ) - db := th.GetMariaDBDatabase(mariaDBDatabaseName) + db := th.GetMariaDBDatabase(names.MariaDBDatabaseName) Expect(db.Spec.Name).To(Equal("placement")) Expect(db.Spec.Secret).To(Equal(SecretName)) - th.SimulateMariaDBDatabaseCompleted(mariaDBDatabaseName) + th.SimulateMariaDBDatabaseCompleted(names.MariaDBDatabaseName) th.ExpectCondition( - placementApiName, + names.PlacementAPIName, ConditionGetterFunc(PlacementConditionGetter), condition.DBReadyCondition, corev1.ConditionTrue, @@ -286,7 +262,7 @@ var _ = Describe("PlacementAPI controller", func() { }) It("creates keystone service", func() { th.ExpectCondition( - placementApiName, + names.PlacementAPIName, ConditionGetterFunc(PlacementConditionGetter), condition.KeystoneServiceReadyCondition, corev1.ConditionUnknown, @@ -297,12 +273,12 @@ var _ = Describe("PlacementAPI controller", func() { th.DeleteDBService, th.CreateDBService(namespace, "openstack", serviceSpec), ) - th.SimulateMariaDBDatabaseCompleted(mariaDBDatabaseName) + th.SimulateMariaDBDatabaseCompleted(names.MariaDBDatabaseName) - th.SimulateKeystoneServiceReady(keystoneServiceName) + th.SimulateKeystoneServiceReady(names.KeystoneServiceName) th.ExpectCondition( - placementApiName, + names.PlacementAPIName, ConditionGetterFunc(PlacementConditionGetter), condition.KeystoneServiceReadyCondition, corev1.ConditionTrue, @@ -310,7 +286,7 @@ var _ = Describe("PlacementAPI controller", func() { }) It("creates keystone endpoint", func() { th.ExpectCondition( - placementApiName, + names.PlacementAPIName, ConditionGetterFunc(PlacementConditionGetter), condition.KeystoneEndpointReadyCondition, corev1.ConditionUnknown, @@ -321,12 +297,12 @@ var _ = Describe("PlacementAPI controller", func() { th.DeleteDBService, th.CreateDBService(namespace, "openstack", serviceSpec), ) - th.SimulateMariaDBDatabaseCompleted(mariaDBDatabaseName) + th.SimulateMariaDBDatabaseCompleted(names.MariaDBDatabaseName) - th.SimulateKeystoneEndpointReady(keystoneEndpointName) + th.SimulateKeystoneEndpointReady(names.KeystoneEndpointName) th.ExpectCondition( - placementApiName, + names.PlacementAPIName, ConditionGetterFunc(PlacementConditionGetter), condition.KeystoneEndpointReadyCondition, corev1.ConditionTrue, @@ -338,16 +314,16 @@ var _ = Describe("PlacementAPI controller", func() { th.DeleteDBService, th.CreateDBService(namespace, "openstack", serviceSpec), ) - th.SimulateMariaDBDatabaseCompleted(mariaDBDatabaseName) + th.SimulateMariaDBDatabaseCompleted(names.MariaDBDatabaseName) th.ExpectCondition( - placementApiName, + names.PlacementAPIName, ConditionGetterFunc(PlacementConditionGetter), condition.DBSyncReadyCondition, corev1.ConditionFalse, ) - job := th.GetJob(dbSyncJobName) + job := th.GetJob(names.DBSyncJobName) Expect(job.Spec.Template.Spec.Volumes).To(HaveLen(3)) Expect(job.Spec.Template.Spec.InitContainers).To(HaveLen(1)) Expect(job.Spec.Template.Spec.Containers).To(HaveLen(1)) @@ -375,10 +351,10 @@ var _ = Describe("PlacementAPI controller", func() { Expect(container.Args[1]).To(ContainSubstring("placement-manage db sync")) Expect(container.Image).To(Equal("quay.io/podified-antelope-centos9/openstack-placement-api:current-podified")) - th.SimulateJobSuccess(dbSyncJobName) + th.SimulateJobSuccess(names.DBSyncJobName) th.ExpectCondition( - placementApiName, + names.PlacementAPIName, ConditionGetterFunc(PlacementConditionGetter), condition.DBSyncReadyCondition, corev1.ConditionTrue, @@ -390,24 +366,24 @@ var _ = Describe("PlacementAPI controller", func() { th.DeleteDBService, th.CreateDBService(namespace, "openstack", serviceSpec), ) - th.SimulateMariaDBDatabaseCompleted(mariaDBDatabaseName) - th.SimulateJobSuccess(dbSyncJobName) + th.SimulateMariaDBDatabaseCompleted(names.MariaDBDatabaseName) + th.SimulateJobSuccess(names.DBSyncJobName) th.ExpectCondition( - placementApiName, + names.PlacementAPIName, ConditionGetterFunc(PlacementConditionGetter), condition.DeploymentReadyCondition, corev1.ConditionUnknown, ) - deployment := th.GetDeployment(deploymentName) + deployment := th.GetDeployment(names.DeploymentName) Expect(int(*deployment.Spec.Replicas)).To(Equal(1)) Expect(deployment.Spec.Selector.MatchLabels).To(Equal(map[string]string{"service": "placement"})) - Expect(deployment.Spec.Template.Spec.ServiceAccountName).To(Equal(serviceAccountName.Name)) - th.SimulateDeploymentReplicaReady(deploymentName) + Expect(deployment.Spec.Template.Spec.ServiceAccountName).To(Equal(names.ServiceAccountName.Name)) + th.SimulateDeploymentReplicaReady(names.DeploymentName) th.ExpectCondition( - placementApiName, + names.PlacementAPIName, ConditionGetterFunc(PlacementConditionGetter), condition.DeploymentReadyCondition, corev1.ConditionTrue, @@ -415,7 +391,7 @@ var _ = Describe("PlacementAPI controller", func() { }) It("exposes the service", func() { th.ExpectCondition( - placementApiName, + names.PlacementAPIName, ConditionGetterFunc(PlacementConditionGetter), condition.ExposeServiceReadyCondition, corev1.ConditionUnknown, @@ -426,17 +402,17 @@ var _ = Describe("PlacementAPI controller", func() { th.DeleteDBService, th.CreateDBService(namespace, "openstack", serviceSpec), ) - th.SimulateMariaDBDatabaseCompleted(mariaDBDatabaseName) - th.SimulateJobSuccess(dbSyncJobName) - th.SimulateDeploymentReplicaReady(deploymentName) + th.SimulateMariaDBDatabaseCompleted(names.MariaDBDatabaseName) + th.SimulateJobSuccess(names.DBSyncJobName) + th.SimulateDeploymentReplicaReady(names.DeploymentName) - public := th.GetService(publicServiceName) + public := th.GetService(names.PublicServiceName) Expect(public.Labels["service"]).To(Equal("placement")) - internal := th.GetService(internalServiceName) + internal := th.GetService(names.InternalServiceName) Expect(internal.Labels["service"]).To(Equal("placement")) th.ExpectCondition( - placementApiName, + names.PlacementAPIName, ConditionGetterFunc(PlacementConditionGetter), condition.ExposeServiceReadyCondition, corev1.ConditionTrue, @@ -445,7 +421,7 @@ var _ = Describe("PlacementAPI controller", func() { It("reports ready when successfully deployed", func() { th.ExpectCondition( - placementApiName, + names.PlacementAPIName, ConditionGetterFunc(PlacementConditionGetter), condition.ReadyCondition, corev1.ConditionFalse, @@ -456,14 +432,14 @@ var _ = Describe("PlacementAPI controller", func() { th.DeleteDBService, th.CreateDBService(namespace, "openstack", serviceSpec), ) - th.SimulateMariaDBDatabaseCompleted(mariaDBDatabaseName) - th.SimulateKeystoneServiceReady(keystoneServiceName) - th.SimulateKeystoneEndpointReady(keystoneEndpointName) - th.SimulateJobSuccess(dbSyncJobName) - th.SimulateDeploymentReplicaReady(deploymentName) + th.SimulateMariaDBDatabaseCompleted(names.MariaDBDatabaseName) + th.SimulateKeystoneServiceReady(names.KeystoneServiceName) + th.SimulateKeystoneEndpointReady(names.KeystoneEndpointName) + th.SimulateJobSuccess(names.DBSyncJobName) + th.SimulateDeploymentReplicaReady(names.DeploymentName) th.ExpectCondition( - placementApiName, + names.PlacementAPIName, ConditionGetterFunc(PlacementConditionGetter), condition.ReadyCondition, corev1.ConditionTrue, @@ -474,7 +450,7 @@ var _ = Describe("PlacementAPI controller", func() { When("A PlacementAPI is created with service override", func() { BeforeEach(func() { DeferCleanup(k8sClient.Delete, ctx, CreatePlacementAPISecret(namespace, SecretName)) - DeferCleanup(th.DeleteKeystoneAPI, th.CreateKeystoneAPI(placementApiName.Namespace)) + DeferCleanup(th.DeleteKeystoneAPI, th.CreateKeystoneAPI(namespace)) spec := GetDefaultPlacementAPISpec() serviceOverride := map[string]interface{}{} @@ -500,37 +476,34 @@ var _ = Describe("PlacementAPI controller", func() { "service": serviceOverride, } - placementAPI := CreatePlacementAPI(placementApiName, spec) + placementAPI := CreatePlacementAPI(names.PlacementAPIName, spec) DeferCleanup( th.DeleteDBService, th.CreateDBService( - placementApiName.Namespace, - GetPlacementAPI(placementApiName).Spec.DatabaseInstance, + namespace, + GetPlacementAPI(names.PlacementAPIName).Spec.DatabaseInstance, corev1.ServiceSpec{ Ports: []corev1.ServicePort{{Port: 3306}}, }, ), ) - th.SimulateMariaDBDatabaseCompleted(placementApiName) - th.SimulateJobSuccess(types.NamespacedName{ - Namespace: placementApiName.Namespace, - Name: fmt.Sprintf("%s-db-sync", placementApiName.Name), - }) - th.SimulateDeploymentReplicaReady(placementApiName) - th.SimulateKeystoneServiceReady(placementApiName) - th.SimulateKeystoneEndpointReady(placementApiName) + th.SimulateMariaDBDatabaseCompleted(names.MariaDBDatabaseName) + th.SimulateJobSuccess(names.DBSyncJobName) + th.SimulateDeploymentReplicaReady(names.DeploymentName) + th.SimulateKeystoneServiceReady(names.KeystoneServiceName) + th.SimulateKeystoneEndpointReady(names.KeystoneEndpointName) DeferCleanup(th.DeleteInstance, placementAPI) }) It("creates KeystoneEndpoint", func() { - keystoneEndpoint := th.GetKeystoneEndpoint(placementApiName) + keystoneEndpoint := th.GetKeystoneEndpoint(names.KeystoneEndpointName) endpoints := keystoneEndpoint.Spec.Endpoints - Expect(endpoints).To(HaveKeyWithValue("public", "http://placement-public."+placementApiName.Namespace+".svc:8778")) - Expect(endpoints).To(HaveKeyWithValue("internal", "http://placement-internal."+placementApiName.Namespace+".svc:8778")) + Expect(endpoints).To(HaveKeyWithValue("public", "http://placement-public."+namespace+".svc:8778")) + Expect(endpoints).To(HaveKeyWithValue("internal", "http://placement-internal."+namespace+".svc:8778")) th.ExpectCondition( - placementApiName, + names.PlacementAPIName, ConditionGetterFunc(PlacementConditionGetter), condition.KeystoneEndpointReadyCondition, corev1.ConditionTrue, @@ -551,7 +524,7 @@ var _ = Describe("PlacementAPI controller", func() { HaveKeyWithValue("metallb.universe.tf/loadBalancerIPs", "internal-lb-ip-1,internal-lb-ip-2")) th.ExpectCondition( - placementApiName, + names.PlacementAPIName, ConditionGetterFunc(PlacementConditionGetter), condition.ReadyCondition, corev1.ConditionTrue, @@ -562,7 +535,7 @@ var _ = Describe("PlacementAPI controller", func() { When("A PlacementAPI is created with service override endpointURL set", func() { BeforeEach(func() { DeferCleanup(k8sClient.Delete, ctx, CreatePlacementAPISecret(namespace, SecretName)) - DeferCleanup(th.DeleteKeystoneAPI, th.CreateKeystoneAPI(placementApiName.Namespace)) + DeferCleanup(th.DeleteKeystoneAPI, th.CreateKeystoneAPI(namespace)) spec := GetDefaultPlacementAPISpec() serviceOverride := map[string]interface{}{} @@ -574,37 +547,34 @@ var _ = Describe("PlacementAPI controller", func() { "service": serviceOverride, } - placementAPI := CreatePlacementAPI(placementApiName, spec) + placementAPI := CreatePlacementAPI(names.PlacementAPIName, spec) DeferCleanup( th.DeleteDBService, th.CreateDBService( - placementApiName.Namespace, - GetPlacementAPI(placementApiName).Spec.DatabaseInstance, + namespace, + GetPlacementAPI(names.PlacementAPIName).Spec.DatabaseInstance, corev1.ServiceSpec{ Ports: []corev1.ServicePort{{Port: 3306}}, }, ), ) - th.SimulateMariaDBDatabaseCompleted(placementApiName) - th.SimulateJobSuccess(types.NamespacedName{ - Namespace: placementApiName.Namespace, - Name: fmt.Sprintf("%s-db-sync", placementApiName.Name), - }) - th.SimulateDeploymentReplicaReady(placementApiName) - th.SimulateKeystoneServiceReady(placementApiName) - th.SimulateKeystoneEndpointReady(placementApiName) + th.SimulateMariaDBDatabaseCompleted(names.MariaDBDatabaseName) + th.SimulateJobSuccess(names.DBSyncJobName) + th.SimulateDeploymentReplicaReady(names.DeploymentName) + th.SimulateKeystoneServiceReady(names.KeystoneServiceName) + th.SimulateKeystoneEndpointReady(names.KeystoneEndpointName) DeferCleanup(th.DeleteInstance, placementAPI) }) It("creates KeystoneEndpoint", func() { - keystoneEndpoint := th.GetKeystoneEndpoint(placementApiName) + keystoneEndpoint := th.GetKeystoneEndpoint(names.KeystoneEndpointName) endpoints := keystoneEndpoint.Spec.Endpoints Expect(endpoints).To(HaveKeyWithValue("public", "http://placement-openstack.apps-crc.testing")) - Expect(endpoints).To(HaveKeyWithValue("internal", "http://placement-internal."+placementApiName.Namespace+".svc:8778")) + Expect(endpoints).To(HaveKeyWithValue("internal", "http://placement-internal."+namespace+".svc:8778")) th.ExpectCondition( - placementApiName, + names.PlacementAPIName, ConditionGetterFunc(PlacementConditionGetter), condition.KeystoneEndpointReadyCondition, corev1.ConditionTrue, diff --git a/tests/functional/suite_test.go b/tests/functional/suite_test.go index 2844c5b7..07ec0767 100644 --- a/tests/functional/suite_test.go +++ b/tests/functional/suite_test.go @@ -29,6 +29,7 @@ import ( "github.com/google/uuid" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/rest" @@ -60,6 +61,7 @@ var ( logger logr.Logger th *TestHelper namespace string + names Names ) const ( @@ -197,4 +199,12 @@ var _ = BeforeEach(func() { // We still request the delete of the Namespace to properly cleanup if // we run the test in an existing cluster. DeferCleanup(th.DeleteNamespace, namespace) + + placementAPIName := types.NamespacedName{ + Namespace: namespace, + // Name: uuid.New().String()[:25], + Name: "placement", + } + + names = CreateNames(placementAPIName) }) From 335ae7265e9050fb11a34fce62f24f03618850f2 Mon Sep 17 00:00:00 2001 From: Balazs Gibizer Date: Thu, 14 Sep 2023 16:12:20 +0200 Subject: [PATCH 6/8] [envtest]Switch to generated PlacementAPI Name This has two benefits: * shows where placement-operator hardcodes names instead of using the name of the PlacementAPI CR like in case of the db sync Job and the Deployment. * allows more test case independency --- tests/functional/base_test.go | 10 ++++++---- tests/functional/placementapi_controller_test.go | 4 +++- tests/functional/suite_test.go | 3 +-- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/tests/functional/base_test.go b/tests/functional/base_test.go index d8236f96..bc90e4ef 100644 --- a/tests/functional/base_test.go +++ b/tests/functional/base_test.go @@ -50,12 +50,14 @@ func CreateNames(placementAPIName types.NamespacedName) Names { ConfigMapName: types.NamespacedName{ Namespace: placementAPIName.Namespace, Name: placementAPIName.Name + "-config-data"}, + // FIXME(gibi): the db sync job name should not be hardcoded + // but based on the name of the PlacementAPI CR DBSyncJobName: types.NamespacedName{ Namespace: placementAPIName.Namespace, - Name: placementAPIName.Name + "-db-sync"}, - MariaDBDatabaseName: types.NamespacedName{ - Namespace: placementAPIName.Namespace, - Name: "placement"}, + Name: "placement-db-sync"}, + MariaDBDatabaseName: placementAPIName, + // FIXME(gibi): the deployment name should not be hardcoded + // but based on the name of the PlacementAPI CR DeploymentName: types.NamespacedName{ Namespace: placementAPIName.Namespace, Name: "placement"}, diff --git a/tests/functional/placementapi_controller_test.go b/tests/functional/placementapi_controller_test.go index 5e5651bb..b7d4a4ff 100644 --- a/tests/functional/placementapi_controller_test.go +++ b/tests/functional/placementapi_controller_test.go @@ -248,7 +248,9 @@ var _ = Describe("PlacementAPI controller", func() { th.CreateDBService(namespace, "openstack", serviceSpec), ) db := th.GetMariaDBDatabase(names.MariaDBDatabaseName) - Expect(db.Spec.Name).To(Equal("placement")) + // FIXME(gibi): this should be hardcoded to "placement" as this is + // the name of the DB schema to be created + Expect(db.Spec.Name).To(Equal(names.PlacementAPIName.Name)) Expect(db.Spec.Secret).To(Equal(SecretName)) th.SimulateMariaDBDatabaseCompleted(names.MariaDBDatabaseName) diff --git a/tests/functional/suite_test.go b/tests/functional/suite_test.go index 07ec0767..3a7dbee2 100644 --- a/tests/functional/suite_test.go +++ b/tests/functional/suite_test.go @@ -202,8 +202,7 @@ var _ = BeforeEach(func() { placementAPIName := types.NamespacedName{ Namespace: namespace, - // Name: uuid.New().String()[:25], - Name: "placement", + Name: uuid.New().String()[:25], } names = CreateNames(placementAPIName) From cb821093bbd286beb31b68698187744a814c1c24 Mon Sep 17 00:00:00 2001 From: Balazs Gibizer Date: Thu, 14 Sep 2023 16:22:11 +0200 Subject: [PATCH 7/8] [envtest]Run test in random order Now that the test global variable handling is improved the test can run in any order. --- Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Makefile b/Makefile index bd048524..3624d6af 100644 --- a/Makefile +++ b/Makefile @@ -107,8 +107,7 @@ vet: gowork ## Run go vet against code. .PHONY: test test: manifests generate gowork fmt vet envtest ginkgo ## Run tests. - # TODO(gibi): enable --randomize-all and fix test failures - KUBEBUILDER_ASSETS="$(shell $(ENVTEST) -v debug --bin-dir $(LOCALBIN) use $(ENVTEST_K8S_VERSION) -p path)" $(GINKGO) --trace --cover --coverpkg=../../pkg/placement,../../controllers,../../api/v1beta1 --coverprofile cover.out --covermode=atomic ${PROC_CMD} $(GINKGO_ARGS) ./tests/... + KUBEBUILDER_ASSETS="$(shell $(ENVTEST) -v debug --bin-dir $(LOCALBIN) use $(ENVTEST_K8S_VERSION) -p path)" $(GINKGO) --trace --cover --coverpkg=../../pkg/placement,../../controllers,../../api/v1beta1 --coverprofile cover.out --covermode=atomic --randomize-all $(GINKGO_ARGS) ./tests/... ##@ Build From 1f33842c2fdc40a7e06ddd72c2b113a2ff7f802f Mon Sep 17 00:00:00 2001 From: Balazs Gibizer Date: Thu, 14 Sep 2023 17:27:15 +0200 Subject: [PATCH 8/8] [envtest]Test delete removing finalizers --- .../placementapi_controller_test.go | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/tests/functional/placementapi_controller_test.go b/tests/functional/placementapi_controller_test.go index b7d4a4ff..88de766e 100644 --- a/tests/functional/placementapi_controller_test.go +++ b/tests/functional/placementapi_controller_test.go @@ -583,4 +583,51 @@ var _ = Describe("PlacementAPI controller", func() { ) }) }) + + Context("PlacementAPI is fully deployed", func() { + BeforeEach(func() { + DeferCleanup(th.DeleteInstance, CreatePlacementAPI(names.PlacementAPIName, GetDefaultPlacementAPISpec())) + DeferCleanup( + k8sClient.Delete, ctx, CreatePlacementAPISecret(namespace, SecretName)) + DeferCleanup(th.DeleteKeystoneAPI, th.CreateKeystoneAPI(namespace)) + + serviceSpec := corev1.ServiceSpec{Ports: []corev1.ServicePort{{Port: 3306}}} + DeferCleanup( + th.DeleteDBService, + th.CreateDBService(namespace, "openstack", serviceSpec), + ) + th.SimulateMariaDBDatabaseCompleted(names.MariaDBDatabaseName) + th.SimulateKeystoneServiceReady(names.KeystoneServiceName) + th.SimulateKeystoneEndpointReady(names.KeystoneEndpointName) + th.SimulateJobSuccess(names.DBSyncJobName) + th.SimulateDeploymentReplicaReady(names.DeploymentName) + + th.ExpectCondition( + names.PlacementAPIName, + ConditionGetterFunc(PlacementConditionGetter), + condition.ReadyCondition, + corev1.ConditionTrue, + ) + }) + + It("removes the finalizers when deleted", func() { + placement := GetPlacementAPI(names.PlacementAPIName) + Expect(placement.Finalizers).To(ContainElement("PlacementAPI")) + keystoneService := th.GetKeystoneService(names.KeystoneServiceName) + Expect(keystoneService.Finalizers).To(ContainElement("PlacementAPI")) + keystoneEndpoint := th.GetKeystoneService(names.KeystoneEndpointName) + Expect(keystoneEndpoint.Finalizers).To(ContainElement("PlacementAPI")) + db := th.GetMariaDBDatabase(names.MariaDBDatabaseName) + Expect(db.Finalizers).To(ContainElement("PlacementAPI")) + + th.DeleteInstance(GetPlacementAPI(names.PlacementAPIName)) + + keystoneService = th.GetKeystoneService(names.KeystoneServiceName) + Expect(keystoneService.Finalizers).NotTo(ContainElement("PlacementAPI")) + keystoneEndpoint = th.GetKeystoneService(names.KeystoneEndpointName) + Expect(keystoneEndpoint.Finalizers).NotTo(ContainElement("PlacementAPI")) + db = th.GetMariaDBDatabase(names.MariaDBDatabaseName) + Expect(db.Finalizers).NotTo(ContainElement("PlacementAPI")) + }) + }) })