Skip to content

Commit

Permalink
Merge pull request #6933 from k8s-infra-cherrypick-robot/cherry-pick-…
Browse files Browse the repository at this point in the history
…6779-to-cluster-autoscaler-release-1.30

[cluster-autoscaler-release-1.30] Refactor Provisioning Request orchestrator unit tests
  • Loading branch information
k8s-ci-robot authored Jul 11, 2024
2 parents bf7bbda + d9eecae commit 0ed4b01
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"context"
"fmt"
"testing"
"time"

"github.com/stretchr/testify/assert"
v1 "k8s.io/api/apps/v1"
Expand All @@ -43,6 +42,9 @@ import (
)

func TestScaleUp(t *testing.T) {
// Set up a cluster with 200 nodes:
// - 100 nodes with high cpu, low memory
// - 100 nodes with high memory, low cpu
allNodes := []*apiv1.Node{}
for i := 0; i < 100; i++ {
name := fmt.Sprintf("test-cpu-node-%d", i)
Expand All @@ -54,13 +56,68 @@ func TestScaleUp(t *testing.T) {
node := BuildTestNode(name, 1, 1000)
allNodes = append(allNodes, node)
}
newCpuProvReq := provreqwrapper.BuildTestProvisioningRequest("ns", "newCpuProvReq", "5m", "5", "", int32(100), false, time.Now(), v1beta1.ProvisioningClassCheckCapacity)
newMemProvReq := provreqwrapper.BuildTestProvisioningRequest("ns", "newMemProvReq", "1m", "100", "", int32(100), false, time.Now(), v1beta1.ProvisioningClassCheckCapacity)
bookedCapacityProvReq := provreqwrapper.BuildTestProvisioningRequest("ns", "bookedCapacity", "1m", "200", "", int32(100), false, time.Now(), v1beta1.ProvisioningClassCheckCapacity)

// Active check capacity requests.
newCheckCapacityCpuProvReq := provreqwrapper.BuildValidTestProvisioningRequestFromOptions(
provreqwrapper.TestProvReqOptions{
Name: "newCheckCapacityCpuProvReq",
CPU: "5m",
Memory: "5",
PodCount: int32(100),
Class: v1beta1.ProvisioningClassCheckCapacity,
})

newCheckCapacityMemProvReq := provreqwrapper.BuildValidTestProvisioningRequestFromOptions(
provreqwrapper.TestProvReqOptions{
Name: "newCheckCapacityMemProvReq",
CPU: "1m",
Memory: "100",
PodCount: int32(100),
Class: v1beta1.ProvisioningClassCheckCapacity,
})

// Active atomic scale up request.
atomicScaleUpProvReq := provreqwrapper.BuildValidTestProvisioningRequestFromOptions(
provreqwrapper.TestProvReqOptions{
Name: "atomicScaleUpProvReq",
CPU: "1",
Memory: "1",
PodCount: int32(5),
Class: v1beta1.ProvisioningClassAtomicScaleUp,
})

// Already provisioned provisioning request - capacity should be booked before processing a new request.
bookedCapacityProvReq := provreqwrapper.BuildValidTestProvisioningRequestFromOptions(
provreqwrapper.TestProvReqOptions{
Name: "bookedCapacityProvReq",
CPU: "1m",
Memory: "200",
PodCount: int32(100),
Class: v1beta1.ProvisioningClassCheckCapacity,
})
bookedCapacityProvReq.SetConditions([]metav1.Condition{{Type: v1beta1.Provisioned, Status: metav1.ConditionTrue, LastTransitionTime: metav1.Now()}})
expiredProvReq := provreqwrapper.BuildTestProvisioningRequest("ns", "bookedCapacity", "1m", "200", "", int32(100), false, time.Now(), v1beta1.ProvisioningClassCheckCapacity)

// Expired provisioning request - should be ignored.
expiredProvReq := provreqwrapper.BuildValidTestProvisioningRequestFromOptions(
provreqwrapper.TestProvReqOptions{
Name: "expiredProvReq",
CPU: "1m",
Memory: "200",
PodCount: int32(100),
Class: v1beta1.ProvisioningClassCheckCapacity,
})
expiredProvReq.SetConditions([]metav1.Condition{{Type: v1beta1.BookingExpired, Status: metav1.ConditionTrue, LastTransitionTime: metav1.Now()}})
differentProvReqClass := provreqwrapper.BuildTestProvisioningRequest("ns", "differentProvReqClass", "1", "1", "", int32(5), false, time.Now(), v1beta1.ProvisioningClassAtomicScaleUp)

// Unsupported provisioning request - should be ignored.
unsupportedProvReq := provreqwrapper.BuildValidTestProvisioningRequestFromOptions(
provreqwrapper.TestProvReqOptions{
Name: "unsupportedProvReq",
CPU: "1",
Memory: "1",
PodCount: int32(5),
Class: "very much unsupported",
})

testCases := []struct {
name string
provReqs []*provreqwrapper.ProvisioningRequest
Expand All @@ -74,27 +131,27 @@ func TestScaleUp(t *testing.T) {
scaleUpResult: status.ScaleUpNotTried,
},
{
name: "one ProvisioningRequest",
provReqs: []*provreqwrapper.ProvisioningRequest{newCpuProvReq},
provReqToScaleUp: newCpuProvReq,
name: "one ProvisioningRequest of check capacity class",
provReqs: []*provreqwrapper.ProvisioningRequest{newCheckCapacityCpuProvReq},
provReqToScaleUp: newCheckCapacityCpuProvReq,
scaleUpResult: status.ScaleUpSuccessful,
},
{
name: "capacity in the cluster is booked",
provReqs: []*provreqwrapper.ProvisioningRequest{newMemProvReq, bookedCapacityProvReq},
provReqToScaleUp: newMemProvReq,
provReqs: []*provreqwrapper.ProvisioningRequest{newCheckCapacityMemProvReq, bookedCapacityProvReq},
provReqToScaleUp: newCheckCapacityMemProvReq,
scaleUpResult: status.ScaleUpNoOptionsAvailable,
},
{
name: "pods from different ProvisioningRequest class",
provReqs: []*provreqwrapper.ProvisioningRequest{newCpuProvReq, bookedCapacityProvReq, differentProvReqClass},
provReqToScaleUp: differentProvReqClass,
name: "unsupported ProvisioningRequest is ignored",
provReqs: []*provreqwrapper.ProvisioningRequest{newCheckCapacityCpuProvReq, bookedCapacityProvReq, atomicScaleUpProvReq, unsupportedProvReq},
provReqToScaleUp: unsupportedProvReq,
scaleUpResult: status.ScaleUpNotTried,
},
{
name: "some capacity is booked, succesfull ScaleUp",
provReqs: []*provreqwrapper.ProvisioningRequest{newCpuProvReq, bookedCapacityProvReq, differentProvReqClass},
provReqToScaleUp: newCpuProvReq,
name: "some capacity is pre-booked, successful capacity check",
provReqs: []*provreqwrapper.ProvisioningRequest{newCheckCapacityCpuProvReq, bookedCapacityProvReq, atomicScaleUpProvReq},
provReqToScaleUp: newCheckCapacityCpuProvReq,
scaleUpResult: status.ScaleUpSuccessful,
},
}
Expand All @@ -106,9 +163,11 @@ func TestScaleUp(t *testing.T) {
provider := testprovider.NewTestCloudProvider(nil, nil)
autoscalingContext, err := NewScaleTestAutoscalingContext(config.AutoscalingOptions{}, &fake.Clientset{}, nil, provider, nil, nil)
assert.NoError(t, err)

clustersnapshot.InitializeClusterSnapshotOrDie(t, autoscalingContext.ClusterSnapshot, allNodes, nil)
prPods, err := pods.PodsForProvisioningRequest(tc.provReqToScaleUp)
assert.NoError(t, err)

client := provreqclient.NewFakeProvisioningRequestClient(context.Background(), t, tc.provReqs...)
orchestrator := &provReqOrchestrator{
client: client,
Expand Down
34 changes: 32 additions & 2 deletions cluster-autoscaler/provisioningrequest/provreqwrapper/testutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,39 @@ import (
"k8s.io/autoscaler/cluster-autoscaler/apis/provisioningrequest/autoscaling.x-k8s.io/v1beta1"
)

// TestProvReqOptions is a helper struct to make constructing test ProvisioningRequest object easier.
type TestProvReqOptions struct {
Namespace string
Name string
CPU string
Memory string
GPU string
PodCount int32
AntiAffinity bool
CreationTimestamp time.Time
Class string
}

func applyDefaults(o TestProvReqOptions) TestProvReqOptions {
if o.Namespace == "" {
o.Namespace = "default"
}
if o.CreationTimestamp.IsZero() {
o.CreationTimestamp = time.Now()
}
return o
}

// BuildValidTestProvisioningRequestFromOptions fills in commonly omitted fields to generate a valid ProvisioningRequest object.
// Simplifies test code.
func BuildValidTestProvisioningRequestFromOptions(o TestProvReqOptions) *ProvisioningRequest {
o = applyDefaults(o)
return BuildTestProvisioningRequest(o.Namespace, o.Name, o.CPU, o.Memory, o.GPU, o.PodCount, o.AntiAffinity, o.CreationTimestamp, o.Class)
}

// BuildTestProvisioningRequest builds ProvisioningRequest wrapper.
func BuildTestProvisioningRequest(namespace, name, cpu, memory, gpu string, podCount int32,
antiAffinity bool, creationTimestamp time.Time, provisioningRequestClass string) *ProvisioningRequest {
antiAffinity bool, creationTimestamp time.Time, class string) *ProvisioningRequest {
gpuResource := resource.Quantity{}
tolerations := []apiv1.Toleration{}
if len(gpu) > 0 {
Expand Down Expand Up @@ -64,7 +94,7 @@ func BuildTestProvisioningRequest(namespace, name, cpu, memory, gpu string, podC
CreationTimestamp: v1.NewTime(creationTimestamp),
},
Spec: v1beta1.ProvisioningRequestSpec{
ProvisioningClassName: provisioningRequestClass,
ProvisioningClassName: class,
PodSets: []v1beta1.PodSet{
{
PodTemplateRef: v1beta1.Reference{Name: fmt.Sprintf("%s-template-name", name)},
Expand Down

0 comments on commit 0ed4b01

Please sign in to comment.