Skip to content

Commit 2788e55

Browse files
committed
test(dynamo): add condition assertions to reconciliation tests
Assert StorageReady and ModelDownloaded status conditions in the 3-phase orchestration tests to catch regressions where conditions stop being set during PVC, download, and full pipeline reconciliation. Signed-off-by: Suraj Deshmukh <suraj.deshmukh@microsoft.com>
1 parent 18691d9 commit 2788e55

1 file changed

Lines changed: 46 additions & 3 deletions

File tree

providers/dynamo/controller_test.go

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
kubeairunwayv1alpha1 "github.com/kaito-project/kubeairunway/controller/api/v1alpha1"
1010
batchv1 "k8s.io/api/batch/v1"
1111
corev1 "k8s.io/api/core/v1"
12+
"k8s.io/apimachinery/pkg/api/meta"
1213
"k8s.io/apimachinery/pkg/api/resource"
1314
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1415
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
@@ -52,6 +53,21 @@ func setDGDGVK(u *unstructured.Unstructured) {
5253
u.SetKind("DynamoGraphDeployment")
5354
}
5455

56+
func assertCondition(t *testing.T, conditions []metav1.Condition, condType string, status metav1.ConditionStatus, reason string) {
57+
t.Helper()
58+
cond := meta.FindStatusCondition(conditions, condType)
59+
if cond == nil {
60+
t.Errorf("expected condition %s to be set", condType)
61+
return
62+
}
63+
if cond.Status != status {
64+
t.Errorf("condition %s: expected status %s, got %s", condType, status, cond.Status)
65+
}
66+
if cond.Reason != reason {
67+
t.Errorf("condition %s: expected reason %q, got %q", condType, reason, cond.Reason)
68+
}
69+
}
70+
5571
func TestValidateCompatibility(t *testing.T) {
5672
r := &DynamoProviderReconciler{}
5773

@@ -407,7 +423,7 @@ func TestReconcileDeletionWithUpstreamResource(t *testing.T) {
407423
dgd.SetName("test")
408424
dgd.SetNamespace("default")
409425
dgd.SetLabels(map[string]string{
410-
kubeairunwayv1alpha1.LabelManagedBy: "kubeairunway",
426+
kubeairunwayv1alpha1.LabelManagedBy: "kubeairunway",
411427
})
412428
dgd.SetOwnerReferences([]metav1.OwnerReference{
413429
{APIVersion: "kubeairunway.ai/v1alpha1", Kind: "ModelDeployment", Name: "test", UID: "test-uid"},
@@ -456,7 +472,7 @@ func TestCreateOrUpdateResourceUpdate(t *testing.T) {
456472
existing.SetName("test")
457473
existing.SetNamespace("default")
458474
existing.SetLabels(map[string]string{
459-
kubeairunwayv1alpha1.LabelManagedBy: "kubeairunway",
475+
kubeairunwayv1alpha1.LabelManagedBy: "kubeairunway",
460476
})
461477
existing.SetOwnerReferences([]metav1.OwnerReference{
462478
{APIVersion: "kubeairunway.ai/v1alpha1", Kind: "ModelDeployment", Name: "test", UID: "test-uid"},
@@ -491,7 +507,7 @@ func TestCreateOrUpdateResourceNoChange(t *testing.T) {
491507
existing.SetName("test")
492508
existing.SetNamespace("default")
493509
existing.SetLabels(map[string]string{
494-
kubeairunwayv1alpha1.LabelManagedBy: "kubeairunway",
510+
kubeairunwayv1alpha1.LabelManagedBy: "kubeairunway",
495511
})
496512
existing.SetOwnerReferences([]metav1.OwnerReference{
497513
{APIVersion: "kubeairunway.ai/v1alpha1", Kind: "ModelDeployment", Name: "test", UID: "test-uid"},
@@ -685,6 +701,17 @@ func TestReconcilePVCNotBound(t *testing.T) {
685701
if err == nil {
686702
t.Error("DGD should NOT be created before PVCs are bound")
687703
}
704+
705+
// Verify conditions were set correctly
706+
var updated kubeairunwayv1alpha1.ModelDeployment
707+
if err := c.Get(context.Background(), types.NamespacedName{Name: "test", Namespace: "default"}, &updated); err != nil {
708+
t.Fatalf("failed to get updated MD: %v", err)
709+
}
710+
assertCondition(t, updated.Status.Conditions, kubeairunwayv1alpha1.ConditionTypeStorageReady, metav1.ConditionFalse, "PVCsPending")
711+
// ModelDownloaded should NOT be set (download phase was never reached)
712+
if meta.FindStatusCondition(updated.Status.Conditions, kubeairunwayv1alpha1.ConditionTypeModelDownloaded) != nil {
713+
t.Error("expected ModelDownloaded condition to NOT be set (download phase not reached)")
714+
}
688715
}
689716

690717
func TestReconcileDownloadNotComplete(t *testing.T) {
@@ -743,6 +770,14 @@ func TestReconcileDownloadNotComplete(t *testing.T) {
743770
if err == nil {
744771
t.Error("DGD should NOT be created before download completes")
745772
}
773+
774+
// Verify conditions were set correctly
775+
var updated kubeairunwayv1alpha1.ModelDeployment
776+
if err := c.Get(context.Background(), types.NamespacedName{Name: "test", Namespace: "default"}, &updated); err != nil {
777+
t.Fatalf("failed to get updated MD: %v", err)
778+
}
779+
assertCondition(t, updated.Status.Conditions, kubeairunwayv1alpha1.ConditionTypeStorageReady, metav1.ConditionTrue, "PVCsBound")
780+
assertCondition(t, updated.Status.Conditions, kubeairunwayv1alpha1.ConditionTypeModelDownloaded, metav1.ConditionFalse, "DownloadInProgress")
746781
}
747782

748783
func TestReconcileFullPipeline(t *testing.T) {
@@ -810,6 +845,14 @@ func TestReconcileFullPipeline(t *testing.T) {
810845
if err != nil {
811846
t.Fatalf("expected DGD to be created: %v", err)
812847
}
848+
849+
// Verify conditions were set correctly
850+
var updated kubeairunwayv1alpha1.ModelDeployment
851+
if err := c.Get(context.Background(), types.NamespacedName{Name: "test", Namespace: "default"}, &updated); err != nil {
852+
t.Fatalf("failed to get updated MD: %v", err)
853+
}
854+
assertCondition(t, updated.Status.Conditions, kubeairunwayv1alpha1.ConditionTypeStorageReady, metav1.ConditionTrue, "PVCsBound")
855+
assertCondition(t, updated.Status.Conditions, kubeairunwayv1alpha1.ConditionTypeModelDownloaded, metav1.ConditionTrue, "DownloadComplete")
813856
}
814857

815858
func TestReconcileNoStorageSkipsPhases(t *testing.T) {

0 commit comments

Comments
 (0)