fix(e2e): add signal handlers and detailed tracing to diagnose exit code 13
This commit is contained in:
parent
f523d8ba3e
commit
75c8422b69
1 changed files with 34 additions and 2 deletions
|
|
@ -1,5 +1,24 @@
|
||||||
import { spawn } from 'node:child_process';
|
import { spawn } from 'node:child_process';
|
||||||
|
|
||||||
|
// Add signal handlers to debug unexpected termination
|
||||||
|
const signals = ['SIGTERM', 'SIGINT', 'SIGHUP', 'SIGPIPE', 'SIGQUIT'];
|
||||||
|
signals.forEach(sig => {
|
||||||
|
process.on(sig, () => {
|
||||||
|
console.error(`[pretest] Received signal: ${sig}`);
|
||||||
|
process.exit(128 + (process[sig] || 1));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
process.on('uncaughtException', (err) => {
|
||||||
|
console.error('[pretest] Uncaught exception:', err);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
process.on('unhandledRejection', (reason, promise) => {
|
||||||
|
console.error('[pretest] Unhandled rejection at:', promise, 'reason:', reason);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
|
||||||
const truthy = (value) => {
|
const truthy = (value) => {
|
||||||
if (!value) return false;
|
if (!value) return false;
|
||||||
return ['1', 'true', 'yes', 'on'].includes(String(value).trim().toLowerCase());
|
return ['1', 'true', 'yes', 'on'].includes(String(value).trim().toLowerCase());
|
||||||
|
|
@ -13,6 +32,7 @@ if (!process.env.PULSE_E2E_BOOTSTRAP_TOKEN) {
|
||||||
process.env.PULSE_E2E_BOOTSTRAP_TOKEN = DEFAULT_E2E_BOOTSTRAP_TOKEN;
|
process.env.PULSE_E2E_BOOTSTRAP_TOKEN = DEFAULT_E2E_BOOTSTRAP_TOKEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const run = (command, args, options = {}) =>
|
const run = (command, args, options = {}) =>
|
||||||
new Promise((resolve, reject) => {
|
new Promise((resolve, reject) => {
|
||||||
const child = spawn(command, args, { stdio: 'inherit', ...options });
|
const child = spawn(command, args, { stdio: 'inherit', ...options });
|
||||||
|
|
@ -35,19 +55,31 @@ const canRun = async (command, args) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const waitForHealth = async (healthURL, timeoutMs = 120_000) => {
|
const waitForHealth = async (healthURL, timeoutMs = 120_000) => {
|
||||||
|
console.log(`[pretest] Starting health check loop for ${healthURL}`);
|
||||||
const startedAt = Date.now();
|
const startedAt = Date.now();
|
||||||
|
let attempt = 0;
|
||||||
while (Date.now() - startedAt < timeoutMs) {
|
while (Date.now() - startedAt < timeoutMs) {
|
||||||
|
attempt++;
|
||||||
|
console.log(`[pretest] Health check attempt ${attempt}...`);
|
||||||
try {
|
try {
|
||||||
|
console.log(`[pretest] Calling fetch...`);
|
||||||
const res = await fetch(healthURL, { method: 'GET' });
|
const res = await fetch(healthURL, { method: 'GET' });
|
||||||
if (res.ok) return;
|
console.log(`[pretest] Fetch returned status ${res.status}`);
|
||||||
} catch {
|
if (res.ok) {
|
||||||
|
console.log(`[pretest] Health check succeeded!`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(`[pretest] Fetch error: ${error.code || error.message}`);
|
||||||
// ignore and retry
|
// ignore and retry
|
||||||
}
|
}
|
||||||
|
console.log(`[pretest] Sleeping 1s before retry...`);
|
||||||
await new Promise((r) => setTimeout(r, 1000));
|
await new Promise((r) => setTimeout(r, 1000));
|
||||||
}
|
}
|
||||||
throw new Error(`Timed out waiting for ${healthURL}`);
|
throw new Error(`Timed out waiting for ${healthURL}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
if (truthy(process.env.PULSE_E2E_INSECURE_TLS)) {
|
if (truthy(process.env.PULSE_E2E_INSECURE_TLS)) {
|
||||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue