@@ -30,10 +30,7 @@ import {
3030 serializeAndroidAdbInvocation ,
3131 type AndroidAdbInvocation ,
3232} from '@agent-device/platform-android/mechanics' ;
33- import {
34- reconnectAttachedLimrunAppLogReader ,
35- reconnectLimrunAppLogReader ,
36- } from './app-log-reconnect.ts' ;
33+ import { reconnectLimrunAppLogReader } from './app-log-reconnect.ts' ;
3734import { attachedLimrunInstanceId } from './instance-access.ts' ;
3835import { createInstanceClient as createIosInstanceClient } from '@limrun/api/ios-client' ;
3936import type {
@@ -49,11 +46,12 @@ test('reattaches an owned Limrun instance without persisting credentials', async
4946 } ) ) ;
5047 const signal = new AbortController ( ) . signal ;
5148 const outcome = await reconnectLimrunAppLogReader ( {
52- limrun : {
53- iosInstances : {
54- get,
55- } ,
56- } as never ,
49+ orgClient : ( ) =>
50+ ( {
51+ iosInstances : {
52+ get,
53+ } ,
54+ } ) as never ,
5755 descriptor : {
5856 transport : 'limrun-log-poller' ,
5957 platform : 'ios' ,
@@ -75,14 +73,15 @@ test('reattaches an owned Limrun instance without persisting credentials', async
7573
7674test ( 'fails closed when the instance labels do not match the descriptor lease' , async ( ) => {
7775 const outcome = await reconnectLimrunAppLogReader ( {
78- limrun : {
79- iosInstances : {
80- get : vi . fn ( async ( ) => ( {
81- metadata : { labels : { provider : 'limrun' , leaseId : 'another-lease' } } ,
82- status : { state : 'ready' , apiUrl : 'https://instance' , token : 'secret' } ,
83- } ) ) ,
84- } ,
85- } as never ,
76+ orgClient : ( ) =>
77+ ( {
78+ iosInstances : {
79+ get : vi . fn ( async ( ) => ( {
80+ metadata : { labels : { provider : 'limrun' , leaseId : 'another-lease' } } ,
81+ status : { state : 'ready' , apiUrl : 'https://instance' , token : 'secret' } ,
82+ } ) ) ,
83+ } ,
84+ } ) as never ,
8685 descriptor : {
8786 transport : 'limrun-log-poller' ,
8887 platform : 'ios' ,
@@ -100,19 +99,20 @@ test('disconnects the Android instance client when tunnel acquisition fails', as
10099 androidClient . disconnect . mockClear ( ) ;
101100 await expect (
102101 reconnectLimrunAppLogReader ( {
103- limrun : {
104- androidInstances : {
105- get : vi . fn ( async ( ) => ( {
106- metadata : { labels : { provider : 'limrun' , leaseId : 'lease-a' } } ,
107- status : {
108- state : 'ready' ,
109- apiUrl : 'https://instance' ,
110- adbWebSocketUrl : 'wss://adb' ,
111- token : 'secret' ,
112- } ,
113- } ) ) ,
114- } ,
115- } as never ,
102+ orgClient : ( ) =>
103+ ( {
104+ androidInstances : {
105+ get : vi . fn ( async ( ) => ( {
106+ metadata : { labels : { provider : 'limrun' , leaseId : 'lease-a' } } ,
107+ status : {
108+ state : 'ready' ,
109+ apiUrl : 'https://instance' ,
110+ adbWebSocketUrl : 'wss://adb' ,
111+ token : 'secret' ,
112+ } ,
113+ } ) ) ,
114+ } ,
115+ } ) as never ,
116116 descriptor : {
117117 transport : 'limrun-log-poller' ,
118118 platform : 'android' ,
@@ -141,19 +141,20 @@ test('addresses app-log adb traffic at the tunnel serial and hands cleanup a com
141141 } ) ) ;
142142 androidClient . disconnect . mockClear ( ) ;
143143 const outcome = await reconnectLimrunAppLogReader ( {
144- limrun : {
145- androidInstances : {
146- get : vi . fn ( async ( ) => ( {
147- metadata : { labels : { provider : 'limrun' , leaseId : 'lease-a' } } ,
148- status : {
149- state : 'ready' ,
150- apiUrl : 'https://instance' ,
151- adbWebSocketUrl : 'wss://adb' ,
152- token : 'secret' ,
153- } ,
154- } ) ) ,
155- } ,
156- } as never ,
144+ orgClient : ( ) =>
145+ ( {
146+ androidInstances : {
147+ get : vi . fn ( async ( ) => ( {
148+ metadata : { labels : { provider : 'limrun' , leaseId : 'lease-a' } } ,
149+ status : {
150+ state : 'ready' ,
151+ apiUrl : 'https://instance' ,
152+ adbWebSocketUrl : 'wss://adb' ,
153+ token : 'secret' ,
154+ } ,
155+ } ) ) ,
156+ } ,
157+ } ) as never ,
157158 descriptor : {
158159 transport : 'limrun-log-poller' ,
159160 platform : 'android' ,
@@ -215,32 +216,72 @@ test('addresses app-log adb traffic at the tunnel serial and hands cleanup a com
215216 expect ( androidClient . disconnect ) . toHaveBeenCalledOnce ( ) ;
216217} ) ;
217218
218- test ( 'reattaches app logs to the attached instance the descriptor names' , async ( ) => {
219- const access = { apiUrl : 'https://attached.example/api' , token : 'instance-token' } ;
220- const descriptor = {
219+ const ATTACHED_ACCESS = { apiUrl : 'https://attached.example/api' , token : 'instance-token' } ;
220+
221+ function attachedDescriptor ( instanceId = attachedLimrunInstanceId ( ATTACHED_ACCESS . apiUrl ) ) {
222+ return {
221223 transport : 'limrun-log-poller' ,
222224 platform : 'ios' ,
223225 leaseId : 'lease-a' ,
224- instanceId : attachedLimrunInstanceId ( access . apiUrl ) ,
226+ instanceId,
225227 appBundleId : 'com.example.app' ,
226228 outputPath : '/sessions/one/app.log' ,
227229 } as const ;
230+ }
231+
232+ function unavailableOrgClient ( ) : never {
233+ throw new Error ( 'the organization API must not be used' ) ;
234+ }
228235
229- const outcome = await reconnectAttachedLimrunAppLogReader ( {
230- instances : { ios : access } ,
231- descriptor,
236+ test ( 'reattaches app logs to the attached instance the descriptor names' , async ( ) => {
237+ const outcome = await reconnectLimrunAppLogReader ( {
238+ orgClient : unavailableOrgClient ,
239+ instances : { ios : ATTACHED_ACCESS } ,
240+ descriptor : attachedDescriptor ( ) ,
232241 dependencies : { } as LimrunRuntimeDependencies ,
233242 } ) ;
234243 expect ( vi . mocked ( createIosInstanceClient ) ) . toHaveBeenLastCalledWith ( {
235- ...access ,
244+ ...ATTACHED_ACCESS ,
236245 logLevel : 'warn' ,
237246 } ) ;
238247 expect ( outcome . status ) . toBe ( 'opened' ) ;
239248
240- const replaced = await reconnectAttachedLimrunAppLogReader ( {
241- instances : { ios : { ...access , apiUrl : 'https://another-instance.example/api' } } ,
242- descriptor,
249+ const replaced = await reconnectLimrunAppLogReader ( {
250+ orgClient : unavailableOrgClient ,
251+ instances : { ios : { ...ATTACHED_ACCESS , apiUrl : 'https://another-instance.example/api' } } ,
252+ descriptor : attachedDescriptor ( ) ,
243253 dependencies : { } as LimrunRuntimeDependencies ,
244254 } ) ;
245255 expect ( replaced ) . toEqual ( { status : 'ownership-lost' } ) ;
246256} ) ;
257+
258+ test ( 'reattaches a created instance through the organization API while another is attached' , async ( ) => {
259+ const get = vi . fn ( async ( ) => ( {
260+ metadata : { labels : { provider : 'limrun' , leaseId : 'lease-a' } } ,
261+ status : { state : 'ready' , apiUrl : 'https://created.example/api' , token : 'created-token' } ,
262+ } ) ) ;
263+ const outcome = await reconnectLimrunAppLogReader ( {
264+ orgClient : ( ) => ( { iosInstances : { get } } ) as never ,
265+ instances : { ios : ATTACHED_ACCESS } ,
266+ descriptor : attachedDescriptor ( 'ios_created_instance' ) ,
267+ dependencies : { } as LimrunRuntimeDependencies ,
268+ } ) ;
269+ expect ( get ) . toHaveBeenCalledOnce ( ) ;
270+ expect ( outcome . status ) . toBe ( 'opened' ) ;
271+ } ) ;
272+
273+ test ( 'does not connect once the reconnect request is aborted' , async ( ) => {
274+ const controller = new AbortController ( ) ;
275+ controller . abort ( ) ;
276+ vi . mocked ( createIosInstanceClient ) . mockClear ( ) ;
277+ await expect (
278+ reconnectLimrunAppLogReader ( {
279+ orgClient : unavailableOrgClient ,
280+ instances : { ios : ATTACHED_ACCESS } ,
281+ descriptor : attachedDescriptor ( ) ,
282+ dependencies : { } as LimrunRuntimeDependencies ,
283+ signal : controller . signal ,
284+ } ) ,
285+ ) . rejects . toThrow ( ) ;
286+ expect ( vi . mocked ( createIosInstanceClient ) ) . not . toHaveBeenCalled ( ) ;
287+ } ) ;
0 commit comments