-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
✅ Your fuels version is up to date: 0.97.0 Config file not found! cleanup not killing node
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
--- | ||
"@fuel-ts/account": patch | ||
"fuels": patch | ||
--- | ||
|
||
fix: `fuels dev` cleanup not killing node |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import { execSync, spawn } from 'child_process'; | ||
import { mkdirSync, rmSync } from 'fs'; | ||
import { tmpdir } from 'os'; | ||
import path from 'path'; | ||
|
||
import { deferPromise, randomUUID } from '../../src'; | ||
import { findChildProcessPid } from '../utils/findChildProcessPid'; | ||
import { isProcessRunning } from '../utils/isProcessRunning'; | ||
|
||
function runInit() { | ||
const fuelsPath = path.join(process.cwd(), 'packages/fuels'); | ||
|
||
const init = path.join(tmpdir(), '.fuels', 'tests', randomUUID()); | ||
|
||
mkdirSync(init, { recursive: true }); | ||
|
||
execSync('pnpm init', { cwd: init }); | ||
execSync(`pnpm link ${fuelsPath}`, { cwd: init }); | ||
Check warning Code scanning / CodeQL Shell command built from environment values Medium test
This shell command depends on an uncontrolled
absolute path Error loading related location Loading |
||
|
||
const contractDir = path.join(init, 'contract'); | ||
const outputDir = path.join(init, 'output'); | ||
mkdirSync(contractDir); | ||
mkdirSync(outputDir); | ||
|
||
execSync(`${process.env.FORC_PATH} init`, { cwd: contractDir }); | ||
Check failure on line 25 in packages/fuels/test/features/dev-2.test.ts GitHub Actions / node@18packages/fuels/test/features/dev-2.test.ts > dev > cleans up resources on graceful shutdown
Check failure on line 25 in packages/fuels/test/features/dev-2.test.ts GitHub Actions / node@20packages/fuels/test/features/dev-2.test.ts > dev > cleans up resources on graceful shutdown
Check failure on line 25 in packages/fuels/test/features/dev-2.test.ts GitHub Actions / node@22packages/fuels/test/features/dev-2.test.ts > dev > cleans up resources on graceful shutdown
|
||
execSync(`pnpm fuels init -o ${outputDir} -c ${contractDir} --fuel-core-port 0`, { cwd: init }); | ||
|
||
return { | ||
init, | ||
[Symbol.dispose]: () => { | ||
rmSync(init, { recursive: true }); | ||
}, | ||
}; | ||
} | ||
|
||
/** | ||
* @group node | ||
*/ | ||
describe('dev', () => { | ||
it( | ||
'cleans up resources on graceful shutdown', | ||
async () => { | ||
using paths = runInit(); | ||
|
||
const devProcess = spawn('pnpm fuels dev', { | ||
shell: 'bash', | ||
detached: true, | ||
cwd: paths.init, | ||
}); | ||
|
||
const devCompleted = deferPromise(); | ||
|
||
devProcess.stdout.on('data', (chunk) => { | ||
const text = chunk.toString(); | ||
if (text.indexOf('Dev completed successfully!') !== -1) { | ||
devCompleted.resolve(undefined); | ||
} | ||
}); | ||
|
||
await devCompleted.promise; | ||
|
||
const devExited = deferPromise(); | ||
devProcess.on('exit', () => { | ||
devExited.resolve(undefined); | ||
}); | ||
|
||
const devPid = devProcess.pid as number; | ||
|
||
const fuelCorePid = findChildProcessPid(devPid, 'fuel-core') as number; | ||
|
||
process.kill(-devPid, 'SIGINT'); | ||
|
||
await devExited.promise; | ||
|
||
expect(isProcessRunning(fuelCorePid)).toBe(false); | ||
}, | ||
{ timeout: 15000 } | ||
); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import { execSync } from 'child_process'; | ||
|
||
export function findChildProcessPid( | ||
parentPid: number, | ||
childProcessName: string | ||
): number | undefined { | ||
const childProcesses = execSync(`ps --ppid ${parentPid} -o pid,cmd --no-headers || true`) | ||
.toString() | ||
.split('\n') | ||
.map((s) => s.trim()) | ||
.filter((s) => s !== ''); | ||
|
||
for (const cp of childProcesses) { | ||
const [pid, name] = cp.split(' '); | ||
if (name.indexOf(childProcessName) !== -1) { | ||
return +pid; | ||
} | ||
const childPid = findChildProcessPid(+pid, childProcessName); | ||
if (childPid) { | ||
return childPid; | ||
} | ||
} | ||
|
||
return undefined; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
export function isProcessRunning(pid: number) { | ||
try { | ||
// Check if the process exists | ||
process.kill(pid, 0); | ||
return true; // If no error, the process is running | ||
} catch (e) { | ||
const error = e as Error & { code: string }; | ||
// Error codes: | ||
// ESRCH: No such process | ||
// EPERM: Permission denied (you don't have permissions to check) | ||
if (error.code === 'ESRCH') { | ||
return false; // No such process | ||
} | ||
if (error.code === 'EPERM') { | ||
return true; // Process exists, but we don't have permission to send a signal | ||
} | ||
throw error; // Some other unexpected error | ||
} | ||
} |