@@ -18,11 +18,14 @@ package capacityscheduling
18
18
19
19
import (
20
20
"context"
21
+ "reflect"
21
22
"sort"
22
23
"testing"
23
24
25
+ "k8s.io/apimachinery/pkg/util/sets"
26
+
24
27
gocmp "github.com/google/go-cmp/cmp"
25
- "k8s.io/api/core/v1"
28
+ v1 "k8s.io/api/core/v1"
26
29
"k8s.io/apimachinery/pkg/api/resource"
27
30
apiruntime "k8s.io/apimachinery/pkg/runtime"
28
31
"k8s.io/apimachinery/pkg/util/wait"
@@ -40,6 +43,8 @@ import (
40
43
st "k8s.io/kubernetes/pkg/scheduler/testing"
41
44
imageutils "k8s.io/kubernetes/test/utils/image"
42
45
46
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
47
+ "sigs.k8s.io/scheduler-plugins/apis/scheduling/v1alpha1"
43
48
testutil "sigs.k8s.io/scheduler-plugins/test/util"
44
49
)
45
50
@@ -370,6 +375,155 @@ func TestDryRunPreemption(t *testing.T) {
370
375
}
371
376
}
372
377
378
+ func TestAddElasticQuota (t * testing.T ) {
379
+ tests := []struct {
380
+ name string
381
+ ns []string
382
+ elasticQuotas []interface {}
383
+ expected map [string ]* ElasticQuotaInfo
384
+ }{
385
+ {
386
+ name : "Add ElasticQuota" ,
387
+ elasticQuotas : []interface {}{
388
+ makeEQ ("ns1" , "t1-eq1" , makeResourceList (100 , 1000 ), makeResourceList (10 , 100 )),
389
+ },
390
+ ns : []string {"ns1" },
391
+ expected : map [string ]* ElasticQuotaInfo {
392
+ "ns1" : {
393
+ Namespace : "ns1" ,
394
+ pods : sets.String {},
395
+ Max : & framework.Resource {
396
+ MilliCPU : 100 ,
397
+ Memory : 1000 ,
398
+ },
399
+ Min : & framework.Resource {
400
+ MilliCPU : 10 ,
401
+ Memory : 100 ,
402
+ },
403
+ Used : & framework.Resource {
404
+ MilliCPU : 0 ,
405
+ Memory : 0 ,
406
+ },
407
+ },
408
+ },
409
+ },
410
+ {
411
+ name : "Add ElasticQuota without Max" ,
412
+ elasticQuotas : []interface {}{
413
+ makeEQ ("ns1" , "t1-eq1" , nil , makeResourceList (10 , 100 )),
414
+ },
415
+ ns : []string {"ns1" },
416
+ expected : map [string ]* ElasticQuotaInfo {
417
+ "ns1" : {
418
+ Namespace : "ns1" ,
419
+ pods : sets.String {},
420
+ Max : & framework.Resource {
421
+ MilliCPU : UpperBoundOfMax ,
422
+ Memory : UpperBoundOfMax ,
423
+ EphemeralStorage : UpperBoundOfMax ,
424
+ },
425
+ Min : & framework.Resource {
426
+ MilliCPU : 10 ,
427
+ Memory : 100 ,
428
+ },
429
+ Used : & framework.Resource {
430
+ MilliCPU : 0 ,
431
+ Memory : 0 ,
432
+ },
433
+ },
434
+ },
435
+ },
436
+ {
437
+ name : "Add ElasticQuota without Min" ,
438
+ elasticQuotas : []interface {}{
439
+ makeEQ ("ns1" , "t1-eq1" , makeResourceList (100 , 1000 ), nil ),
440
+ },
441
+ ns : []string {"ns1" },
442
+ expected : map [string ]* ElasticQuotaInfo {
443
+ "ns1" : {
444
+ Namespace : "ns1" ,
445
+ pods : sets.String {},
446
+ Max : & framework.Resource {
447
+ MilliCPU : 100 ,
448
+ Memory : 1000 ,
449
+ },
450
+ Min : & framework.Resource {
451
+ MilliCPU : LowerBoundOfMin ,
452
+ Memory : LowerBoundOfMin ,
453
+ EphemeralStorage : LowerBoundOfMin ,
454
+ },
455
+ Used : & framework.Resource {
456
+ MilliCPU : 0 ,
457
+ Memory : 0 ,
458
+ },
459
+ },
460
+ },
461
+ },
462
+ {
463
+ name : "Add ElasticQuota without Max and Min" ,
464
+ elasticQuotas : []interface {}{
465
+ makeEQ ("ns1" , "t1-eq1" , nil , nil ),
466
+ },
467
+ ns : []string {"ns1" },
468
+ expected : map [string ]* ElasticQuotaInfo {
469
+ "ns1" : {
470
+ Namespace : "ns1" ,
471
+ pods : sets.String {},
472
+ Max : & framework.Resource {
473
+ MilliCPU : UpperBoundOfMax ,
474
+ Memory : UpperBoundOfMax ,
475
+ EphemeralStorage : UpperBoundOfMax ,
476
+ },
477
+ Min : & framework.Resource {
478
+ MilliCPU : LowerBoundOfMin ,
479
+ Memory : LowerBoundOfMin ,
480
+ EphemeralStorage : LowerBoundOfMin ,
481
+ },
482
+ Used : & framework.Resource {
483
+ MilliCPU : 0 ,
484
+ Memory : 0 ,
485
+ },
486
+ },
487
+ },
488
+ },
489
+ }
490
+ for _ , tt := range tests {
491
+ t .Run (tt .name , func (t * testing.T ) {
492
+ var registerPlugins []st.RegisterPluginFunc
493
+ registeredPlugins := append (
494
+ registerPlugins ,
495
+ st .RegisterQueueSortPlugin (queuesort .Name , queuesort .New ),
496
+ st .RegisterBindPlugin (defaultbinder .Name , defaultbinder .New ),
497
+ )
498
+
499
+ fwk , err := st .NewFramework (
500
+ registeredPlugins , "" , wait .NeverStop ,
501
+ frameworkruntime .WithPodNominator (testutil .NewPodNominator (nil )),
502
+ frameworkruntime .WithSnapshotSharedLister (testutil .NewFakeSharedLister (make ([]* v1.Pod , 0 ), make ([]* v1.Node , 0 ))),
503
+ )
504
+
505
+ if err != nil {
506
+ t .Fatal (err )
507
+ }
508
+
509
+ cs := & CapacityScheduling {
510
+ elasticQuotaInfos : map [string ]* ElasticQuotaInfo {},
511
+ fh : fwk ,
512
+ }
513
+
514
+ for _ , elasticQuota := range tt .elasticQuotas {
515
+ cs .addElasticQuota (elasticQuota )
516
+ }
517
+
518
+ for _ , ns := range tt .ns {
519
+ if got := cs .elasticQuotaInfos [ns ]; ! reflect .DeepEqual (got , tt .expected [ns ]) {
520
+ t .Errorf ("expected %v, got %v" , tt .expected [ns ], got )
521
+ }
522
+ }
523
+ })
524
+ }
525
+ }
526
+
373
527
func makePod (podName string , namespace string , memReq int64 , cpuReq int64 , gpuReq int64 , priority int32 , uid string , nodeName string ) * v1.Pod {
374
528
pause := imageutils .GetPauseImageName ()
375
529
pod := st .MakePod ().Namespace (namespace ).Name (podName ).Container (pause ).
@@ -383,3 +537,23 @@ func makePod(podName string, namespace string, memReq int64, cpuReq int64, gpuRe
383
537
}
384
538
return pod
385
539
}
540
+
541
+ func makeEQ (namespace , name string , max , min v1.ResourceList ) * v1alpha1.ElasticQuota {
542
+ eq := & v1alpha1.ElasticQuota {
543
+ TypeMeta : metav1.TypeMeta {Kind : "ElasticQuota" , APIVersion : "scheduling.sigs.k8s.io/v1alpha1" },
544
+ ObjectMeta : metav1.ObjectMeta {
545
+ Name : name ,
546
+ Namespace : namespace ,
547
+ },
548
+ }
549
+ eq .Spec .Max = max
550
+ eq .Spec .Min = min
551
+ return eq
552
+ }
553
+
554
+ func makeResourceList (cpu , mem int64 ) v1.ResourceList {
555
+ return v1.ResourceList {
556
+ v1 .ResourceCPU : * resource .NewMilliQuantity (cpu , resource .DecimalSI ),
557
+ v1 .ResourceMemory : * resource .NewQuantity (mem , resource .BinarySI ),
558
+ }
559
+ }
0 commit comments