@@ -31,6 +31,7 @@ import (
31
31
"k8s.io/apimachinery/pkg/runtime"
32
32
"k8s.io/apimachinery/pkg/types"
33
33
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
34
+ "k8s.io/utils/ptr"
34
35
"sigs.k8s.io/controller-runtime/pkg/client/fake"
35
36
36
37
v1 "sigs.k8s.io/gateway-api-inference-extension/api/v1"
@@ -54,7 +55,7 @@ type mockSaturationDetector struct {
54
55
isSaturated bool
55
56
}
56
57
57
- func (m * mockSaturationDetector ) IsSaturated (_ context.Context ) bool {
58
+ func (m * mockSaturationDetector ) IsSaturated (_ context.Context , _ []backendmetrics. PodMetrics ) bool {
58
59
return m .isSaturated
59
60
}
60
61
@@ -67,6 +68,23 @@ func (m *mockScheduler) Schedule(_ context.Context, _ *schedulingtypes.LLMReques
67
68
return m .scheduleResults , m .scheduleErr
68
69
}
69
70
71
+ type mockDatastore struct {
72
+ pods []backendmetrics.PodMetrics
73
+ }
74
+
75
+ func (ds * mockDatastore ) PoolGet () (* v1.InferencePool , error ) { return nil , nil }
76
+ func (ds * mockDatastore ) ObjectiveGet (_ string ) * v1alpha2.InferenceObjective { return nil }
77
+ func (ds * mockDatastore ) PodList (predicate func (backendmetrics.PodMetrics ) bool ) []backendmetrics.PodMetrics {
78
+ res := []backendmetrics.PodMetrics {}
79
+ for _ , pod := range ds .pods {
80
+ if predicate (pod ) {
81
+ res = append (res , pod )
82
+ }
83
+ }
84
+
85
+ return res
86
+ }
87
+
70
88
func TestDirector_HandleRequest (t * testing.T ) {
71
89
ctx := logutil .NewTestLoggerIntoContext (context .Background ())
72
90
@@ -442,119 +460,72 @@ func TestGetCandidatePodsForScheduling(t *testing.T) {
442
460
}
443
461
}
444
462
445
- testInput := []* corev1.Pod {
446
- {
447
- ObjectMeta : metav1.ObjectMeta {
448
- Name : "pod1" ,
449
- },
450
- Status : corev1.PodStatus {
451
- PodIP : "10.0.0.1" ,
452
- },
453
- },
454
- {
455
- ObjectMeta : metav1.ObjectMeta {
456
- Name : "pod2" ,
457
- },
458
- Status : corev1.PodStatus {
459
- PodIP : "10.0.0.2" ,
460
- },
461
- },
462
- }
463
-
464
- outputPod1 := & backend.Pod {
463
+ pod1 := & backend.Pod {
465
464
NamespacedName : types.NamespacedName {Name : "pod1" },
466
465
Address : "10.0.0.1" ,
467
466
Labels : map [string ]string {},
468
467
}
469
468
470
- outputPod2 := & backend.Pod {
469
+ pod2 := & backend.Pod {
471
470
NamespacedName : types.NamespacedName {Name : "pod2" },
472
471
Address : "10.0.0.2" ,
473
472
Labels : map [string ]string {},
474
473
}
475
474
475
+ testInput := []backendmetrics.PodMetrics {
476
+ & backendmetrics.FakePodMetrics {Pod : pod1 },
477
+ & backendmetrics.FakePodMetrics {Pod : pod2 },
478
+ }
479
+
476
480
tests := []struct {
477
481
name string
478
482
metadata map [string ]any
479
- output []schedulingtypes. Pod
483
+ output []backendmetrics. PodMetrics
480
484
}{
481
485
{
482
486
name : "SubsetFilter, filter not present — return all pods" ,
483
487
metadata : map [string ]any {},
484
- output : []schedulingtypes.Pod {
485
- & schedulingtypes.PodMetrics {
486
- Pod : outputPod1 ,
487
- MetricsState : backendmetrics .NewMetricsState (),
488
- },
489
- & schedulingtypes.PodMetrics {
490
- Pod : outputPod2 ,
491
- MetricsState : backendmetrics .NewMetricsState (),
492
- },
493
- },
488
+ output : testInput ,
494
489
},
495
490
{
496
491
name : "SubsetFilter, namespace present filter not present — return all pods" ,
497
492
metadata : map [string ]any {metadata .SubsetFilterNamespace : map [string ]any {}},
498
- output : []schedulingtypes.Pod {
499
- & schedulingtypes.PodMetrics {
500
- Pod : outputPod1 ,
501
- MetricsState : backendmetrics .NewMetricsState (),
502
- },
503
- & schedulingtypes.PodMetrics {
504
- Pod : outputPod2 ,
505
- MetricsState : backendmetrics .NewMetricsState (),
506
- },
507
- },
493
+ output : testInput ,
508
494
},
509
495
{
510
496
name : "SubsetFilter, filter present with empty list — return error" ,
511
497
metadata : makeFilterMetadata ([]any {}),
512
- output : []schedulingtypes. Pod {},
498
+ output : []backendmetrics. PodMetrics {},
513
499
},
514
500
{
515
501
name : "SubsetFilter, subset with one matching pod" ,
516
502
metadata : makeFilterMetadata ([]any {"10.0.0.1" }),
517
- output : []schedulingtypes.Pod {
518
- & schedulingtypes.PodMetrics {
519
- Pod : outputPod1 ,
520
- MetricsState : backendmetrics .NewMetricsState (),
503
+ output : []backendmetrics.PodMetrics {
504
+ & backendmetrics.FakePodMetrics {
505
+ Pod : pod1 ,
521
506
},
522
507
},
523
508
},
524
509
{
525
510
name : "SubsetFilter, subset with multiple matching pods" ,
526
511
metadata : makeFilterMetadata ([]any {"10.0.0.1" , "10.0.0.2" , "10.0.0.3" }),
527
- output : []schedulingtypes.Pod {
528
- & schedulingtypes.PodMetrics {
529
- Pod : outputPod1 ,
530
- MetricsState : backendmetrics .NewMetricsState (),
531
- },
532
- & schedulingtypes.PodMetrics {
533
- Pod : outputPod2 ,
534
- MetricsState : backendmetrics .NewMetricsState (),
535
- },
536
- },
512
+ output : testInput ,
537
513
},
538
514
{
539
515
name : "SubsetFilter, subset with no matching pods" ,
540
516
metadata : makeFilterMetadata ([]any {"10.0.0.3" }),
541
- output : []schedulingtypes. Pod {},
517
+ output : []backendmetrics. PodMetrics {},
542
518
},
543
519
}
544
520
545
- pmf := backendmetrics .NewPodMetricsFactory (& backendmetrics.FakePodMetricsClient {}, time .Second , time .Second * 2 )
546
- ds := datastore .NewDatastore (t .Context (), pmf )
547
- for _ , testPod := range testInput {
548
- ds .PodUpdateOrAddIfNotExist (testPod )
549
- }
550
-
521
+ ds := & mockDatastore {pods : testInput }
551
522
for _ , test := range tests {
552
523
t .Run (test .name , func (t * testing.T ) {
553
524
director := NewDirectorWithConfig (ds , & mockScheduler {}, & mockSaturationDetector {}, NewConfig ())
554
525
555
526
got := director .getCandidatePodsForScheduling (context .Background (), test .metadata )
556
527
557
- diff := cmp .Diff (test .output , got , cmpopts .SortSlices (func (a , b schedulingtypes. Pod ) bool {
528
+ diff := cmp .Diff (test .output , got , cmpopts .SortSlices (func (a , b backendmetrics. PodMetrics ) bool {
558
529
return a .GetPod ().NamespacedName .String () < b .GetPod ().NamespacedName .String ()
559
530
}))
560
531
if diff != "" {
@@ -578,8 +549,8 @@ func TestRandomWeightedDraw(t *testing.T) {
578
549
model : & v1alpha2.InferenceObjective {
579
550
Spec : v1alpha2.InferenceObjectiveSpec {
580
551
TargetModels : []v1alpha2.TargetModel {
581
- {Name : "canary" , Weight : pointer ( 50 )},
582
- {Name : "v1" , Weight : pointer ( 50 )},
552
+ {Name : "canary" , Weight : ptr . To ( int32 ( 50 ) )},
553
+ {Name : "v1" , Weight : ptr . To ( int32 ( 50 ) )},
583
554
},
584
555
},
585
556
},
@@ -590,9 +561,9 @@ func TestRandomWeightedDraw(t *testing.T) {
590
561
model : & v1alpha2.InferenceObjective {
591
562
Spec : v1alpha2.InferenceObjectiveSpec {
592
563
TargetModels : []v1alpha2.TargetModel {
593
- {Name : "canary" , Weight : pointer ( 25 )},
594
- {Name : "v1.1" , Weight : pointer ( 55 )},
595
- {Name : "v1" , Weight : pointer ( 50 )},
564
+ {Name : "canary" , Weight : ptr . To ( int32 ( 25 ) )},
565
+ {Name : "v1.1" , Weight : ptr . To ( int32 ( 55 ) )},
566
+ {Name : "v1" , Weight : ptr . To ( int32 ( 50 ) )},
596
567
},
597
568
},
598
569
},
@@ -603,9 +574,9 @@ func TestRandomWeightedDraw(t *testing.T) {
603
574
model : & v1alpha2.InferenceObjective {
604
575
Spec : v1alpha2.InferenceObjectiveSpec {
605
576
TargetModels : []v1alpha2.TargetModel {
606
- {Name : "canary" , Weight : pointer ( 20 )},
607
- {Name : "v1.1" , Weight : pointer ( 20 )},
608
- {Name : "v1" , Weight : pointer ( 10 )},
577
+ {Name : "canary" , Weight : ptr . To ( int32 ( 20 ) )},
578
+ {Name : "v1.1" , Weight : ptr . To ( int32 ( 20 ) )},
579
+ {Name : "v1" , Weight : ptr . To ( int32 ( 10 ) )},
609
580
},
610
581
},
611
582
},
@@ -683,10 +654,6 @@ func TestGetRandomPod(t *testing.T) {
683
654
}
684
655
}
685
656
686
- func pointer (v int32 ) * int32 {
687
- return & v
688
- }
689
-
690
657
func TestDirector_HandleResponse (t * testing.T ) {
691
658
pr1 := newTestPostResponse ("pr1" )
692
659
0 commit comments