@@ -3,6 +3,8 @@ import execa from 'execa';
33import yargs from 'yargs' ;
44import assert from 'assert' ;
55import path from 'path' ;
6+ import { createServer } from 'http' ;
7+ import { connect } from 'net' ;
68
79const TAR_NAME = 'openai.tgz' ;
810const PACK_FOLDER = '.pack' ;
@@ -109,6 +111,35 @@ const projectRunners = {
109111let projectNames = Object . keys ( projectRunners ) as Array < keyof typeof projectRunners > ;
110112const projectNamesSet = new Set ( projectNames ) ;
111113
114+ async function startProxy ( ) {
115+ const proxy = createServer ( ( _req , res ) => {
116+ res . end ( ) ;
117+ } ) ;
118+
119+ proxy . on ( 'connect' , ( req , clientSocket , head ) => {
120+ console . log ( 'got proxied connection' ) ;
121+ const serverSocket = connect ( 443 , 'api.openai.com' , ( ) => {
122+ clientSocket . write (
123+ 'HTTP/1.1 200 Connection Established\r\n' + 'Proxy-agent: Node.js-Proxy\r\n' + '\r\n' ,
124+ ) ;
125+ serverSocket . write ( head ) ;
126+ serverSocket . pipe ( clientSocket ) ;
127+ clientSocket . pipe ( serverSocket ) ;
128+ } ) ;
129+ } ) ;
130+
131+ await new Promise < void > ( ( resolve ) => proxy . listen ( 0 , '127.0.0.1' , resolve ) ) ;
132+
133+ const address = proxy . address ( ) ;
134+ assert ( address && typeof address !== 'string' ) ;
135+ process . env [ 'ECOSYSTEM_TESTS_PROXY' ] = 'http://127.0.0.1:' + address . port ;
136+
137+ return ( ) => {
138+ delete process . env [ 'ECOSYSTEM_TESTS_PROXY' ] ;
139+ proxy . close ( ) ;
140+ } ;
141+ }
142+
112143function parseArgs ( ) {
113144 return yargs ( process . argv . slice ( 2 ) )
114145 . scriptName ( 'ecosystem-tests' )
@@ -287,112 +318,118 @@ async function main() {
287318 await fileCache . cacheFiles ( tmpFolderPath ) ;
288319 }
289320
290- if ( jobs > 1 ) {
291- const queue = [ ...projectsToRun ] ;
292- const runningProjects = new Set ( ) ;
293-
294- const cursorLeft = '\x1B[G' ;
295- const eraseLine = '\x1B[2K' ;
296-
297- let progressDisplayed = false ;
298- function clearProgress ( ) {
299- if ( progressDisplayed ) {
300- process . stderr . write ( cursorLeft + eraseLine ) ;
301- progressDisplayed = false ;
321+ const stopProxy = await startProxy ( ) ;
322+ try {
323+ if ( jobs > 1 ) {
324+ const queue = [ ...projectsToRun ] ;
325+ const runningProjects = new Set ( ) ;
326+
327+ const cursorLeft = '\x1B[G' ;
328+ const eraseLine = '\x1B[2K' ;
329+
330+ let progressDisplayed = false ;
331+ function clearProgress ( ) {
332+ if ( progressDisplayed ) {
333+ process . stderr . write ( cursorLeft + eraseLine ) ;
334+ progressDisplayed = false ;
335+ }
336+ }
337+ const spinner = [ '|' , '/' , '-' , '\\' ] ;
338+
339+ function showProgress ( ) {
340+ clearProgress ( ) ;
341+ progressDisplayed = true ;
342+ const spin = spinner [ Math . floor ( Date . now ( ) / 500 ) % spinner . length ] ;
343+ process . stderr . write (
344+ `${ spin } Running ${ [ ...runningProjects ] . join ( ', ' ) } ` . substring ( 0 , process . stdout . columns - 3 ) +
345+ '...' ,
346+ ) ;
302347 }
303- }
304- const spinner = [ '|' , '/' , '-' , '\\' ] ;
305348
306- function showProgress ( ) {
307- clearProgress ( ) ;
308- progressDisplayed = true ;
309- const spin = spinner [ Math . floor ( Date . now ( ) / 500 ) % spinner . length ] ;
310- process . stderr . write (
311- `${ spin } Running ${ [ ...runningProjects ] . join ( ', ' ) } ` . substring ( 0 , process . stdout . columns - 3 ) + '...' ,
312- ) ;
313- }
349+ const progressInterval = setInterval ( showProgress , process . stdout . isTTY ? 500 : 5000 ) ;
350+ showProgress ( ) ;
351+
352+ await Promise . all (
353+ [ ...Array ( jobs ) . keys ( ) ] . map ( async ( ) => {
354+ while ( queue . length ) {
355+ const project = queue . shift ( ) ;
356+ if ( ! project ) {
357+ break ;
358+ }
314359
315- const progressInterval = setInterval ( showProgress , process . stdout . isTTY ? 500 : 5000 ) ;
316- showProgress ( ) ;
360+ // preserve interleaved ordering of writes to stdout/stderr
361+ const chunks : { dest : 'stdout' | 'stderr' ; data : string | Buffer } [ ] = [ ] ;
362+ try {
363+ runningProjects . add ( project ) ;
364+ const child = execa (
365+ 'yarn' ,
366+ [
367+ 'tsn' ,
368+ __filename ,
369+ project ,
370+ '--skip-pack' ,
371+ '--noCleanup' ,
372+ `--retry=${ args . retry } ` ,
373+ ...( args . live ? [ '--live' ] : [ ] ) ,
374+ ...( args . verbose ? [ '--verbose' ] : [ ] ) ,
375+ ...( args . deploy ? [ '--deploy' ] : [ ] ) ,
376+ ...( args . fromNpm ? [ '--from-npm' ] : [ ] ) ,
377+ ] ,
378+ { stdio : 'pipe' , encoding : 'utf8' , maxBuffer : 100 * 1024 * 1024 } ,
379+ ) ;
380+ child . stdout ?. on ( 'data' , ( data ) => chunks . push ( { dest : 'stdout' , data } ) ) ;
381+ child . stderr ?. on ( 'data' , ( data ) => chunks . push ( { dest : 'stderr' , data } ) ) ;
382+
383+ await child ;
384+ } catch ( error ) {
385+ failed . push ( project ) ;
386+ } finally {
387+ runningProjects . delete ( project ) ;
388+ }
317389
318- await Promise . all (
319- [ ...Array ( jobs ) . keys ( ) ] . map ( async ( ) => {
320- while ( queue . length ) {
321- const project = queue . shift ( ) ;
322- if ( ! project ) {
323- break ;
324- }
390+ if ( IS_CI ) {
391+ console . log ( `::group::${ failed . includes ( project ) ? '❌' : '✅' } ${ project } ` ) ;
392+ }
325393
326- // preserve interleaved ordering of writes to stdout/stderr
327- const chunks : { dest : 'stdout' | 'stderr' ; data : string | Buffer } [ ] = [ ] ;
328- try {
329- runningProjects . add ( project ) ;
330- const child = execa (
331- 'yarn' ,
332- [
333- 'tsn' ,
334- __filename ,
335- project ,
336- '--skip-pack' ,
337- '--noCleanup' ,
338- `--retry=${ args . retry } ` ,
339- ...( args . live ? [ '--live' ] : [ ] ) ,
340- ...( args . verbose ? [ '--verbose' ] : [ ] ) ,
341- ...( args . deploy ? [ '--deploy' ] : [ ] ) ,
342- ...( args . fromNpm ? [ '--from-npm' ] : [ ] ) ,
343- ] ,
344- { stdio : 'pipe' , encoding : 'utf8' , maxBuffer : 100 * 1024 * 1024 } ,
345- ) ;
346- child . stdout ?. on ( 'data' , ( data ) => chunks . push ( { dest : 'stdout' , data } ) ) ;
347- child . stderr ?. on ( 'data' , ( data ) => chunks . push ( { dest : 'stderr' , data } ) ) ;
348-
349- await child ;
350- } catch ( error ) {
351- failed . push ( project ) ;
352- } finally {
353- runningProjects . delete ( project ) ;
394+ for ( const { data } of chunks ) {
395+ process . stdout . write ( data ) ;
396+ }
397+ if ( IS_CI ) console . log ( '::endgroup::' ) ;
354398 }
399+ } ) ,
400+ ) ;
355401
356- if ( IS_CI ) {
357- console . log ( `::group::${ failed . includes ( project ) ? '❌' : '✅' } ${ project } ` ) ;
358- }
402+ clearInterval ( progressInterval ) ;
403+ clearProgress ( ) ;
404+ } else {
405+ for ( const project of projectsToRun ) {
406+ const fn = projectRunners [ project ] ;
359407
360- for ( const { data } of chunks ) {
361- process . stdout . write ( data ) ;
362- }
363- if ( IS_CI ) console . log ( '::endgroup::' ) ;
364- }
365- } ) ,
366- ) ;
367-
368- clearInterval ( progressInterval ) ;
369- clearProgress ( ) ;
370- } else {
371- for ( const project of projectsToRun ) {
372- const fn = projectRunners [ project ] ;
373-
374- await withChdir ( path . join ( rootDir , 'ecosystem-tests' , project ) , async ( ) => {
375- console . error ( '\n' ) ;
376- console . error ( banner ( `▶️ ${ project } ` ) ) ;
377- console . error ( '\n' ) ;
378-
379- try {
380- await withRetry ( fn , project , state . retry , state . retryDelay ) ;
408+ await withChdir ( path . join ( rootDir , 'ecosystem-tests' , project ) , async ( ) => {
409+ console . error ( '\n' ) ;
410+ console . error ( banner ( `▶️ ${ project } ` ) ) ;
381411 console . error ( '\n' ) ;
382- console . error ( `✅ ${ project } ` ) ;
383- } catch ( err ) {
384- if ( err && ( err as any ) . shortMessage ) {
385- console . error ( ( err as any ) . shortMessage ) ;
386- } else {
387- console . error ( err ) ;
412+
413+ try {
414+ await withRetry ( fn , project , state . retry , state . retryDelay ) ;
415+ console . error ( '\n' ) ;
416+ console . error ( `✅ ${ project } ` ) ;
417+ } catch ( err ) {
418+ if ( err && ( err as any ) . shortMessage ) {
419+ console . error ( ( err as any ) . shortMessage ) ;
420+ } else {
421+ console . error ( err ) ;
422+ }
423+ console . error ( '\n' ) ;
424+ console . error ( `❌ ${ project } ` ) ;
425+ failed . push ( project ) ;
388426 }
389427 console . error ( '\n' ) ;
390- console . error ( `❌ ${ project } ` ) ;
391- failed . push ( project ) ;
392- }
393- console . error ( '\n' ) ;
394- } ) ;
428+ } ) ;
429+ }
395430 }
431+ } finally {
432+ stopProxy ( ) ;
396433 }
397434
398435 if ( ! args . noCleanup ) {
0 commit comments