Skip to content

Commit 71b95e6

Browse files
committed
add filter test TestLoRASoftAffinityDistribution
1 parent be3ce8b commit 71b95e6

File tree

1 file changed

+84
-0
lines changed

1 file changed

+84
-0
lines changed

pkg/epp/scheduling/filter_test.go

+84
Original file line numberDiff line numberDiff line change
@@ -429,3 +429,87 @@ func TestFilterFunc(t *testing.T) {
429429
})
430430
}
431431
}
432+
433+
// TestLoRASoftAffinityDistribution tests that the loRASoftAffinityFilter function
434+
// properly distributes requests according to the loraAffinityThreshold
435+
func TestLoRASoftAffinityDistribution(t *testing.T) {
436+
logger := logutil.NewTestLogger()
437+
438+
const (
439+
testModelName = "test-model"
440+
testAffinityModel = "test-affinity-model"
441+
numIterations = 10000
442+
tolerancePercent = 5.0 // Allow 5% tolerance from expected distribution
443+
)
444+
445+
// Create a test request and pods
446+
req := &LLMRequest{
447+
Model: testAffinityModel,
448+
ResolvedTargetModel: testAffinityModel,
449+
}
450+
451+
// Test setup: One affinity pod and one available pod
452+
pods := []*datastore.PodMetrics{
453+
{
454+
Pod: datastore.Pod{NamespacedName: types.NamespacedName{Name: "affinity-pod"}},
455+
Metrics: datastore.Metrics{
456+
MaxActiveModels: 2,
457+
ActiveModels: map[string]int{
458+
testAffinityModel: 1,
459+
},
460+
},
461+
},
462+
{
463+
Pod: datastore.Pod{NamespacedName: types.NamespacedName{Name: "available-pod"}},
464+
Metrics: datastore.Metrics{
465+
MaxActiveModels: 2,
466+
ActiveModels: map[string]int{},
467+
},
468+
},
469+
}
470+
471+
// Run the filter function multiple times and count the results
472+
affinityCount := 0
473+
availableCount := 0
474+
475+
// Use the actual loraAffinityThreshold as defined in the original code
476+
// This test should work with whatever value is set there
477+
expectedAffinityPercent := loraAffinityThreshold * 100
478+
479+
for i := 0; i < numIterations; i++ {
480+
result, err := loRASoftAffinityFilter(logger, req, pods)
481+
if err != nil {
482+
t.Fatalf("Unexpected error: %v", err)
483+
}
484+
485+
// Check which type of pod was returned
486+
if len(result) != 1 {
487+
t.Fatalf("Expected exactly one pod in result, got %d", len(result))
488+
}
489+
490+
// Identify if the returned pod is the affinity pod or available pod
491+
if _, exists := result[0].ActiveModels[testAffinityModel]; exists {
492+
affinityCount++
493+
} else {
494+
availableCount++
495+
}
496+
}
497+
498+
// Calculate the actual percentages
499+
actualAffinityPercent := float64(affinityCount) / float64(numIterations) * 100
500+
actualAvailablePercent := float64(availableCount) / float64(numIterations) * 100
501+
502+
// Check if the distribution matches expected threshold within tolerance
503+
affinityLowerBound := expectedAffinityPercent - tolerancePercent
504+
affinityUpperBound := expectedAffinityPercent + tolerancePercent
505+
506+
t.Logf("Distribution results over %d iterations:", numIterations)
507+
t.Logf("Expected affinity percent: %.2f%% (threshold: %.2f)", expectedAffinityPercent, loraAffinityThreshold)
508+
t.Logf("Actual affinity percent: %.2f%% (%d out of %d)", actualAffinityPercent, affinityCount, numIterations)
509+
t.Logf("Actual available percent: %.2f%% (%d out of %d)", actualAvailablePercent, availableCount, numIterations)
510+
511+
if actualAffinityPercent < affinityLowerBound || actualAffinityPercent > affinityUpperBound {
512+
t.Errorf("Affinity selection percent %.2f%% outside expected range %.2f%% to %.2f%%",
513+
actualAffinityPercent, affinityLowerBound, affinityUpperBound)
514+
}
515+
}

0 commit comments

Comments
 (0)