11#!/usr/bin/env node
22
3- import { spawnSync } from "node:child_process" ;
3+ import { spawnSync as defaultSpawnSync } from "node:child_process" ;
44import fs from "node:fs" ;
55import path from "node:path" ;
66import process from "node:process" ;
7+ import { pathToFileURL } from "node:url" ;
78import { collectGatewayCpuObservations } from "./lib/plugin-gateway-gauntlet.mjs" ;
89import { createPnpmRunnerSpawnSpec } from "./pnpm-runner.mjs" ;
910
@@ -137,9 +138,10 @@ function readJsonIfExists(filePath) {
137138 return JSON . parse ( fs . readFileSync ( filePath , "utf8" ) ) ;
138139}
139140
140- function runStep ( name , command , args , options = { } ) {
141+ function runStep ( name , command , args , options = { } , params = { } ) {
141142 console . error ( `[gateway-cpu] start ${ name } ` ) ;
142- const result = spawnSync ( command , args , {
143+ const spawn = params . spawnSync ?? defaultSpawnSync ;
144+ const result = spawn ( command , args , {
143145 cwd : process . cwd ( ) ,
144146 env : process . env ,
145147 stdio : "inherit" ,
@@ -167,8 +169,7 @@ function toRepoRelativePath(absolutePath) {
167169 return relativePath ;
168170}
169171
170- async function main ( ) {
171- const options = parseArgs ( process . argv . slice ( 2 ) ) ;
172+ async function runGatewayCpuScenarios ( options , params = { } ) {
172173 fs . mkdirSync ( options . outputDir , { recursive : true } ) ;
173174
174175 const startupOutput = path . join ( options . outputDir , "gateway-startup-bench.json" ) ;
@@ -177,19 +178,35 @@ async function main() {
177178 const steps = [ ] ;
178179
179180 if ( ! options . skipStartup ) {
181+ const startupBuild = runStep (
182+ "startup build" ,
183+ process . execPath ,
184+ [ "scripts/ensure-cli-startup-build.mjs" ] ,
185+ { } ,
186+ params ,
187+ ) ;
188+ steps . push ( startupBuild ) ;
180189 steps . push (
181- runStep ( "startup bench" , process . execPath , [
182- "--import" ,
183- "tsx" ,
184- "scripts/bench-gateway-startup.ts" ,
185- "--runs" ,
186- String ( options . runs ) ,
187- "--warmup" ,
188- String ( options . warmup ) ,
189- "--output" ,
190- startupOutput ,
191- ...options . startupCases . flatMap ( ( id ) => [ "--case" , id ] ) ,
192- ] ) ,
190+ startupBuild . status === 0
191+ ? runStep (
192+ "startup bench" ,
193+ process . execPath ,
194+ [
195+ "--import" ,
196+ "tsx" ,
197+ "scripts/bench-gateway-startup.ts" ,
198+ "--runs" ,
199+ String ( options . runs ) ,
200+ "--warmup" ,
201+ String ( options . warmup ) ,
202+ "--output" ,
203+ startupOutput ,
204+ ...options . startupCases . flatMap ( ( id ) => [ "--case" , id ] ) ,
205+ ] ,
206+ { } ,
207+ params ,
208+ )
209+ : { name : "startup bench" , signal : null , status : 1 } ,
193210 ) ;
194211 }
195212
@@ -207,7 +224,7 @@ async function main() {
207224 ...options . qaScenarios . flatMap ( ( id ) => [ "--scenario" , id ] ) ,
208225 ] ) ;
209226 steps . push (
210- runStep ( "qa suite" , qaCommand . command , qaCommand . args , qaCommand . options ) ,
227+ runStep ( "qa suite" , qaCommand . command , qaCommand . args , qaCommand . options , params ) ,
211228 ) ;
212229 }
213230
@@ -239,14 +256,30 @@ async function main() {
239256 } ;
240257 const summaryPath = path . join ( options . outputDir , "summary.json" ) ;
241258 fs . writeFileSync ( summaryPath , `${ JSON . stringify ( summary , null , 2 ) } \n` ) ;
242- console . log ( JSON . stringify ( summary , null , 2 ) ) ;
259+ if ( ! params . silent ) {
260+ console . log ( JSON . stringify ( summary , null , 2 ) ) ;
261+ }
262+
263+ const exitCode = steps . some ( ( step ) => step . status !== 0 ) ? 1 : 0 ;
264+ return { exitCode, summary } ;
265+ }
243266
244- if ( steps . some ( ( step ) => step . status !== 0 ) ) {
267+ async function main ( params = { } ) {
268+ const options = parseArgs ( params . argv ?? process . argv . slice ( 2 ) ) ;
269+ const result = await runGatewayCpuScenarios ( options , params ) ;
270+ if ( result . exitCode !== 0 ) {
245271 process . exitCode = 1 ;
246272 }
247273}
248274
249- main ( ) . catch ( ( error ) => {
250- console . error ( error instanceof Error ? error . stack : String ( error ) ) ;
251- process . exitCode = 1 ;
252- } ) ;
275+ export const testing = {
276+ parseArgs,
277+ runGatewayCpuScenarios,
278+ } ;
279+
280+ if ( process . argv [ 1 ] && import . meta. url === pathToFileURL ( process . argv [ 1 ] ) . href ) {
281+ main ( ) . catch ( ( error ) => {
282+ console . error ( error instanceof Error ? error . stack : String ( error ) ) ;
283+ process . exitCode = 1 ;
284+ } ) ;
285+ }
0 commit comments