Skip to content

Commit 1ebc3f9

Browse files
ryanaolearyYgnas
authored andcommitted
Add KubeRay e2e Test for custom idleTimeoutSeconds with v2 Autoscaler (ray-project#2725)
1 parent 059c912 commit 1ebc3f9

File tree

2 files changed

+70
-0
lines changed

2 files changed

+70
-0
lines changed

ray-operator/Makefile

+3
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ test-e2e: WHAT ?= ./test/e2e
7272
test-e2e: manifests fmt vet ## Run e2e tests.
7373
go test -timeout 30m -v $(WHAT)
7474

75+
test-e2e-autoscaler: WHAT ?= ./test/e2eautoscaler
76+
test-e2e-autoscaler: manifests fmt vet ## Run e2e autoscaler tests.
77+
go test -timeout 30m -v $(WHAT)
7578

7679
test-sampleyaml: WHAT ?= ./test/sampleyaml
7780
test-sampleyaml: manifests fmt vet

ray-operator/test/e2eautoscaler/raycluster_autoscaler_test.go

+67
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package e2eautoscaler
33
import (
44
"fmt"
55
"testing"
6+
"time"
67

78
"github.com/onsi/gomega"
89
corev1ac "k8s.io/client-go/applyconfigurations/core/v1"
@@ -355,3 +356,69 @@ func TestRayClusterAutoscalerMinReplicasUpdate(t *testing.T) {
355356
})
356357
}
357358
}
359+
360+
func TestRayClusterAutoscalerV2IdleTimeout(t *testing.T) {
361+
// Only test with the V2 Autoscaler
362+
name := "Create a RayCluster with autoscaler v2 enabled"
363+
tc := tests["Create a RayCluster with autoscaler v2 enabled"]
364+
365+
test := With(t)
366+
g := gomega.NewWithT(t)
367+
368+
// Create a namespace
369+
namespace := test.NewTestNamespace()
370+
371+
// Minimum Ray Version for custom idleTimeoutSeconds
372+
idleTimeoutMinRayVersion := "2.40.0"
373+
374+
customIdleTimeoutSeconds := int32(30)
375+
defaultIdleTimeoutSeconds := int32(60)
376+
377+
test.T().Run(name, func(_ *testing.T) {
378+
rayClusterSpecAC := rayv1ac.RayClusterSpec().
379+
WithEnableInTreeAutoscaling(true).
380+
WithRayVersion(idleTimeoutMinRayVersion).
381+
WithHeadGroupSpec(rayv1ac.HeadGroupSpec().
382+
WithRayStartParams(map[string]string{"num-cpus": "0"}).
383+
WithTemplate(tc.HeadPodTemplateGetter())).
384+
WithWorkerGroupSpecs(
385+
rayv1ac.WorkerGroupSpec().
386+
WithReplicas(1).
387+
WithMinReplicas(0).
388+
WithMaxReplicas(4).
389+
WithGroupName("no-idle-timeout-group").
390+
WithRayStartParams(map[string]string{"num-cpus": "1"}).
391+
WithTemplate(tc.WorkerPodTemplateGetter()),
392+
rayv1ac.WorkerGroupSpec().
393+
WithReplicas(1).
394+
WithMinReplicas(0).
395+
WithMaxReplicas(4).
396+
WithIdleTimeoutSeconds(customIdleTimeoutSeconds).
397+
WithGroupName("custom-idle-timeout-group").
398+
WithRayStartParams(map[string]string{"num-cpus": "1"}).
399+
WithTemplate(tc.WorkerPodTemplateGetter()),
400+
)
401+
rayClusterAC := rayv1ac.RayCluster("ray-cluster", namespace.Name).WithSpec((rayClusterSpecAC))
402+
403+
rayCluster, err := test.Client().Ray().RayV1().RayClusters(namespace.Name).Apply(test.Ctx(), rayClusterAC, TestApplyOptions)
404+
g.Expect(err).NotTo(gomega.HaveOccurred())
405+
test.T().Logf("Created RayCluster %s/%s successfully", rayCluster.Namespace, rayCluster.Name)
406+
407+
// Wait for RayCluster to become ready and verify the number of available worker replicas.
408+
g.Eventually(RayCluster(test, rayCluster.Namespace, rayCluster.Name), TestTimeoutMedium).
409+
Should(gomega.WithTransform(RayClusterState, gomega.Equal(rayv1.Ready)))
410+
g.Expect(GetRayCluster(test, rayCluster.Namespace, rayCluster.Name)).To(gomega.WithTransform(RayClusterDesiredWorkerReplicas, gomega.Equal(int32(2))))
411+
412+
headPod, err := GetHeadPod(test, rayCluster)
413+
g.Expect(err).NotTo(gomega.HaveOccurred())
414+
test.T().Logf("Found head pod %s/%s", headPod.Namespace, headPod.Name)
415+
416+
// After customIdleTimeoutSeconds, the replica in the worker group with custom idleTimeoutSeconds set should be scaled down.
417+
g.Eventually(RayCluster(test, rayCluster.Namespace, rayCluster.Name), time.Duration(customIdleTimeoutSeconds)*time.Second).
418+
Should(gomega.WithTransform(RayClusterDesiredWorkerReplicas, gomega.Equal(int32(1))))
419+
420+
// After the default idleTimeoutSeconds, all worker replicas should be scaled down.
421+
g.Eventually(RayCluster(test, rayCluster.Namespace, rayCluster.Name), time.Duration(defaultIdleTimeoutSeconds)*time.Second).
422+
Should(gomega.WithTransform(RayClusterDesiredWorkerReplicas, gomega.Equal(int32(0))))
423+
})
424+
}

0 commit comments

Comments
 (0)