From 77a1268fedf2ada042c2cea96c85752ed105dfce Mon Sep 17 00:00:00 2001 From: Marek Grabowski Date: Thu, 15 Feb 2018 14:07:08 +0000 Subject: [PATCH] Add quotas to density and load tests --- test/e2e/scalability/density.go | 16 +++++++++++- test/e2e/scalability/load.go | 45 ++++++++++++++++++++++++++++++++- 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/test/e2e/scalability/density.go b/test/e2e/scalability/density.go index 2942dc62eea..c136b5c0cde 100644 --- a/test/e2e/scalability/density.go +++ b/test/e2e/scalability/density.go @@ -467,6 +467,7 @@ var _ = SIGDescribe("Density", func() { secretsPerPod int configMapsPerPod int daemonsPerNode int + quotas bool } densityTests := []Density{ @@ -485,13 +486,19 @@ var _ = SIGDescribe("Density", func() { {podsPerNode: 30, runLatencyTest: true, kind: extensions.Kind("Deployment"), secretsPerPod: 2}, // Test with configmaps {podsPerNode: 30, runLatencyTest: true, kind: extensions.Kind("Deployment"), configMapsPerPod: 2}, + // Test with quotas + {podsPerNode: 30, runLatencyTest: true, kind: api.Kind("ReplicationController"), quotas: true}, + } + + isCanonical := func(test *Density) bool { + return test.kind == api.Kind("ReplicationController") && test.daemonsPerNode == 0 && test.secretsPerPod == 0 && test.configMapsPerPod == 0 && !test.quotas } for _, testArg := range densityTests { feature := "ManualPerformance" switch testArg.podsPerNode { case 30: - if testArg.kind == api.Kind("ReplicationController") && testArg.daemonsPerNode == 0 && testArg.secretsPerPod == 0 && testArg.configMapsPerPod == 0 { + if isCanonical(&testArg) { feature = "Performance" } case 95: @@ -506,6 +513,9 @@ var _ = SIGDescribe("Density", func() { testArg.configMapsPerPod, testArg.daemonsPerNode, ) + if testArg.quotas { + name += " with quotas" + } itArg := testArg It(name, func() { nodePrepPhase := testPhaseDurations.StartPhase(100, "node preparation") @@ -531,6 +541,10 @@ var _ = SIGDescribe("Density", func() { numberOfCollections := (nodeCount + nodeCountPerNamespace - 1) / nodeCountPerNamespace namespaces, err := CreateNamespaces(f, numberOfCollections, fmt.Sprintf("density-%v", testArg.podsPerNode), testPhaseDurations.StartPhase(200, "namespace creation")) framework.ExpectNoError(err) + if itArg.quotas { + err := CreateQuotas(f, namespaces, totalPods+nodeCount, testPhaseDurations.StartPhase(210, "quota creation")) + framework.ExpectNoError(err) + } configs := make([]testutils.RunObjectConfig, numberOfCollections) secretConfigs := make([]*testutils.SecretConfig, 0, numberOfCollections*itArg.secretsPerPod) diff --git a/test/e2e/scalability/load.go b/test/e2e/scalability/load.go index 0febdd0eeb8..9246e2a9d63 100644 --- a/test/e2e/scalability/load.go +++ b/test/e2e/scalability/load.go @@ -28,7 +28,9 @@ import ( "time" "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime/schema" @@ -171,6 +173,7 @@ var _ = SIGDescribe("Load capacity", func() { secretsPerPod int configMapsPerPod int daemonsPerNode int + quotas bool } loadTests := []Load{ @@ -188,11 +191,18 @@ var _ = SIGDescribe("Load capacity", func() { {podsPerNode: 30, image: framework.ServeHostnameImage, kind: extensions.Kind("Deployment"), configMapsPerPod: 2}, // Special test case which randomizes created resources {podsPerNode: 30, image: framework.ServeHostnameImage, kind: randomKind}, + // Test with quotas + {podsPerNode: 30, image: framework.ServeHostnameImage, kind: api.Kind("ReplicationController"), quotas: true}, + {podsPerNode: 30, image: framework.ServeHostnameImage, kind: randomKind, quotas: true}, + } + + isCanonical := func(test *Load) bool { + return test.podsPerNode == 30 && test.kind == api.Kind("ReplicationController") && test.daemonsPerNode == 0 && test.secretsPerPod == 0 && test.configMapsPerPod == 0 && !test.quotas } for _, testArg := range loadTests { feature := "ManualPerformance" - if testArg.podsPerNode == 30 && testArg.kind == api.Kind("ReplicationController") && testArg.daemonsPerNode == 0 && testArg.secretsPerPod == 0 && testArg.configMapsPerPod == 0 { + if isCanonical(&testArg) { feature = "Performance" } name := fmt.Sprintf("[Feature:%s] should be able to handle %v pods per node %v with %v secrets, %v configmaps and %v daemons", @@ -203,6 +213,9 @@ var _ = SIGDescribe("Load capacity", func() { testArg.configMapsPerPod, testArg.daemonsPerNode, ) + if testArg.quotas { + name += " with quotas" + } itArg := testArg itArg.services = os.Getenv("CREATE_SERVICES") != "false" @@ -215,6 +228,11 @@ var _ = SIGDescribe("Load capacity", func() { totalPods := (itArg.podsPerNode - itArg.daemonsPerNode) * nodeCount configs, secretConfigs, configMapConfigs = generateConfigs(totalPods, itArg.image, itArg.command, namespaces, itArg.kind, itArg.secretsPerPod, itArg.configMapsPerPod) + if itArg.quotas { + err := CreateQuotas(f, namespaces, 2*totalPods, testPhaseDurations.StartPhase(115, "quota creation")) + framework.ExpectNoError(err) + } + serviceCreationPhase := testPhaseDurations.StartPhase(120, "services creation") defer serviceCreationPhase.End() if itArg.services { @@ -703,3 +721,28 @@ func CreateNamespaces(f *framework.Framework, namespaceCount int, namePrefix str } return namespaces, nil } + +func CreateQuotas(f *framework.Framework, namespaces []*v1.Namespace, podCount int, testPhase *timer.Phase) error { + defer testPhase.End() + quotaTemplate := &v1.ResourceQuota{ + Spec: v1.ResourceQuotaSpec{ + Hard: v1.ResourceList{"pods": *resource.NewQuantity(int64(podCount), resource.DecimalSI)}, + }, + } + + for _, ns := range namespaces { + if err := wait.PollImmediate(2*time.Second, 30*time.Second, func() (bool, error) { + quotaTemplate.Name = ns.Name + "-quota" + _, err := f.ClientSet.CoreV1().ResourceQuotas(ns.Name).Create(quotaTemplate) + if err != nil && !errors.IsAlreadyExists(err) { + framework.Logf("Unexpected error while creating resource quota: %v", err) + return false, nil + } + return true, nil + }); err != nil { + return fmt.Errorf("Failed to create quota: %v", err) + } + } + + return nil +}