...

Source file src/sigs.k8s.io/cli-utils/test/stress/thousand_deployments_test.go

Documentation: sigs.k8s.io/cli-utils/test/stress

     1  // Copyright 2022 The Kubernetes Authors.
     2  // SPDX-License-Identifier: Apache-2.0
     3  
     4  package stress
     5  
     6  import (
     7  	"context"
     8  	"fmt"
     9  	"time"
    10  
    11  	. "github.com/onsi/ginkgo/v2"
    12  	. "github.com/onsi/gomega"
    13  	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
    14  	"k8s.io/klog/v2"
    15  	"sigs.k8s.io/cli-utils/pkg/apply"
    16  	"sigs.k8s.io/cli-utils/pkg/common"
    17  	"sigs.k8s.io/cli-utils/pkg/inventory"
    18  	"sigs.k8s.io/cli-utils/test/e2e/e2eutil"
    19  	"sigs.k8s.io/cli-utils/test/e2e/invconfig"
    20  	"sigs.k8s.io/controller-runtime/pkg/client"
    21  )
    22  
    23  // thousandDeploymentsTest tests one pre-existing namespace with 1,000
    24  // Deployments in it.
    25  //
    26  // The Deployments themselves are easy to get status on, but with the retrieval
    27  // of generated resource status (ReplicaSets & Pods), this becomes expensive.
    28  func thousandDeploymentsTest(ctx context.Context, c client.Client, invConfig invconfig.InventoryConfig, inventoryName, namespaceName string) {
    29  	By("Apply LOTS of resources")
    30  	applier := invConfig.ApplierFactoryFunc()
    31  	inventoryID := fmt.Sprintf("%s-%s", inventoryName, namespaceName)
    32  
    33  	inventoryInfo := invconfig.CreateInventoryInfo(invConfig, inventoryName, namespaceName, inventoryID)
    34  
    35  	resources := []*unstructured.Unstructured{}
    36  
    37  	deploymentObjTemplate := e2eutil.ManifestToUnstructured([]byte(deploymentYaml))
    38  	deploymentObjTemplate.SetLabels(map[string]string{e2eutil.TestIDLabel: inventoryID})
    39  
    40  	objectCount := 1000
    41  
    42  	for i := 1; i <= objectCount; i++ {
    43  		deploymentObj := deploymentObjTemplate.DeepCopy()
    44  		deploymentObj.SetNamespace(namespaceName)
    45  
    46  		// change name & selector labels to avoid overlap between deployments
    47  		name := fmt.Sprintf("nginx-%d", i)
    48  		deploymentObj.SetName(name)
    49  		err := unstructured.SetNestedField(deploymentObj.Object, name, "spec", "selector", "matchLabels", "app")
    50  		Expect(err).ToNot(HaveOccurred())
    51  		err = unstructured.SetNestedField(deploymentObj.Object, name, "spec", "template", "metadata", "labels", "app")
    52  		Expect(err).ToNot(HaveOccurred())
    53  
    54  		resources = append(resources, deploymentObj)
    55  	}
    56  
    57  	defer func() {
    58  		By("Cleanup Deployments")
    59  		e2eutil.DeleteAllUnstructuredIfExists(ctx, c, deploymentObjTemplate)
    60  	}()
    61  
    62  	start := time.Now()
    63  
    64  	applierEvents := e2eutil.RunCollect(applier.Run(ctx, inventoryInfo, resources, apply.ApplierOptions{
    65  		// SSA reduces GET+PATCH to just PATCH, which is faster
    66  		ServerSideOptions: common.ServerSideOptions{
    67  			ServerSideApply: true,
    68  			ForceConflicts:  true,
    69  			FieldManager:    "cli-utils.kubernetes.io",
    70  		},
    71  		ReconcileTimeout: 30 * time.Minute,
    72  		EmitStatusEvents: false,
    73  	}))
    74  
    75  	duration := time.Since(start)
    76  	klog.Infof("Applier.Run execution time: %v", duration)
    77  
    78  	e2eutil.ExpectNoEventErrors(applierEvents)
    79  	e2eutil.ExpectNoReconcileTimeouts(applierEvents)
    80  
    81  	By("Verify inventory created")
    82  	invConfig.InvSizeVerifyFunc(ctx, c, inventoryName, namespaceName, inventoryID, len(resources), len(resources))
    83  
    84  	By(fmt.Sprintf("Verify %d Deployments created", objectCount))
    85  	e2eutil.AssertUnstructuredCount(ctx, c, deploymentObjTemplate, objectCount)
    86  
    87  	By("Destroy LOTS of resources")
    88  	destroyer := invConfig.DestroyerFactoryFunc()
    89  
    90  	start = time.Now()
    91  
    92  	destroyerEvents := e2eutil.RunCollect(destroyer.Run(ctx, inventoryInfo, apply.DestroyerOptions{
    93  		InventoryPolicy: inventory.PolicyAdoptIfNoInventory,
    94  		DeleteTimeout:   30 * time.Minute,
    95  	}))
    96  
    97  	duration = time.Since(start)
    98  	klog.Infof("Destroyer.Run execution time: %v", duration)
    99  
   100  	e2eutil.ExpectNoEventErrors(destroyerEvents)
   101  	e2eutil.ExpectNoReconcileTimeouts(destroyerEvents)
   102  
   103  	By("Verify inventory deleted")
   104  	invConfig.InvNotExistsFunc(ctx, c, inventoryName, namespaceName, inventoryID)
   105  
   106  	By(fmt.Sprintf("Verify %d Deployments deleted", objectCount))
   107  	e2eutil.AssertUnstructuredCount(ctx, c, deploymentObjTemplate, 0)
   108  }
   109  

View as plain text