@@ -25,6 +25,7 @@ import (
25
25
"testing"
26
26
27
27
"github.com/moby/sys/userns"
28
+ "github.com/opencontainers/runtime-spec/specs-go"
28
29
"gotest.tools/v3/assert"
29
30
30
31
"github.com/containerd/cgroups/v3"
@@ -421,3 +422,124 @@ func TestRunBlkioWeightCgroupV2(t *testing.T) {
421
422
base .Cmd ("update" , containerName , "--blkio-weight" , "400" ).AssertOK ()
422
423
base .Cmd ("exec" , containerName , "cat" , "io.bfq.weight" ).AssertOutExactly ("default 400\n " )
423
424
}
425
+
426
+ func TestRunBlkioSettingCgroupV2 (t * testing.T ) {
427
+ t .Parallel ()
428
+ testutil .DockerIncompatible (t )
429
+ if cgroups .Mode () != cgroups .Unified {
430
+ t .Skip ("test requires cgroup v2" )
431
+ }
432
+
433
+ // TODO: Fix logic to check if bfq is set as the scheduler for the block device
434
+ //
435
+ // if _, err := os.Stat("/sys/module/bfq"); err != nil {
436
+ // t.Skipf("test requires \"bfq\" module to be loaded: %v", err)
437
+ // }
438
+
439
+ base := testutil .NewBase (t )
440
+ info := base .Info ()
441
+ switch info .CgroupDriver {
442
+ case "none" , "" :
443
+ t .Skip ("test requires cgroup driver" )
444
+ }
445
+
446
+ tests := []struct {
447
+ name string
448
+ args []string
449
+ validate func (t * testing.T , blockIO * specs.LinuxBlockIO )
450
+ }{
451
+ {
452
+ name : "blkio-weight" ,
453
+ args : []string {"--blkio-weight" , "150" },
454
+ validate : func (t * testing.T , blockIO * specs.LinuxBlockIO ) {
455
+ assert .Equal (t , uint16 (150 ), * blockIO .Weight )
456
+ },
457
+ },
458
+ {
459
+ name : "blkio-weight-device" ,
460
+ args : []string {"--blkio-weight-device" , "/dev/sda:100" },
461
+ validate : func (t * testing.T , blockIO * specs.LinuxBlockIO ) {
462
+ assert .Equal (t , 1 , len (blockIO .WeightDevice ))
463
+ assert .Equal (t , uint16 (100 ), * blockIO .WeightDevice [0 ].Weight )
464
+ },
465
+ },
466
+ {
467
+ name : "device-read-bps" ,
468
+ args : []string {"--device-read-bps" , "/dev/sda:1048576" },
469
+ validate : func (t * testing.T , blockIO * specs.LinuxBlockIO ) {
470
+ assert .Equal (t , 1 , len (blockIO .ThrottleReadBpsDevice ))
471
+ assert .Equal (t , uint64 (1048576 ), blockIO .ThrottleReadBpsDevice [0 ].Rate )
472
+ },
473
+ },
474
+ {
475
+ name : "device-write-bps" ,
476
+ args : []string {"--device-write-bps" , "/dev/sda:2097152" },
477
+ validate : func (t * testing.T , blockIO * specs.LinuxBlockIO ) {
478
+ assert .Equal (t , 1 , len (blockIO .ThrottleWriteBpsDevice ))
479
+ assert .Equal (t , uint64 (2097152 ), blockIO .ThrottleWriteBpsDevice [0 ].Rate )
480
+ },
481
+ },
482
+ {
483
+ name : "device-read-iops" ,
484
+ args : []string {"--device-read-iops" , "/dev/sda:1000" },
485
+ validate : func (t * testing.T , blockIO * specs.LinuxBlockIO ) {
486
+ assert .Equal (t , 1 , len (blockIO .ThrottleReadIOPSDevice ))
487
+ assert .Equal (t , uint64 (1000 ), blockIO .ThrottleReadIOPSDevice [0 ].Rate )
488
+ },
489
+ },
490
+ {
491
+ name : "device-write-iops" ,
492
+ args : []string {"--device-write-iops" , "/dev/sda:2000" },
493
+ validate : func (t * testing.T , blockIO * specs.LinuxBlockIO ) {
494
+ assert .Equal (t , 1 , len (blockIO .ThrottleWriteIOPSDevice ))
495
+ assert .Equal (t , uint64 (2000 ), blockIO .ThrottleWriteIOPSDevice [0 ].Rate )
496
+ },
497
+ },
498
+ }
499
+
500
+ for _ , tt := range tests {
501
+ tt := tt // capture range variable
502
+ t .Run (tt .name , func (t * testing.T ) {
503
+ t .Parallel ()
504
+ containerName := testutil .Identifier (t )
505
+
506
+ args := []string {"run" , "-d" , "--name" , containerName }
507
+ args = append (args , tt .args ... )
508
+ args = append (args , testutil .AlpineImage , "sleep" , "infinity" )
509
+ base .Cmd (args ... ).AssertOK ()
510
+ t .Cleanup (func () {
511
+ base .Cmd ("rm" , "-f" , containerName ).Run ()
512
+ })
513
+
514
+ // Connect to containerd
515
+ addr := base .ContainerdAddress ()
516
+ client , err := containerd .New (addr , containerd .WithDefaultNamespace (testutil .Namespace ))
517
+ assert .NilError (t , err )
518
+ ctx := context .Background ()
519
+
520
+ // Get container ID
521
+ var cid string
522
+ walker := & containerwalker.ContainerWalker {
523
+ Client : client ,
524
+ OnFound : func (ctx context.Context , found containerwalker.Found ) error {
525
+ if found .MatchCount > 1 {
526
+ return fmt .Errorf ("multiple IDs found with provided prefix: %s" , found .Req )
527
+ }
528
+ cid = found .Container .ID ()
529
+ return nil
530
+ },
531
+ }
532
+ err = walker .WalkAll (ctx , []string {containerName }, true )
533
+ assert .NilError (t , err )
534
+
535
+ // Get container spec
536
+ container , err := client .LoadContainer (ctx , cid )
537
+ assert .NilError (t , err )
538
+ spec , err := container .Spec (ctx )
539
+ assert .NilError (t , err )
540
+
541
+ // Run the validation function
542
+ tt .validate (t , spec .Linux .Resources .BlockIO )
543
+ })
544
+ }
545
+ }
0 commit comments