cli-utils/test/stress/thousand_deployments_test.go

131 lines
4.3 KiB
Go

// Copyright 2022 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package stress
import (
"context"
"fmt"
"time"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/klog/v2"
"sigs.k8s.io/cli-utils/pkg/apply"
"sigs.k8s.io/cli-utils/pkg/apply/event"
"sigs.k8s.io/cli-utils/pkg/common"
"sigs.k8s.io/cli-utils/pkg/inventory"
"sigs.k8s.io/cli-utils/test/e2e/e2eutil"
"sigs.k8s.io/cli-utils/test/e2e/invconfig"
"sigs.k8s.io/controller-runtime/pkg/client"
)
// thousandDeploymentsTest tests one pre-existing namespace with 1,000
// Deployments in it.
//
// The Deployments themselves are easy to get status on, but with the retrieval
// of generated resource status (ReplicaSets & Pods), this becomes expensive.
func thousandDeploymentsTest(ctx context.Context, c client.Client, invConfig invconfig.InventoryConfig, inventoryName, namespaceName string) {
By("Apply LOTS of resources")
applier := invConfig.ApplierFactoryFunc()
inventoryID := fmt.Sprintf("%s-%s", inventoryName, namespaceName)
inventoryInfo := invconfig.CreateInventoryInfo(invConfig, inventoryName, namespaceName, inventoryID)
resources := []*unstructured.Unstructured{}
labelKey := "created-for"
labelValue := "stress-test"
deploymentObjTemplate := e2eutil.ManifestToUnstructured([]byte(deploymentYaml))
deploymentObjTemplate.SetLabels(map[string]string{labelKey: labelValue})
objectCount := 1000
for i := 1; i <= objectCount; i++ {
deploymentObj := deploymentObjTemplate.DeepCopy()
deploymentObj.SetNamespace(namespaceName)
// change name & selector labels to avoid overlap between deployments
name := fmt.Sprintf("nginx-%d", i)
deploymentObj.SetName(name)
err := unstructured.SetNestedField(deploymentObj.Object, name, "spec", "selector", "matchLabels", "app")
Expect(err).ToNot(HaveOccurred())
err = unstructured.SetNestedField(deploymentObj.Object, name, "spec", "template", "metadata", "labels", "app")
Expect(err).ToNot(HaveOccurred())
resources = append(resources, deploymentObj)
}
defer func() {
By("Cleanup Deployments")
e2eutil.DeleteAllUnstructuredIfExists(ctx, c, deploymentObjTemplate)
}()
start := time.Now()
applierEvents := e2eutil.RunCollect(applier.Run(ctx, inventoryInfo, resources, apply.ApplierOptions{
// SSA reduces GET+PATCH to just PATCH, which is faster
ServerSideOptions: common.ServerSideOptions{
ServerSideApply: true,
ForceConflicts: true,
FieldManager: "cli-utils.kubernetes.io",
},
ReconcileTimeout: 30 * time.Minute,
EmitStatusEvents: false,
}))
duration := time.Since(start)
klog.Infof("Applier.Run execution time: %v", duration)
for _, e := range applierEvents {
Expect(e.ErrorEvent.Err).To(BeNil())
}
for _, e := range applierEvents {
Expect(e.ApplyEvent.Error).To(BeNil(), "ApplyEvent: %v", e.ApplyEvent)
}
for _, e := range applierEvents {
if e.Type == event.WaitType {
Expect(e.WaitEvent.Status).To(BeElementOf(event.ReconcilePending, event.ReconcileSuccessful), "WaitEvent: %v", e.WaitEvent)
}
}
By("Verify inventory created")
invConfig.InvSizeVerifyFunc(ctx, c, inventoryName, namespaceName, inventoryID, len(resources), len(resources))
By(fmt.Sprintf("Verify %d Deployments created", objectCount))
e2eutil.AssertUnstructuredCount(ctx, c, deploymentObjTemplate, objectCount)
By("Destroy LOTS of resources")
destroyer := invConfig.DestroyerFactoryFunc()
start = time.Now()
destroyerEvents := e2eutil.RunCollect(destroyer.Run(ctx, inventoryInfo, apply.DestroyerOptions{
InventoryPolicy: inventory.PolicyAdoptIfNoInventory,
DeleteTimeout: 30 * time.Minute,
}))
duration = time.Since(start)
klog.Infof("Destroyer.Run execution time: %v", duration)
for _, e := range destroyerEvents {
Expect(e.ErrorEvent.Err).To(BeNil())
}
for _, e := range destroyerEvents {
Expect(e.PruneEvent.Error).To(BeNil(), "PruneEvent: %v", e.PruneEvent)
}
for _, e := range destroyerEvents {
if e.Type == event.WaitType {
Expect(e.WaitEvent.Status).To(BeElementOf(event.ReconcilePending, event.ReconcileSuccessful), "WaitEvent: %v", e.WaitEvent)
}
}
By("Verify inventory deleted")
invConfig.InvNotExistsFunc(ctx, c, inventoryName, namespaceName, inventoryID)
By(fmt.Sprintf("Verify %d Deployments deleted", objectCount))
e2eutil.AssertUnstructuredCount(ctx, c, deploymentObjTemplate, 0)
}