mirror of https://github.com/k3s-io/k3s
Fix golint failures of test/e2e/autoscaling
parent
81a61ae0e3
commit
c101f40e18
|
@ -590,7 +590,6 @@ staging/src/k8s.io/sample-apiserver/pkg/apis/wardle
|
||||||
staging/src/k8s.io/sample-apiserver/pkg/apis/wardle/v1alpha1
|
staging/src/k8s.io/sample-apiserver/pkg/apis/wardle/v1alpha1
|
||||||
staging/src/k8s.io/sample-apiserver/pkg/registry/wardle/fischer
|
staging/src/k8s.io/sample-apiserver/pkg/registry/wardle/fischer
|
||||||
staging/src/k8s.io/sample-apiserver/pkg/registry/wardle/flunder
|
staging/src/k8s.io/sample-apiserver/pkg/registry/wardle/flunder
|
||||||
test/e2e/autoscaling
|
|
||||||
test/e2e/chaosmonkey
|
test/e2e/chaosmonkey
|
||||||
test/e2e/common
|
test/e2e/common
|
||||||
test/e2e/lifecycle/bootstrap
|
test/e2e/lifecycle/bootstrap
|
||||||
|
|
|
@ -25,15 +25,15 @@ import (
|
||||||
"k8s.io/kubernetes/test/e2e/common"
|
"k8s.io/kubernetes/test/e2e/common"
|
||||||
"k8s.io/kubernetes/test/e2e/framework"
|
"k8s.io/kubernetes/test/e2e/framework"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
"github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
"github.com/onsi/gomega"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = SIGDescribe("[Feature:ClusterSizeAutoscalingScaleUp] [Slow] Autoscaling", func() {
|
var _ = SIGDescribe("[Feature:ClusterSizeAutoscalingScaleUp] [Slow] Autoscaling", func() {
|
||||||
f := framework.NewDefaultFramework("autoscaling")
|
f := framework.NewDefaultFramework("autoscaling")
|
||||||
|
|
||||||
SIGDescribe("Autoscaling a service", func() {
|
SIGDescribe("Autoscaling a service", func() {
|
||||||
BeforeEach(func() {
|
ginkgo.BeforeEach(func() {
|
||||||
// Check if Cloud Autoscaler is enabled by trying to get its ConfigMap.
|
// Check if Cloud Autoscaler is enabled by trying to get its ConfigMap.
|
||||||
_, err := f.ClientSet.CoreV1().ConfigMaps("kube-system").Get("cluster-autoscaler-status", metav1.GetOptions{})
|
_, err := f.ClientSet.CoreV1().ConfigMaps("kube-system").Get("cluster-autoscaler-status", metav1.GetOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -41,12 +41,12 @@ var _ = SIGDescribe("[Feature:ClusterSizeAutoscalingScaleUp] [Slow] Autoscaling"
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
Context("from 1 pod and 3 nodes to 8 pods and >=4 nodes", func() {
|
ginkgo.Context("from 1 pod and 3 nodes to 8 pods and >=4 nodes", func() {
|
||||||
const nodesNum = 3 // Expect there to be 3 nodes before and after the test.
|
const nodesNum = 3 // Expect there to be 3 nodes before and after the test.
|
||||||
var nodeGroupName string // Set by BeforeEach, used by AfterEach to scale this node group down after the test.
|
var nodeGroupName string // Set by BeforeEach, used by AfterEach to scale this node group down after the test.
|
||||||
var nodes *v1.NodeList // Set by BeforeEach, used by Measure to calculate CPU request based on node's sizes.
|
var nodes *v1.NodeList // Set by BeforeEach, used by Measure to calculate CPU request based on node's sizes.
|
||||||
|
|
||||||
BeforeEach(func() {
|
ginkgo.BeforeEach(func() {
|
||||||
// Make sure there is only 1 node group, otherwise this test becomes useless.
|
// Make sure there is only 1 node group, otherwise this test becomes useless.
|
||||||
nodeGroups := strings.Split(framework.TestContext.CloudConfig.NodeInstanceGroup, ",")
|
nodeGroups := strings.Split(framework.TestContext.CloudConfig.NodeInstanceGroup, ",")
|
||||||
if len(nodeGroups) != 1 {
|
if len(nodeGroups) != 1 {
|
||||||
|
@ -64,10 +64,10 @@ var _ = SIGDescribe("[Feature:ClusterSizeAutoscalingScaleUp] [Slow] Autoscaling"
|
||||||
// Make sure all nodes are schedulable, otherwise we are in some kind of a problem state.
|
// Make sure all nodes are schedulable, otherwise we are in some kind of a problem state.
|
||||||
nodes = framework.GetReadySchedulableNodesOrDie(f.ClientSet)
|
nodes = framework.GetReadySchedulableNodesOrDie(f.ClientSet)
|
||||||
schedulableCount := len(nodes.Items)
|
schedulableCount := len(nodes.Items)
|
||||||
Expect(schedulableCount).To(Equal(nodeGroupSize), "not all nodes are schedulable")
|
gomega.Expect(schedulableCount).To(gomega.Equal(nodeGroupSize), "not all nodes are schedulable")
|
||||||
})
|
})
|
||||||
|
|
||||||
AfterEach(func() {
|
ginkgo.AfterEach(func() {
|
||||||
// Attempt cleanup only if a node group was targeted for scale up.
|
// Attempt cleanup only if a node group was targeted for scale up.
|
||||||
// Otherwise the test was probably skipped and we'll get a gcloud error due to invalid parameters.
|
// Otherwise the test was probably skipped and we'll get a gcloud error due to invalid parameters.
|
||||||
if len(nodeGroupName) > 0 {
|
if len(nodeGroupName) > 0 {
|
||||||
|
@ -77,7 +77,7 @@ var _ = SIGDescribe("[Feature:ClusterSizeAutoscalingScaleUp] [Slow] Autoscaling"
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
Measure("takes less than 15 minutes", func(b Benchmarker) {
|
ginkgo.Measure("takes less than 15 minutes", func(b ginkgo.Benchmarker) {
|
||||||
// Measured over multiple samples, scaling takes 10 +/- 2 minutes, so 15 minutes should be fully sufficient.
|
// Measured over multiple samples, scaling takes 10 +/- 2 minutes, so 15 minutes should be fully sufficient.
|
||||||
const timeToWait = 15 * time.Minute
|
const timeToWait = 15 * time.Minute
|
||||||
|
|
||||||
|
@ -85,8 +85,8 @@ var _ = SIGDescribe("[Feature:ClusterSizeAutoscalingScaleUp] [Slow] Autoscaling"
|
||||||
// This test expects that 8 pods will not fit in 'nodesNum' nodes, but will fit in >='nodesNum'+1 nodes.
|
// This test expects that 8 pods will not fit in 'nodesNum' nodes, but will fit in >='nodesNum'+1 nodes.
|
||||||
// Make it so that 'nodesNum' pods fit perfectly per node.
|
// Make it so that 'nodesNum' pods fit perfectly per node.
|
||||||
nodeCpus := nodes.Items[0].Status.Allocatable[v1.ResourceCPU]
|
nodeCpus := nodes.Items[0].Status.Allocatable[v1.ResourceCPU]
|
||||||
nodeCpuMillis := (&nodeCpus).MilliValue()
|
nodeCPUMillis := (&nodeCpus).MilliValue()
|
||||||
cpuRequestMillis := int64(nodeCpuMillis / nodesNum)
|
cpuRequestMillis := int64(nodeCPUMillis / nodesNum)
|
||||||
|
|
||||||
// Start the service we want to scale and wait for it to be up and running.
|
// Start the service we want to scale and wait for it to be up and running.
|
||||||
nodeMemoryBytes := nodes.Items[0].Status.Allocatable[v1.ResourceMemory]
|
nodeMemoryBytes := nodes.Items[0].Status.Allocatable[v1.ResourceMemory]
|
||||||
|
@ -99,10 +99,10 @@ var _ = SIGDescribe("[Feature:ClusterSizeAutoscalingScaleUp] [Slow] Autoscaling"
|
||||||
|
|
||||||
// Enable Horizontal Pod Autoscaler with 50% target utilization and
|
// Enable Horizontal Pod Autoscaler with 50% target utilization and
|
||||||
// scale up the CPU usage to trigger autoscaling to 8 pods for target to be satisfied.
|
// scale up the CPU usage to trigger autoscaling to 8 pods for target to be satisfied.
|
||||||
targetCpuUtilizationPercent := int32(50)
|
targetCPUUtilizationPercent := int32(50)
|
||||||
hpa := common.CreateCPUHorizontalPodAutoscaler(resourceConsumer, targetCpuUtilizationPercent, 1, 10)
|
hpa := common.CreateCPUHorizontalPodAutoscaler(resourceConsumer, targetCPUUtilizationPercent, 1, 10)
|
||||||
defer common.DeleteHorizontalPodAutoscaler(resourceConsumer, hpa.Name)
|
defer common.DeleteHorizontalPodAutoscaler(resourceConsumer, hpa.Name)
|
||||||
cpuLoad := 8 * cpuRequestMillis * int64(targetCpuUtilizationPercent) / 100 // 8 pods utilized to the target level
|
cpuLoad := 8 * cpuRequestMillis * int64(targetCPUUtilizationPercent) / 100 // 8 pods utilized to the target level
|
||||||
resourceConsumer.ConsumeCPU(int(cpuLoad))
|
resourceConsumer.ConsumeCPU(int(cpuLoad))
|
||||||
|
|
||||||
// Measure the time it takes for the service to scale to 8 pods with 50% CPU utilization each.
|
// Measure the time it takes for the service to scale to 8 pods with 50% CPU utilization each.
|
||||||
|
|
|
@ -33,8 +33,8 @@ import (
|
||||||
testutils "k8s.io/kubernetes/test/utils"
|
testutils "k8s.io/kubernetes/test/utils"
|
||||||
imageutils "k8s.io/kubernetes/test/utils/image"
|
imageutils "k8s.io/kubernetes/test/utils/image"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
"github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
"github.com/onsi/gomega"
|
||||||
"k8s.io/klog"
|
"k8s.io/klog"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ var _ = framework.KubeDescribe("Cluster size autoscaler scalability [Slow]", fun
|
||||||
var originalSizes map[string]int
|
var originalSizes map[string]int
|
||||||
var sum int
|
var sum int
|
||||||
|
|
||||||
BeforeEach(func() {
|
ginkgo.BeforeEach(func() {
|
||||||
framework.SkipUnlessProviderIs("gce", "gke", "kubemark")
|
framework.SkipUnlessProviderIs("gce", "gke", "kubemark")
|
||||||
|
|
||||||
// Check if Cloud Autoscaler is enabled by trying to get its ConfigMap.
|
// Check if Cloud Autoscaler is enabled by trying to get its ConfigMap.
|
||||||
|
@ -81,7 +81,7 @@ var _ = framework.KubeDescribe("Cluster size autoscaler scalability [Slow]", fun
|
||||||
for _, mig := range strings.Split(framework.TestContext.CloudConfig.NodeInstanceGroup, ",") {
|
for _, mig := range strings.Split(framework.TestContext.CloudConfig.NodeInstanceGroup, ",") {
|
||||||
size, err := framework.GroupSize(mig)
|
size, err := framework.GroupSize(mig)
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
By(fmt.Sprintf("Initial size of %s: %d", mig, size))
|
ginkgo.By(fmt.Sprintf("Initial size of %s: %d", mig, size))
|
||||||
originalSizes[mig] = size
|
originalSizes[mig] = size
|
||||||
sum += size
|
sum += size
|
||||||
}
|
}
|
||||||
|
@ -91,13 +91,13 @@ var _ = framework.KubeDescribe("Cluster size autoscaler scalability [Slow]", fun
|
||||||
|
|
||||||
nodes := framework.GetReadySchedulableNodesOrDie(f.ClientSet)
|
nodes := framework.GetReadySchedulableNodesOrDie(f.ClientSet)
|
||||||
nodeCount = len(nodes.Items)
|
nodeCount = len(nodes.Items)
|
||||||
Expect(nodeCount).NotTo(BeZero())
|
gomega.Expect(nodeCount).NotTo(gomega.BeZero())
|
||||||
cpu := nodes.Items[0].Status.Capacity[v1.ResourceCPU]
|
cpu := nodes.Items[0].Status.Capacity[v1.ResourceCPU]
|
||||||
mem := nodes.Items[0].Status.Capacity[v1.ResourceMemory]
|
mem := nodes.Items[0].Status.Capacity[v1.ResourceMemory]
|
||||||
coresPerNode = int((&cpu).MilliValue() / 1000)
|
coresPerNode = int((&cpu).MilliValue() / 1000)
|
||||||
memCapacityMb = int((&mem).Value() / 1024 / 1024)
|
memCapacityMb = int((&mem).Value() / 1024 / 1024)
|
||||||
|
|
||||||
Expect(nodeCount).Should(Equal(sum))
|
gomega.Expect(nodeCount).Should(gomega.Equal(sum))
|
||||||
|
|
||||||
if framework.ProviderIs("gke") {
|
if framework.ProviderIs("gke") {
|
||||||
val, err := isAutoscalerEnabled(3)
|
val, err := isAutoscalerEnabled(3)
|
||||||
|
@ -109,8 +109,8 @@ var _ = framework.KubeDescribe("Cluster size autoscaler scalability [Slow]", fun
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
AfterEach(func() {
|
ginkgo.AfterEach(func() {
|
||||||
By(fmt.Sprintf("Restoring initial size of the cluster"))
|
ginkgo.By(fmt.Sprintf("Restoring initial size of the cluster"))
|
||||||
setMigSizes(originalSizes)
|
setMigSizes(originalSizes)
|
||||||
framework.ExpectNoError(framework.WaitForReadyNodes(c, nodeCount, scaleDownTimeout))
|
framework.ExpectNoError(framework.WaitForReadyNodes(c, nodeCount, scaleDownTimeout))
|
||||||
nodes, err := c.CoreV1().Nodes().List(metav1.ListOptions{})
|
nodes, err := c.CoreV1().Nodes().List(metav1.ListOptions{})
|
||||||
|
@ -132,7 +132,7 @@ var _ = framework.KubeDescribe("Cluster size autoscaler scalability [Slow]", fun
|
||||||
klog.Infof("Made nodes schedulable again in %v", time.Since(s).String())
|
klog.Infof("Made nodes schedulable again in %v", time.Since(s).String())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should scale up at all [Feature:ClusterAutoscalerScalability1]", func() {
|
ginkgo.It("should scale up at all [Feature:ClusterAutoscalerScalability1]", func() {
|
||||||
perNodeReservation := int(float64(memCapacityMb) * 0.95)
|
perNodeReservation := int(float64(memCapacityMb) * 0.95)
|
||||||
replicasPerNode := 10
|
replicasPerNode := 10
|
||||||
|
|
||||||
|
@ -155,7 +155,7 @@ var _ = framework.KubeDescribe("Cluster size autoscaler scalability [Slow]", fun
|
||||||
defer testCleanup()
|
defer testCleanup()
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should scale up twice [Feature:ClusterAutoscalerScalability2]", func() {
|
ginkgo.It("should scale up twice [Feature:ClusterAutoscalerScalability2]", func() {
|
||||||
perNodeReservation := int(float64(memCapacityMb) * 0.95)
|
perNodeReservation := int(float64(memCapacityMb) * 0.95)
|
||||||
replicasPerNode := 10
|
replicasPerNode := 10
|
||||||
additionalNodes1 := int(math.Ceil(0.7 * maxNodes))
|
additionalNodes1 := int(math.Ceil(0.7 * maxNodes))
|
||||||
|
@ -204,7 +204,7 @@ var _ = framework.KubeDescribe("Cluster size autoscaler scalability [Slow]", fun
|
||||||
klog.Infof("Scaled up twice")
|
klog.Infof("Scaled up twice")
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should scale down empty nodes [Feature:ClusterAutoscalerScalability3]", func() {
|
ginkgo.It("should scale down empty nodes [Feature:ClusterAutoscalerScalability3]", func() {
|
||||||
perNodeReservation := int(float64(memCapacityMb) * 0.7)
|
perNodeReservation := int(float64(memCapacityMb) * 0.7)
|
||||||
replicas := int(math.Ceil(maxNodes * 0.7))
|
replicas := int(math.Ceil(maxNodes * 0.7))
|
||||||
totalNodes := maxNodes
|
totalNodes := maxNodes
|
||||||
|
@ -232,7 +232,7 @@ var _ = framework.KubeDescribe("Cluster size autoscaler scalability [Slow]", fun
|
||||||
}, scaleDownTimeout))
|
}, scaleDownTimeout))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should scale down underutilized nodes [Feature:ClusterAutoscalerScalability4]", func() {
|
ginkgo.It("should scale down underutilized nodes [Feature:ClusterAutoscalerScalability4]", func() {
|
||||||
perPodReservation := int(float64(memCapacityMb) * 0.01)
|
perPodReservation := int(float64(memCapacityMb) * 0.01)
|
||||||
// underutilizedNodes are 10% full
|
// underutilizedNodes are 10% full
|
||||||
underutilizedPerNodeReplicas := 10
|
underutilizedPerNodeReplicas := 10
|
||||||
|
@ -291,7 +291,7 @@ var _ = framework.KubeDescribe("Cluster size autoscaler scalability [Slow]", fun
|
||||||
}, timeout))
|
}, timeout))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("shouldn't scale down with underutilized nodes due to host port conflicts [Feature:ClusterAutoscalerScalability5]", func() {
|
ginkgo.It("shouldn't scale down with underutilized nodes due to host port conflicts [Feature:ClusterAutoscalerScalability5]", func() {
|
||||||
fullReservation := int(float64(memCapacityMb) * 0.9)
|
fullReservation := int(float64(memCapacityMb) * 0.9)
|
||||||
hostPortPodReservation := int(float64(memCapacityMb) * 0.3)
|
hostPortPodReservation := int(float64(memCapacityMb) * 0.3)
|
||||||
totalNodes := maxNodes
|
totalNodes := maxNodes
|
||||||
|
@ -307,28 +307,28 @@ var _ = framework.KubeDescribe("Cluster size autoscaler scalability [Slow]", fun
|
||||||
fullNodesCount := divider
|
fullNodesCount := divider
|
||||||
underutilizedNodesCount := totalNodes - fullNodesCount
|
underutilizedNodesCount := totalNodes - fullNodesCount
|
||||||
|
|
||||||
By("Reserving full nodes")
|
ginkgo.By("Reserving full nodes")
|
||||||
// run RC1 w/o host port
|
// run RC1 w/o host port
|
||||||
cleanup := ReserveMemory(f, "filling-pod", fullNodesCount, fullNodesCount*fullReservation, true, largeScaleUpTimeout*2)
|
cleanup := ReserveMemory(f, "filling-pod", fullNodesCount, fullNodesCount*fullReservation, true, largeScaleUpTimeout*2)
|
||||||
defer cleanup()
|
defer cleanup()
|
||||||
|
|
||||||
By("Reserving host ports on remaining nodes")
|
ginkgo.By("Reserving host ports on remaining nodes")
|
||||||
// run RC2 w/ host port
|
// run RC2 w/ host port
|
||||||
cleanup2 := createHostPortPodsWithMemory(f, "underutilizing-host-port-pod", underutilizedNodesCount, reservedPort, underutilizedNodesCount*hostPortPodReservation, largeScaleUpTimeout)
|
cleanup2 := createHostPortPodsWithMemory(f, "underutilizing-host-port-pod", underutilizedNodesCount, reservedPort, underutilizedNodesCount*hostPortPodReservation, largeScaleUpTimeout)
|
||||||
defer cleanup2()
|
defer cleanup2()
|
||||||
|
|
||||||
waitForAllCaPodsReadyInNamespace(f, c)
|
waitForAllCaPodsReadyInNamespace(f, c)
|
||||||
// wait and check scale down doesn't occur
|
// wait and check scale down doesn't occur
|
||||||
By(fmt.Sprintf("Sleeping %v minutes...", scaleDownTimeout.Minutes()))
|
ginkgo.By(fmt.Sprintf("Sleeping %v minutes...", scaleDownTimeout.Minutes()))
|
||||||
time.Sleep(scaleDownTimeout)
|
time.Sleep(scaleDownTimeout)
|
||||||
|
|
||||||
By("Checking if the number of nodes is as expected")
|
ginkgo.By("Checking if the number of nodes is as expected")
|
||||||
nodes := framework.GetReadySchedulableNodesOrDie(f.ClientSet)
|
nodes := framework.GetReadySchedulableNodesOrDie(f.ClientSet)
|
||||||
klog.Infof("Nodes: %v, expected: %v", len(nodes.Items), totalNodes)
|
klog.Infof("Nodes: %v, expected: %v", len(nodes.Items), totalNodes)
|
||||||
Expect(len(nodes.Items)).Should(Equal(totalNodes))
|
gomega.Expect(len(nodes.Items)).Should(gomega.Equal(totalNodes))
|
||||||
})
|
})
|
||||||
|
|
||||||
Specify("CA ignores unschedulable pods while scheduling schedulable pods [Feature:ClusterAutoscalerScalability6]", func() {
|
ginkgo.Specify("CA ignores unschedulable pods while scheduling schedulable pods [Feature:ClusterAutoscalerScalability6]", func() {
|
||||||
// Start a number of pods saturating existing nodes.
|
// Start a number of pods saturating existing nodes.
|
||||||
perNodeReservation := int(float64(memCapacityMb) * 0.80)
|
perNodeReservation := int(float64(memCapacityMb) * 0.80)
|
||||||
replicasPerNode := 10
|
replicasPerNode := 10
|
||||||
|
@ -348,7 +348,7 @@ var _ = framework.KubeDescribe("Cluster size autoscaler scalability [Slow]", fun
|
||||||
defer framework.DeleteRCAndWaitForGC(f.ClientSet, f.Namespace.Name, podsConfig.Name)
|
defer framework.DeleteRCAndWaitForGC(f.ClientSet, f.Namespace.Name, podsConfig.Name)
|
||||||
|
|
||||||
// Ensure that no new nodes have been added so far.
|
// Ensure that no new nodes have been added so far.
|
||||||
Expect(framework.NumberOfReadyNodes(f.ClientSet)).To(Equal(nodeCount))
|
gomega.Expect(framework.NumberOfReadyNodes(f.ClientSet)).To(gomega.Equal(nodeCount))
|
||||||
|
|
||||||
// Start a number of schedulable pods to ensure CA reacts.
|
// Start a number of schedulable pods to ensure CA reacts.
|
||||||
additionalNodes := maxNodes - nodeCount
|
additionalNodes := maxNodes - nodeCount
|
||||||
|
@ -375,7 +375,7 @@ func anyKey(input map[string]int) string {
|
||||||
func simpleScaleUpTestWithTolerance(f *framework.Framework, config *scaleUpTestConfig, tolerateMissingNodeCount int, tolerateMissingPodCount int) func() error {
|
func simpleScaleUpTestWithTolerance(f *framework.Framework, config *scaleUpTestConfig, tolerateMissingNodeCount int, tolerateMissingPodCount int) func() error {
|
||||||
// resize cluster to start size
|
// resize cluster to start size
|
||||||
// run rc based on config
|
// run rc based on config
|
||||||
By(fmt.Sprintf("Running RC %v from config", config.extraPods.Name))
|
ginkgo.By(fmt.Sprintf("Running RC %v from config", config.extraPods.Name))
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
framework.ExpectNoError(framework.RunRC(*config.extraPods))
|
framework.ExpectNoError(framework.RunRC(*config.extraPods))
|
||||||
// check results
|
// check results
|
||||||
|
@ -461,7 +461,7 @@ func addAnnotation(f *framework.Framework, nodes []v1.Node, key, value string) e
|
||||||
}
|
}
|
||||||
|
|
||||||
func createHostPortPodsWithMemory(f *framework.Framework, id string, replicas, port, megabytes int, timeout time.Duration) func() error {
|
func createHostPortPodsWithMemory(f *framework.Framework, id string, replicas, port, megabytes int, timeout time.Duration) func() error {
|
||||||
By(fmt.Sprintf("Running RC which reserves host port and memory"))
|
ginkgo.By(fmt.Sprintf("Running RC which reserves host port and memory"))
|
||||||
request := int64(1024 * 1024 * megabytes / replicas)
|
request := int64(1024 * 1024 * megabytes / replicas)
|
||||||
config := &testutils.RCConfig{
|
config := &testutils.RCConfig{
|
||||||
Client: f.ClientSet,
|
Client: f.ClientSet,
|
||||||
|
|
|
@ -48,8 +48,8 @@ import (
|
||||||
testutils "k8s.io/kubernetes/test/utils"
|
testutils "k8s.io/kubernetes/test/utils"
|
||||||
imageutils "k8s.io/kubernetes/test/utils/image"
|
imageutils "k8s.io/kubernetes/test/utils/image"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
"github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
"github.com/onsi/gomega"
|
||||||
"k8s.io/klog"
|
"k8s.io/klog"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
var memAllocatableMb int
|
var memAllocatableMb int
|
||||||
var originalSizes map[string]int
|
var originalSizes map[string]int
|
||||||
|
|
||||||
BeforeEach(func() {
|
ginkgo.BeforeEach(func() {
|
||||||
c = f.ClientSet
|
c = f.ClientSet
|
||||||
framework.SkipUnlessProviderIs("gce", "gke")
|
framework.SkipUnlessProviderIs("gce", "gke")
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
for _, mig := range strings.Split(framework.TestContext.CloudConfig.NodeInstanceGroup, ",") {
|
for _, mig := range strings.Split(framework.TestContext.CloudConfig.NodeInstanceGroup, ",") {
|
||||||
size, err := framework.GroupSize(mig)
|
size, err := framework.GroupSize(mig)
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
By(fmt.Sprintf("Initial size of %s: %d", mig, size))
|
ginkgo.By(fmt.Sprintf("Initial size of %s: %d", mig, size))
|
||||||
originalSizes[mig] = size
|
originalSizes[mig] = size
|
||||||
sum += size
|
sum += size
|
||||||
}
|
}
|
||||||
|
@ -117,12 +117,12 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
quantity := node.Status.Allocatable[v1.ResourceCPU]
|
quantity := node.Status.Allocatable[v1.ResourceCPU]
|
||||||
coreCount += quantity.Value()
|
coreCount += quantity.Value()
|
||||||
}
|
}
|
||||||
By(fmt.Sprintf("Initial number of schedulable nodes: %v", nodeCount))
|
ginkgo.By(fmt.Sprintf("Initial number of schedulable nodes: %v", nodeCount))
|
||||||
Expect(nodeCount).NotTo(BeZero())
|
gomega.Expect(nodeCount).NotTo(gomega.BeZero())
|
||||||
mem := nodes.Items[0].Status.Allocatable[v1.ResourceMemory]
|
mem := nodes.Items[0].Status.Allocatable[v1.ResourceMemory]
|
||||||
memAllocatableMb = int((&mem).Value() / 1024 / 1024)
|
memAllocatableMb = int((&mem).Value() / 1024 / 1024)
|
||||||
|
|
||||||
Expect(nodeCount).Should(Equal(sum))
|
gomega.Expect(nodeCount).Should(gomega.Equal(sum))
|
||||||
|
|
||||||
if framework.ProviderIs("gke") {
|
if framework.ProviderIs("gke") {
|
||||||
val, err := isAutoscalerEnabled(5)
|
val, err := isAutoscalerEnabled(5)
|
||||||
|
@ -134,9 +134,9 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
AfterEach(func() {
|
ginkgo.AfterEach(func() {
|
||||||
framework.SkipUnlessProviderIs("gce", "gke")
|
framework.SkipUnlessProviderIs("gce", "gke")
|
||||||
By(fmt.Sprintf("Restoring initial size of the cluster"))
|
ginkgo.By(fmt.Sprintf("Restoring initial size of the cluster"))
|
||||||
setMigSizes(originalSizes)
|
setMigSizes(originalSizes)
|
||||||
expectedNodes := 0
|
expectedNodes := 0
|
||||||
for _, size := range originalSizes {
|
for _, size := range originalSizes {
|
||||||
|
@ -163,29 +163,29 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
klog.Infof("Made nodes schedulable again in %v", time.Since(s).String())
|
klog.Infof("Made nodes schedulable again in %v", time.Since(s).String())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("shouldn't increase cluster size if pending pod is too large [Feature:ClusterSizeAutoscalingScaleUp]", func() {
|
ginkgo.It("shouldn't increase cluster size if pending pod is too large [Feature:ClusterSizeAutoscalingScaleUp]", func() {
|
||||||
By("Creating unschedulable pod")
|
ginkgo.By("Creating unschedulable pod")
|
||||||
ReserveMemory(f, "memory-reservation", 1, int(1.1*float64(memAllocatableMb)), false, defaultTimeout)
|
ReserveMemory(f, "memory-reservation", 1, int(1.1*float64(memAllocatableMb)), false, defaultTimeout)
|
||||||
defer framework.DeleteRCAndWaitForGC(f.ClientSet, f.Namespace.Name, "memory-reservation")
|
defer framework.DeleteRCAndWaitForGC(f.ClientSet, f.Namespace.Name, "memory-reservation")
|
||||||
|
|
||||||
By("Waiting for scale up hoping it won't happen")
|
ginkgo.By("Waiting for scale up hoping it won't happen")
|
||||||
// Verify that the appropriate event was generated
|
// Verify that the appropriate event was generated
|
||||||
eventFound := false
|
eventFound := false
|
||||||
EventsLoop:
|
EventsLoop:
|
||||||
for start := time.Now(); time.Since(start) < scaleUpTimeout; time.Sleep(20 * time.Second) {
|
for start := time.Now(); time.Since(start) < scaleUpTimeout; time.Sleep(20 * time.Second) {
|
||||||
By("Waiting for NotTriggerScaleUp event")
|
ginkgo.By("Waiting for NotTriggerScaleUp event")
|
||||||
events, err := f.ClientSet.CoreV1().Events(f.Namespace.Name).List(metav1.ListOptions{})
|
events, err := f.ClientSet.CoreV1().Events(f.Namespace.Name).List(metav1.ListOptions{})
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
|
|
||||||
for _, e := range events.Items {
|
for _, e := range events.Items {
|
||||||
if e.InvolvedObject.Kind == "Pod" && e.Reason == "NotTriggerScaleUp" && strings.Contains(e.Message, "it wouldn't fit if a new node is added") {
|
if e.InvolvedObject.Kind == "Pod" && e.Reason == "NotTriggerScaleUp" && strings.Contains(e.Message, "it wouldn't fit if a new node is added") {
|
||||||
By("NotTriggerScaleUp event found")
|
ginkgo.By("NotTriggerScaleUp event found")
|
||||||
eventFound = true
|
eventFound = true
|
||||||
break EventsLoop
|
break EventsLoop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Expect(eventFound).Should(Equal(true))
|
gomega.Expect(eventFound).Should(gomega.Equal(true))
|
||||||
// Verify that cluster size is not changed
|
// Verify that cluster size is not changed
|
||||||
framework.ExpectNoError(WaitForClusterSizeFunc(f.ClientSet,
|
framework.ExpectNoError(WaitForClusterSizeFunc(f.ClientSet,
|
||||||
func(size int) bool { return size <= nodeCount }, time.Second))
|
func(size int) bool { return size <= nodeCount }, time.Second))
|
||||||
|
@ -201,12 +201,12 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
framework.ExpectNoError(waitForAllCaPodsReadyInNamespace(f, c))
|
framework.ExpectNoError(waitForAllCaPodsReadyInNamespace(f, c))
|
||||||
}
|
}
|
||||||
|
|
||||||
It("should increase cluster size if pending pods are small [Feature:ClusterSizeAutoscalingScaleUp]",
|
ginkgo.It("should increase cluster size if pending pods are small [Feature:ClusterSizeAutoscalingScaleUp]",
|
||||||
func() { simpleScaleUpTest(0) })
|
func() { simpleScaleUpTest(0) })
|
||||||
|
|
||||||
gpuType := os.Getenv("TESTED_GPU_TYPE")
|
gpuType := os.Getenv("TESTED_GPU_TYPE")
|
||||||
|
|
||||||
It(fmt.Sprintf("Should scale up GPU pool from 0 [GpuType:%s] [Feature:ClusterSizeAutoscalingGpu]", gpuType), func() {
|
ginkgo.It(fmt.Sprintf("Should scale up GPU pool from 0 [GpuType:%s] [Feature:ClusterSizeAutoscalingGpu]", gpuType), func() {
|
||||||
framework.SkipUnlessProviderIs("gke")
|
framework.SkipUnlessProviderIs("gke")
|
||||||
if gpuType == "" {
|
if gpuType == "" {
|
||||||
framework.Failf("TEST_GPU_TYPE not defined")
|
framework.Failf("TEST_GPU_TYPE not defined")
|
||||||
|
@ -219,21 +219,21 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
|
|
||||||
installNvidiaDriversDaemonSet()
|
installNvidiaDriversDaemonSet()
|
||||||
|
|
||||||
By("Enable autoscaler")
|
ginkgo.By("Enable autoscaler")
|
||||||
framework.ExpectNoError(enableAutoscaler(gpuPoolName, 0, 1))
|
framework.ExpectNoError(enableAutoscaler(gpuPoolName, 0, 1))
|
||||||
defer disableAutoscaler(gpuPoolName, 0, 1)
|
defer disableAutoscaler(gpuPoolName, 0, 1)
|
||||||
Expect(len(getPoolNodes(f, gpuPoolName))).Should(Equal(0))
|
gomega.Expect(len(getPoolNodes(f, gpuPoolName))).Should(gomega.Equal(0))
|
||||||
|
|
||||||
By("Schedule a pod which requires GPU")
|
ginkgo.By("Schedule a pod which requires GPU")
|
||||||
framework.ExpectNoError(ScheduleAnySingleGpuPod(f, "gpu-pod-rc"))
|
framework.ExpectNoError(ScheduleAnySingleGpuPod(f, "gpu-pod-rc"))
|
||||||
defer framework.DeleteRCAndWaitForGC(f.ClientSet, f.Namespace.Name, "gpu-pod-rc")
|
defer framework.DeleteRCAndWaitForGC(f.ClientSet, f.Namespace.Name, "gpu-pod-rc")
|
||||||
|
|
||||||
framework.ExpectNoError(WaitForClusterSizeFunc(f.ClientSet,
|
framework.ExpectNoError(WaitForClusterSizeFunc(f.ClientSet,
|
||||||
func(size int) bool { return size == nodeCount+1 }, scaleUpTimeout))
|
func(size int) bool { return size == nodeCount+1 }, scaleUpTimeout))
|
||||||
Expect(len(getPoolNodes(f, gpuPoolName))).Should(Equal(1))
|
gomega.Expect(len(getPoolNodes(f, gpuPoolName))).Should(gomega.Equal(1))
|
||||||
})
|
})
|
||||||
|
|
||||||
It(fmt.Sprintf("Should scale up GPU pool from 1 [GpuType:%s] [Feature:ClusterSizeAutoscalingGpu]", gpuType), func() {
|
ginkgo.It(fmt.Sprintf("Should scale up GPU pool from 1 [GpuType:%s] [Feature:ClusterSizeAutoscalingGpu]", gpuType), func() {
|
||||||
framework.SkipUnlessProviderIs("gke")
|
framework.SkipUnlessProviderIs("gke")
|
||||||
if gpuType == "" {
|
if gpuType == "" {
|
||||||
framework.Failf("TEST_GPU_TYPE not defined")
|
framework.Failf("TEST_GPU_TYPE not defined")
|
||||||
|
@ -246,24 +246,24 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
|
|
||||||
installNvidiaDriversDaemonSet()
|
installNvidiaDriversDaemonSet()
|
||||||
|
|
||||||
By("Schedule a single pod which requires GPU")
|
ginkgo.By("Schedule a single pod which requires GPU")
|
||||||
framework.ExpectNoError(ScheduleAnySingleGpuPod(f, "gpu-pod-rc"))
|
framework.ExpectNoError(ScheduleAnySingleGpuPod(f, "gpu-pod-rc"))
|
||||||
defer framework.DeleteRCAndWaitForGC(f.ClientSet, f.Namespace.Name, "gpu-pod-rc")
|
defer framework.DeleteRCAndWaitForGC(f.ClientSet, f.Namespace.Name, "gpu-pod-rc")
|
||||||
|
|
||||||
By("Enable autoscaler")
|
ginkgo.By("Enable autoscaler")
|
||||||
framework.ExpectNoError(enableAutoscaler(gpuPoolName, 0, 2))
|
framework.ExpectNoError(enableAutoscaler(gpuPoolName, 0, 2))
|
||||||
defer disableAutoscaler(gpuPoolName, 0, 2)
|
defer disableAutoscaler(gpuPoolName, 0, 2)
|
||||||
Expect(len(getPoolNodes(f, gpuPoolName))).Should(Equal(1))
|
gomega.Expect(len(getPoolNodes(f, gpuPoolName))).Should(gomega.Equal(1))
|
||||||
|
|
||||||
By("Scale GPU deployment")
|
ginkgo.By("Scale GPU deployment")
|
||||||
framework.ScaleRC(f.ClientSet, f.ScalesGetter, f.Namespace.Name, "gpu-pod-rc", 2, true)
|
framework.ScaleRC(f.ClientSet, f.ScalesGetter, f.Namespace.Name, "gpu-pod-rc", 2, true)
|
||||||
|
|
||||||
framework.ExpectNoError(WaitForClusterSizeFunc(f.ClientSet,
|
framework.ExpectNoError(WaitForClusterSizeFunc(f.ClientSet,
|
||||||
func(size int) bool { return size == nodeCount+2 }, scaleUpTimeout))
|
func(size int) bool { return size == nodeCount+2 }, scaleUpTimeout))
|
||||||
Expect(len(getPoolNodes(f, gpuPoolName))).Should(Equal(2))
|
gomega.Expect(len(getPoolNodes(f, gpuPoolName))).Should(gomega.Equal(2))
|
||||||
})
|
})
|
||||||
|
|
||||||
It(fmt.Sprintf("Should not scale GPU pool up if pod does not require GPUs [GpuType:%s] [Feature:ClusterSizeAutoscalingGpu]", gpuType), func() {
|
ginkgo.It(fmt.Sprintf("Should not scale GPU pool up if pod does not require GPUs [GpuType:%s] [Feature:ClusterSizeAutoscalingGpu]", gpuType), func() {
|
||||||
framework.SkipUnlessProviderIs("gke")
|
framework.SkipUnlessProviderIs("gke")
|
||||||
if gpuType == "" {
|
if gpuType == "" {
|
||||||
framework.Failf("TEST_GPU_TYPE not defined")
|
framework.Failf("TEST_GPU_TYPE not defined")
|
||||||
|
@ -276,12 +276,12 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
|
|
||||||
installNvidiaDriversDaemonSet()
|
installNvidiaDriversDaemonSet()
|
||||||
|
|
||||||
By("Enable autoscaler")
|
ginkgo.By("Enable autoscaler")
|
||||||
framework.ExpectNoError(enableAutoscaler(gpuPoolName, 0, 1))
|
framework.ExpectNoError(enableAutoscaler(gpuPoolName, 0, 1))
|
||||||
defer disableAutoscaler(gpuPoolName, 0, 1)
|
defer disableAutoscaler(gpuPoolName, 0, 1)
|
||||||
Expect(len(getPoolNodes(f, gpuPoolName))).Should(Equal(0))
|
gomega.Expect(len(getPoolNodes(f, gpuPoolName))).Should(gomega.Equal(0))
|
||||||
|
|
||||||
By("Schedule bunch of pods beyond point of filling default pool but do not request any GPUs")
|
ginkgo.By("Schedule bunch of pods beyond point of filling default pool but do not request any GPUs")
|
||||||
ReserveMemory(f, "memory-reservation", 100, nodeCount*memAllocatableMb, false, 1*time.Second)
|
ReserveMemory(f, "memory-reservation", 100, nodeCount*memAllocatableMb, false, 1*time.Second)
|
||||||
defer framework.DeleteRCAndWaitForGC(f.ClientSet, f.Namespace.Name, "memory-reservation")
|
defer framework.DeleteRCAndWaitForGC(f.ClientSet, f.Namespace.Name, "memory-reservation")
|
||||||
// Verify that cluster size is increased
|
// Verify that cluster size is increased
|
||||||
|
@ -289,10 +289,10 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
func(size int) bool { return size >= nodeCount+1 }, scaleUpTimeout))
|
func(size int) bool { return size >= nodeCount+1 }, scaleUpTimeout))
|
||||||
|
|
||||||
// Expect gpu pool to stay intact
|
// Expect gpu pool to stay intact
|
||||||
Expect(len(getPoolNodes(f, gpuPoolName))).Should(Equal(0))
|
gomega.Expect(len(getPoolNodes(f, gpuPoolName))).Should(gomega.Equal(0))
|
||||||
})
|
})
|
||||||
|
|
||||||
It(fmt.Sprintf("Should scale down GPU pool from 1 [GpuType:%s] [Feature:ClusterSizeAutoscalingGpu]", gpuType), func() {
|
ginkgo.It(fmt.Sprintf("Should scale down GPU pool from 1 [GpuType:%s] [Feature:ClusterSizeAutoscalingGpu]", gpuType), func() {
|
||||||
framework.SkipUnlessProviderIs("gke")
|
framework.SkipUnlessProviderIs("gke")
|
||||||
if gpuType == "" {
|
if gpuType == "" {
|
||||||
framework.Failf("TEST_GPU_TYPE not defined")
|
framework.Failf("TEST_GPU_TYPE not defined")
|
||||||
|
@ -305,29 +305,29 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
|
|
||||||
installNvidiaDriversDaemonSet()
|
installNvidiaDriversDaemonSet()
|
||||||
|
|
||||||
By("Schedule a single pod which requires GPU")
|
ginkgo.By("Schedule a single pod which requires GPU")
|
||||||
framework.ExpectNoError(ScheduleAnySingleGpuPod(f, "gpu-pod-rc"))
|
framework.ExpectNoError(ScheduleAnySingleGpuPod(f, "gpu-pod-rc"))
|
||||||
defer framework.DeleteRCAndWaitForGC(f.ClientSet, f.Namespace.Name, "gpu-pod-rc")
|
defer framework.DeleteRCAndWaitForGC(f.ClientSet, f.Namespace.Name, "gpu-pod-rc")
|
||||||
|
|
||||||
By("Enable autoscaler")
|
ginkgo.By("Enable autoscaler")
|
||||||
framework.ExpectNoError(enableAutoscaler(gpuPoolName, 0, 1))
|
framework.ExpectNoError(enableAutoscaler(gpuPoolName, 0, 1))
|
||||||
defer disableAutoscaler(gpuPoolName, 0, 1)
|
defer disableAutoscaler(gpuPoolName, 0, 1)
|
||||||
Expect(len(getPoolNodes(f, gpuPoolName))).Should(Equal(1))
|
gomega.Expect(len(getPoolNodes(f, gpuPoolName))).Should(gomega.Equal(1))
|
||||||
|
|
||||||
By("Remove the only POD requiring GPU")
|
ginkgo.By("Remove the only POD requiring GPU")
|
||||||
framework.DeleteRCAndWaitForGC(f.ClientSet, f.Namespace.Name, "gpu-pod-rc")
|
framework.DeleteRCAndWaitForGC(f.ClientSet, f.Namespace.Name, "gpu-pod-rc")
|
||||||
|
|
||||||
framework.ExpectNoError(WaitForClusterSizeFunc(f.ClientSet,
|
framework.ExpectNoError(WaitForClusterSizeFunc(f.ClientSet,
|
||||||
func(size int) bool { return size == nodeCount }, scaleDownTimeout))
|
func(size int) bool { return size == nodeCount }, scaleDownTimeout))
|
||||||
Expect(len(getPoolNodes(f, gpuPoolName))).Should(Equal(0))
|
gomega.Expect(len(getPoolNodes(f, gpuPoolName))).Should(gomega.Equal(0))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should increase cluster size if pending pods are small and one node is broken [Feature:ClusterSizeAutoscalingScaleUp]",
|
ginkgo.It("should increase cluster size if pending pods are small and one node is broken [Feature:ClusterSizeAutoscalingScaleUp]",
|
||||||
func() {
|
func() {
|
||||||
framework.TestUnderTemporaryNetworkFailure(c, "default", getAnyNode(c), func() { simpleScaleUpTest(1) })
|
framework.TestUnderTemporaryNetworkFailure(c, "default", getAnyNode(c), func() { simpleScaleUpTest(1) })
|
||||||
})
|
})
|
||||||
|
|
||||||
It("shouldn't trigger additional scale-ups during processing scale-up [Feature:ClusterSizeAutoscalingScaleUp]", func() {
|
ginkgo.It("shouldn't trigger additional scale-ups during processing scale-up [Feature:ClusterSizeAutoscalingScaleUp]", func() {
|
||||||
// Wait for the situation to stabilize - CA should be running and have up-to-date node readiness info.
|
// Wait for the situation to stabilize - CA should be running and have up-to-date node readiness info.
|
||||||
status, err := waitForScaleUpStatus(c, func(s *scaleUpStatus) bool {
|
status, err := waitForScaleUpStatus(c, func(s *scaleUpStatus) bool {
|
||||||
return s.ready == s.target && s.ready <= nodeCount
|
return s.ready == s.target && s.ready <= nodeCount
|
||||||
|
@ -336,7 +336,7 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
|
|
||||||
unmanagedNodes := nodeCount - status.ready
|
unmanagedNodes := nodeCount - status.ready
|
||||||
|
|
||||||
By("Schedule more pods than can fit and wait for cluster to scale-up")
|
ginkgo.By("Schedule more pods than can fit and wait for cluster to scale-up")
|
||||||
ReserveMemory(f, "memory-reservation", 100, nodeCount*memAllocatableMb, false, 1*time.Second)
|
ReserveMemory(f, "memory-reservation", 100, nodeCount*memAllocatableMb, false, 1*time.Second)
|
||||||
defer framework.DeleteRCAndWaitForGC(f.ClientSet, f.Namespace.Name, "memory-reservation")
|
defer framework.DeleteRCAndWaitForGC(f.ClientSet, f.Namespace.Name, "memory-reservation")
|
||||||
|
|
||||||
|
@ -347,7 +347,7 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
target := status.target
|
target := status.target
|
||||||
framework.ExpectNoError(waitForAllCaPodsReadyInNamespace(f, c))
|
framework.ExpectNoError(waitForAllCaPodsReadyInNamespace(f, c))
|
||||||
|
|
||||||
By("Expect no more scale-up to be happening after all pods are scheduled")
|
ginkgo.By("Expect no more scale-up to be happening after all pods are scheduled")
|
||||||
|
|
||||||
// wait for a while until scale-up finishes; we cannot read CA status immediately
|
// wait for a while until scale-up finishes; we cannot read CA status immediately
|
||||||
// after pods are scheduled as status config map is updated by CA once every loop iteration
|
// after pods are scheduled as status config map is updated by CA once every loop iteration
|
||||||
|
@ -359,16 +359,16 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
if status.target != target {
|
if status.target != target {
|
||||||
klog.Warningf("Final number of nodes (%v) does not match initial scale-up target (%v).", status.target, target)
|
klog.Warningf("Final number of nodes (%v) does not match initial scale-up target (%v).", status.target, target)
|
||||||
}
|
}
|
||||||
Expect(status.timestamp.Add(freshStatusLimit).Before(time.Now())).Should(Equal(false))
|
gomega.Expect(status.timestamp.Add(freshStatusLimit).Before(time.Now())).Should(gomega.Equal(false))
|
||||||
Expect(status.status).Should(Equal(caNoScaleUpStatus))
|
gomega.Expect(status.status).Should(gomega.Equal(caNoScaleUpStatus))
|
||||||
Expect(status.ready).Should(Equal(status.target))
|
gomega.Expect(status.ready).Should(gomega.Equal(status.target))
|
||||||
Expect(len(framework.GetReadySchedulableNodesOrDie(f.ClientSet).Items)).Should(Equal(status.target + unmanagedNodes))
|
gomega.Expect(len(framework.GetReadySchedulableNodesOrDie(f.ClientSet).Items)).Should(gomega.Equal(status.target + unmanagedNodes))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should increase cluster size if pending pods are small and there is another node pool that is not autoscaled [Feature:ClusterSizeAutoscalingScaleUp]", func() {
|
ginkgo.It("should increase cluster size if pending pods are small and there is another node pool that is not autoscaled [Feature:ClusterSizeAutoscalingScaleUp]", func() {
|
||||||
framework.SkipUnlessProviderIs("gke")
|
framework.SkipUnlessProviderIs("gke")
|
||||||
|
|
||||||
By("Creating new node-pool with n1-standard-4 machines")
|
ginkgo.By("Creating new node-pool with n1-standard-4 machines")
|
||||||
const extraPoolName = "extra-pool"
|
const extraPoolName = "extra-pool"
|
||||||
addNodePool(extraPoolName, "n1-standard-4", 1)
|
addNodePool(extraPoolName, "n1-standard-4", 1)
|
||||||
defer deleteNodePool(extraPoolName)
|
defer deleteNodePool(extraPoolName)
|
||||||
|
@ -379,16 +379,16 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
framework.ExpectNoError(framework.WaitForAllNodesSchedulable(c, resizeTimeout))
|
framework.ExpectNoError(framework.WaitForAllNodesSchedulable(c, resizeTimeout))
|
||||||
klog.Infof("Not enabling cluster autoscaler for the node pool (on purpose).")
|
klog.Infof("Not enabling cluster autoscaler for the node pool (on purpose).")
|
||||||
|
|
||||||
By("Getting memory available on new nodes, so we can account for it when creating RC")
|
ginkgo.By("Getting memory available on new nodes, so we can account for it when creating RC")
|
||||||
nodes := getPoolNodes(f, extraPoolName)
|
nodes := getPoolNodes(f, extraPoolName)
|
||||||
Expect(len(nodes)).Should(Equal(extraNodes))
|
gomega.Expect(len(nodes)).Should(gomega.Equal(extraNodes))
|
||||||
extraMemMb := 0
|
extraMemMb := 0
|
||||||
for _, node := range nodes {
|
for _, node := range nodes {
|
||||||
mem := node.Status.Allocatable[v1.ResourceMemory]
|
mem := node.Status.Allocatable[v1.ResourceMemory]
|
||||||
extraMemMb += int((&mem).Value() / 1024 / 1024)
|
extraMemMb += int((&mem).Value() / 1024 / 1024)
|
||||||
}
|
}
|
||||||
|
|
||||||
By("Reserving 0.1x more memory than the cluster holds to trigger scale up")
|
ginkgo.By("Reserving 0.1x more memory than the cluster holds to trigger scale up")
|
||||||
totalMemoryReservation := int(1.1 * float64(nodeCount*memAllocatableMb+extraMemMb))
|
totalMemoryReservation := int(1.1 * float64(nodeCount*memAllocatableMb+extraMemMb))
|
||||||
defer framework.DeleteRCAndWaitForGC(f.ClientSet, f.Namespace.Name, "memory-reservation")
|
defer framework.DeleteRCAndWaitForGC(f.ClientSet, f.Namespace.Name, "memory-reservation")
|
||||||
ReserveMemory(f, "memory-reservation", 100, totalMemoryReservation, false, defaultTimeout)
|
ReserveMemory(f, "memory-reservation", 100, totalMemoryReservation, false, defaultTimeout)
|
||||||
|
@ -399,10 +399,10 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
framework.ExpectNoError(waitForAllCaPodsReadyInNamespace(f, c))
|
framework.ExpectNoError(waitForAllCaPodsReadyInNamespace(f, c))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should disable node pool autoscaling [Feature:ClusterSizeAutoscalingScaleUp]", func() {
|
ginkgo.It("should disable node pool autoscaling [Feature:ClusterSizeAutoscalingScaleUp]", func() {
|
||||||
framework.SkipUnlessProviderIs("gke")
|
framework.SkipUnlessProviderIs("gke")
|
||||||
|
|
||||||
By("Creating new node-pool with n1-standard-4 machines")
|
ginkgo.By("Creating new node-pool with n1-standard-4 machines")
|
||||||
const extraPoolName = "extra-pool"
|
const extraPoolName = "extra-pool"
|
||||||
addNodePool(extraPoolName, "n1-standard-4", 1)
|
addNodePool(extraPoolName, "n1-standard-4", 1)
|
||||||
defer deleteNodePool(extraPoolName)
|
defer deleteNodePool(extraPoolName)
|
||||||
|
@ -412,7 +412,7 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
framework.ExpectNoError(disableAutoscaler(extraPoolName, 1, 2))
|
framework.ExpectNoError(disableAutoscaler(extraPoolName, 1, 2))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should increase cluster size if pods are pending due to host port conflict [Feature:ClusterSizeAutoscalingScaleUp]", func() {
|
ginkgo.It("should increase cluster size if pods are pending due to host port conflict [Feature:ClusterSizeAutoscalingScaleUp]", func() {
|
||||||
scheduling.CreateHostPortPods(f, "host-port", nodeCount+2, false)
|
scheduling.CreateHostPortPods(f, "host-port", nodeCount+2, false)
|
||||||
defer framework.DeleteRCAndWaitForGC(f.ClientSet, f.Namespace.Name, "host-port")
|
defer framework.DeleteRCAndWaitForGC(f.ClientSet, f.Namespace.Name, "host-port")
|
||||||
|
|
||||||
|
@ -421,18 +421,18 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
framework.ExpectNoError(waitForAllCaPodsReadyInNamespace(f, c))
|
framework.ExpectNoError(waitForAllCaPodsReadyInNamespace(f, c))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should increase cluster size if pods are pending due to pod anti-affinity [Feature:ClusterSizeAutoscalingScaleUp]", func() {
|
ginkgo.It("should increase cluster size if pods are pending due to pod anti-affinity [Feature:ClusterSizeAutoscalingScaleUp]", func() {
|
||||||
pods := nodeCount
|
pods := nodeCount
|
||||||
newPods := 2
|
newPods := 2
|
||||||
labels := map[string]string{
|
labels := map[string]string{
|
||||||
"anti-affinity": "yes",
|
"anti-affinity": "yes",
|
||||||
}
|
}
|
||||||
By("starting a pod with anti-affinity on each node")
|
ginkgo.By("starting a pod with anti-affinity on each node")
|
||||||
framework.ExpectNoError(runAntiAffinityPods(f, f.Namespace.Name, pods, "some-pod", labels, labels))
|
framework.ExpectNoError(runAntiAffinityPods(f, f.Namespace.Name, pods, "some-pod", labels, labels))
|
||||||
defer framework.DeleteRCAndWaitForGC(f.ClientSet, f.Namespace.Name, "some-pod")
|
defer framework.DeleteRCAndWaitForGC(f.ClientSet, f.Namespace.Name, "some-pod")
|
||||||
framework.ExpectNoError(waitForAllCaPodsReadyInNamespace(f, c))
|
framework.ExpectNoError(waitForAllCaPodsReadyInNamespace(f, c))
|
||||||
|
|
||||||
By("scheduling extra pods with anti-affinity to existing ones")
|
ginkgo.By("scheduling extra pods with anti-affinity to existing ones")
|
||||||
framework.ExpectNoError(runAntiAffinityPods(f, f.Namespace.Name, newPods, "extra-pod", labels, labels))
|
framework.ExpectNoError(runAntiAffinityPods(f, f.Namespace.Name, newPods, "extra-pod", labels, labels))
|
||||||
defer framework.DeleteRCAndWaitForGC(f.ClientSet, f.Namespace.Name, "extra-pod")
|
defer framework.DeleteRCAndWaitForGC(f.ClientSet, f.Namespace.Name, "extra-pod")
|
||||||
|
|
||||||
|
@ -440,8 +440,8 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
framework.ExpectNoError(framework.WaitForReadyNodes(c, nodeCount+newPods, scaleUpTimeout))
|
framework.ExpectNoError(framework.WaitForReadyNodes(c, nodeCount+newPods, scaleUpTimeout))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should increase cluster size if pod requesting EmptyDir volume is pending [Feature:ClusterSizeAutoscalingScaleUp]", func() {
|
ginkgo.It("should increase cluster size if pod requesting EmptyDir volume is pending [Feature:ClusterSizeAutoscalingScaleUp]", func() {
|
||||||
By("creating pods")
|
ginkgo.By("creating pods")
|
||||||
pods := nodeCount
|
pods := nodeCount
|
||||||
newPods := 1
|
newPods := 1
|
||||||
labels := map[string]string{
|
labels := map[string]string{
|
||||||
|
@ -450,10 +450,10 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
framework.ExpectNoError(runAntiAffinityPods(f, f.Namespace.Name, pods, "some-pod", labels, labels))
|
framework.ExpectNoError(runAntiAffinityPods(f, f.Namespace.Name, pods, "some-pod", labels, labels))
|
||||||
defer framework.DeleteRCAndWaitForGC(f.ClientSet, f.Namespace.Name, "some-pod")
|
defer framework.DeleteRCAndWaitForGC(f.ClientSet, f.Namespace.Name, "some-pod")
|
||||||
|
|
||||||
By("waiting for all pods before triggering scale up")
|
ginkgo.By("waiting for all pods before triggering scale up")
|
||||||
framework.ExpectNoError(waitForAllCaPodsReadyInNamespace(f, c))
|
framework.ExpectNoError(waitForAllCaPodsReadyInNamespace(f, c))
|
||||||
|
|
||||||
By("creating a pod requesting EmptyDir")
|
ginkgo.By("creating a pod requesting EmptyDir")
|
||||||
framework.ExpectNoError(runVolumeAntiAffinityPods(f, f.Namespace.Name, newPods, "extra-pod", labels, labels, emptyDirVolumes))
|
framework.ExpectNoError(runVolumeAntiAffinityPods(f, f.Namespace.Name, newPods, "extra-pod", labels, labels, emptyDirVolumes))
|
||||||
defer framework.DeleteRCAndWaitForGC(f.ClientSet, f.Namespace.Name, "extra-pod")
|
defer framework.DeleteRCAndWaitForGC(f.ClientSet, f.Namespace.Name, "extra-pod")
|
||||||
|
|
||||||
|
@ -461,7 +461,7 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
framework.ExpectNoError(framework.WaitForReadyNodes(c, nodeCount+newPods, scaleUpTimeout))
|
framework.ExpectNoError(framework.WaitForReadyNodes(c, nodeCount+newPods, scaleUpTimeout))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should increase cluster size if pod requesting volume is pending [Feature:ClusterSizeAutoscalingScaleUp]", func() {
|
ginkgo.It("should increase cluster size if pod requesting volume is pending [Feature:ClusterSizeAutoscalingScaleUp]", func() {
|
||||||
framework.SkipUnlessProviderIs("gce", "gke")
|
framework.SkipUnlessProviderIs("gce", "gke")
|
||||||
|
|
||||||
volumeLabels := labels.Set{
|
volumeLabels := labels.Set{
|
||||||
|
@ -469,7 +469,7 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
}
|
}
|
||||||
selector := metav1.SetAsLabelSelector(volumeLabels)
|
selector := metav1.SetAsLabelSelector(volumeLabels)
|
||||||
|
|
||||||
By("creating volume & pvc")
|
ginkgo.By("creating volume & pvc")
|
||||||
diskName, err := framework.CreatePDWithRetry()
|
diskName, err := framework.CreatePDWithRetry()
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
pvConfig := framework.PersistentVolumeConfig{
|
pvConfig := framework.PersistentVolumeConfig{
|
||||||
|
@ -505,7 +505,7 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
By("creating pods")
|
ginkgo.By("creating pods")
|
||||||
pods := nodeCount
|
pods := nodeCount
|
||||||
labels := map[string]string{
|
labels := map[string]string{
|
||||||
"anti-affinity": "yes",
|
"anti-affinity": "yes",
|
||||||
|
@ -516,10 +516,10 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
klog.Infof("RC and pods not using volume deleted")
|
klog.Infof("RC and pods not using volume deleted")
|
||||||
}()
|
}()
|
||||||
|
|
||||||
By("waiting for all pods before triggering scale up")
|
ginkgo.By("waiting for all pods before triggering scale up")
|
||||||
framework.ExpectNoError(waitForAllCaPodsReadyInNamespace(f, c))
|
framework.ExpectNoError(waitForAllCaPodsReadyInNamespace(f, c))
|
||||||
|
|
||||||
By("creating a pod requesting PVC")
|
ginkgo.By("creating a pod requesting PVC")
|
||||||
pvcPodName := "pvc-pod"
|
pvcPodName := "pvc-pod"
|
||||||
newPods := 1
|
newPods := 1
|
||||||
volumes := buildVolumes(pv, pvc)
|
volumes := buildVolumes(pv, pvc)
|
||||||
|
@ -533,11 +533,11 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
framework.ExpectNoError(framework.WaitForReadyNodes(c, nodeCount+newPods, scaleUpTimeout))
|
framework.ExpectNoError(framework.WaitForReadyNodes(c, nodeCount+newPods, scaleUpTimeout))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should add node to the particular mig [Feature:ClusterSizeAutoscalingScaleUp]", func() {
|
ginkgo.It("should add node to the particular mig [Feature:ClusterSizeAutoscalingScaleUp]", func() {
|
||||||
labelKey := "cluster-autoscaling-test.special-node"
|
labelKey := "cluster-autoscaling-test.special-node"
|
||||||
labelValue := "true"
|
labelValue := "true"
|
||||||
|
|
||||||
By("Finding the smallest MIG")
|
ginkgo.By("Finding the smallest MIG")
|
||||||
minMig := ""
|
minMig := ""
|
||||||
minSize := nodeCount
|
minSize := nodeCount
|
||||||
for mig, size := range originalSizes {
|
for mig, size := range originalSizes {
|
||||||
|
@ -557,7 +557,7 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
removeLabels := func(nodesToClean sets.String) {
|
removeLabels := func(nodesToClean sets.String) {
|
||||||
By("Removing labels from nodes")
|
ginkgo.By("Removing labels from nodes")
|
||||||
for node := range nodesToClean {
|
for node := range nodesToClean {
|
||||||
framework.RemoveLabelOffNode(c, node, labelKey)
|
framework.RemoveLabelOffNode(c, node, labelKey)
|
||||||
}
|
}
|
||||||
|
@ -567,7 +567,7 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
nodesSet := sets.NewString(nodes...)
|
nodesSet := sets.NewString(nodes...)
|
||||||
defer removeLabels(nodesSet)
|
defer removeLabels(nodesSet)
|
||||||
By(fmt.Sprintf("Annotating nodes of the smallest MIG(%s): %v", minMig, nodes))
|
ginkgo.By(fmt.Sprintf("Annotating nodes of the smallest MIG(%s): %v", minMig, nodes))
|
||||||
|
|
||||||
for node := range nodesSet {
|
for node := range nodesSet {
|
||||||
framework.AddOrUpdateLabelOnNode(c, node, labelKey, labelValue)
|
framework.AddOrUpdateLabelOnNode(c, node, labelKey, labelValue)
|
||||||
|
@ -575,7 +575,7 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
|
|
||||||
scheduling.CreateNodeSelectorPods(f, "node-selector", minSize+1, map[string]string{labelKey: labelValue}, false)
|
scheduling.CreateNodeSelectorPods(f, "node-selector", minSize+1, map[string]string{labelKey: labelValue}, false)
|
||||||
|
|
||||||
By("Waiting for new node to appear and annotating it")
|
ginkgo.By("Waiting for new node to appear and annotating it")
|
||||||
framework.WaitForGroupSize(minMig, int32(minSize+1))
|
framework.WaitForGroupSize(minMig, int32(minSize+1))
|
||||||
// Verify that cluster size is increased
|
// Verify that cluster size is increased
|
||||||
framework.ExpectNoError(WaitForClusterSizeFunc(f.ClientSet,
|
framework.ExpectNoError(WaitForClusterSizeFunc(f.ClientSet,
|
||||||
|
@ -586,7 +586,7 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
newNodesSet := sets.NewString(newNodes...)
|
newNodesSet := sets.NewString(newNodes...)
|
||||||
newNodesSet.Delete(nodes...)
|
newNodesSet.Delete(nodes...)
|
||||||
if len(newNodesSet) > 1 {
|
if len(newNodesSet) > 1 {
|
||||||
By(fmt.Sprintf("Spotted following new nodes in %s: %v", minMig, newNodesSet))
|
ginkgo.By(fmt.Sprintf("Spotted following new nodes in %s: %v", minMig, newNodesSet))
|
||||||
klog.Infof("Usually only 1 new node is expected, investigating")
|
klog.Infof("Usually only 1 new node is expected, investigating")
|
||||||
klog.Infof("Kubectl:%s\n", framework.RunKubectlOrDie("get", "nodes", "-o", "json"))
|
klog.Infof("Kubectl:%s\n", framework.RunKubectlOrDie("get", "nodes", "-o", "json"))
|
||||||
if output, err := exec.Command("gcloud", "compute", "instances", "list",
|
if output, err := exec.Command("gcloud", "compute", "instances", "list",
|
||||||
|
@ -612,7 +612,7 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
// However at this moment we DO WANT it to crash so that we don't check all test runs for the
|
// However at this moment we DO WANT it to crash so that we don't check all test runs for the
|
||||||
// rare behavior, but only the broken ones.
|
// rare behavior, but only the broken ones.
|
||||||
}
|
}
|
||||||
By(fmt.Sprintf("New nodes: %v\n", newNodesSet))
|
ginkgo.By(fmt.Sprintf("New nodes: %v\n", newNodesSet))
|
||||||
registeredNodes := sets.NewString()
|
registeredNodes := sets.NewString()
|
||||||
for nodeName := range newNodesSet {
|
for nodeName := range newNodesSet {
|
||||||
node, err := f.ClientSet.CoreV1().Nodes().Get(nodeName, metav1.GetOptions{})
|
node, err := f.ClientSet.CoreV1().Nodes().Get(nodeName, metav1.GetOptions{})
|
||||||
|
@ -622,7 +622,7 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
klog.Errorf("Failed to get node %v: %v", nodeName, err)
|
klog.Errorf("Failed to get node %v: %v", nodeName, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
By(fmt.Sprintf("Setting labels for registered new nodes: %v", registeredNodes.List()))
|
ginkgo.By(fmt.Sprintf("Setting labels for registered new nodes: %v", registeredNodes.List()))
|
||||||
for node := range registeredNodes {
|
for node := range registeredNodes {
|
||||||
framework.AddOrUpdateLabelOnNode(c, node, labelKey, labelValue)
|
framework.AddOrUpdateLabelOnNode(c, node, labelKey, labelValue)
|
||||||
}
|
}
|
||||||
|
@ -633,10 +633,10 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
framework.ExpectNoError(framework.DeleteRCAndWaitForGC(f.ClientSet, f.Namespace.Name, "node-selector"))
|
framework.ExpectNoError(framework.DeleteRCAndWaitForGC(f.ClientSet, f.Namespace.Name, "node-selector"))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should scale up correct target pool [Feature:ClusterSizeAutoscalingScaleUp]", func() {
|
ginkgo.It("should scale up correct target pool [Feature:ClusterSizeAutoscalingScaleUp]", func() {
|
||||||
framework.SkipUnlessProviderIs("gke")
|
framework.SkipUnlessProviderIs("gke")
|
||||||
|
|
||||||
By("Creating new node-pool with n1-standard-4 machines")
|
ginkgo.By("Creating new node-pool with n1-standard-4 machines")
|
||||||
const extraPoolName = "extra-pool"
|
const extraPoolName = "extra-pool"
|
||||||
addNodePool(extraPoolName, "n1-standard-4", 1)
|
addNodePool(extraPoolName, "n1-standard-4", 1)
|
||||||
defer deleteNodePool(extraPoolName)
|
defer deleteNodePool(extraPoolName)
|
||||||
|
@ -647,7 +647,7 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
|
|
||||||
extraPods := extraNodes + 1
|
extraPods := extraNodes + 1
|
||||||
totalMemoryReservation := int(float64(extraPods) * 1.5 * float64(memAllocatableMb))
|
totalMemoryReservation := int(float64(extraPods) * 1.5 * float64(memAllocatableMb))
|
||||||
By(fmt.Sprintf("Creating rc with %v pods too big to fit default-pool but fitting extra-pool", extraPods))
|
ginkgo.By(fmt.Sprintf("Creating rc with %v pods too big to fit default-pool but fitting extra-pool", extraPods))
|
||||||
defer framework.DeleteRCAndWaitForGC(f.ClientSet, f.Namespace.Name, "memory-reservation")
|
defer framework.DeleteRCAndWaitForGC(f.ClientSet, f.Namespace.Name, "memory-reservation")
|
||||||
ReserveMemory(f, "memory-reservation", extraPods, totalMemoryReservation, false, defaultTimeout)
|
ReserveMemory(f, "memory-reservation", extraPods, totalMemoryReservation, false, defaultTimeout)
|
||||||
|
|
||||||
|
@ -663,7 +663,7 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
defer cleanup()
|
defer cleanup()
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
|
|
||||||
By("Manually increase cluster size")
|
ginkgo.By("Manually increase cluster size")
|
||||||
increasedSize := 0
|
increasedSize := 0
|
||||||
newSizes := make(map[string]int)
|
newSizes := make(map[string]int)
|
||||||
for key, val := range originalSizes {
|
for key, val := range originalSizes {
|
||||||
|
@ -674,20 +674,20 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
framework.ExpectNoError(WaitForClusterSizeFuncWithUnready(f.ClientSet,
|
framework.ExpectNoError(WaitForClusterSizeFuncWithUnready(f.ClientSet,
|
||||||
func(size int) bool { return size >= increasedSize }, manualResizeTimeout, unready))
|
func(size int) bool { return size >= increasedSize }, manualResizeTimeout, unready))
|
||||||
|
|
||||||
By("Some node should be removed")
|
ginkgo.By("Some node should be removed")
|
||||||
framework.ExpectNoError(WaitForClusterSizeFuncWithUnready(f.ClientSet,
|
framework.ExpectNoError(WaitForClusterSizeFuncWithUnready(f.ClientSet,
|
||||||
func(size int) bool { return size < increasedSize }, scaleDownTimeout, unready))
|
func(size int) bool { return size < increasedSize }, scaleDownTimeout, unready))
|
||||||
}
|
}
|
||||||
|
|
||||||
It("should correctly scale down after a node is not needed [Feature:ClusterSizeAutoscalingScaleDown]",
|
ginkgo.It("should correctly scale down after a node is not needed [Feature:ClusterSizeAutoscalingScaleDown]",
|
||||||
func() { simpleScaleDownTest(0) })
|
func() { simpleScaleDownTest(0) })
|
||||||
|
|
||||||
It("should correctly scale down after a node is not needed and one node is broken [Feature:ClusterSizeAutoscalingScaleDown]",
|
ginkgo.It("should correctly scale down after a node is not needed and one node is broken [Feature:ClusterSizeAutoscalingScaleDown]",
|
||||||
func() {
|
func() {
|
||||||
framework.TestUnderTemporaryNetworkFailure(c, "default", getAnyNode(c), func() { simpleScaleDownTest(1) })
|
framework.TestUnderTemporaryNetworkFailure(c, "default", getAnyNode(c), func() { simpleScaleDownTest(1) })
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should correctly scale down after a node is not needed when there is non autoscaled pool[Feature:ClusterSizeAutoscalingScaleDown]", func() {
|
ginkgo.It("should correctly scale down after a node is not needed when there is non autoscaled pool[Feature:ClusterSizeAutoscalingScaleDown]", func() {
|
||||||
framework.SkipUnlessProviderIs("gke")
|
framework.SkipUnlessProviderIs("gke")
|
||||||
|
|
||||||
increasedSize := manuallyIncreaseClusterSize(f, originalSizes)
|
increasedSize := manuallyIncreaseClusterSize(f, originalSizes)
|
||||||
|
@ -700,7 +700,7 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
framework.ExpectNoError(WaitForClusterSizeFunc(f.ClientSet,
|
framework.ExpectNoError(WaitForClusterSizeFunc(f.ClientSet,
|
||||||
func(size int) bool { return size >= increasedSize+extraNodes }, scaleUpTimeout))
|
func(size int) bool { return size >= increasedSize+extraNodes }, scaleUpTimeout))
|
||||||
|
|
||||||
By("Some node should be removed")
|
ginkgo.By("Some node should be removed")
|
||||||
// Apparently GKE master is restarted couple minutes after the node pool is added
|
// Apparently GKE master is restarted couple minutes after the node pool is added
|
||||||
// reseting all the timers in scale down code. Adding 10 extra minutes to workaround
|
// reseting all the timers in scale down code. Adding 10 extra minutes to workaround
|
||||||
// this issue.
|
// this issue.
|
||||||
|
@ -709,44 +709,44 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
func(size int) bool { return size < increasedSize+extraNodes }, scaleDownTimeout+10*time.Minute))
|
func(size int) bool { return size < increasedSize+extraNodes }, scaleDownTimeout+10*time.Minute))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should be able to scale down when rescheduling a pod is required and pdb allows for it[Feature:ClusterSizeAutoscalingScaleDown]", func() {
|
ginkgo.It("should be able to scale down when rescheduling a pod is required and pdb allows for it[Feature:ClusterSizeAutoscalingScaleDown]", func() {
|
||||||
runDrainTest(f, originalSizes, f.Namespace.Name, 1, 1, func(increasedSize int) {
|
runDrainTest(f, originalSizes, f.Namespace.Name, 1, 1, func(increasedSize int) {
|
||||||
By("Some node should be removed")
|
ginkgo.By("Some node should be removed")
|
||||||
framework.ExpectNoError(WaitForClusterSizeFunc(f.ClientSet,
|
framework.ExpectNoError(WaitForClusterSizeFunc(f.ClientSet,
|
||||||
func(size int) bool { return size < increasedSize }, scaleDownTimeout))
|
func(size int) bool { return size < increasedSize }, scaleDownTimeout))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
It("shouldn't be able to scale down when rescheduling a pod is required, but pdb doesn't allow drain[Feature:ClusterSizeAutoscalingScaleDown]", func() {
|
ginkgo.It("shouldn't be able to scale down when rescheduling a pod is required, but pdb doesn't allow drain[Feature:ClusterSizeAutoscalingScaleDown]", func() {
|
||||||
runDrainTest(f, originalSizes, f.Namespace.Name, 1, 0, func(increasedSize int) {
|
runDrainTest(f, originalSizes, f.Namespace.Name, 1, 0, func(increasedSize int) {
|
||||||
By("No nodes should be removed")
|
ginkgo.By("No nodes should be removed")
|
||||||
time.Sleep(scaleDownTimeout)
|
time.Sleep(scaleDownTimeout)
|
||||||
nodes := framework.GetReadySchedulableNodesOrDie(f.ClientSet)
|
nodes := framework.GetReadySchedulableNodesOrDie(f.ClientSet)
|
||||||
Expect(len(nodes.Items)).Should(Equal(increasedSize))
|
gomega.Expect(len(nodes.Items)).Should(gomega.Equal(increasedSize))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should be able to scale down by draining multiple pods one by one as dictated by pdb[Feature:ClusterSizeAutoscalingScaleDown]", func() {
|
ginkgo.It("should be able to scale down by draining multiple pods one by one as dictated by pdb[Feature:ClusterSizeAutoscalingScaleDown]", func() {
|
||||||
runDrainTest(f, originalSizes, f.Namespace.Name, 2, 1, func(increasedSize int) {
|
runDrainTest(f, originalSizes, f.Namespace.Name, 2, 1, func(increasedSize int) {
|
||||||
By("Some node should be removed")
|
ginkgo.By("Some node should be removed")
|
||||||
framework.ExpectNoError(WaitForClusterSizeFunc(f.ClientSet,
|
framework.ExpectNoError(WaitForClusterSizeFunc(f.ClientSet,
|
||||||
func(size int) bool { return size < increasedSize }, scaleDownTimeout))
|
func(size int) bool { return size < increasedSize }, scaleDownTimeout))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should be able to scale down by draining system pods with pdb[Feature:ClusterSizeAutoscalingScaleDown]", func() {
|
ginkgo.It("should be able to scale down by draining system pods with pdb[Feature:ClusterSizeAutoscalingScaleDown]", func() {
|
||||||
runDrainTest(f, originalSizes, "kube-system", 2, 1, func(increasedSize int) {
|
runDrainTest(f, originalSizes, "kube-system", 2, 1, func(increasedSize int) {
|
||||||
By("Some node should be removed")
|
ginkgo.By("Some node should be removed")
|
||||||
framework.ExpectNoError(WaitForClusterSizeFunc(f.ClientSet,
|
framework.ExpectNoError(WaitForClusterSizeFunc(f.ClientSet,
|
||||||
func(size int) bool { return size < increasedSize }, scaleDownTimeout))
|
func(size int) bool { return size < increasedSize }, scaleDownTimeout))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
It("Should be able to scale a node group up from 0[Feature:ClusterSizeAutoscalingScaleUp]", func() {
|
ginkgo.It("Should be able to scale a node group up from 0[Feature:ClusterSizeAutoscalingScaleUp]", func() {
|
||||||
// Provider-specific setup
|
// Provider-specific setup
|
||||||
if framework.ProviderIs("gke") {
|
if framework.ProviderIs("gke") {
|
||||||
// GKE-specific setup
|
// GKE-specific setup
|
||||||
By("Add a new node pool with 0 nodes and min size 0")
|
ginkgo.By("Add a new node pool with 0 nodes and min size 0")
|
||||||
const extraPoolName = "extra-pool"
|
const extraPoolName = "extra-pool"
|
||||||
addNodePool(extraPoolName, "n1-standard-4", 0)
|
addNodePool(extraPoolName, "n1-standard-4", 0)
|
||||||
defer deleteNodePool(extraPoolName)
|
defer deleteNodePool(extraPoolName)
|
||||||
|
@ -756,7 +756,7 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
// on GCE, run only if there are already at least 2 node groups
|
// on GCE, run only if there are already at least 2 node groups
|
||||||
framework.SkipUnlessAtLeast(len(originalSizes), 2, "At least 2 node groups are needed for scale-to-0 tests")
|
framework.SkipUnlessAtLeast(len(originalSizes), 2, "At least 2 node groups are needed for scale-to-0 tests")
|
||||||
|
|
||||||
By("Manually scale smallest node group to 0")
|
ginkgo.By("Manually scale smallest node group to 0")
|
||||||
minMig := ""
|
minMig := ""
|
||||||
minSize := nodeCount
|
minSize := nodeCount
|
||||||
for mig, size := range originalSizes {
|
for mig, size := range originalSizes {
|
||||||
|
@ -769,7 +769,7 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
framework.ExpectNoError(framework.WaitForReadyNodes(c, nodeCount-minSize, resizeTimeout))
|
framework.ExpectNoError(framework.WaitForReadyNodes(c, nodeCount-minSize, resizeTimeout))
|
||||||
}
|
}
|
||||||
|
|
||||||
By("Make remaining nodes unschedulable")
|
ginkgo.By("Make remaining nodes unschedulable")
|
||||||
nodes, err := f.ClientSet.CoreV1().Nodes().List(metav1.ListOptions{FieldSelector: fields.Set{
|
nodes, err := f.ClientSet.CoreV1().Nodes().List(metav1.ListOptions{FieldSelector: fields.Set{
|
||||||
"spec.unschedulable": "false",
|
"spec.unschedulable": "false",
|
||||||
}.AsSelector().String()})
|
}.AsSelector().String()})
|
||||||
|
@ -785,7 +785,7 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
By("Run a scale-up test")
|
ginkgo.By("Run a scale-up test")
|
||||||
ReserveMemory(f, "memory-reservation", 1, 100, false, 1*time.Second)
|
ReserveMemory(f, "memory-reservation", 1, 100, false, 1*time.Second)
|
||||||
defer framework.DeleteRCAndWaitForGC(f.ClientSet, f.Namespace.Name, "memory-reservation")
|
defer framework.DeleteRCAndWaitForGC(f.ClientSet, f.Namespace.Name, "memory-reservation")
|
||||||
|
|
||||||
|
@ -807,7 +807,7 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
// verify the targeted node pool/MIG is of size 0
|
// verify the targeted node pool/MIG is of size 0
|
||||||
gkeScaleToZero := func() {
|
gkeScaleToZero := func() {
|
||||||
// GKE-specific setup
|
// GKE-specific setup
|
||||||
By("Add a new node pool with size 1 and min size 0")
|
ginkgo.By("Add a new node pool with size 1 and min size 0")
|
||||||
const extraPoolName = "extra-pool"
|
const extraPoolName = "extra-pool"
|
||||||
addNodePool(extraPoolName, "n1-standard-4", 1)
|
addNodePool(extraPoolName, "n1-standard-4", 1)
|
||||||
defer deleteNodePool(extraPoolName)
|
defer deleteNodePool(extraPoolName)
|
||||||
|
@ -817,9 +817,9 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
defer disableAutoscaler(extraPoolName, 0, 1)
|
defer disableAutoscaler(extraPoolName, 0, 1)
|
||||||
|
|
||||||
ngNodes := getPoolNodes(f, extraPoolName)
|
ngNodes := getPoolNodes(f, extraPoolName)
|
||||||
Expect(len(ngNodes)).To(Equal(extraNodes))
|
gomega.Expect(len(ngNodes)).To(gomega.Equal(extraNodes))
|
||||||
for _, node := range ngNodes {
|
for _, node := range ngNodes {
|
||||||
By(fmt.Sprintf("Target node for scale-down: %s", node.Name))
|
ginkgo.By(fmt.Sprintf("Target node for scale-down: %s", node.Name))
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, node := range ngNodes {
|
for _, node := range ngNodes {
|
||||||
|
@ -830,12 +830,12 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
|
|
||||||
// GKE-specific check
|
// GKE-specific check
|
||||||
newSize := getPoolSize(f, extraPoolName)
|
newSize := getPoolSize(f, extraPoolName)
|
||||||
Expect(newSize).Should(Equal(0))
|
gomega.Expect(newSize).Should(gomega.Equal(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
gceScaleToZero := func() {
|
gceScaleToZero := func() {
|
||||||
// non-GKE only
|
// non-GKE only
|
||||||
By("Find smallest node group and manually scale it to a single node")
|
ginkgo.By("Find smallest node group and manually scale it to a single node")
|
||||||
minMig := ""
|
minMig := ""
|
||||||
minSize := nodeCount
|
minSize := nodeCount
|
||||||
for mig, size := range originalSizes {
|
for mig, size := range originalSizes {
|
||||||
|
@ -848,9 +848,9 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
framework.ExpectNoError(framework.WaitForReadyNodes(c, nodeCount-minSize+1, resizeTimeout))
|
framework.ExpectNoError(framework.WaitForReadyNodes(c, nodeCount-minSize+1, resizeTimeout))
|
||||||
ngNodes, err := framework.GetGroupNodes(minMig)
|
ngNodes, err := framework.GetGroupNodes(minMig)
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
Expect(len(ngNodes) == 1).To(BeTrue())
|
gomega.Expect(len(ngNodes) == 1).To(gomega.BeTrue())
|
||||||
node, err := f.ClientSet.CoreV1().Nodes().Get(ngNodes[0], metav1.GetOptions{})
|
node, err := f.ClientSet.CoreV1().Nodes().Get(ngNodes[0], metav1.GetOptions{})
|
||||||
By(fmt.Sprintf("Target node for scale-down: %s", node.Name))
|
ginkgo.By(fmt.Sprintf("Target node for scale-down: %s", node.Name))
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
|
|
||||||
// this part is identical
|
// this part is identical
|
||||||
|
@ -861,10 +861,10 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
// non-GKE only
|
// non-GKE only
|
||||||
newSize, err := framework.GroupSize(minMig)
|
newSize, err := framework.GroupSize(minMig)
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
Expect(newSize).Should(Equal(0))
|
gomega.Expect(newSize).Should(gomega.Equal(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
It("Should be able to scale a node group down to 0[Feature:ClusterSizeAutoscalingScaleDown]", func() {
|
ginkgo.It("Should be able to scale a node group down to 0[Feature:ClusterSizeAutoscalingScaleDown]", func() {
|
||||||
if framework.ProviderIs("gke") { // In GKE, we can just add a node pool
|
if framework.ProviderIs("gke") { // In GKE, we can just add a node pool
|
||||||
gkeScaleToZero()
|
gkeScaleToZero()
|
||||||
} else if len(originalSizes) >= 2 {
|
} else if len(originalSizes) >= 2 {
|
||||||
|
@ -874,7 +874,7 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
It("Shouldn't perform scale up operation and should list unhealthy status if most of the cluster is broken[Feature:ClusterSizeAutoscalingScaleUp]", func() {
|
ginkgo.It("Shouldn't perform scale up operation and should list unhealthy status if most of the cluster is broken[Feature:ClusterSizeAutoscalingScaleUp]", func() {
|
||||||
clusterSize := nodeCount
|
clusterSize := nodeCount
|
||||||
for clusterSize < unhealthyClusterThreshold+1 {
|
for clusterSize < unhealthyClusterThreshold+1 {
|
||||||
clusterSize = manuallyIncreaseClusterSize(f, originalSizes)
|
clusterSize = manuallyIncreaseClusterSize(f, originalSizes)
|
||||||
|
@ -893,13 +893,13 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
// making no assumptions about minimal node startup time.
|
// making no assumptions about minimal node startup time.
|
||||||
time.Sleep(2 * time.Minute)
|
time.Sleep(2 * time.Minute)
|
||||||
|
|
||||||
By("Block network connectivity to some nodes to simulate unhealthy cluster")
|
ginkgo.By("Block network connectivity to some nodes to simulate unhealthy cluster")
|
||||||
nodesToBreakCount := int(math.Ceil(math.Max(float64(unhealthyClusterThreshold), 0.5*float64(clusterSize))))
|
nodesToBreakCount := int(math.Ceil(math.Max(float64(unhealthyClusterThreshold), 0.5*float64(clusterSize))))
|
||||||
nodes, err := f.ClientSet.CoreV1().Nodes().List(metav1.ListOptions{FieldSelector: fields.Set{
|
nodes, err := f.ClientSet.CoreV1().Nodes().List(metav1.ListOptions{FieldSelector: fields.Set{
|
||||||
"spec.unschedulable": "false",
|
"spec.unschedulable": "false",
|
||||||
}.AsSelector().String()})
|
}.AsSelector().String()})
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
Expect(nodesToBreakCount <= len(nodes.Items)).To(BeTrue())
|
gomega.Expect(nodesToBreakCount <= len(nodes.Items)).To(gomega.BeTrue())
|
||||||
nodesToBreak := nodes.Items[:nodesToBreakCount]
|
nodesToBreak := nodes.Items[:nodesToBreakCount]
|
||||||
|
|
||||||
// TestUnderTemporaryNetworkFailure only removes connectivity to a single node,
|
// TestUnderTemporaryNetworkFailure only removes connectivity to a single node,
|
||||||
|
@ -917,11 +917,11 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
time.Sleep(scaleUpTimeout)
|
time.Sleep(scaleUpTimeout)
|
||||||
currentNodes := framework.GetReadySchedulableNodesOrDie(f.ClientSet)
|
currentNodes := framework.GetReadySchedulableNodesOrDie(f.ClientSet)
|
||||||
e2elog.Logf("Currently available nodes: %v, nodes available at the start of test: %v, disabled nodes: %v", len(currentNodes.Items), len(nodes.Items), nodesToBreakCount)
|
e2elog.Logf("Currently available nodes: %v, nodes available at the start of test: %v, disabled nodes: %v", len(currentNodes.Items), len(nodes.Items), nodesToBreakCount)
|
||||||
Expect(len(currentNodes.Items)).Should(Equal(len(nodes.Items) - nodesToBreakCount))
|
gomega.Expect(len(currentNodes.Items)).Should(gomega.Equal(len(nodes.Items) - nodesToBreakCount))
|
||||||
status, err := getClusterwideStatus(c)
|
status, err := getClusterwideStatus(c)
|
||||||
e2elog.Logf("Clusterwide status: %v", status)
|
e2elog.Logf("Clusterwide status: %v", status)
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
Expect(status).Should(Equal("Unhealthy"))
|
gomega.Expect(status).Should(gomega.Equal("Unhealthy"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
testFunction()
|
testFunction()
|
||||||
|
@ -929,19 +929,19 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
framework.ExpectNoError(framework.WaitForReadyNodes(c, len(nodes.Items), nodesRecoverTimeout))
|
framework.ExpectNoError(framework.WaitForReadyNodes(c, len(nodes.Items), nodesRecoverTimeout))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("shouldn't scale up when expendable pod is created [Feature:ClusterSizeAutoscalingScaleUp]", func() {
|
ginkgo.It("shouldn't scale up when expendable pod is created [Feature:ClusterSizeAutoscalingScaleUp]", func() {
|
||||||
defer createPriorityClasses(f)()
|
defer createPriorityClasses(f)()
|
||||||
// Create nodesCountAfterResize+1 pods allocating 0.7 allocatable on present nodes. One more node will have to be created.
|
// Create nodesCountAfterResize+1 pods allocating 0.7 allocatable on present nodes. One more node will have to be created.
|
||||||
cleanupFunc := ReserveMemoryWithPriority(f, "memory-reservation", nodeCount+1, int(float64(nodeCount+1)*float64(0.7)*float64(memAllocatableMb)), false, time.Second, expendablePriorityClassName)
|
cleanupFunc := ReserveMemoryWithPriority(f, "memory-reservation", nodeCount+1, int(float64(nodeCount+1)*float64(0.7)*float64(memAllocatableMb)), false, time.Second, expendablePriorityClassName)
|
||||||
defer cleanupFunc()
|
defer cleanupFunc()
|
||||||
By(fmt.Sprintf("Waiting for scale up hoping it won't happen, sleep for %s", scaleUpTimeout.String()))
|
ginkgo.By(fmt.Sprintf("Waiting for scale up hoping it won't happen, sleep for %s", scaleUpTimeout.String()))
|
||||||
time.Sleep(scaleUpTimeout)
|
time.Sleep(scaleUpTimeout)
|
||||||
// Verify that cluster size is not changed
|
// Verify that cluster size is not changed
|
||||||
framework.ExpectNoError(WaitForClusterSizeFunc(f.ClientSet,
|
framework.ExpectNoError(WaitForClusterSizeFunc(f.ClientSet,
|
||||||
func(size int) bool { return size == nodeCount }, time.Second))
|
func(size int) bool { return size == nodeCount }, time.Second))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should scale up when non expendable pod is created [Feature:ClusterSizeAutoscalingScaleUp]", func() {
|
ginkgo.It("should scale up when non expendable pod is created [Feature:ClusterSizeAutoscalingScaleUp]", func() {
|
||||||
defer createPriorityClasses(f)()
|
defer createPriorityClasses(f)()
|
||||||
// Create nodesCountAfterResize+1 pods allocating 0.7 allocatable on present nodes. One more node will have to be created.
|
// Create nodesCountAfterResize+1 pods allocating 0.7 allocatable on present nodes. One more node will have to be created.
|
||||||
cleanupFunc := ReserveMemoryWithPriority(f, "memory-reservation", nodeCount+1, int(float64(nodeCount+1)*float64(0.7)*float64(memAllocatableMb)), true, scaleUpTimeout, highPriorityClassName)
|
cleanupFunc := ReserveMemoryWithPriority(f, "memory-reservation", nodeCount+1, int(float64(nodeCount+1)*float64(0.7)*float64(memAllocatableMb)), true, scaleUpTimeout, highPriorityClassName)
|
||||||
|
@ -951,7 +951,7 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
func(size int) bool { return size > nodeCount }, time.Second))
|
func(size int) bool { return size > nodeCount }, time.Second))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("shouldn't scale up when expendable pod is preempted [Feature:ClusterSizeAutoscalingScaleUp]", func() {
|
ginkgo.It("shouldn't scale up when expendable pod is preempted [Feature:ClusterSizeAutoscalingScaleUp]", func() {
|
||||||
defer createPriorityClasses(f)()
|
defer createPriorityClasses(f)()
|
||||||
// Create nodesCountAfterResize pods allocating 0.7 allocatable on present nodes - one pod per node.
|
// Create nodesCountAfterResize pods allocating 0.7 allocatable on present nodes - one pod per node.
|
||||||
cleanupFunc1 := ReserveMemoryWithPriority(f, "memory-reservation1", nodeCount, int(float64(nodeCount)*float64(0.7)*float64(memAllocatableMb)), true, defaultTimeout, expendablePriorityClassName)
|
cleanupFunc1 := ReserveMemoryWithPriority(f, "memory-reservation1", nodeCount, int(float64(nodeCount)*float64(0.7)*float64(memAllocatableMb)), true, defaultTimeout, expendablePriorityClassName)
|
||||||
|
@ -963,24 +963,24 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
func(size int) bool { return size == nodeCount }, time.Second))
|
func(size int) bool { return size == nodeCount }, time.Second))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should scale down when expendable pod is running [Feature:ClusterSizeAutoscalingScaleDown]", func() {
|
ginkgo.It("should scale down when expendable pod is running [Feature:ClusterSizeAutoscalingScaleDown]", func() {
|
||||||
defer createPriorityClasses(f)()
|
defer createPriorityClasses(f)()
|
||||||
increasedSize := manuallyIncreaseClusterSize(f, originalSizes)
|
increasedSize := manuallyIncreaseClusterSize(f, originalSizes)
|
||||||
// Create increasedSize pods allocating 0.7 allocatable on present nodes - one pod per node.
|
// Create increasedSize pods allocating 0.7 allocatable on present nodes - one pod per node.
|
||||||
cleanupFunc := ReserveMemoryWithPriority(f, "memory-reservation", increasedSize, int(float64(increasedSize)*float64(0.7)*float64(memAllocatableMb)), true, scaleUpTimeout, expendablePriorityClassName)
|
cleanupFunc := ReserveMemoryWithPriority(f, "memory-reservation", increasedSize, int(float64(increasedSize)*float64(0.7)*float64(memAllocatableMb)), true, scaleUpTimeout, expendablePriorityClassName)
|
||||||
defer cleanupFunc()
|
defer cleanupFunc()
|
||||||
By("Waiting for scale down")
|
ginkgo.By("Waiting for scale down")
|
||||||
framework.ExpectNoError(WaitForClusterSizeFunc(f.ClientSet,
|
framework.ExpectNoError(WaitForClusterSizeFunc(f.ClientSet,
|
||||||
func(size int) bool { return size == nodeCount }, scaleDownTimeout))
|
func(size int) bool { return size == nodeCount }, scaleDownTimeout))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("shouldn't scale down when non expendable pod is running [Feature:ClusterSizeAutoscalingScaleDown]", func() {
|
ginkgo.It("shouldn't scale down when non expendable pod is running [Feature:ClusterSizeAutoscalingScaleDown]", func() {
|
||||||
defer createPriorityClasses(f)()
|
defer createPriorityClasses(f)()
|
||||||
increasedSize := manuallyIncreaseClusterSize(f, originalSizes)
|
increasedSize := manuallyIncreaseClusterSize(f, originalSizes)
|
||||||
// Create increasedSize pods allocating 0.7 allocatable on present nodes - one pod per node.
|
// Create increasedSize pods allocating 0.7 allocatable on present nodes - one pod per node.
|
||||||
cleanupFunc := ReserveMemoryWithPriority(f, "memory-reservation", increasedSize, int(float64(increasedSize)*float64(0.7)*float64(memAllocatableMb)), true, scaleUpTimeout, highPriorityClassName)
|
cleanupFunc := ReserveMemoryWithPriority(f, "memory-reservation", increasedSize, int(float64(increasedSize)*float64(0.7)*float64(memAllocatableMb)), true, scaleUpTimeout, highPriorityClassName)
|
||||||
defer cleanupFunc()
|
defer cleanupFunc()
|
||||||
By(fmt.Sprintf("Waiting for scale down hoping it won't happen, sleep for %s", scaleDownTimeout.String()))
|
ginkgo.By(fmt.Sprintf("Waiting for scale down hoping it won't happen, sleep for %s", scaleDownTimeout.String()))
|
||||||
time.Sleep(scaleDownTimeout)
|
time.Sleep(scaleDownTimeout)
|
||||||
framework.ExpectNoError(WaitForClusterSizeFunc(f.ClientSet,
|
framework.ExpectNoError(WaitForClusterSizeFunc(f.ClientSet,
|
||||||
func(size int) bool { return size == increasedSize }, time.Second))
|
func(size int) bool { return size == increasedSize }, time.Second))
|
||||||
|
@ -988,7 +988,7 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
func installNvidiaDriversDaemonSet() {
|
func installNvidiaDriversDaemonSet() {
|
||||||
By("Add daemonset which installs nvidia drivers")
|
ginkgo.By("Add daemonset which installs nvidia drivers")
|
||||||
// the link differs from one in GKE documentation; discussed with @mindprince this one should be used
|
// the link differs from one in GKE documentation; discussed with @mindprince this one should be used
|
||||||
framework.RunKubectlOrDie("apply", "-f", "https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/daemonset.yaml")
|
framework.RunKubectlOrDie("apply", "-f", "https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/daemonset.yaml")
|
||||||
}
|
}
|
||||||
|
@ -1012,7 +1012,7 @@ func runDrainTest(f *framework.Framework, migSizes map[string]int, namespace str
|
||||||
|
|
||||||
defer framework.DeleteRCAndWaitForGC(f.ClientSet, namespace, "reschedulable-pods")
|
defer framework.DeleteRCAndWaitForGC(f.ClientSet, namespace, "reschedulable-pods")
|
||||||
|
|
||||||
By("Create a PodDisruptionBudget")
|
ginkgo.By("Create a PodDisruptionBudget")
|
||||||
minAvailable := intstr.FromInt(numPods - pdbSize)
|
minAvailable := intstr.FromInt(numPods - pdbSize)
|
||||||
pdb := &policy.PodDisruptionBudget{
|
pdb := &policy.PodDisruptionBudget{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
@ -1034,15 +1034,15 @@ func runDrainTest(f *framework.Framework, migSizes map[string]int, namespace str
|
||||||
verifyFunction(increasedSize)
|
verifyFunction(increasedSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getGkeApiEndpoint() string {
|
func getGkeAPIEndpoint() string {
|
||||||
gkeApiEndpoint := os.Getenv("CLOUDSDK_API_ENDPOINT_OVERRIDES_CONTAINER")
|
gkeAPIEndpoint := os.Getenv("CLOUDSDK_API_ENDPOINT_OVERRIDES_CONTAINER")
|
||||||
if gkeApiEndpoint == "" {
|
if gkeAPIEndpoint == "" {
|
||||||
gkeApiEndpoint = "https://test-container.sandbox.googleapis.com"
|
gkeAPIEndpoint = "https://test-container.sandbox.googleapis.com"
|
||||||
}
|
}
|
||||||
if strings.HasSuffix(gkeApiEndpoint, "/") {
|
if strings.HasSuffix(gkeAPIEndpoint, "/") {
|
||||||
gkeApiEndpoint = gkeApiEndpoint[:len(gkeApiEndpoint)-1]
|
gkeAPIEndpoint = gkeAPIEndpoint[:len(gkeAPIEndpoint)-1]
|
||||||
}
|
}
|
||||||
return gkeApiEndpoint
|
return gkeAPIEndpoint
|
||||||
}
|
}
|
||||||
|
|
||||||
func getGKEURL(apiVersion string, suffix string) string {
|
func getGKEURL(apiVersion string, suffix string) string {
|
||||||
|
@ -1051,7 +1051,7 @@ func getGKEURL(apiVersion string, suffix string) string {
|
||||||
token := strings.Replace(string(out), "\n", "", -1)
|
token := strings.Replace(string(out), "\n", "", -1)
|
||||||
|
|
||||||
return fmt.Sprintf("%s/%s/%s?access_token=%s",
|
return fmt.Sprintf("%s/%s/%s?access_token=%s",
|
||||||
getGkeApiEndpoint(),
|
getGkeAPIEndpoint(),
|
||||||
apiVersion,
|
apiVersion,
|
||||||
suffix,
|
suffix,
|
||||||
token)
|
token)
|
||||||
|
@ -1064,12 +1064,11 @@ func getGKEClusterURL(apiVersion string) string {
|
||||||
framework.TestContext.CloudConfig.ProjectID,
|
framework.TestContext.CloudConfig.ProjectID,
|
||||||
framework.TestContext.CloudConfig.Region,
|
framework.TestContext.CloudConfig.Region,
|
||||||
framework.TestContext.CloudConfig.Cluster))
|
framework.TestContext.CloudConfig.Cluster))
|
||||||
} else {
|
|
||||||
return getGKEURL(apiVersion, fmt.Sprintf("projects/%s/zones/%s/clusters/%s",
|
|
||||||
framework.TestContext.CloudConfig.ProjectID,
|
|
||||||
framework.TestContext.CloudConfig.Zone,
|
|
||||||
framework.TestContext.CloudConfig.Cluster))
|
|
||||||
}
|
}
|
||||||
|
return getGKEURL(apiVersion, fmt.Sprintf("projects/%s/zones/%s/clusters/%s",
|
||||||
|
framework.TestContext.CloudConfig.ProjectID,
|
||||||
|
framework.TestContext.CloudConfig.Zone,
|
||||||
|
framework.TestContext.CloudConfig.Cluster))
|
||||||
}
|
}
|
||||||
|
|
||||||
func getCluster(apiVersion string) (string, error) {
|
func getCluster(apiVersion string) (string, error) {
|
||||||
|
@ -1107,9 +1106,8 @@ func isAutoscalerEnabled(expectedMaxNodeCountInTargetPool int) (bool, error) {
|
||||||
func getClusterLocation() string {
|
func getClusterLocation() string {
|
||||||
if isRegionalCluster() {
|
if isRegionalCluster() {
|
||||||
return "--region=" + framework.TestContext.CloudConfig.Region
|
return "--region=" + framework.TestContext.CloudConfig.Region
|
||||||
} else {
|
|
||||||
return "--zone=" + framework.TestContext.CloudConfig.Zone
|
|
||||||
}
|
}
|
||||||
|
return "--zone=" + framework.TestContext.CloudConfig.Zone
|
||||||
}
|
}
|
||||||
|
|
||||||
func getGcloudCommandFromTrack(commandTrack string, args []string) []string {
|
func getGcloudCommandFromTrack(commandTrack string, args []string) []string {
|
||||||
|
@ -1248,7 +1246,7 @@ func getPoolInitialSize(poolName string) int {
|
||||||
klog.Infof("Node-pool initial size: %s", output)
|
klog.Infof("Node-pool initial size: %s", output)
|
||||||
framework.ExpectNoError(err, string(output))
|
framework.ExpectNoError(err, string(output))
|
||||||
fields := strings.Fields(string(output))
|
fields := strings.Fields(string(output))
|
||||||
Expect(len(fields)).Should(Equal(1))
|
gomega.Expect(len(fields)).Should(gomega.Equal(1))
|
||||||
size, err := strconv.ParseInt(fields[0], 10, 64)
|
size, err := strconv.ParseInt(fields[0], 10, 64)
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
|
|
||||||
|
@ -1274,7 +1272,7 @@ func getPoolSize(f *framework.Framework, poolName string) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
func reserveMemory(f *framework.Framework, id string, replicas, megabytes int, expectRunning bool, timeout time.Duration, selector map[string]string, tolerations []v1.Toleration, priorityClassName string) func() error {
|
func reserveMemory(f *framework.Framework, id string, replicas, megabytes int, expectRunning bool, timeout time.Duration, selector map[string]string, tolerations []v1.Toleration, priorityClassName string) func() error {
|
||||||
By(fmt.Sprintf("Running RC which reserves %v MB of memory", megabytes))
|
ginkgo.By(fmt.Sprintf("Running RC which reserves %v MB of memory", megabytes))
|
||||||
request := int64(1024 * 1024 * megabytes / replicas)
|
request := int64(1024 * 1024 * megabytes / replicas)
|
||||||
config := &testutils.RCConfig{
|
config := &testutils.RCConfig{
|
||||||
Client: f.ClientSet,
|
Client: f.ClientSet,
|
||||||
|
@ -1311,7 +1309,7 @@ func ReserveMemoryWithPriority(f *framework.Framework, id string, replicas, mega
|
||||||
return reserveMemory(f, id, replicas, megabytes, expectRunning, timeout, nil, nil, priorityClassName)
|
return reserveMemory(f, id, replicas, megabytes, expectRunning, timeout, nil, nil, priorityClassName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReserveMemoryWithSelector creates a replication controller with pods with node selector that, in summation,
|
// ReserveMemoryWithSelectorAndTolerations creates a replication controller with pods with node selector that, in summation,
|
||||||
// request the specified amount of memory.
|
// request the specified amount of memory.
|
||||||
func ReserveMemoryWithSelectorAndTolerations(f *framework.Framework, id string, replicas, megabytes int, expectRunning bool, timeout time.Duration, selector map[string]string, tolerations []v1.Toleration) func() error {
|
func ReserveMemoryWithSelectorAndTolerations(f *framework.Framework, id string, replicas, megabytes int, expectRunning bool, timeout time.Duration, selector map[string]string, tolerations []v1.Toleration) func() error {
|
||||||
return reserveMemory(f, id, replicas, megabytes, expectRunning, timeout, selector, tolerations, "")
|
return reserveMemory(f, id, replicas, megabytes, expectRunning, timeout, selector, tolerations, "")
|
||||||
|
@ -1418,7 +1416,7 @@ func setMigSizes(sizes map[string]int) bool {
|
||||||
currentSize, err := framework.GroupSize(mig)
|
currentSize, err := framework.GroupSize(mig)
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
if desiredSize != currentSize {
|
if desiredSize != currentSize {
|
||||||
By(fmt.Sprintf("Setting size of %s to %d", mig, desiredSize))
|
ginkgo.By(fmt.Sprintf("Setting size of %s to %d", mig, desiredSize))
|
||||||
err = framework.ResizeGroup(mig, int32(desiredSize))
|
err = framework.ResizeGroup(mig, int32(desiredSize))
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
madeChanges = true
|
madeChanges = true
|
||||||
|
@ -1428,10 +1426,10 @@ func setMigSizes(sizes map[string]int) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func drainNode(f *framework.Framework, node *v1.Node) {
|
func drainNode(f *framework.Framework, node *v1.Node) {
|
||||||
By("Make the single node unschedulable")
|
ginkgo.By("Make the single node unschedulable")
|
||||||
makeNodeUnschedulable(f.ClientSet, node)
|
makeNodeUnschedulable(f.ClientSet, node)
|
||||||
|
|
||||||
By("Manually drain the single node")
|
ginkgo.By("Manually drain the single node")
|
||||||
podOpts := metav1.ListOptions{FieldSelector: fields.OneTermEqualSelector(api.PodHostField, node.Name).String()}
|
podOpts := metav1.ListOptions{FieldSelector: fields.OneTermEqualSelector(api.PodHostField, node.Name).String()}
|
||||||
pods, err := f.ClientSet.CoreV1().Pods(metav1.NamespaceAll).List(podOpts)
|
pods, err := f.ClientSet.CoreV1().Pods(metav1.NamespaceAll).List(podOpts)
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
|
@ -1442,7 +1440,7 @@ func drainNode(f *framework.Framework, node *v1.Node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeNodeUnschedulable(c clientset.Interface, node *v1.Node) error {
|
func makeNodeUnschedulable(c clientset.Interface, node *v1.Node) error {
|
||||||
By(fmt.Sprintf("Taint node %s", node.Name))
|
ginkgo.By(fmt.Sprintf("Taint node %s", node.Name))
|
||||||
for j := 0; j < 3; j++ {
|
for j := 0; j < 3; j++ {
|
||||||
freshNode, err := c.CoreV1().Nodes().Get(node.Name, metav1.GetOptions{})
|
freshNode, err := c.CoreV1().Nodes().Get(node.Name, metav1.GetOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1479,7 +1477,7 @@ func (CriticalAddonsOnlyError) Error() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeNodeSchedulable(c clientset.Interface, node *v1.Node, failOnCriticalAddonsOnly bool) error {
|
func makeNodeSchedulable(c clientset.Interface, node *v1.Node, failOnCriticalAddonsOnly bool) error {
|
||||||
By(fmt.Sprintf("Remove taint from node %s", node.Name))
|
ginkgo.By(fmt.Sprintf("Remove taint from node %s", node.Name))
|
||||||
for j := 0; j < 3; j++ {
|
for j := 0; j < 3; j++ {
|
||||||
freshNode, err := c.CoreV1().Nodes().Get(node.Name, metav1.GetOptions{})
|
freshNode, err := c.CoreV1().Nodes().Get(node.Name, metav1.GetOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1634,7 +1632,7 @@ func buildAntiAffinity(labels map[string]string) *v1.Affinity {
|
||||||
// 3a. enable scheduling on that node
|
// 3a. enable scheduling on that node
|
||||||
// 3b. increase number of replicas in RC by podsPerNode
|
// 3b. increase number of replicas in RC by podsPerNode
|
||||||
func runReplicatedPodOnEachNode(f *framework.Framework, nodes []v1.Node, namespace string, podsPerNode int, id string, labels map[string]string, memRequest int64) error {
|
func runReplicatedPodOnEachNode(f *framework.Framework, nodes []v1.Node, namespace string, podsPerNode int, id string, labels map[string]string, memRequest int64) error {
|
||||||
By("Run a pod on each node")
|
ginkgo.By("Run a pod on each node")
|
||||||
for _, node := range nodes {
|
for _, node := range nodes {
|
||||||
err := makeNodeUnschedulable(f.ClientSet, &node)
|
err := makeNodeUnschedulable(f.ClientSet, &node)
|
||||||
|
|
||||||
|
@ -1709,7 +1707,7 @@ func runReplicatedPodOnEachNode(f *framework.Framework, nodes []v1.Node, namespa
|
||||||
// Increase cluster size by newNodesForScaledownTests to create some unused nodes
|
// Increase cluster size by newNodesForScaledownTests to create some unused nodes
|
||||||
// that can be later removed by cluster autoscaler.
|
// that can be later removed by cluster autoscaler.
|
||||||
func manuallyIncreaseClusterSize(f *framework.Framework, originalSizes map[string]int) int {
|
func manuallyIncreaseClusterSize(f *framework.Framework, originalSizes map[string]int) int {
|
||||||
By("Manually increase cluster size")
|
ginkgo.By("Manually increase cluster size")
|
||||||
increasedSize := 0
|
increasedSize := 0
|
||||||
newSizes := make(map[string]int)
|
newSizes := make(map[string]int)
|
||||||
for key, val := range originalSizes {
|
for key, val := range originalSizes {
|
||||||
|
@ -1857,13 +1855,13 @@ func waitForScaleUpStatus(c clientset.Interface, cond func(s *scaleUpStatus) boo
|
||||||
// This is a temporary fix to allow CA to migrate some kube-system pods
|
// This is a temporary fix to allow CA to migrate some kube-system pods
|
||||||
// TODO: Remove this when the PDB is added for some of those components
|
// TODO: Remove this when the PDB is added for some of those components
|
||||||
func addKubeSystemPdbs(f *framework.Framework) (func(), error) {
|
func addKubeSystemPdbs(f *framework.Framework) (func(), error) {
|
||||||
By("Create PodDisruptionBudgets for kube-system components, so they can be migrated if required")
|
ginkgo.By("Create PodDisruptionBudgets for kube-system components, so they can be migrated if required")
|
||||||
|
|
||||||
var newPdbs []string
|
var newPdbs []string
|
||||||
cleanup := func() {
|
cleanup := func() {
|
||||||
var finalErr error
|
var finalErr error
|
||||||
for _, newPdbName := range newPdbs {
|
for _, newPdbName := range newPdbs {
|
||||||
By(fmt.Sprintf("Delete PodDisruptionBudget %v", newPdbName))
|
ginkgo.By(fmt.Sprintf("Delete PodDisruptionBudget %v", newPdbName))
|
||||||
err := f.ClientSet.PolicyV1beta1().PodDisruptionBudgets("kube-system").Delete(newPdbName, &metav1.DeleteOptions{})
|
err := f.ClientSet.PolicyV1beta1().PodDisruptionBudgets("kube-system").Delete(newPdbName, &metav1.DeleteOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// log error, but attempt to remove other pdbs
|
// log error, but attempt to remove other pdbs
|
||||||
|
@ -1888,7 +1886,7 @@ func addKubeSystemPdbs(f *framework.Framework) (func(), error) {
|
||||||
{label: "glbc", minAvailable: 0},
|
{label: "glbc", minAvailable: 0},
|
||||||
}
|
}
|
||||||
for _, pdbData := range pdbsToAdd {
|
for _, pdbData := range pdbsToAdd {
|
||||||
By(fmt.Sprintf("Create PodDisruptionBudget for %v", pdbData.label))
|
ginkgo.By(fmt.Sprintf("Create PodDisruptionBudget for %v", pdbData.label))
|
||||||
labelMap := map[string]string{"k8s-app": pdbData.label}
|
labelMap := map[string]string{"k8s-app": pdbData.label}
|
||||||
pdbName := fmt.Sprintf("test-pdb-for-%v", pdbData.label)
|
pdbName := fmt.Sprintf("test-pdb-for-%v", pdbData.label)
|
||||||
minAvailable := intstr.FromInt(pdbData.minAvailable)
|
minAvailable := intstr.FromInt(pdbData.minAvailable)
|
||||||
|
@ -1922,7 +1920,7 @@ func createPriorityClasses(f *framework.Framework) func() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
klog.Errorf("Error creating priority class: %v", err)
|
klog.Errorf("Error creating priority class: %v", err)
|
||||||
}
|
}
|
||||||
Expect(err == nil || errors.IsAlreadyExists(err)).To(Equal(true))
|
gomega.Expect(err == nil || errors.IsAlreadyExists(err)).To(gomega.Equal(true))
|
||||||
}
|
}
|
||||||
|
|
||||||
return func() {
|
return func() {
|
||||||
|
|
|
@ -33,7 +33,7 @@ import (
|
||||||
e2elog "k8s.io/kubernetes/test/e2e/framework/log"
|
e2elog "k8s.io/kubernetes/test/e2e/framework/log"
|
||||||
"k8s.io/kubernetes/test/e2e/instrumentation/monitoring"
|
"k8s.io/kubernetes/test/e2e/instrumentation/monitoring"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
"github.com/onsi/ginkgo"
|
||||||
"golang.org/x/oauth2/google"
|
"golang.org/x/oauth2/google"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -45,13 +45,13 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = SIGDescribe("[HPA] Horizontal pod autoscaling (scale resource: Custom Metrics from Stackdriver)", func() {
|
var _ = SIGDescribe("[HPA] Horizontal pod autoscaling (scale resource: Custom Metrics from Stackdriver)", func() {
|
||||||
BeforeEach(func() {
|
ginkgo.BeforeEach(func() {
|
||||||
framework.SkipUnlessProviderIs("gce", "gke")
|
framework.SkipUnlessProviderIs("gce", "gke")
|
||||||
})
|
})
|
||||||
|
|
||||||
f := framework.NewDefaultFramework("horizontal-pod-autoscaling")
|
f := framework.NewDefaultFramework("horizontal-pod-autoscaling")
|
||||||
|
|
||||||
It("should scale down with Custom Metric of type Pod from Stackdriver [Feature:CustomMetricsAutoscaling]", func() {
|
ginkgo.It("should scale down with Custom Metric of type Pod from Stackdriver [Feature:CustomMetricsAutoscaling]", func() {
|
||||||
initialReplicas := 2
|
initialReplicas := 2
|
||||||
// metric should cause scale down
|
// metric should cause scale down
|
||||||
metricValue := int64(100)
|
metricValue := int64(100)
|
||||||
|
@ -66,7 +66,7 @@ var _ = SIGDescribe("[HPA] Horizontal pod autoscaling (scale resource: Custom Me
|
||||||
tc.Run()
|
tc.Run()
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should scale down with Custom Metric of type Object from Stackdriver [Feature:CustomMetricsAutoscaling]", func() {
|
ginkgo.It("should scale down with Custom Metric of type Object from Stackdriver [Feature:CustomMetricsAutoscaling]", func() {
|
||||||
initialReplicas := 2
|
initialReplicas := 2
|
||||||
// metric should cause scale down
|
// metric should cause scale down
|
||||||
metricValue := int64(100)
|
metricValue := int64(100)
|
||||||
|
@ -83,7 +83,7 @@ var _ = SIGDescribe("[HPA] Horizontal pod autoscaling (scale resource: Custom Me
|
||||||
tc.Run()
|
tc.Run()
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should scale down with External Metric with target value from Stackdriver [Feature:CustomMetricsAutoscaling]", func() {
|
ginkgo.It("should scale down with External Metric with target value from Stackdriver [Feature:CustomMetricsAutoscaling]", func() {
|
||||||
initialReplicas := 2
|
initialReplicas := 2
|
||||||
// metric should cause scale down
|
// metric should cause scale down
|
||||||
metricValue := externalMetricValue
|
metricValue := externalMetricValue
|
||||||
|
@ -106,7 +106,7 @@ var _ = SIGDescribe("[HPA] Horizontal pod autoscaling (scale resource: Custom Me
|
||||||
tc.Run()
|
tc.Run()
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should scale down with External Metric with target average value from Stackdriver [Feature:CustomMetricsAutoscaling]", func() {
|
ginkgo.It("should scale down with External Metric with target average value from Stackdriver [Feature:CustomMetricsAutoscaling]", func() {
|
||||||
initialReplicas := 2
|
initialReplicas := 2
|
||||||
// metric should cause scale down
|
// metric should cause scale down
|
||||||
metricValue := externalMetricValue
|
metricValue := externalMetricValue
|
||||||
|
@ -129,7 +129,7 @@ var _ = SIGDescribe("[HPA] Horizontal pod autoscaling (scale resource: Custom Me
|
||||||
tc.Run()
|
tc.Run()
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should scale down with Custom Metric of type Pod from Stackdriver with Prometheus [Feature:CustomMetricsAutoscaling]", func() {
|
ginkgo.It("should scale down with Custom Metric of type Pod from Stackdriver with Prometheus [Feature:CustomMetricsAutoscaling]", func() {
|
||||||
initialReplicas := 2
|
initialReplicas := 2
|
||||||
// metric should cause scale down
|
// metric should cause scale down
|
||||||
metricValue := int64(100)
|
metricValue := int64(100)
|
||||||
|
@ -144,7 +144,7 @@ var _ = SIGDescribe("[HPA] Horizontal pod autoscaling (scale resource: Custom Me
|
||||||
tc.Run()
|
tc.Run()
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should scale up with two metrics of type Pod from Stackdriver [Feature:CustomMetricsAutoscaling]", func() {
|
ginkgo.It("should scale up with two metrics of type Pod from Stackdriver [Feature:CustomMetricsAutoscaling]", func() {
|
||||||
initialReplicas := 1
|
initialReplicas := 1
|
||||||
// metric 1 would cause a scale down, if not for metric 2
|
// metric 1 would cause a scale down, if not for metric 2
|
||||||
metric1Value := int64(100)
|
metric1Value := int64(100)
|
||||||
|
@ -175,7 +175,7 @@ var _ = SIGDescribe("[HPA] Horizontal pod autoscaling (scale resource: Custom Me
|
||||||
tc.Run()
|
tc.Run()
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should scale up with two External metrics from Stackdriver [Feature:CustomMetricsAutoscaling]", func() {
|
ginkgo.It("should scale up with two External metrics from Stackdriver [Feature:CustomMetricsAutoscaling]", func() {
|
||||||
initialReplicas := 1
|
initialReplicas := 1
|
||||||
// metric 1 would cause a scale down, if not for metric 2
|
// metric 1 would cause a scale down, if not for metric 2
|
||||||
metric1Value := externalMetricValue
|
metric1Value := externalMetricValue
|
||||||
|
@ -216,6 +216,7 @@ var _ = SIGDescribe("[HPA] Horizontal pod autoscaling (scale resource: Custom Me
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// CustomMetricTestCase is a struct for test cases.
|
||||||
type CustomMetricTestCase struct {
|
type CustomMetricTestCase struct {
|
||||||
framework *framework.Framework
|
framework *framework.Framework
|
||||||
hpa *as.HorizontalPodAutoscaler
|
hpa *as.HorizontalPodAutoscaler
|
||||||
|
@ -226,8 +227,9 @@ type CustomMetricTestCase struct {
|
||||||
scaledReplicas int
|
scaledReplicas int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Run starts test case.
|
||||||
func (tc *CustomMetricTestCase) Run() {
|
func (tc *CustomMetricTestCase) Run() {
|
||||||
projectId := framework.TestContext.CloudConfig.ProjectID
|
projectID := framework.TestContext.CloudConfig.ProjectID
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
client, err := google.DefaultClient(ctx, gcm.CloudPlatformScope)
|
client, err := google.DefaultClient(ctx, gcm.CloudPlatformScope)
|
||||||
|
@ -251,11 +253,11 @@ func (tc *CustomMetricTestCase) Run() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up a cluster: create a custom metric and set up k8s-sd adapter
|
// Set up a cluster: create a custom metric and set up k8s-sd adapter
|
||||||
err = monitoring.CreateDescriptors(gcmService, projectId)
|
err = monitoring.CreateDescriptors(gcmService, projectID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
framework.Failf("Failed to create metric descriptor: %v", err)
|
framework.Failf("Failed to create metric descriptor: %v", err)
|
||||||
}
|
}
|
||||||
defer monitoring.CleanupDescriptors(gcmService, projectId)
|
defer monitoring.CleanupDescriptors(gcmService, projectID)
|
||||||
|
|
||||||
err = monitoring.CreateAdapter(monitoring.AdapterDefault)
|
err = monitoring.CreateAdapter(monitoring.AdapterDefault)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -31,10 +31,11 @@ import (
|
||||||
"k8s.io/kubernetes/test/e2e/framework"
|
"k8s.io/kubernetes/test/e2e/framework"
|
||||||
e2elog "k8s.io/kubernetes/test/e2e/framework/log"
|
e2elog "k8s.io/kubernetes/test/e2e/framework/log"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
"github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
"github.com/onsi/gomega"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Constants used in dns-autoscaling test.
|
||||||
const (
|
const (
|
||||||
DNSdefaultTimeout = 5 * time.Minute
|
DNSdefaultTimeout = 5 * time.Minute
|
||||||
ClusterAddonLabelKey = "k8s-app"
|
ClusterAddonLabelKey = "k8s-app"
|
||||||
|
@ -47,18 +48,18 @@ var _ = SIGDescribe("DNS horizontal autoscaling", func() {
|
||||||
var c clientset.Interface
|
var c clientset.Interface
|
||||||
var previousParams map[string]string
|
var previousParams map[string]string
|
||||||
var originDNSReplicasCount int
|
var originDNSReplicasCount int
|
||||||
var DNSParams_1 DNSParamsLinear
|
var DNSParams1 DNSParamsLinear
|
||||||
var DNSParams_2 DNSParamsLinear
|
var DNSParams2 DNSParamsLinear
|
||||||
var DNSParams_3 DNSParamsLinear
|
var DNSParams3 DNSParamsLinear
|
||||||
|
|
||||||
BeforeEach(func() {
|
ginkgo.BeforeEach(func() {
|
||||||
framework.SkipUnlessProviderIs("gce", "gke")
|
framework.SkipUnlessProviderIs("gce", "gke")
|
||||||
c = f.ClientSet
|
c = f.ClientSet
|
||||||
|
|
||||||
nodeCount := len(framework.GetReadySchedulableNodesOrDie(c).Items)
|
nodeCount := len(framework.GetReadySchedulableNodesOrDie(c).Items)
|
||||||
Expect(nodeCount).NotTo(BeZero())
|
gomega.Expect(nodeCount).NotTo(gomega.BeZero())
|
||||||
|
|
||||||
By("Collecting original replicas count and DNS scaling params")
|
ginkgo.By("Collecting original replicas count and DNS scaling params")
|
||||||
var err error
|
var err error
|
||||||
originDNSReplicasCount, err = getDNSReplicas(c)
|
originDNSReplicasCount, err = getDNSReplicas(c)
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
|
@ -68,13 +69,13 @@ var _ = SIGDescribe("DNS horizontal autoscaling", func() {
|
||||||
previousParams = pcm.Data
|
previousParams = pcm.Data
|
||||||
|
|
||||||
if nodeCount <= 500 {
|
if nodeCount <= 500 {
|
||||||
DNSParams_1 = DNSParamsLinear{
|
DNSParams1 = DNSParamsLinear{
|
||||||
nodesPerReplica: 1,
|
nodesPerReplica: 1,
|
||||||
}
|
}
|
||||||
DNSParams_2 = DNSParamsLinear{
|
DNSParams2 = DNSParamsLinear{
|
||||||
nodesPerReplica: 2,
|
nodesPerReplica: 2,
|
||||||
}
|
}
|
||||||
DNSParams_3 = DNSParamsLinear{
|
DNSParams3 = DNSParamsLinear{
|
||||||
nodesPerReplica: 3,
|
nodesPerReplica: 3,
|
||||||
coresPerReplica: 3,
|
coresPerReplica: 3,
|
||||||
}
|
}
|
||||||
|
@ -84,13 +85,13 @@ var _ = SIGDescribe("DNS horizontal autoscaling", func() {
|
||||||
// The default setup is: 256 cores/replica, 16 nodes/replica.
|
// The default setup is: 256 cores/replica, 16 nodes/replica.
|
||||||
// With nodeCount > 500, nodes/13, nodes/14, nodes/15 and nodes/16
|
// With nodeCount > 500, nodes/13, nodes/14, nodes/15 and nodes/16
|
||||||
// are different numbers.
|
// are different numbers.
|
||||||
DNSParams_1 = DNSParamsLinear{
|
DNSParams1 = DNSParamsLinear{
|
||||||
nodesPerReplica: 13,
|
nodesPerReplica: 13,
|
||||||
}
|
}
|
||||||
DNSParams_2 = DNSParamsLinear{
|
DNSParams2 = DNSParamsLinear{
|
||||||
nodesPerReplica: 14,
|
nodesPerReplica: 14,
|
||||||
}
|
}
|
||||||
DNSParams_3 = DNSParamsLinear{
|
DNSParams3 = DNSParamsLinear{
|
||||||
nodesPerReplica: 15,
|
nodesPerReplica: 15,
|
||||||
coresPerReplica: 15,
|
coresPerReplica: 15,
|
||||||
}
|
}
|
||||||
|
@ -99,25 +100,25 @@ var _ = SIGDescribe("DNS horizontal autoscaling", func() {
|
||||||
|
|
||||||
// This test is separated because it is slow and need to run serially.
|
// This test is separated because it is slow and need to run serially.
|
||||||
// Will take around 5 minutes to run on a 4 nodes cluster.
|
// Will take around 5 minutes to run on a 4 nodes cluster.
|
||||||
It("[Serial] [Slow] kube-dns-autoscaler should scale kube-dns pods when cluster size changed", func() {
|
ginkgo.It("[Serial] [Slow] kube-dns-autoscaler should scale kube-dns pods when cluster size changed", func() {
|
||||||
numNodes, err := framework.NumberOfRegisteredNodes(c)
|
numNodes, err := framework.NumberOfRegisteredNodes(c)
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
|
|
||||||
By("Replace the dns autoscaling parameters with testing parameters")
|
ginkgo.By("Replace the dns autoscaling parameters with testing parameters")
|
||||||
err = updateDNSScalingConfigMap(c, packDNSScalingConfigMap(packLinearParams(&DNSParams_1)))
|
err = updateDNSScalingConfigMap(c, packDNSScalingConfigMap(packLinearParams(&DNSParams1)))
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
defer func() {
|
defer func() {
|
||||||
By("Restoring initial dns autoscaling parameters")
|
ginkgo.By("Restoring initial dns autoscaling parameters")
|
||||||
err = updateDNSScalingConfigMap(c, packDNSScalingConfigMap(previousParams))
|
err = updateDNSScalingConfigMap(c, packDNSScalingConfigMap(previousParams))
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
|
|
||||||
By("Wait for number of running and ready kube-dns pods recover")
|
ginkgo.By("Wait for number of running and ready kube-dns pods recover")
|
||||||
label := labels.SelectorFromSet(labels.Set(map[string]string{ClusterAddonLabelKey: DNSLabelName}))
|
label := labels.SelectorFromSet(labels.Set(map[string]string{ClusterAddonLabelKey: DNSLabelName}))
|
||||||
_, err := framework.WaitForPodsWithLabelRunningReady(c, metav1.NamespaceSystem, label, originDNSReplicasCount, DNSdefaultTimeout)
|
_, err := framework.WaitForPodsWithLabelRunningReady(c, metav1.NamespaceSystem, label, originDNSReplicasCount, DNSdefaultTimeout)
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
}()
|
}()
|
||||||
By("Wait for kube-dns scaled to expected number")
|
ginkgo.By("Wait for kube-dns scaled to expected number")
|
||||||
getExpectReplicasLinear := getExpectReplicasFuncLinear(c, &DNSParams_1)
|
getExpectReplicasLinear := getExpectReplicasFuncLinear(c, &DNSParams1)
|
||||||
err = waitForDNSReplicasSatisfied(c, getExpectReplicasLinear, DNSdefaultTimeout)
|
err = waitForDNSReplicasSatisfied(c, getExpectReplicasLinear, DNSdefaultTimeout)
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
|
|
||||||
|
@ -125,11 +126,11 @@ var _ = SIGDescribe("DNS horizontal autoscaling", func() {
|
||||||
for _, mig := range strings.Split(framework.TestContext.CloudConfig.NodeInstanceGroup, ",") {
|
for _, mig := range strings.Split(framework.TestContext.CloudConfig.NodeInstanceGroup, ",") {
|
||||||
size, err := framework.GroupSize(mig)
|
size, err := framework.GroupSize(mig)
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
By(fmt.Sprintf("Initial size of %s: %d", mig, size))
|
ginkgo.By(fmt.Sprintf("Initial size of %s: %d", mig, size))
|
||||||
originalSizes[mig] = size
|
originalSizes[mig] = size
|
||||||
}
|
}
|
||||||
|
|
||||||
By("Manually increase cluster size")
|
ginkgo.By("Manually increase cluster size")
|
||||||
increasedSizes := make(map[string]int)
|
increasedSizes := make(map[string]int)
|
||||||
for key, val := range originalSizes {
|
for key, val := range originalSizes {
|
||||||
increasedSizes[key] = val + 1
|
increasedSizes[key] = val + 1
|
||||||
|
@ -139,87 +140,88 @@ var _ = SIGDescribe("DNS horizontal autoscaling", func() {
|
||||||
func(size int) bool { return size == numNodes+len(originalSizes) }, scaleUpTimeout)
|
func(size int) bool { return size == numNodes+len(originalSizes) }, scaleUpTimeout)
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
|
|
||||||
By("Wait for kube-dns scaled to expected number")
|
ginkgo.By("Wait for kube-dns scaled to expected number")
|
||||||
getExpectReplicasLinear = getExpectReplicasFuncLinear(c, &DNSParams_1)
|
getExpectReplicasLinear = getExpectReplicasFuncLinear(c, &DNSParams1)
|
||||||
err = waitForDNSReplicasSatisfied(c, getExpectReplicasLinear, DNSdefaultTimeout)
|
err = waitForDNSReplicasSatisfied(c, getExpectReplicasLinear, DNSdefaultTimeout)
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
|
|
||||||
By("Replace the dns autoscaling parameters with another testing parameters")
|
ginkgo.By("Replace the dns autoscaling parameters with another testing parameters")
|
||||||
err = updateDNSScalingConfigMap(c, packDNSScalingConfigMap(packLinearParams(&DNSParams_3)))
|
err = updateDNSScalingConfigMap(c, packDNSScalingConfigMap(packLinearParams(&DNSParams3)))
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
|
|
||||||
By("Wait for kube-dns scaled to expected number")
|
ginkgo.By("Wait for kube-dns scaled to expected number")
|
||||||
getExpectReplicasLinear = getExpectReplicasFuncLinear(c, &DNSParams_3)
|
getExpectReplicasLinear = getExpectReplicasFuncLinear(c, &DNSParams3)
|
||||||
err = waitForDNSReplicasSatisfied(c, getExpectReplicasLinear, DNSdefaultTimeout)
|
err = waitForDNSReplicasSatisfied(c, getExpectReplicasLinear, DNSdefaultTimeout)
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
|
|
||||||
By("Restoring cluster size")
|
ginkgo.By("Restoring cluster size")
|
||||||
setMigSizes(originalSizes)
|
setMigSizes(originalSizes)
|
||||||
err = framework.WaitForReadyNodes(c, numNodes, scaleDownTimeout)
|
err = framework.WaitForReadyNodes(c, numNodes, scaleDownTimeout)
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
|
|
||||||
By("Wait for kube-dns scaled to expected number")
|
ginkgo.By("Wait for kube-dns scaled to expected number")
|
||||||
err = waitForDNSReplicasSatisfied(c, getExpectReplicasLinear, DNSdefaultTimeout)
|
err = waitForDNSReplicasSatisfied(c, getExpectReplicasLinear, DNSdefaultTimeout)
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
})
|
})
|
||||||
|
|
||||||
// TODO: Get rid of [DisabledForLargeClusters] tag when issue #55779 is fixed.
|
// TODO: Get rid of [DisabledForLargeClusters] tag when issue #55779 is fixed.
|
||||||
It("[DisabledForLargeClusters] kube-dns-autoscaler should scale kube-dns pods in both nonfaulty and faulty scenarios", func() {
|
ginkgo.It("[DisabledForLargeClusters] kube-dns-autoscaler should scale kube-dns pods in both nonfaulty and faulty scenarios", func() {
|
||||||
|
|
||||||
By("Replace the dns autoscaling parameters with testing parameters")
|
ginkgo.By("Replace the dns autoscaling parameters with testing parameters")
|
||||||
err := updateDNSScalingConfigMap(c, packDNSScalingConfigMap(packLinearParams(&DNSParams_1)))
|
err := updateDNSScalingConfigMap(c, packDNSScalingConfigMap(packLinearParams(&DNSParams1)))
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
defer func() {
|
defer func() {
|
||||||
By("Restoring initial dns autoscaling parameters")
|
ginkgo.By("Restoring initial dns autoscaling parameters")
|
||||||
err = updateDNSScalingConfigMap(c, packDNSScalingConfigMap(previousParams))
|
err = updateDNSScalingConfigMap(c, packDNSScalingConfigMap(previousParams))
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
}()
|
}()
|
||||||
By("Wait for kube-dns scaled to expected number")
|
ginkgo.By("Wait for kube-dns scaled to expected number")
|
||||||
getExpectReplicasLinear := getExpectReplicasFuncLinear(c, &DNSParams_1)
|
getExpectReplicasLinear := getExpectReplicasFuncLinear(c, &DNSParams1)
|
||||||
err = waitForDNSReplicasSatisfied(c, getExpectReplicasLinear, DNSdefaultTimeout)
|
err = waitForDNSReplicasSatisfied(c, getExpectReplicasLinear, DNSdefaultTimeout)
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
|
|
||||||
By("--- Scenario: should scale kube-dns based on changed parameters ---")
|
ginkgo.By("--- Scenario: should scale kube-dns based on changed parameters ---")
|
||||||
By("Replace the dns autoscaling parameters with another testing parameters")
|
ginkgo.By("Replace the dns autoscaling parameters with another testing parameters")
|
||||||
err = updateDNSScalingConfigMap(c, packDNSScalingConfigMap(packLinearParams(&DNSParams_3)))
|
err = updateDNSScalingConfigMap(c, packDNSScalingConfigMap(packLinearParams(&DNSParams3)))
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
By("Wait for kube-dns scaled to expected number")
|
ginkgo.By("Wait for kube-dns scaled to expected number")
|
||||||
getExpectReplicasLinear = getExpectReplicasFuncLinear(c, &DNSParams_3)
|
getExpectReplicasLinear = getExpectReplicasFuncLinear(c, &DNSParams3)
|
||||||
err = waitForDNSReplicasSatisfied(c, getExpectReplicasLinear, DNSdefaultTimeout)
|
err = waitForDNSReplicasSatisfied(c, getExpectReplicasLinear, DNSdefaultTimeout)
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
|
|
||||||
By("--- Scenario: should re-create scaling parameters with default value when parameters got deleted ---")
|
ginkgo.By("--- Scenario: should re-create scaling parameters with default value when parameters got deleted ---")
|
||||||
By("Delete the ConfigMap for autoscaler")
|
ginkgo.By("Delete the ConfigMap for autoscaler")
|
||||||
err = deleteDNSScalingConfigMap(c)
|
err = deleteDNSScalingConfigMap(c)
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
|
|
||||||
By("Wait for the ConfigMap got re-created")
|
ginkgo.By("Wait for the ConfigMap got re-created")
|
||||||
_, err = waitForDNSConfigMapCreated(c, DNSdefaultTimeout)
|
_, err = waitForDNSConfigMapCreated(c, DNSdefaultTimeout)
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
|
|
||||||
By("Replace the dns autoscaling parameters with another testing parameters")
|
ginkgo.By("Replace the dns autoscaling parameters with another testing parameters")
|
||||||
err = updateDNSScalingConfigMap(c, packDNSScalingConfigMap(packLinearParams(&DNSParams_2)))
|
err = updateDNSScalingConfigMap(c, packDNSScalingConfigMap(packLinearParams(&DNSParams2)))
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
By("Wait for kube-dns scaled to expected number")
|
ginkgo.By("Wait for kube-dns scaled to expected number")
|
||||||
getExpectReplicasLinear = getExpectReplicasFuncLinear(c, &DNSParams_2)
|
getExpectReplicasLinear = getExpectReplicasFuncLinear(c, &DNSParams2)
|
||||||
err = waitForDNSReplicasSatisfied(c, getExpectReplicasLinear, DNSdefaultTimeout)
|
err = waitForDNSReplicasSatisfied(c, getExpectReplicasLinear, DNSdefaultTimeout)
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
|
|
||||||
By("--- Scenario: should recover after autoscaler pod got deleted ---")
|
ginkgo.By("--- Scenario: should recover after autoscaler pod got deleted ---")
|
||||||
By("Delete the autoscaler pod for kube-dns")
|
ginkgo.By("Delete the autoscaler pod for kube-dns")
|
||||||
err = deleteDNSAutoscalerPod(c)
|
err = deleteDNSAutoscalerPod(c)
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
|
|
||||||
By("Replace the dns autoscaling parameters with another testing parameters")
|
ginkgo.By("Replace the dns autoscaling parameters with another testing parameters")
|
||||||
err = updateDNSScalingConfigMap(c, packDNSScalingConfigMap(packLinearParams(&DNSParams_1)))
|
err = updateDNSScalingConfigMap(c, packDNSScalingConfigMap(packLinearParams(&DNSParams1)))
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
By("Wait for kube-dns scaled to expected number")
|
ginkgo.By("Wait for kube-dns scaled to expected number")
|
||||||
getExpectReplicasLinear = getExpectReplicasFuncLinear(c, &DNSParams_1)
|
getExpectReplicasLinear = getExpectReplicasFuncLinear(c, &DNSParams1)
|
||||||
err = waitForDNSReplicasSatisfied(c, getExpectReplicasLinear, DNSdefaultTimeout)
|
err = waitForDNSReplicasSatisfied(c, getExpectReplicasLinear, DNSdefaultTimeout)
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// DNSParamsLinear is a struct for number of DNS pods.
|
||||||
type DNSParamsLinear struct {
|
type DNSParamsLinear struct {
|
||||||
nodesPerReplica float64
|
nodesPerReplica float64
|
||||||
coresPerReplica float64
|
coresPerReplica float64
|
||||||
|
|
|
@ -18,6 +18,7 @@ package autoscaling
|
||||||
|
|
||||||
import "github.com/onsi/ginkgo"
|
import "github.com/onsi/ginkgo"
|
||||||
|
|
||||||
|
// SIGDescribe annotates the test with the SIG label.
|
||||||
func SIGDescribe(text string, body func()) bool {
|
func SIGDescribe(text string, body func()) bool {
|
||||||
return ginkgo.Describe("[sig-autoscaling] "+text, body)
|
return ginkgo.Describe("[sig-autoscaling] "+text, body)
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ import (
|
||||||
"k8s.io/kubernetes/test/e2e/common"
|
"k8s.io/kubernetes/test/e2e/common"
|
||||||
"k8s.io/kubernetes/test/e2e/framework"
|
"k8s.io/kubernetes/test/e2e/framework"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
"github.com/onsi/ginkgo"
|
||||||
)
|
)
|
||||||
|
|
||||||
// These tests don't seem to be running properly in parallel: issue: #20338.
|
// These tests don't seem to be running properly in parallel: issue: #20338.
|
||||||
|
@ -37,20 +37,20 @@ var _ = SIGDescribe("[HPA] Horizontal pod autoscaling (scale resource: CPU)", fu
|
||||||
|
|
||||||
SIGDescribe("[Serial] [Slow] Deployment", func() {
|
SIGDescribe("[Serial] [Slow] Deployment", func() {
|
||||||
// CPU tests via deployments
|
// CPU tests via deployments
|
||||||
It(titleUp, func() {
|
ginkgo.It(titleUp, func() {
|
||||||
scaleUp("test-deployment", common.KindDeployment, false, rc, f)
|
scaleUp("test-deployment", common.KindDeployment, false, rc, f)
|
||||||
})
|
})
|
||||||
It(titleDown, func() {
|
ginkgo.It(titleDown, func() {
|
||||||
scaleDown("test-deployment", common.KindDeployment, false, rc, f)
|
scaleDown("test-deployment", common.KindDeployment, false, rc, f)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
SIGDescribe("[Serial] [Slow] ReplicaSet", func() {
|
SIGDescribe("[Serial] [Slow] ReplicaSet", func() {
|
||||||
// CPU tests via ReplicaSets
|
// CPU tests via ReplicaSets
|
||||||
It(titleUp, func() {
|
ginkgo.It(titleUp, func() {
|
||||||
scaleUp("rs", common.KindReplicaSet, false, rc, f)
|
scaleUp("rs", common.KindReplicaSet, false, rc, f)
|
||||||
})
|
})
|
||||||
It(titleDown, func() {
|
ginkgo.It(titleDown, func() {
|
||||||
scaleDown("rs", common.KindReplicaSet, false, rc, f)
|
scaleDown("rs", common.KindReplicaSet, false, rc, f)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -58,16 +58,16 @@ var _ = SIGDescribe("[HPA] Horizontal pod autoscaling (scale resource: CPU)", fu
|
||||||
// These tests take ~20 minutes each.
|
// These tests take ~20 minutes each.
|
||||||
SIGDescribe("[Serial] [Slow] ReplicationController", func() {
|
SIGDescribe("[Serial] [Slow] ReplicationController", func() {
|
||||||
// CPU tests via replication controllers
|
// CPU tests via replication controllers
|
||||||
It(titleUp+" and verify decision stability", func() {
|
ginkgo.It(titleUp+" and verify decision stability", func() {
|
||||||
scaleUp("rc", common.KindRC, true, rc, f)
|
scaleUp("rc", common.KindRC, true, rc, f)
|
||||||
})
|
})
|
||||||
It(titleDown+" and verify decision stability", func() {
|
ginkgo.It(titleDown+" and verify decision stability", func() {
|
||||||
scaleDown("rc", common.KindRC, true, rc, f)
|
scaleDown("rc", common.KindRC, true, rc, f)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
SIGDescribe("ReplicationController light", func() {
|
SIGDescribe("ReplicationController light", func() {
|
||||||
It("Should scale from 1 pod to 2 pods", func() {
|
ginkgo.It("Should scale from 1 pod to 2 pods", func() {
|
||||||
scaleTest := &HPAScaleTest{
|
scaleTest := &HPAScaleTest{
|
||||||
initPods: 1,
|
initPods: 1,
|
||||||
totalInitialCPUUsage: 150,
|
totalInitialCPUUsage: 150,
|
||||||
|
@ -79,7 +79,7 @@ var _ = SIGDescribe("[HPA] Horizontal pod autoscaling (scale resource: CPU)", fu
|
||||||
}
|
}
|
||||||
scaleTest.run("rc-light", common.KindRC, rc, f)
|
scaleTest.run("rc-light", common.KindRC, rc, f)
|
||||||
})
|
})
|
||||||
It("Should scale from 2 pods to 1 pod", func() {
|
ginkgo.It("Should scale from 2 pods to 1 pod", func() {
|
||||||
scaleTest := &HPAScaleTest{
|
scaleTest := &HPAScaleTest{
|
||||||
initPods: 2,
|
initPods: 2,
|
||||||
totalInitialCPUUsage: 50,
|
totalInitialCPUUsage: 50,
|
||||||
|
|
Loading…
Reference in New Issue