@@ -470,6 +470,137 @@ async def test_not_assigns_job_to_foreign_fleet_if_not_imported(
470470 assert not job .instance_assigned
471471 assert job .instance is None
472472
473+ @pytest .mark .asyncio
474+ @pytest .mark .parametrize ("test_db" , ["sqlite" , "postgres" ], indirect = True )
475+ async def test_assigns_second_replica_to_same_imported_fleet (
476+ self , test_db , session : AsyncSession
477+ ):
478+ user = await create_user (session , global_role = GlobalRole .USER )
479+ exporter_project = await create_project (session , name = "exporter-project" , owner = user )
480+ importer_project = await create_project (session , name = "importer-project" , owner = user )
481+ fleet = await create_fleet (
482+ session = session ,
483+ project = exporter_project ,
484+ spec = get_fleet_spec (get_ssh_fleet_configuration ()),
485+ name = "exported-fleet" ,
486+ )
487+ instance_0 = await create_instance (
488+ session = session ,
489+ project = exporter_project ,
490+ fleet = fleet ,
491+ name = "exported-fleet-0" ,
492+ status = InstanceStatus .BUSY ,
493+ )
494+ instance_1 = await create_instance (
495+ session = session ,
496+ project = exporter_project ,
497+ fleet = fleet ,
498+ name = "exported-fleet-1" ,
499+ status = InstanceStatus .IDLE ,
500+ )
501+ await create_export (
502+ session = session ,
503+ exporter_project = exporter_project ,
504+ importer_projects = [importer_project ],
505+ exported_fleets = [fleet ],
506+ )
507+ repo = await create_repo (session = session , project_id = importer_project .id )
508+ run = await create_run (
509+ session = session ,
510+ project = importer_project ,
511+ repo = repo ,
512+ user = user ,
513+ fleet = fleet ,
514+ )
515+ await create_job (
516+ session = session ,
517+ run = run ,
518+ fleet = fleet ,
519+ instance = instance_0 ,
520+ instance_assigned = True ,
521+ status = JobStatus .RUNNING ,
522+ job_num = 0 ,
523+ replica_num = 0 ,
524+ )
525+ job_1 = await create_job (
526+ session = session ,
527+ run = run ,
528+ instance_assigned = False ,
529+ status = JobStatus .SUBMITTED ,
530+ job_num = 0 ,
531+ replica_num = 1 ,
532+ )
533+ await process_submitted_jobs ()
534+ await session .refresh (job_1 )
535+ assert job_1 .status == JobStatus .SUBMITTED
536+ assert job_1 .instance_assigned
537+ assert job_1 .instance_id == instance_1 .id
538+ assert job_1 .fleet_id == fleet .id
539+
540+ @pytest .mark .asyncio
541+ @pytest .mark .parametrize ("test_db" , ["sqlite" , "postgres" ], indirect = True )
542+ async def test_second_job_fails_if_imported_fleet_has_no_capacity (
543+ self , test_db , session : AsyncSession
544+ ):
545+ user = await create_user (session , global_role = GlobalRole .USER )
546+ exporter_project = await create_project (session , name = "exporter-project" , owner = user )
547+ importer_project = await create_project (session , name = "importer-project" , owner = user )
548+ fleet = await create_fleet (
549+ session = session ,
550+ project = exporter_project ,
551+ spec = get_fleet_spec (get_ssh_fleet_configuration ()),
552+ name = "exported-fleet" ,
553+ )
554+ instance_0 = await create_instance (
555+ session = session ,
556+ project = exporter_project ,
557+ fleet = fleet ,
558+ name = "exported-fleet-0" ,
559+ status = InstanceStatus .BUSY ,
560+ )
561+ await create_export (
562+ session = session ,
563+ exporter_project = exporter_project ,
564+ importer_projects = [importer_project ],
565+ exported_fleets = [fleet ],
566+ )
567+ repo = await create_repo (session = session , project_id = importer_project .id )
568+ run = await create_run (
569+ session = session ,
570+ project = importer_project ,
571+ repo = repo ,
572+ user = user ,
573+ fleet = fleet ,
574+ )
575+ await create_job (
576+ session = session ,
577+ run = run ,
578+ fleet = fleet ,
579+ instance = instance_0 ,
580+ instance_assigned = True ,
581+ status = JobStatus .RUNNING ,
582+ job_num = 0 ,
583+ replica_num = 0 ,
584+ )
585+ job_1 = await create_job (
586+ session = session ,
587+ run = run ,
588+ instance_assigned = False ,
589+ status = JobStatus .SUBMITTED ,
590+ job_num = 0 ,
591+ replica_num = 1 ,
592+ )
593+ await process_submitted_jobs ()
594+ await session .refresh (job_1 )
595+ assert job_1 .status == JobStatus .SUBMITTED
596+ assert job_1 .instance_assigned
597+ assert job_1 .instance_id is None
598+
599+ await process_submitted_jobs ()
600+ await session .refresh (job_1 )
601+ assert job_1 .status == JobStatus .TERMINATING
602+ assert job_1 .termination_reason == JobTerminationReason .FAILED_TO_START_DUE_TO_NO_CAPACITY
603+
473604 @pytest .mark .asyncio
474605 @pytest .mark .parametrize ("test_db" , ["sqlite" , "postgres" ], indirect = True )
475606 async def test_does_no_reuse_unavailable_instances (self , test_db , session : AsyncSession ):
0 commit comments