@@ -289,6 +289,60 @@ describe('suite plan', () => {
289289 expect ( plan . items [ 0 ] ) . toMatchObject ( { action : 'conflict' } ) ;
290290 expect ( plan . items [ 0 ] ?. reason ) . toContain ( 'add testId' ) ;
291291 } ) ;
292+
293+ it ( 'times out stalled presigned code downloads using the configured request deadline' , async ( ) => {
294+ const { manifestPath } = writeSuite ( [
295+ { key : 'slow' , testId : 'test_slow' , name : 'Slow' , codeFile : 'slow.py' } ,
296+ ] ) ;
297+ const fetchImpl : FetchImpl = async ( input , init ) => {
298+ const url = new URL ( String ( input ) ) ;
299+ if ( url . pathname . endsWith ( '/tests' ) ) {
300+ return json ( {
301+ items : [
302+ {
303+ id : 'test_slow' ,
304+ projectId : 'proj_suite_1' ,
305+ name : 'Slow' ,
306+ type : 'backend' ,
307+ createdFrom : 'cli' ,
308+ status : 'ready' ,
309+ produces : [ ] ,
310+ consumes : [ ] ,
311+ createdAt : '2026-01-01T00:00:00.000Z' ,
312+ updatedAt : '2026-01-01T00:00:00.000Z' ,
313+ } ,
314+ ] ,
315+ nextToken : null ,
316+ } ) ;
317+ }
318+ if ( url . pathname . endsWith ( '/tests/test_slow/code' ) ) {
319+ return json ( {
320+ testId : 'test_slow' ,
321+ language : 'python' ,
322+ framework : 'pytest' ,
323+ code : 'https://storage.example.test/slow.py' ,
324+ codeVersion : 'v1' ,
325+ } ) ;
326+ }
327+ if ( url . hostname === 'storage.example.test' ) {
328+ return new Promise < Response > ( ( _resolve , reject ) => {
329+ const signal = init ?. signal ;
330+ if ( ! signal ) {
331+ reject ( new Error ( 'expected a request timeout signal' ) ) ;
332+ return ;
333+ }
334+ const rejectFromAbort = ( ) => reject ( signal . reason ) ;
335+ if ( signal . aborted ) rejectFromAbort ( ) ;
336+ else signal . addEventListener ( 'abort' , rejectFromAbort , { once : true } ) ;
337+ } ) ;
338+ }
339+ throw new Error ( `unexpected request: ${ url } ` ) ;
340+ } ;
341+
342+ await expect (
343+ runSuitePlan ( { ...common ( fetchImpl ) , manifestPath, requestTimeoutMs : 1 } , common ( fetchImpl ) ) ,
344+ ) . rejects . toMatchObject ( { name : 'RequestTimeoutError' , timeoutMs : 1_000 } ) ;
345+ } ) ;
292346} ) ;
293347
294348describe ( 'suite apply' , ( ) => {
@@ -400,6 +454,108 @@ describe('suite apply', () => {
400454 } ) ;
401455 } ) ;
402456
457+ it ( 'refuses to apply a plan containing conflicts without sending mutations' , async ( ) => {
458+ const { manifestPath } = writeSuite ( [ { key : 'health' , name : 'Health' , codeFile : 'health.py' } ] ) ;
459+ let mutations = 0 ;
460+ const fetchImpl : FetchImpl = async ( _input , init ) => {
461+ if ( ( init ?. method ?? 'GET' ) !== 'GET' ) mutations += 1 ;
462+ return json ( {
463+ items : [
464+ {
465+ id : 'test_existing' ,
466+ projectId : 'proj_suite_1' ,
467+ name : 'Health' ,
468+ type : 'backend' ,
469+ createdFrom : 'portal' ,
470+ status : 'ready' ,
471+ createdAt : '2026-01-01T00:00:00.000Z' ,
472+ updatedAt : '2026-01-01T00:00:00.000Z' ,
473+ } ,
474+ ] ,
475+ nextToken : null ,
476+ } ) ;
477+ } ;
478+
479+ await expect (
480+ runSuiteApply ( { ...common ( fetchImpl ) , manifestPath, confirm : true } , common ( fetchImpl ) ) ,
481+ ) . rejects . toMatchObject ( {
482+ code : 'VALIDATION_ERROR' ,
483+ nextAction : expect . stringContaining ( 'plan contains 1 conflict' ) ,
484+ } ) ;
485+ expect ( mutations ) . toBe ( 0 ) ;
486+ } ) ;
487+
488+ it ( 'does not churn an unchanged lock entry timestamp on repeated apply' , async ( ) => {
489+ const { manifestPath, lockPath } = writeSuite ( [
490+ { key : 'health' , name : 'Health' , codeFile : 'health.py' } ,
491+ ] ) ;
492+ const createFetch : FetchImpl = async ( input , init ) => {
493+ const url = new URL ( String ( input ) ) ;
494+ if ( ( init ?. method ?? 'GET' ) === 'GET' && url . pathname . endsWith ( '/tests' ) ) {
495+ return json ( { items : [ ] , nextToken : null } ) ;
496+ }
497+ if ( ( init ?. method ?? 'GET' ) === 'POST' && url . pathname . endsWith ( '/tests' ) ) {
498+ return json ( {
499+ testId : 'test_health' ,
500+ type : 'backend' ,
501+ codeVersion : 'v1' ,
502+ createdAt : 'now' ,
503+ } ) ;
504+ }
505+ throw new Error ( `unexpected request: ${ init ?. method ?? 'GET' } ${ url . pathname } ` ) ;
506+ } ;
507+ await runSuiteApply (
508+ { ...common ( createFetch ) , manifestPath, confirm : true } ,
509+ common ( createFetch ) ,
510+ ) ;
511+ const before = readFileSync ( lockPath , 'utf8' ) ;
512+
513+ const noopFetch : FetchImpl = async input => {
514+ const url = new URL ( String ( input ) ) ;
515+ if ( url . pathname . endsWith ( '/tests' ) ) {
516+ return json ( {
517+ items : [
518+ {
519+ id : 'test_health' ,
520+ projectId : 'proj_suite_1' ,
521+ name : 'Health' ,
522+ type : 'backend' ,
523+ createdFrom : 'cli' ,
524+ status : 'ready' ,
525+ produces : [ ] ,
526+ consumes : [ ] ,
527+ createdAt : '2026-01-01T00:00:00.000Z' ,
528+ updatedAt : '2026-01-01T00:00:00.000Z' ,
529+ } ,
530+ ] ,
531+ nextToken : null ,
532+ } ) ;
533+ }
534+ if ( url . pathname . endsWith ( '/tests/test_health/code' ) ) {
535+ return json ( {
536+ testId : 'test_health' ,
537+ language : 'python' ,
538+ framework : 'pytest' ,
539+ code : 'def test_health():\n assert True\n' ,
540+ codeVersion : 'v1' ,
541+ } ) ;
542+ }
543+ throw new Error ( `unexpected request: ${ url } ` ) ;
544+ } ;
545+ const later = {
546+ ...common ( noopFetch ) ,
547+ now : ( ) => new Date ( '2026-07-22T12:00:00.000Z' ) ,
548+ } ;
549+ const result = await runSuiteApply ( { ...later , manifestPath, confirm : true } , later ) ;
550+
551+ expect ( 'summary' in result && result . summary ) . toEqual ( {
552+ created : 0 ,
553+ updated : 0 ,
554+ unchanged : 1 ,
555+ } ) ;
556+ expect ( readFileSync ( lockPath , 'utf8' ) ) . toBe ( before ) ;
557+ } ) ;
558+
403559 it ( 'resumes an unchanged pending create and conflicts if its definition drifted' , async ( ) => {
404560 const { manifestPath, lockPath, dir } = writeSuite ( [
405561 { key : 'health' , name : 'Health' , codeFile : 'health.py' } ,
0 commit comments