diff --git a/docs/plans/current_spec.md b/docs/plans/current_spec.md index 91ffcbe2..03e308b3 100644 --- a/docs/plans/current_spec.md +++ b/docs/plans/current_spec.md @@ -89,6 +89,7 @@ npx playwright test - [x] Modify playwright.config.js to comment out security projects - [x] Remove security-tests dependency from browser projects - [x] Fix Go cache path in e2e-tests.yml workflow +- [x] Optimize global-setup.ts to prevent hanging on emergency reset - [ ] Commit with clear diagnostic message - [ ] Trigger CI run - [ ] Analyze results and document findings @@ -119,3 +120,42 @@ Restore cache failed: Dependencies file is not found in /home/runner/work/Charon ``` **Impact**: The Go module cache will now properly restore, speeding up the build process by ~30-60 seconds per run. + +### Global Setup Optimization (Hanging Prevention) + +**Issue**: Shards were hanging after the "Skipping authenticated security reset" message during global-setup.ts execution. + +**Root Cause**: +1. Emergency security reset API calls had no timeout - could hang indefinitely +2. 2-second propagation delay after each reset (called twice = 4+ seconds) +3. Pre-auth reset was being attempted even on fresh containers where it's unnecessary + +**Fixes Applied**: +1. **Added 5-second timeout** to emergency reset API calls to prevent indefinite hangs +2. **Reduced propagation delay** from 2000ms to 500ms (fresh containers don't need long waits) +3. **Skip pre-auth reset in CI** when using default test token (fresh containers start clean) + +**Before**: +```typescript +const response = await requestContext.post('/api/v1/emergency/security-reset', { + headers: { 'X-Emergency-Token': emergencyToken }, + // No timeout - could hang forever +}); +// ... +await new Promise(resolve => setTimeout(resolve, 2000)); // 2s wait +``` + +**After**: +```typescript +const response = await requestContext.post('/api/v1/emergency/security-reset', { + headers: { 'X-Emergency-Token': emergencyToken }, + timeout: 5000, // 5s timeout prevents hanging +}); +// ... +await new Promise(resolve => setTimeout(resolve, 500)); // 500ms wait +``` + +**Impact**: +- ✅ Prevents shards from hanging on global-setup +- ✅ Reduces global-setup time by ~3-4 seconds per shard +- ✅ Skips unnecessary emergency reset on fresh CI containers diff --git a/tests/global-setup.ts b/tests/global-setup.ts index e7f0466e..8b6a21cf 100644 --- a/tests/global-setup.ts +++ b/tests/global-setup.ts @@ -28,13 +28,18 @@ async function globalSetup(): Promise { // Pre-auth security reset attempt (crash protection failsafe) // This attempts to disable security modules BEFORE auth, in case a previous run crashed // with security enabled blocking the auth endpoint. - const preAuthContext = await request.newContext({ baseURL }); - try { - await emergencySecurityReset(preAuthContext); - } catch (e) { - console.log('Pre-auth security reset skipped (may require auth)'); + // SKIPPED in CI when CHARON_EMERGENCY_TOKEN is not set - fresh containers don't need reset + if (process.env.CHARON_EMERGENCY_TOKEN && process.env.CHARON_EMERGENCY_TOKEN !== 'test-emergency-token-for-e2e-32chars') { + const preAuthContext = await request.newContext({ baseURL }); + try { + await emergencySecurityReset(preAuthContext); + } catch (e) { + console.log('⏭️ Pre-auth security reset skipped (may require auth)'); + } + await preAuthContext.dispose(); + } else { + console.log('⏭️ Pre-auth security reset skipped (fresh container, no custom token)'); } - await preAuthContext.dispose(); // Create a request context const requestContext = await request.newContext({ @@ -135,6 +140,7 @@ async function emergencySecurityReset(requestContext: APIRequestContext): Promis headers: { 'X-Emergency-Token': emergencyToken, }, + timeout: 5000, // 5s timeout to prevent hanging }); if (!response.ok()) { @@ -146,15 +152,15 @@ async function emergencySecurityReset(requestContext: APIRequestContext): Promis const result = await response.json(); console.log(' ✅ Emergency reset successful'); console.log(` ✅ Disabled modules: ${result.disabled_modules?.join(', ')}`); + + // Reduced wait time - fresh containers don't need long propagation + console.log(' ⏳ Waiting for security reset to propagate...'); + await new Promise(resolve => setTimeout(resolve, 500)); } catch (e) { console.error(` ❌ Emergency reset error: ${e}`); throw e; } - // Wait for settings to propagate - console.log(' ⏳ Waiting for security reset to propagate...'); - await new Promise(resolve => setTimeout(resolve, 2000)); - console.log(' ✅ Security reset complete'); }