11import { assertEquals , assertStringIncludes } from "jsr:@std/assert@^1.0.0" ;
2+ import { fromFileUrl } from "jsr:@std/path@^1.0.0/from-file-url" ;
23
3- const SMOKE_FIXTURE_PATH = new URL (
4- "./runtime-teardown.smoke-fixture.ts" ,
5- import . meta. url ,
6- ) . pathname ;
4+ const SMOKE_FIXTURE_PATH = fromFileUrl (
5+ new URL (
6+ "./runtime-teardown.smoke-fixture.ts" ,
7+ import . meta. url ,
8+ ) ,
9+ ) ;
710
811const smokeRunPermission = await Deno . permissions . query ( {
912 name : "run" ,
@@ -38,6 +41,52 @@ const waitForExit = async (
3841 }
3942} ;
4043
44+ const waitForText = async (
45+ stream : ReadableStream < Uint8Array > | null ,
46+ expected : string ,
47+ ) : Promise < {
48+ seen : string ;
49+ remainder : Promise < string > ;
50+ } > => {
51+ if ( ! stream ) {
52+ return { seen : "" , remainder : Promise . resolve ( "" ) } ;
53+ }
54+ const reader = stream . getReader ( ) ;
55+ const decoder = new TextDecoder ( ) ;
56+ let seen = "" ;
57+
58+ try {
59+ while ( ! seen . includes ( expected ) ) {
60+ const { value, done } = await reader . read ( ) ;
61+ if ( done ) break ;
62+ if ( ! value ) continue ;
63+ seen += decoder . decode ( value , { stream : true } ) ;
64+ }
65+ seen += decoder . decode ( ) ;
66+
67+ const remainder = ( async ( ) => {
68+ let output = seen ;
69+ try {
70+ for ( ; ; ) {
71+ const { value, done } = await reader . read ( ) ;
72+ if ( done ) break ;
73+ if ( ! value ) continue ;
74+ output += decoder . decode ( value , { stream : true } ) ;
75+ }
76+ output += decoder . decode ( ) ;
77+ return output ;
78+ } finally {
79+ reader . releaseLock ( ) ;
80+ }
81+ } ) ( ) ;
82+
83+ return { seen, remainder } ;
84+ } catch ( error ) {
85+ reader . releaseLock ( ) ;
86+ throw error ;
87+ }
88+ } ;
89+
4190Deno . test ( {
4291 name :
4392 "runtime teardown smoke: gracefully exits a live node-style host process on first SIGINT" ,
@@ -50,18 +99,18 @@ Deno.test({
5099 stderr : "piped" ,
51100 } ) . spawn ( ) ;
52101
53- const stdoutPromise = new Response ( child . stdout ) . text ( ) ;
102+ const stdoutState = await waitForText ( child . stdout , "ready\n" ) ;
54103 const stderrPromise = new Response ( child . stderr ) . text ( ) ;
55104
56- await new Promise ( ( resolve ) => setTimeout ( resolve , 100 ) ) ;
57105 child . kill ( "SIGINT" ) ;
58106
59107 const status = await waitForExit ( child , 2_000 ) ;
60- const [ stdout , stderr ] = await Promise . all ( [ stdoutPromise , stderrPromise ] ) ;
108+ const stdout = await stdoutState . remainder ;
109+ const stderr = await stderrPromise ;
61110
62111 assertEquals ( status . success , false ) ;
63112 assertEquals ( status . code , 130 ) ;
64- assertStringIncludes ( stdout , "ready\n" ) ;
113+ assertStringIncludes ( stdoutState . seen , "ready\n" ) ;
65114 assertStringIncludes ( stdout , "teardown-run\n" ) ;
66115 assertStringIncludes (
67116 stderr ,
0 commit comments