Skip to content

Commit 62af5d9

Browse files
committed
add testing
1 parent c90a5ef commit 62af5d9

File tree

2 files changed

+113
-0
lines changed

2 files changed

+113
-0
lines changed

ray-operator/controllers/ray/raycluster_controller_unit_test.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"github.com/ray-project/kuberay/ray-operator/controllers/ray/common"
2626
"github.com/ray-project/kuberay/ray-operator/controllers/ray/utils"
2727
"github.com/ray-project/kuberay/ray-operator/pkg/client/clientset/versioned/scheme"
28+
"github.com/ray-project/kuberay/ray-operator/pkg/features"
2829

2930
. "github.com/onsi/ginkgo/v2"
3031
"github.com/stretchr/testify/assert"
@@ -33,6 +34,7 @@ import (
3334
corev1 "k8s.io/api/core/v1"
3435
rbacv1 "k8s.io/api/rbac/v1"
3536
k8serrors "k8s.io/apimachinery/pkg/api/errors"
37+
"k8s.io/apimachinery/pkg/api/meta"
3638
"k8s.io/apimachinery/pkg/api/resource"
3739
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3840
"k8s.io/apimachinery/pkg/labels"
@@ -1664,6 +1666,12 @@ func TestCalculateStatus(t *testing.T) {
16641666
Status: corev1.PodStatus{
16651667
PodIP: headNodeIP,
16661668
Phase: corev1.PodRunning,
1669+
Conditions: []corev1.PodCondition{
1670+
{
1671+
Type: corev1.PodReady,
1672+
Status: corev1.ConditionTrue,
1673+
},
1674+
},
16671675
},
16681676
}
16691677
runtimeObjects := []runtime.Object{headPod, headService}
@@ -1687,6 +1695,47 @@ func TestCalculateStatus(t *testing.T) {
16871695
assert.Equal(t, headService.Name, newInstance.Status.Head.ServiceName)
16881696
assert.NotNil(t, newInstance.Status.StateTransitionTimes, "Cluster state transition timestamp should be created")
16891697
assert.Equal(t, newInstance.Status.LastUpdateTime, newInstance.Status.StateTransitionTimes[rayv1.Ready])
1698+
1699+
// Test empty conditions with feature gate disabled
1700+
newInstance, _ = r.calculateStatus(ctx, testRayCluster, nil)
1701+
assert.Empty(t, newInstance.Status.Conditions)
1702+
1703+
// enable feature gate for the following tests
1704+
defer features.SetFeatureGateDuringTest(t, features.RayClusterStatusConditions, true)()
1705+
1706+
// Test CheckRayHeadRunningAndReady with head pod running and ready
1707+
newInstance, _ = r.calculateStatus(ctx, testRayCluster, nil)
1708+
assert.True(t, meta.IsStatusConditionPresentAndEqual(newInstance.Status.Conditions, string(rayv1.HeadReady), metav1.ConditionTrue))
1709+
condition := meta.FindStatusCondition(newInstance.Status.Conditions, string(rayv1.HeadReady))
1710+
assert.Equal(t, "HeadPodRunningAndReady", condition.Reason)
1711+
assert.Equal(t, "Head pod is running and ready", condition.Message)
1712+
1713+
// Test CheckRayHeadRunningAndReady with head pod not ready
1714+
headPod.Status.Conditions = []corev1.PodCondition{
1715+
{
1716+
Type: corev1.PodReady,
1717+
Status: corev1.ConditionFalse,
1718+
},
1719+
}
1720+
runtimeObjects = []runtime.Object{headPod, headService}
1721+
fakeClient = clientFake.NewClientBuilder().WithScheme(newScheme).WithRuntimeObjects(runtimeObjects...).Build()
1722+
r.Client = fakeClient
1723+
newInstance, _ = r.calculateStatus(ctx, testRayCluster, nil)
1724+
assert.True(t, meta.IsStatusConditionPresentAndEqual(newInstance.Status.Conditions, string(rayv1.HeadReady), metav1.ConditionFalse))
1725+
condition = meta.FindStatusCondition(newInstance.Status.Conditions, string(rayv1.HeadReady))
1726+
assert.Equal(t, "HeadPodNotReady", condition.Reason)
1727+
assert.Equal(t, "Head pod is not ready", condition.Message)
1728+
1729+
// Test CheckRayHeadRunningAndReady with head pod not running
1730+
headPod.Status.Phase = corev1.PodFailed
1731+
runtimeObjects = []runtime.Object{headPod, headService}
1732+
fakeClient = clientFake.NewClientBuilder().WithScheme(newScheme).WithRuntimeObjects(runtimeObjects...).Build()
1733+
r.Client = fakeClient
1734+
newInstance, _ = r.calculateStatus(ctx, testRayCluster, nil)
1735+
assert.True(t, meta.IsStatusConditionPresentAndEqual(newInstance.Status.Conditions, string(rayv1.HeadReady), metav1.ConditionFalse))
1736+
condition = meta.FindStatusCondition(newInstance.Status.Conditions, string(rayv1.HeadReady))
1737+
assert.Equal(t, "HeadPodNotRunning", condition.Reason)
1738+
assert.Equal(t, "Head pod is not running", condition.Message)
16901739
}
16911740

16921741
func TestStateTransitionTimes_NoStateChange(t *testing.T) {

ray-operator/controllers/ray/utils/util_test.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,31 @@ func createSomePodWithCondition(typ corev1.PodConditionType, status corev1.Condi
201201
}
202202
}
203203

204+
func createRayHeadPodWithPhaseAndCOndition(phase corev1.PodPhase, typ corev1.PodConditionType, status corev1.ConditionStatus) (pod *corev1.Pod) {
205+
return &corev1.Pod{
206+
TypeMeta: metav1.TypeMeta{
207+
APIVersion: "v1",
208+
Kind: "Pod",
209+
},
210+
ObjectMeta: metav1.ObjectMeta{
211+
Name: "raycluster-sample-head",
212+
Namespace: "default",
213+
Labels: map[string]string{
214+
"ray.io/node-type": string(rayv1.HeadNode),
215+
},
216+
},
217+
Status: corev1.PodStatus{
218+
Phase: phase,
219+
Conditions: []corev1.PodCondition{
220+
{
221+
Type: typ,
222+
Status: status,
223+
},
224+
},
225+
},
226+
}
227+
}
228+
204229
func TestGetHeadGroupServiceAccountName(t *testing.T) {
205230
tests := map[string]struct {
206231
input *rayv1.RayCluster
@@ -523,3 +548,42 @@ env_vars:
523548
})
524549
}
525550
}
551+
552+
func TestCheckRayHeadRunningAndReady(t *testing.T) {
553+
tests := map[string]struct {
554+
pods corev1.PodList
555+
expected bool
556+
}{
557+
"should return true if Ray head pod is running and ready": {
558+
pods: corev1.PodList{
559+
Items: []corev1.Pod{
560+
*createRayHeadPodWithPhaseAndCOndition(corev1.PodRunning, corev1.PodReady, corev1.ConditionTrue),
561+
},
562+
},
563+
expected: true,
564+
},
565+
"should return false if Ray head pod is not running": {
566+
pods: corev1.PodList{
567+
Items: []corev1.Pod{
568+
*createRayHeadPodWithPhaseAndCOndition(corev1.PodPending, corev1.PodReady, corev1.ConditionFalse),
569+
},
570+
},
571+
expected: false,
572+
},
573+
"should return false if Ray head pod is not ready": {
574+
pods: corev1.PodList{
575+
Items: []corev1.Pod{
576+
*createRayHeadPodWithPhaseAndCOndition(corev1.PodRunning, corev1.PodReady, corev1.ConditionFalse),
577+
},
578+
},
579+
expected: false,
580+
},
581+
}
582+
583+
for name, tc := range tests {
584+
t.Run(name, func(t *testing.T) {
585+
isRunning, _, _ := CheckRayHeadRunningAndReady(context.Background(), tc.pods)
586+
assert.Equal(t, tc.expected, isRunning)
587+
})
588+
}
589+
}

0 commit comments

Comments
 (0)