@@ -14,122 +14,82 @@ See the License for the specific language governing permissions and
1414limitations under the License.
1515*/
1616
17- package picker_test
17+ package picker
1818
1919import (
2020 "context"
2121 "testing"
2222
2323 "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/backend"
24- "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling/framework/plugins/picker"
2524 "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling/types"
2625
2726 k8stypes "k8s.io/apimachinery/pkg/types"
2827)
2928
30- // Picks the pod with the highest unique score.
31- func TestPickMaxScorePicker_SingleMax (t * testing.T ) {
32- p := picker .NewMaxScorePicker ()
33- ctx := context .Background ()
34-
35- scoredPods := []* types.ScoredPod {
29+ func TestPickMaxScorePicker (t * testing.T ) {
30+ tests := []struct {
31+ name string
32+ scoredPods []* types.ScoredPod
33+ wantNames []string
34+ shouldPanic bool
35+ }{
3636 {
37- Pod : & types.PodMetrics {
38- Pod : & backend.Pod {
39- NamespacedName : k8stypes.NamespacedName {Name : "pod1" },
40- },
37+ name : "Single max score" ,
38+ scoredPods : []* types.ScoredPod {
39+ {Pod : & types.PodMetrics {Pod : & backend.Pod {NamespacedName : k8stypes.NamespacedName {Name : "pod1" }}}, Score : 10 },
40+ {Pod : & types.PodMetrics {Pod : & backend.Pod {NamespacedName : k8stypes.NamespacedName {Name : "pod2" }}}, Score : 25 },
41+ {Pod : & types.PodMetrics {Pod : & backend.Pod {NamespacedName : k8stypes.NamespacedName {Name : "pod3" }}}, Score : 15 },
4142 },
42- Score : 10 ,
43+ wantNames : [] string { "pod2" } ,
4344 },
4445 {
45- Pod : & types.PodMetrics {
46- Pod : & backend.Pod {
47- NamespacedName : k8stypes.NamespacedName {Name : "pod2" },
48- },
46+ name : "Multiple max scores" ,
47+ scoredPods : []* types.ScoredPod {
48+ {Pod : & types.PodMetrics {Pod : & backend.Pod {NamespacedName : k8stypes.NamespacedName {Name : "podA" }}}, Score : 50 },
49+ {Pod : & types.PodMetrics {Pod : & backend.Pod {NamespacedName : k8stypes.NamespacedName {Name : "podB" }}}, Score : 50 },
50+ {Pod : & types.PodMetrics {Pod : & backend.Pod {NamespacedName : k8stypes.NamespacedName {Name : "podC" }}}, Score : 30 },
4951 },
50- Score : 25 ,
52+ wantNames : [] string { "podA" , "podB" } ,
5153 },
5254 {
53- Pod : & types.PodMetrics {
54- Pod : & backend.Pod {
55- NamespacedName : k8stypes.NamespacedName {Name : "pod3" },
56- },
57- },
58- Score : 15 ,
55+ name : "Empty pod list" ,
56+ scoredPods : []* types.ScoredPod {},
57+ wantNames : nil ,
58+ shouldPanic : true ,
5959 },
6060 }
6161
62- result := p .Pick (ctx , nil , scoredPods )
63-
64- if result == nil {
65- t .Fatal ("expected a result but got nil" )
66- }
67-
68- picked := result .TargetPod .GetPod ().NamespacedName .Name
69- if picked != "pod2" {
70- t .Errorf ("expected pod2, but got %s" , picked )
71- }
72- }
73-
74- // Picks randomly when multiple pods share top score.
75- func TestPickMaxScorePicker_MultipleMax (t * testing.T ) {
76- p := picker .NewMaxScorePicker ()
77- ctx := context .Background ()
78-
79- scoredPods := []* types.ScoredPod {
80- {
81- Pod : & types.PodMetrics {
82- Pod : & backend.Pod {
83- NamespacedName : k8stypes.NamespacedName {Name : "podA" },
84- },
85- },
86- Score : 50 ,
87- },
88- {
89- Pod : & types.PodMetrics {
90- Pod : & backend.Pod {
91- NamespacedName : k8stypes.NamespacedName {Name : "podB" },
92- },
93- },
94- Score : 50 ,
95- },
96- {
97- Pod : & types.PodMetrics {
98- Pod : & backend.Pod {
99- NamespacedName : k8stypes.NamespacedName {Name : "podC" },
100- },
101- },
102- Score : 30 ,
103- },
104- }
105-
106- result := p .Pick (ctx , nil , scoredPods )
107-
108- if result == nil {
109- t .Fatal ("expected a result but got nil" )
110- }
111-
112- picked := result .TargetPod .GetPod ().NamespacedName .Name
113- if picked != "podA" && picked != "podB" {
114- t .Errorf ("expected podA or podB, but got %s" , picked )
115- }
116- }
117-
118- // Returns nil or panics on empty pod list.
119- func TestPickMaxScorePicker_EmptyList (t * testing.T ) {
120- defer func () {
121- if r := recover (); r != nil {
122- t .Logf ("plugin panicked as expected for empty input: %v" , r )
123- }
124- }()
125-
126- p := picker .NewMaxScorePicker ()
127- ctx := context .Background ()
128-
129- var scoredPods []* types.ScoredPod
130-
131- result := p .Pick (ctx , nil , scoredPods )
132- if result != nil {
133- t .Errorf ("expected nil result for empty input, got %+v" , result )
62+ for _ , tt := range tests {
63+ t .Run (tt .name , func (t * testing.T ) {
64+ if tt .shouldPanic {
65+ defer func () {
66+ if r := recover (); r == nil {
67+ t .Errorf ("expected panic but did not get one" )
68+ }
69+ }()
70+ }
71+
72+ p := NewMaxScorePicker ()
73+ result := p .Pick (context .Background (), nil , tt .scoredPods )
74+
75+ if len (tt .scoredPods ) == 0 && result != nil {
76+ t .Errorf ("expected nil result for empty input, got %+v" , result )
77+ return
78+ }
79+
80+ if result != nil {
81+ got := result .TargetPod .GetPod ().NamespacedName .Name
82+ match := false
83+ for _ , want := range tt .wantNames {
84+ if got == want {
85+ match = true
86+ break
87+ }
88+ }
89+ if ! match {
90+ t .Errorf ("got %q, want one of %v" , got , tt .wantNames )
91+ }
92+ }
93+ })
13494 }
13595}
0 commit comments