@@ -45,6 +45,7 @@ use nativelink_util::action_messages::{
4545use nativelink_util:: common:: DigestInfo ;
4646use nativelink_util:: digest_hasher:: DigestHasherFunc ;
4747use nativelink_util:: operation_state_manager:: { UpdateOperationType , WorkerStateManager } ;
48+ use nativelink_util:: platform_properties:: PlatformProperties ;
4849use pretty_assertions:: assert_eq;
4950use tokio:: join;
5051use tokio:: sync:: { Notify , mpsc} ;
@@ -143,6 +144,14 @@ const fn static_now_fn() -> Result<Duration, Error> {
143144}
144145
145146async fn setup_api_server ( worker_timeout : u64 , now_fn : NowFn ) -> Result < TestContext , Error > {
147+ setup_api_server_with_task_limit ( worker_timeout, now_fn, 0 ) . await
148+ }
149+
150+ async fn setup_api_server_with_task_limit (
151+ worker_timeout : u64 ,
152+ now_fn : NowFn ,
153+ max_worker_tasks : u64 ,
154+ ) -> Result < TestContext , Error > {
146155 const SCHEDULER_NAME : & str = "DUMMY_SCHEDULE_NAME" ;
147156
148157 const UUID_SIZE : usize = 36 ;
@@ -172,7 +181,10 @@ async fn setup_api_server(worker_timeout: u64, now_fn: NowFn) -> Result<TestCont
172181 )
173182 . err_tip ( || "Error creating WorkerApiServer" ) ?;
174183
175- let connect_worker_request = ConnectWorkerRequest :: default ( ) ;
184+ let connect_worker_request = ConnectWorkerRequest {
185+ max_inflight_tasks : max_worker_tasks,
186+ ..Default :: default ( )
187+ } ;
176188 let ( tx, rx) = mpsc:: channel ( 1 ) ;
177189 tx. send ( Update :: ConnectWorkerRequest ( connect_worker_request) )
178190 . await
@@ -545,3 +557,75 @@ pub async fn execution_response_success_test() -> Result<(), Box<dyn core::error
545557 }
546558 Ok ( ( ) )
547559}
560+
561+ #[ nativelink_test]
562+ pub async fn workers_only_allow_max_tasks ( ) -> Result < ( ) , Box < dyn core:: error:: Error > > {
563+ let test_context =
564+ setup_api_server_with_task_limit ( BASE_WORKER_TIMEOUT_S , Box :: new ( static_now_fn) , 1 ) . await ?;
565+
566+ let selected_worker = test_context
567+ . scheduler
568+ . find_worker_for_action ( & PlatformProperties :: new ( HashMap :: new ( ) ) , true )
569+ . await ;
570+ assert_eq ! (
571+ selected_worker,
572+ Some ( test_context. worker_id. clone( ) ) ,
573+ "Expected worker to permit tasks to begin with"
574+ ) ;
575+
576+ let action_digest = DigestInfo :: new ( [ 7u8 ; 32 ] , 123 ) ;
577+ let instance_name = "instance_name" . to_string ( ) ;
578+
579+ let unique_qualifier = ActionUniqueQualifier :: Uncacheable ( ActionUniqueKey {
580+ instance_name : instance_name. clone ( ) ,
581+ digest_function : DigestHasherFunc :: Sha256 ,
582+ digest : action_digest,
583+ } ) ;
584+
585+ let action_info = Arc :: new ( ActionInfo {
586+ command_digest : DigestInfo :: new ( [ 0u8 ; 32 ] , 0 ) ,
587+ input_root_digest : DigestInfo :: new ( [ 0u8 ; 32 ] , 0 ) ,
588+ timeout : Duration :: MAX ,
589+ platform_properties : HashMap :: new ( ) ,
590+ priority : 0 ,
591+ load_timestamp : make_system_time ( 0 ) ,
592+ insert_timestamp : make_system_time ( 0 ) ,
593+ unique_qualifier,
594+ } ) ;
595+
596+ let platform_properties = test_context
597+ . scheduler
598+ . get_platform_property_manager ( )
599+ . make_platform_properties ( action_info. platform_properties . clone ( ) )
600+ . err_tip ( || "Failed to make platform properties in SimpleScheduler::do_try_match" ) ?;
601+
602+ let expected_operation_id = OperationId :: default ( ) ;
603+
604+ test_context
605+ . scheduler
606+ . worker_notify_run_action (
607+ test_context. worker_id . clone ( ) ,
608+ expected_operation_id,
609+ ActionInfoWithProps {
610+ inner : action_info,
611+ platform_properties,
612+ } ,
613+ )
614+ . await
615+ . unwrap ( ) ;
616+
617+ let selected_worker = test_context
618+ . scheduler
619+ . find_worker_for_action ( & PlatformProperties :: new ( HashMap :: new ( ) ) , true )
620+ . await ;
621+ assert_eq ! (
622+ selected_worker, None ,
623+ "Expected not to be able to give worker a second task"
624+ ) ;
625+
626+ assert ! ( logs_contain(
627+ "cannot accept work: is_paused=false, is_draining=false, inflight=1/1"
628+ ) ) ;
629+
630+ Ok ( ( ) )
631+ }
0 commit comments