@@ -491,7 +491,7 @@ def test_scheduler_deadline_too_small_runtime():
491491
492492 except subprocess .CalledProcessError as e :
493493 output = e .output .decode ('utf-8' , errors = 'ignore' ) if e .output else ''
494- if "sched_setattr: `SCHED_DEADLINE` runtime " in output and " must be between " in output :
494+ if "sched_setattr: `SCHED_DEADLINE` runtime " in output and " must be >= 1024 and < " in output :
495495 return 0 # Expected validation error
496496 logger .info ("unexpected error: %s" , output )
497497 return - 1
@@ -512,7 +512,7 @@ def test_scheduler_deadline_too_big_runtime():
512512
513513 conf ['process' ]['scheduler' ] = {
514514 'policy' : 'SCHED_DEADLINE' ,
515- 'runtime' : 9223372036854775809 ,
515+ 'runtime' : 9223372036854775809 , # 2^63 + 1
516516 'deadline' : 9223372036854775810 ,
517517 }
518518
@@ -525,7 +525,268 @@ def test_scheduler_deadline_too_big_runtime():
525525
526526 except subprocess .CalledProcessError as e :
527527 output = e .output .decode ('utf-8' , errors = 'ignore' ) if e .output else ''
528- if "sched_setattr: `SCHED_DEADLINE` runtime " in output and " must be between " in output :
528+ if "sched_setattr: `SCHED_DEADLINE` runtime " in output and " must be >= 1024 and < " in output :
529+ return 0 # Expected validation error
530+ logger .info ("unexpected error: %s" , output )
531+ return - 1
532+ except Exception as e :
533+ logger .info ("test failed: %s" , e )
534+ return - 1
535+
536+
537+ def test_scheduler_deadline_valid_upper_boundary ():
538+ """Test SCHED_DEADLINE userspace validation accepts large valid values."""
539+ if is_rootless ():
540+ return (77 , "SCHED_DEADLINE requires root" )
541+ if not is_sched_deadline_available ():
542+ return (77 , "SCHED_DEADLINE not available in kernel" )
543+
544+ conf = base_config ()
545+ add_all_namespaces (conf )
546+
547+ # Test that crun accepts large values that are clearly within the valid range
548+ # This verifies the upper bound check doesn't incorrectly reject valid values
549+ conf ['process' ]['scheduler' ] = {
550+ 'policy' : 'SCHED_DEADLINE' ,
551+ 'runtime' : 1000000000000 , # 1 second (well within range, << 2^63)
552+ 'deadline' : 2000000000000 , # 2 seconds (well within range)
553+ 'period' : 2000000000000 # 2 seconds (well within range)
554+ }
555+
556+ conf ['process' ]['args' ] = ['/init' , 'true' ]
557+
558+ try :
559+ out , _ = run_and_get_output (conf , hide_stderr = False )
560+ return 0 # Crun accepted it and kernel also accepted it
561+
562+ except subprocess .CalledProcessError as e :
563+ output = e .output .decode ('utf-8' , errors = 'ignore' ) if e .output else ''
564+ # Verify crun's range validation passed (no "must be >= 1024 and <" error)
565+ if "must be >= 1024 and <" in output :
566+ logger .info ("crun incorrectly rejected valid large value: %s" , output )
567+ return - 1
568+ # Kernel may reject for other reasons (admission control, etc.) - that's acceptable
569+ # We only care that crun's validation passed
570+ logger .info ("kernel rejected large value (acceptable): %s" , output )
571+ return 0
572+ except Exception as e :
573+ logger .info ("test failed: %s" , e )
574+ return - 1
575+
576+
577+ def test_scheduler_deadline_invalid_upper_boundary ():
578+ """Test SCHED_DEADLINE validation - runtime = 2^63 (invalid)."""
579+ if is_rootless ():
580+ return (77 , "SCHED_DEADLINE requires root" )
581+ if not is_sched_deadline_available ():
582+ return (77 , "SCHED_DEADLINE not available in kernel" )
583+
584+ conf = base_config ()
585+ add_all_namespaces (conf )
586+
587+ # Test the exact boundary: 2^63 should be rejected
588+ conf ['process' ]['scheduler' ] = {
589+ 'policy' : 'SCHED_DEADLINE' ,
590+ 'runtime' : 9223372036854775808 , # 2^63 (invalid, must be < 2^63)
591+ 'deadline' : 9223372036854775808 , # 2^63
592+ }
593+
594+ conf ['process' ]['args' ] = ['/init' , 'true' ]
595+
596+ try :
597+ out , _ = run_and_get_output (conf , hide_stderr = False )
598+ # Should have failed due to runtime >= 2^63
599+ return - 1
600+
601+ except subprocess .CalledProcessError as e :
602+ output = e .output .decode ('utf-8' , errors = 'ignore' ) if e .output else ''
603+ if "sched_setattr: `SCHED_DEADLINE` runtime " in output and " must be >= 1024 and < " in output :
604+ return 0 # Expected validation error for value >= 2^63
605+ logger .info ("unexpected error: %s" , output )
606+ return - 1
607+ except Exception as e :
608+ logger .info ("test failed: %s" , e )
609+ return - 1
610+
611+
612+ def test_scheduler_deadline_period_invalid_upper_boundary ():
613+ """Test SCHED_DEADLINE validation - period = 2^63 (invalid)."""
614+ if is_rootless ():
615+ return (77 , "SCHED_DEADLINE requires root" )
616+ if not is_sched_deadline_available ():
617+ return (77 , "SCHED_DEADLINE not available in kernel" )
618+
619+ conf = base_config ()
620+ add_all_namespaces (conf )
621+
622+ # Test the exact boundary for period: 2^63 should be rejected
623+ conf ['process' ]['scheduler' ] = {
624+ 'policy' : 'SCHED_DEADLINE' ,
625+ 'runtime' : 10000000 , # valid
626+ 'deadline' : 20000000 , # valid
627+ 'period' : 9223372036854775808 # 2^63 (invalid, must be < 2^63)
628+ }
629+
630+ conf ['process' ]['args' ] = ['/init' , 'true' ]
631+
632+ try :
633+ out , _ = run_and_get_output (conf , hide_stderr = False )
634+ # Should have failed due to period >= 2^63
635+ return - 1
636+
637+ except subprocess .CalledProcessError as e :
638+ output = e .output .decode ('utf-8' , errors = 'ignore' ) if e .output else ''
639+ if "sched_setattr: `SCHED_DEADLINE` period " in output and " must be >= 1024 and < " in output :
640+ return 0 # Expected validation error for value >= 2^63
641+ logger .info ("unexpected error: %s" , output )
642+ return - 1
643+ except Exception as e :
644+ logger .info ("test failed: %s" , e )
645+ return - 1
646+
647+
648+ def test_scheduler_deadline_deadline_invalid_upper_boundary ():
649+ """Test SCHED_DEADLINE validation - deadline = 2^63 (invalid)."""
650+ if is_rootless ():
651+ return (77 , "SCHED_DEADLINE requires root" )
652+ if not is_sched_deadline_available ():
653+ return (77 , "SCHED_DEADLINE not available in kernel" )
654+
655+ conf = base_config ()
656+ add_all_namespaces (conf )
657+
658+ # Test the exact boundary for deadline: 2^63 should be rejected
659+ conf ['process' ]['scheduler' ] = {
660+ 'policy' : 'SCHED_DEADLINE' ,
661+ 'runtime' : 10000000 , # valid
662+ 'deadline' : 9223372036854775808 , # 2^63 (invalid, must be < 2^63)
663+ 'period' : 9223372036854775809 # 2^63 + 1 (invalid, but larger than deadline)
664+ }
665+
666+ conf ['process' ]['args' ] = ['/init' , 'true' ]
667+
668+ try :
669+ out , _ = run_and_get_output (conf , hide_stderr = False )
670+ # Should have failed due to deadline >= 2^63
671+ return - 1
672+
673+ except subprocess .CalledProcessError as e :
674+ output = e .output .decode ('utf-8' , errors = 'ignore' ) if e .output else ''
675+ if "sched_setattr: `SCHED_DEADLINE` deadline " in output and " must be >= 1024 and < " in output :
676+ return 0 # Expected validation error for value >= 2^63
677+ logger .info ("unexpected error: %s" , output )
678+ return - 1
679+ except Exception as e :
680+ logger .info ("test failed: %s" , e )
681+ return - 1
682+
683+
684+ def test_scheduler_deadline_valid_lower_boundary ():
685+ """Test SCHED_DEADLINE userspace validation accepts minimum valid values."""
686+ if is_rootless ():
687+ return (77 , "SCHED_DEADLINE requires root" )
688+ if not is_sched_deadline_available ():
689+ return (77 , "SCHED_DEADLINE not available in kernel" )
690+
691+ conf = base_config ()
692+ add_all_namespaces (conf )
693+
694+ # Test that crun accepts the minimum valid value (1024)
695+ # Use slightly larger values for deadline/period to be realistic
696+ conf ['process' ]['scheduler' ] = {
697+ 'policy' : 'SCHED_DEADLINE' ,
698+ 'runtime' : 1024 , # minimum valid per crun (1 microsecond)
699+ 'deadline' : 5000 , # 5 microseconds (still small but realistic)
700+ 'period' : 5000 # 5 microseconds
701+ }
702+
703+ conf ['process' ]['args' ] = ['/init' , 'true' ]
704+
705+ try :
706+ out , _ = run_and_get_output (conf , hide_stderr = False )
707+ return 0 # Crun accepted it and kernel also accepted it
708+
709+ except subprocess .CalledProcessError as e :
710+ output = e .output .decode ('utf-8' , errors = 'ignore' ) if e .output else ''
711+ # Verify crun's range validation passed (no "must be >= 1024 and <" error)
712+ if "must be >= 1024 and <" in output :
713+ logger .info ("crun incorrectly rejected valid minimum value: %s" , output )
714+ return - 1
715+ # Kernel may reject for other reasons (admission control, etc.) - that's acceptable
716+ # We only care that crun's validation passed
717+ logger .info ("kernel rejected minimum value (acceptable): %s" , output )
718+ return 0
719+ except Exception as e :
720+ logger .info ("test failed: %s" , e )
721+ return - 1
722+
723+
724+ def test_scheduler_deadline_boundary_1023_rejected ():
725+ """Test SCHED_DEADLINE userspace validation rejects 1023 (below minimum)."""
726+ if is_rootless ():
727+ return (77 , "SCHED_DEADLINE requires root" )
728+ if not is_sched_deadline_available ():
729+ return (77 , "SCHED_DEADLINE not available in kernel" )
730+
731+ conf = base_config ()
732+ add_all_namespaces (conf )
733+
734+ # Test that crun rejects 1023 (one below minimum)
735+ conf ['process' ]['scheduler' ] = {
736+ 'policy' : 'SCHED_DEADLINE' ,
737+ 'runtime' : 1023 , # one below minimum
738+ 'deadline' : 5000 , # valid
739+ 'period' : 5000 # valid
740+ }
741+
742+ conf ['process' ]['args' ] = ['/init' , 'true' ]
743+
744+ try :
745+ out , _ = run_and_get_output (conf , hide_stderr = False )
746+ # Should have failed due to range validation
747+ return - 1
748+
749+ except subprocess .CalledProcessError as e :
750+ output = e .output .decode ('utf-8' , errors = 'ignore' ) if e .output else ''
751+ # Verify crun's range validation rejected it with the expected error
752+ if "sched_setattr: `SCHED_DEADLINE` runtime " in output and " must be >= 1024 and < " in output :
753+ return 0 # Expected validation error
754+ logger .info ("unexpected error: %s" , output )
755+ return - 1
756+ except Exception as e :
757+ logger .info ("test failed: %s" , e )
758+ return - 1
759+
760+
761+ def test_scheduler_deadline_boundary_2pow63_rejected ():
762+ """Test SCHED_DEADLINE userspace validation rejects exactly 2^63."""
763+ if is_rootless ():
764+ return (77 , "SCHED_DEADLINE requires root" )
765+ if not is_sched_deadline_available ():
766+ return (77 , "SCHED_DEADLINE not available in kernel" )
767+
768+ conf = base_config ()
769+ add_all_namespaces (conf )
770+
771+ # Test that crun rejects exactly 2^63 (the invalid boundary)
772+ conf ['process' ]['scheduler' ] = {
773+ 'policy' : 'SCHED_DEADLINE' ,
774+ 'runtime' : 9223372036854775808 , # exactly 2^63 (invalid)
775+ 'deadline' : 9223372036854775809 , # slightly larger
776+ 'period' : 9223372036854775809 # slightly larger
777+ }
778+
779+ conf ['process' ]['args' ] = ['/init' , 'true' ]
780+
781+ try :
782+ out , _ = run_and_get_output (conf , hide_stderr = False )
783+ # Should have failed due to range validation
784+ return - 1
785+
786+ except subprocess .CalledProcessError as e :
787+ output = e .output .decode ('utf-8' , errors = 'ignore' ) if e .output else ''
788+ # Verify crun's range validation rejected it with the expected error
789+ if "sched_setattr: `SCHED_DEADLINE` runtime " in output and " must be >= 1024 and < " in output :
529790 return 0 # Expected validation error
530791 logger .info ("unexpected error: %s" , output )
531792 return - 1
@@ -551,6 +812,13 @@ def test_scheduler_deadline_too_big_runtime():
551812 "scheduler-deadline-invalid-deadline-period" : test_scheduler_deadline_invalid_deadline_period ,
552813 "scheduler-deadline-too-small-runtime" : test_scheduler_deadline_too_small_runtime ,
553814 "scheduler-deadline-too-big-runtime" : test_scheduler_deadline_too_big_runtime ,
815+ "scheduler-deadline-valid-large-values" : test_scheduler_deadline_valid_upper_boundary ,
816+ "scheduler-deadline-invalid-upper-boundary" : test_scheduler_deadline_invalid_upper_boundary ,
817+ "scheduler-deadline-period-invalid-upper-boundary" : test_scheduler_deadline_period_invalid_upper_boundary ,
818+ "scheduler-deadline-deadline-invalid-upper-boundary" : test_scheduler_deadline_deadline_invalid_upper_boundary ,
819+ "scheduler-deadline-valid-minimum-values" : test_scheduler_deadline_valid_lower_boundary ,
820+ "scheduler-deadline-boundary-1023-rejected" : test_scheduler_deadline_boundary_1023_rejected ,
821+ "scheduler-deadline-boundary-2pow63-rejected" : test_scheduler_deadline_boundary_2pow63_rejected ,
554822}
555823
556824if __name__ == "__main__" :
0 commit comments