Skip to content

Commit da4bd4b

Browse files
committed
test: fix VA fixtures for maxReplicas validation and add CRD field tests for minReplicas, maxReplicas, and behavior
Signed-off-by: Vivek Karunai Kiri Ragavan <vkarunai@redhat.com>
1 parent 79a0a80 commit da4bd4b

6 files changed

Lines changed: 185 additions & 23 deletions

File tree

api/v1alpha1/variantautoscaling_types_test.go

Lines changed: 144 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
autoscalingv2 "k8s.io/api/autoscaling/v2"
1010
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1111
"k8s.io/apimachinery/pkg/runtime"
12+
"k8s.io/utils/ptr"
1213
)
1314

1415
// helper: build a valid VariantAutoscaling object
@@ -31,7 +32,8 @@ func makeValidVA() *VariantAutoscaling {
3132
Kind: "Deployment",
3233
Name: "va-sample-deployment",
3334
},
34-
ModelID: "model-123",
35+
ModelID: "model-123",
36+
MaxReplicas: 10,
3537
},
3638
Status: VariantAutoscalingStatus{
3739
// CurrentAlloc: Allocation{...} -- Removed
@@ -218,3 +220,144 @@ func jsonContainsKey(b []byte, key string) bool {
218220
_, ok := m[key]
219221
return ok
220222
}
223+
224+
func TestMinMaxReplicasJSON(t *testing.T) {
225+
minVal := int32(2)
226+
va := &VariantAutoscaling{
227+
ObjectMeta: metav1.ObjectMeta{Name: "va-replicas", Namespace: "default"},
228+
Spec: VariantAutoscalingSpec{
229+
ScaleTargetRef: autoscalingv2.CrossVersionObjectReference{
230+
Kind: "Deployment",
231+
Name: "my-deploy",
232+
},
233+
ModelID: "model-x",
234+
MinReplicas: &minVal,
235+
MaxReplicas: 5,
236+
},
237+
}
238+
239+
b, err := json.Marshal(va)
240+
if err != nil {
241+
t.Fatalf("marshal failed: %v", err)
242+
}
243+
244+
var probe struct {
245+
Spec struct {
246+
MinReplicas *int32 `json:"minReplicas"`
247+
MaxReplicas int32 `json:"maxReplicas"`
248+
} `json:"spec"`
249+
}
250+
if err := json.Unmarshal(b, &probe); err != nil {
251+
t.Fatalf("unmarshal failed: %v", err)
252+
}
253+
if probe.Spec.MinReplicas == nil || *probe.Spec.MinReplicas != 2 {
254+
t.Errorf("expected minReplicas=2, got %v", probe.Spec.MinReplicas)
255+
}
256+
if probe.Spec.MaxReplicas != 5 {
257+
t.Errorf("expected maxReplicas=5, got %d", probe.Spec.MaxReplicas)
258+
}
259+
260+
// minReplicas must be absent from JSON when nil (omitempty)
261+
vaNoMin := &VariantAutoscaling{
262+
ObjectMeta: metav1.ObjectMeta{Name: "va-no-min", Namespace: "default"},
263+
Spec: VariantAutoscalingSpec{
264+
ScaleTargetRef: autoscalingv2.CrossVersionObjectReference{
265+
Kind: "Deployment",
266+
Name: "my-deploy",
267+
},
268+
ModelID: "model-x",
269+
MaxReplicas: 5,
270+
},
271+
}
272+
b2, err := json.Marshal(vaNoMin)
273+
if err != nil {
274+
t.Fatalf("marshal failed: %v", err)
275+
}
276+
var probeSpec struct {
277+
Spec map[string]any `json:"spec"`
278+
}
279+
if err := json.Unmarshal(b2, &probeSpec); err != nil {
280+
t.Fatalf("unmarshal failed: %v", err)
281+
}
282+
if _, ok := probeSpec.Spec["minReplicas"]; ok {
283+
t.Errorf("expected minReplicas to be absent when nil, but it was present")
284+
}
285+
}
286+
287+
func TestBehaviorOmitEmpty(t *testing.T) {
288+
va := makeValidVA()
289+
// behavior should be absent when nil
290+
b, err := json.Marshal(va)
291+
if err != nil {
292+
t.Fatalf("marshal failed: %v", err)
293+
}
294+
var probeSpec struct {
295+
Spec map[string]any `json:"spec"`
296+
}
297+
if err := json.Unmarshal(b, &probeSpec); err != nil {
298+
t.Fatalf("unmarshal failed: %v", err)
299+
}
300+
if _, ok := probeSpec.Spec["behavior"]; ok {
301+
t.Errorf("expected behavior to be absent when nil, but it was present")
302+
}
303+
}
304+
305+
func TestBehaviorJSONRoundTrip(t *testing.T) {
306+
va := makeValidVA()
307+
va.Spec.Behavior = &autoscalingv2.HorizontalPodAutoscalerBehavior{
308+
ScaleUp: &autoscalingv2.HPAScalingRules{
309+
StabilizationWindowSeconds: ptr.To(int32(0)),
310+
Policies: []autoscalingv2.HPAScalingPolicy{
311+
{
312+
Type: autoscalingv2.PodsScalingPolicy,
313+
Value: 4,
314+
PeriodSeconds: 60,
315+
},
316+
},
317+
},
318+
ScaleDown: &autoscalingv2.HPAScalingRules{
319+
StabilizationWindowSeconds: ptr.To(int32(300)),
320+
Policies: []autoscalingv2.HPAScalingPolicy{
321+
{
322+
Type: autoscalingv2.PercentScalingPolicy,
323+
Value: 10,
324+
PeriodSeconds: 60,
325+
},
326+
},
327+
},
328+
}
329+
330+
b, err := json.Marshal(va)
331+
if err != nil {
332+
t.Fatalf("marshal failed: %v", err)
333+
}
334+
335+
var back VariantAutoscaling
336+
if err := json.Unmarshal(b, &back); err != nil {
337+
t.Fatalf("unmarshal failed: %v", err)
338+
}
339+
340+
if back.Spec.Behavior == nil {
341+
t.Fatal("expected behavior to be present after round-trip")
342+
}
343+
if back.Spec.Behavior.ScaleUp == nil {
344+
t.Fatal("expected scaleUp to be present after round-trip")
345+
}
346+
if *back.Spec.Behavior.ScaleUp.StabilizationWindowSeconds != 0 {
347+
t.Errorf("expected scaleUp.stabilizationWindowSeconds=0, got %d",
348+
*back.Spec.Behavior.ScaleUp.StabilizationWindowSeconds)
349+
}
350+
if len(back.Spec.Behavior.ScaleUp.Policies) != 1 {
351+
t.Fatalf("expected 1 scaleUp policy, got %d", len(back.Spec.Behavior.ScaleUp.Policies))
352+
}
353+
if back.Spec.Behavior.ScaleUp.Policies[0].Value != 4 {
354+
t.Errorf("expected scaleUp policy value=4, got %d", back.Spec.Behavior.ScaleUp.Policies[0].Value)
355+
}
356+
if back.Spec.Behavior.ScaleDown == nil {
357+
t.Fatal("expected scaleDown to be present after round-trip")
358+
}
359+
if *back.Spec.Behavior.ScaleDown.StabilizationWindowSeconds != 300 {
360+
t.Errorf("expected scaleDown.stabilizationWindowSeconds=300, got %d",
361+
*back.Spec.Behavior.ScaleDown.StabilizationWindowSeconds)
362+
}
363+
}

internal/actuator/actuator_test.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ var _ = Describe("Actuator", func() {
122122
Kind: "Deployment",
123123
Name: resourceName,
124124
},
125+
MaxReplicas: 10,
125126
},
126127
}
127128

@@ -213,7 +214,8 @@ var _ = Describe("Actuator", func() {
213214
Kind: "Deployment",
214215
Name: contextResourceName,
215216
},
216-
ModelID: "test-model/variant-1",
217+
ModelID: "test-model/variant-1",
218+
MaxReplicas: 10,
217219
},
218220
Status: llmdVariantAutoscalingV1alpha1.VariantAutoscalingStatus{
219221
DesiredOptimizedAlloc: llmdVariantAutoscalingV1alpha1.OptimizedAlloc{
@@ -331,7 +333,8 @@ var _ = Describe("Actuator", func() {
331333
Kind: "Deployment",
332334
Name: contextResourceName,
333335
},
334-
ModelID: "test-model/metrics-test",
336+
ModelID: "test-model/metrics-test",
337+
MaxReplicas: 10,
335338
},
336339
Status: llmdVariantAutoscalingV1alpha1.VariantAutoscalingStatus{
337340
DesiredOptimizedAlloc: llmdVariantAutoscalingV1alpha1.OptimizedAlloc{
@@ -391,7 +394,8 @@ var _ = Describe("Actuator", func() {
391394
Kind: "Deployment",
392395
Name: "incomplete-va",
393396
},
394-
ModelID: "test-model/incomplete",
397+
ModelID: "test-model/incomplete",
398+
MaxReplicas: 10,
395399
},
396400
Status: llmdVariantAutoscalingV1alpha1.VariantAutoscalingStatus{
397401
// DesiredOptimizedAlloc.NumReplicas will be 0 by default
@@ -460,7 +464,8 @@ var _ = Describe("Actuator", func() {
460464
Kind: "Deployment",
461465
Name: contextResourceName,
462466
},
463-
ModelID: "test-model/validation-test",
467+
ModelID: "test-model/validation-test",
468+
MaxReplicas: 10,
464469
},
465470
Status: llmdVariantAutoscalingV1alpha1.VariantAutoscalingStatus{
466471
DesiredOptimizedAlloc: llmdVariantAutoscalingV1alpha1.OptimizedAlloc{

internal/controller/indexers/indexers_test.go

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,8 @@ var _ = Describe("Indexers", Ordered, func() {
115115
Kind: "Deployment",
116116
Name: deploymentName,
117117
},
118-
ModelID: "model-1",
118+
ModelID: "model-1",
119+
MaxReplicas: 10,
119120
},
120121
}
121122
Expect(k8sClient.Create(testCtx, va1)).To(Succeed())
@@ -132,7 +133,8 @@ var _ = Describe("Indexers", Ordered, func() {
132133
Kind: "Deployment",
133134
Name: "other-deployment",
134135
},
135-
ModelID: "model-other",
136+
ModelID: "model-other",
137+
MaxReplicas: 10,
136138
},
137139
}
138140
Expect(k8sClient.Create(testCtx, vaOther)).To(Succeed())
@@ -187,7 +189,8 @@ var _ = Describe("Indexers", Ordered, func() {
187189
Kind: "Deployment",
188190
Name: deploymentName, // Same deployment name but different namespace
189191
},
190-
ModelID: "model-other-ns",
192+
ModelID: "model-other-ns",
193+
MaxReplicas: 10,
191194
},
192195
}
193196
Expect(k8sClient.Create(testCtx, vaOtherNs)).To(Succeed())
@@ -222,7 +225,8 @@ var _ = Describe("Indexers", Ordered, func() {
222225
Kind: "Deployment",
223226
Name: sharedName,
224227
},
225-
ModelID: "model-deploy",
228+
ModelID: "model-deploy",
229+
MaxReplicas: 10,
226230
},
227231
}
228232
Expect(k8sClient.Create(testCtx, vaDeployment)).To(Succeed())
@@ -242,7 +246,8 @@ var _ = Describe("Indexers", Ordered, func() {
242246
Kind: "StatefulSet",
243247
Name: sharedName,
244248
},
245-
ModelID: "model-sts",
249+
ModelID: "model-sts",
250+
MaxReplicas: 10,
246251
},
247252
}
248253
Expect(k8sClient.Create(testCtx, vaStatefulSet)).To(Succeed())
@@ -287,7 +292,8 @@ var _ = Describe("Indexers", Ordered, func() {
287292
Kind: "Deployment",
288293
Name: sharedName,
289294
},
290-
ModelID: "model-dup-1",
295+
ModelID: "model-dup-1",
296+
MaxReplicas: 10,
291297
},
292298
}
293299
Expect(k8sClient.Create(testCtx, va1)).To(Succeed())
@@ -306,7 +312,8 @@ var _ = Describe("Indexers", Ordered, func() {
306312
Kind: "Deployment",
307313
Name: sharedName,
308314
},
309-
ModelID: "model-dup-2",
315+
ModelID: "model-dup-2",
316+
MaxReplicas: 10,
310317
},
311318
}
312319
Expect(k8sClient.Create(testCtx, va2)).To(Succeed())
@@ -340,7 +347,8 @@ var _ = Describe("Indexers", Ordered, func() {
340347
Kind: "Deployment",
341348
Name: deploymentName,
342349
},
343-
ModelID: "model-apiversion",
350+
ModelID: "model-apiversion",
351+
MaxReplicas: 10,
344352
},
345353
}
346354
Expect(k8sClient.Create(testCtx, va)).To(Succeed())
@@ -372,7 +380,8 @@ var _ = Describe("Indexers", Ordered, func() {
372380
Kind: "Deployment",
373381
Name: deploymentName,
374382
},
375-
ModelID: "model-no-apiversion",
383+
ModelID: "model-no-apiversion",
384+
MaxReplicas: 10,
376385
},
377386
}
378387
Expect(k8sClient.Create(testCtx, va)).To(Succeed())

internal/controller/variantautoscaling_controller_test.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@ var _ = Describe("VariantAutoscalings Controller", func() {
8989
Kind: "Deployment",
9090
Name: resourceName,
9191
},
92-
// Example spec fields, adjust as necessary
93-
ModelID: "default-default",
92+
ModelID: "default-default",
93+
MaxReplicas: 10,
9494
},
9595
}
9696
Expect(k8sClient.Create(ctx, resource)).To(Succeed())
@@ -196,8 +196,8 @@ var _ = Describe("VariantAutoscalings Controller", func() {
196196
Kind: "Deployment",
197197
Name: "invalid-model-id",
198198
},
199-
ModelID: "", // Empty ModelID
200-
199+
ModelID: "", // Empty ModelID
200+
MaxReplicas: 10,
201201
},
202202
}
203203
err := k8sClient.Create(ctx, resource)
@@ -314,7 +314,8 @@ var _ = Describe("VariantAutoscalings Controller", func() {
314314
Kind: "Deployment",
315315
Name: resourceName,
316316
},
317-
ModelID: "default-default",
317+
ModelID: "default-default",
318+
MaxReplicas: 10,
318319
},
319320
}
320321
Expect(k8sClient.Create(ctx, resource)).To(Succeed())
@@ -406,7 +407,8 @@ var _ = Describe("VariantAutoscalings Controller", func() {
406407
Kind: "Deployment",
407408
Name: resourceName,
408409
},
409-
ModelID: "test-model",
410+
ModelID: "test-model",
411+
MaxReplicas: 10,
410412
},
411413
}
412414
Expect(k8sClient.Create(ctx, resource)).To(Succeed())

internal/engines/saturation/engine_test.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,8 @@ data:
149149
Kind: "Deployment",
150150
Name: name,
151151
},
152-
ModelID: modelID,
152+
ModelID: modelID,
153+
MaxReplicas: 10,
153154
},
154155
}
155156
Expect(k8sClient.Create(ctx, r)).To(Succeed())
@@ -385,7 +386,8 @@ data:
385386
Kind: "Deployment",
386387
Name: name,
387388
},
388-
ModelID: modelID,
389+
ModelID: modelID,
390+
MaxReplicas: 10,
389391
},
390392
}
391393
Expect(k8sClient.Create(ctx, r)).To(Succeed())

test/e2e/fixtures/va_builder.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,8 @@ func buildVariantAutoscaling(namespace, name, deploymentName, modelID, accelerat
111111
Kind: "Deployment",
112112
Name: deploymentName,
113113
},
114-
ModelID: modelID,
114+
ModelID: modelID,
115+
MaxReplicas: 10,
115116
VariantAutoscalingConfigSpec: variantautoscalingv1alpha1.VariantAutoscalingConfigSpec{
116117
VariantCost: fmt.Sprintf("%.1f", cost),
117118
},

0 commit comments

Comments
 (0)