From 15cb9fe91843353d93ef3515951a4ac7540cfe49 Mon Sep 17 00:00:00 2001 From: sudacode Date: Thu, 1 Oct 2026 01:42:10 -0700 Subject: [PATCH] test(launcher): allow Windows bootstrap integration startup time Cold and cached launches each have a 15-second command timeout. Give the integration test time for both launches and executable copies instead of the default five-second budget on hosted Windows runners. --- .../windows-launcher-bootstrap.test.ts | 121 ++++++++++-------- 1 file changed, 66 insertions(+), 55 deletions(-) diff --git a/src/main/runtime/windows-launcher-bootstrap.test.ts b/src/main/runtime/windows-launcher-bootstrap.test.ts index 5f17c30c..6cd1a918 100644 --- a/src/main/runtime/windows-launcher-bootstrap.test.ts +++ b/src/main/runtime/windows-launcher-bootstrap.test.ts @@ -68,61 +68,72 @@ test('preparation failures keep their exit code and never continue to the launch assert.match(content, /set "ELECTRON_RUN_AS_NODE="/); }); -test('Windows bootstrap prepares once and forwards metacharacter arguments', async (t) => { - if (process.platform !== 'win32') return; +// Cold and cached launches each allow 15 seconds, plus executable copies during setup. +test( + 'Windows bootstrap prepares once and forwards metacharacter arguments', + { timeout: 45_000 }, + async (t) => { + if (process.platform !== 'win32') return; - const root = workspace(t); - const appDirectory = path.join(root, 'Installed & App 100% !'); - const appPath = path.join(appDirectory, 'SubMiner.exe'); - const resourcesPath = path.join(appDirectory, 'resources'); - const launcherDirectory = path.join(resourcesPath, 'launcher'); - const localAppData = path.join(root, 'Local App Data'); - const bootstrapPath = path.join(root, 'subminer.cmd'); - const version = '1.2.3-test'; - const cachedBunPath = path.join(localAppData, 'SubMiner', 'launcher-runtime', version, 'bun.exe'); - fs.mkdirSync(launcherDirectory, { recursive: true }); - fs.copyFileSync(process.execPath, appPath); - fs.writeFileSync(path.join(launcherDirectory, 'version'), version); - fs.writeFileSync( - path.join(launcherDirectory, 'subminer.js'), - 'console.log(JSON.stringify({args:process.argv.slice(2),app:process.env.SUBMINER_BINARY_PATH,resources:process.env.SUBMINER_RESOURCES_PATH,managed:process.env.SUBMINER_MANAGED_LAUNCHER}));', - ); - fs.writeFileSync( - path.join(launcherDirectory, 'prepare.cjs'), - `const fs=require('node:fs');const path=require('node:path');exports.prepareLauncherRuntime=()=>{const target=${JSON.stringify(cachedBunPath)};fs.mkdirSync(path.dirname(target),{recursive:true});fs.copyFileSync(process.execPath,target);};`, - ); - fs.writeFileSync(bootstrapPath, windowsLauncherBootstrapContent(appPath)); + const root = workspace(t); + const appDirectory = path.join(root, 'Installed & App 100% !'); + const appPath = path.join(appDirectory, 'SubMiner.exe'); + const resourcesPath = path.join(appDirectory, 'resources'); + const launcherDirectory = path.join(resourcesPath, 'launcher'); + const localAppData = path.join(root, 'Local App Data'); + const bootstrapPath = path.join(root, 'subminer.cmd'); + const version = '1.2.3-test'; + const cachedBunPath = path.join( + localAppData, + 'SubMiner', + 'launcher-runtime', + version, + 'bun.exe', + ); + fs.mkdirSync(launcherDirectory, { recursive: true }); + fs.copyFileSync(process.execPath, appPath); + fs.writeFileSync(path.join(launcherDirectory, 'version'), version); + fs.writeFileSync( + path.join(launcherDirectory, 'subminer.js'), + 'console.log(JSON.stringify({args:process.argv.slice(2),app:process.env.SUBMINER_BINARY_PATH,resources:process.env.SUBMINER_RESOURCES_PATH,managed:process.env.SUBMINER_MANAGED_LAUNCHER}));', + ); + fs.writeFileSync( + path.join(launcherDirectory, 'prepare.cjs'), + `const fs=require('node:fs');const path=require('node:path');exports.prepareLauncherRuntime=()=>{const target=${JSON.stringify(cachedBunPath)};fs.mkdirSync(path.dirname(target),{recursive:true});fs.copyFileSync(process.execPath,target);};`, + ); + fs.writeFileSync(bootstrapPath, windowsLauncherBootstrapContent(appPath)); - const args = [ - 'spaces here', - '100%', - 'p%TEMP%q', - 'bang!', - 'a&b', - 'x|y', - '', - 'caret^', - 'say "hi"', - '日本語', - ]; - const env = { ...process.env, PATH: '', Path: '', LOCALAPPDATA: localAppData }; - const first = await getRunCommand({})(bootstrapPath, args, { env }); - assert.equal(first.exitCode, 0, first.stderr); - assert.ok(fs.existsSync(cachedBunPath)); - const firstPayload: unknown = JSON.parse(first.stdout); - assert.deepEqual(firstPayload, { - args, - app: appPath, - resources: resourcesPath, - managed: '1', - }); + const args = [ + 'spaces here', + '100%', + 'p%TEMP%q', + 'bang!', + 'a&b', + 'x|y', + '', + 'caret^', + 'say "hi"', + '日本語', + ]; + const env = { ...process.env, PATH: '', Path: '', LOCALAPPDATA: localAppData }; + const first = await getRunCommand({})(bootstrapPath, args, { env }); + assert.equal(first.exitCode, 0, first.stderr); + assert.ok(fs.existsSync(cachedBunPath)); + const firstPayload: unknown = JSON.parse(first.stdout); + assert.deepEqual(firstPayload, { + args, + app: appPath, + resources: resourcesPath, + managed: '1', + }); - fs.writeFileSync( - path.join(launcherDirectory, 'prepare.cjs'), - "throw new Error('cached launch should not prepare');", - ); - const second = await getRunCommand({})(bootstrapPath, args, { env }); - assert.equal(second.exitCode, 0, second.stderr); - const secondPayload: unknown = JSON.parse(second.stdout); - assert.deepEqual(secondPayload, firstPayload); -}); + fs.writeFileSync( + path.join(launcherDirectory, 'prepare.cjs'), + "throw new Error('cached launch should not prepare');", + ); + const second = await getRunCommand({})(bootstrapPath, args, { env }); + assert.equal(second.exitCode, 0, second.stderr); + const secondPayload: unknown = JSON.parse(second.stdout); + assert.deepEqual(secondPayload, firstPayload); + }, +);