@@ -108,6 +108,7 @@ import {
108108 validateRunnerDevice ,
109109} from '../runner-session.ts' ;
110110import {
111+ cleanupRunnerLeasesForOwner ,
111112 RUNNER_OWNER_START_TIME ,
112113 RUNNER_OWNER_TOKEN ,
113114 writeRunnerLease ,
@@ -710,6 +711,40 @@ test('runner session startup reclaims dead foreign runner lease before launching
710711 ) ;
711712} ) ;
712713
714+ test ( 'runner lease cleanup reclaims only leases owned by the stopped daemon' , async ( ) => {
715+ const ownerPid = 999_999_991 ;
716+ const ownerStartTime = 'Fri Jun 19 12:00:00 2026' ;
717+ const owned = makeRunnerLease ( {
718+ deviceId : 'runner-session-clean-owned-lease' ,
719+ ownerPid,
720+ ownerStartTime,
721+ ownerToken : 'owner-clean-owned' ,
722+ } ) ;
723+ const foreign = makeRunnerLease ( {
724+ deviceId : 'runner-session-clean-foreign-lease' ,
725+ ownerPid,
726+ ownerStartTime : 'Fri Jun 19 12:01:00 2026' ,
727+ ownerToken : 'owner-clean-foreign' ,
728+ } ) ;
729+ writeRunnerLease ( owned ) ;
730+ writeRunnerLease ( foreign ) ;
731+
732+ await cleanupRunnerLeasesForOwner (
733+ { pid : ownerPid , startTime : ownerStartTime } ,
734+ {
735+ cleanupRunnerProcessTree : async ( ) => { } ,
736+ cleanupRunnerXcodebuildProcesses : async ( ) => { } ,
737+ cleanupTempFile : mockCleanupTempFile ,
738+ } ,
739+ ) ;
740+
741+ const leaseDir = process . env . AGENT_DEVICE_IOS_RUNNER_LEASE_DIR ;
742+ assert . ok ( leaseDir ) ;
743+ assert . equal ( fs . existsSync ( path . join ( leaseDir , `${ owned . deviceId } .json` ) ) , false ) ;
744+ assert . equal ( fs . existsSync ( path . join ( leaseDir , `${ foreign . deviceId } .json` ) ) , true ) ;
745+ assert . deepEqual ( mockCleanupTempFile . mock . calls , [ [ owned . xctestrunPath ] , [ owned . jsonPath ] ] ) ;
746+ } ) ;
747+
713748test ( 'runner session restarts alive runner when expected xctestrun artifact changes' , async ( ) => {
714749 const device = { ...IOS_SIMULATOR , id : 'runner-session-stale-artifact-sim' } ;
715750
0 commit comments