From 241b8e4547232dbe5ae3d977ca03d537f14c20c1 Mon Sep 17 00:00:00 2001 From: Mohammed Boukhalfa Date: Thu, 24 Oct 2024 20:19:18 +0300 Subject: [PATCH] Make scale e2e test reusable for CAPM3 and other providers - Export ScaleSpec and ScaleSpecInput to allow reuse in other providers. - Add PostScaleClusterNamespaceCreated hook to be called after generating cluster name and namespace but before applying the template. Signed-off-by: Mohammed Boukhalfa --- test/e2e/scale.go | 44 ++++++++++++++++++++++++++++++++---------- test/e2e/scale_test.go | 4 ++-- 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/test/e2e/scale.go b/test/e2e/scale.go index 5b106d9276bd..7cadb86f1299 100644 --- a/test/e2e/scale.go +++ b/test/e2e/scale.go @@ -60,8 +60,8 @@ const ( scaleClusterNamespacePlaceholder = "scale-cluster-namespace-placeholder" ) -// scaleSpecInput is the input for scaleSpec. -type scaleSpecInput struct { +// ScaleSpecInput is the input for ScaleSpec. +type ScaleSpecInput struct { E2EConfig *clusterctl.E2EConfig ClusterctlConfigPath string BootstrapClusterProxy framework.ClusterProxy @@ -119,6 +119,16 @@ type scaleSpecInput struct { // If not specified, this is a no-op. PostNamespaceCreated func(managementClusterProxy framework.ClusterProxy, workloadClusterNamespace string) + // Allows to inject a function to be run after test workload cluster name and namespace are generated and + // before applying the clusterclass and the cluster template. + // If not specified, this is a no-op. + PostScaleClusterNamespaceCreated func( + clusterProxy framework.ClusterProxy, + clusterNamespace string, + clusterName string, + clusterClassYAML []byte, + clusterTemplateYAML []byte) ([]byte, []byte) + // FailFast if set to true will return immediately after the first cluster operation fails. // If set to false, the test suite will not exit immediately after the first cluster operation fails. // Example: When creating clusters from c1 to c20 consider c6 fails creation. If FailFast is set to true @@ -141,11 +151,11 @@ type scaleSpecInput struct { SkipWaitForCreation bool } -// scaleSpec implements a scale test for clusters with MachineDeployments. -func scaleSpec(ctx context.Context, inputGetter func() scaleSpecInput) { +// ScaleSpec implements a scale test for clusters with MachineDeployments. +func ScaleSpec(ctx context.Context, inputGetter func() ScaleSpecInput) { var ( specName = "scale" - input scaleSpecInput + input ScaleSpecInput namespace *corev1.Namespace cancelWatches context.CancelFunc ) @@ -331,7 +341,7 @@ func scaleSpec(ctx context.Context, inputGetter func() scaleSpecInput) { Concurrency: concurrency, FailFast: input.FailFast, WorkerFunc: func(ctx context.Context, inputChan chan string, resultChan chan workResult, wg *sync.WaitGroup) { - createClusterWorker(ctx, input.BootstrapClusterProxy, inputChan, resultChan, wg, namespace.Name, input.DeployClusterInSeparateNamespaces, baseClusterClassYAML, baseClusterTemplateYAML, creator) + createClusterWorker(ctx, input.BootstrapClusterProxy, inputChan, resultChan, wg, namespace.Name, input.DeployClusterInSeparateNamespaces, baseClusterClassYAML, baseClusterTemplateYAML, creator, input.PostScaleClusterNamespaceCreated) }, }) if err != nil { @@ -568,7 +578,9 @@ func getClusterCreateFn(clusterProxy framework.ClusterProxy) clusterCreator { } } -func createClusterWorker(ctx context.Context, clusterProxy framework.ClusterProxy, inputChan <-chan string, resultChan chan<- workResult, wg *sync.WaitGroup, defaultNamespace string, deployClusterInSeparateNamespaces bool, baseClusterClassYAML, baseClusterTemplateYAML []byte, create clusterCreator) { +type PostScaleClusterNamespaceCreated func(clusterProxy framework.ClusterProxy, clusterNamespace string, clusterName string, clusterClassYAML []byte, clusterTemplateYAML []byte) ([]byte, []byte) + +func createClusterWorker(ctx context.Context, clusterProxy framework.ClusterProxy, inputChan <-chan string, resultChan chan<- workResult, wg *sync.WaitGroup, defaultNamespace string, deployClusterInSeparateNamespaces bool, baseClusterClassYAML, baseClusterTemplateYAML []byte, create clusterCreator, postScaleClusterNamespaceCreated PostScaleClusterNamespaceCreated) { defer wg.Done() for { @@ -604,7 +616,6 @@ func createClusterWorker(ctx context.Context, clusterProxy framework.ClusterProx // If every cluster should be deployed in a separate namespace: // * Adjust namespace in ClusterClass YAML. // * Create new namespace. - // * Deploy ClusterClass in new namespace. if deployClusterInSeparateNamespaces { log.Logf("Create namespace %", namespaceName) _ = framework.CreateNamespace(ctx, framework.CreateNamespaceInput{ @@ -612,16 +623,29 @@ func createClusterWorker(ctx context.Context, clusterProxy framework.ClusterProx Name: namespaceName, IgnoreAlreadyExists: true, }, "40s", "10s") + } + // Call postScaleClusterNamespaceCreated hook to apply custom requirements based on the cluster name and namespace + // User might need to apply additional custom resource in the cluster namespace or customize the templates + customizedClusterTemplateYAML := baseClusterTemplateYAML + customizedClusterClassYAML := baseClusterClassYAML + if postScaleClusterNamespaceCreated != nil { + log.Logf("Calling postScaleClusterNamespaceCreated for cluster %s in namespace %s", clusterName, namespaceName) + customizedClusterClassYAML, customizedClusterTemplateYAML = postScaleClusterNamespaceCreated(clusterProxy, namespaceName, clusterName, baseClusterClassYAML, baseClusterTemplateYAML) + } + + // If every cluster should be deployed in a separate namespace: + // * Deploy ClusterClass in new namespace. + if deployClusterInSeparateNamespaces { log.Logf("Apply ClusterClass in namespace %", namespaceName) - clusterClassYAML := bytes.Replace(baseClusterClassYAML, []byte(scaleClusterNamespacePlaceholder), []byte(namespaceName), -1) + clusterClassYAML := bytes.Replace(customizedClusterClassYAML, []byte(scaleClusterNamespacePlaceholder), []byte(namespaceName), -1) Eventually(func() error { return clusterProxy.CreateOrUpdate(ctx, clusterClassYAML) }, 1*time.Minute).Should(Succeed()) } // Adjust namespace and name in Cluster YAML - clusterTemplateYAML := bytes.Replace(baseClusterTemplateYAML, []byte(scaleClusterNamespacePlaceholder), []byte(namespaceName), -1) + clusterTemplateYAML := bytes.Replace(customizedClusterTemplateYAML, []byte(scaleClusterNamespacePlaceholder), []byte(namespaceName), -1) clusterTemplateYAML = bytes.Replace(clusterTemplateYAML, []byte(scaleClusterNamePlaceholder), []byte(clusterName), -1) // Deploy Cluster. diff --git a/test/e2e/scale_test.go b/test/e2e/scale_test.go index ac184f78b66d..541dee0ec56e 100644 --- a/test/e2e/scale_test.go +++ b/test/e2e/scale_test.go @@ -26,8 +26,8 @@ import ( var _ = Describe("When testing the machinery for scale testing using in-memory provider", func() { // Note: This test does not support MachinePools. - scaleSpec(ctx, func() scaleSpecInput { - return scaleSpecInput{ + ScaleSpec(ctx, func() ScaleSpecInput { + return ScaleSpecInput{ E2EConfig: e2eConfig, ClusterctlConfigPath: clusterctlConfigPath, InfrastructureProvider: ptr.To("in-memory"),