Skip to content

Commit ba1a270

Browse files
JPeer264claude
andauthored
test(node): Fix flaky ANR tests by waiting for debugger to be ready (#21011)
closes #20704 closes [JS-2372](https://linear.app/getsentry/issue/JS-2372/flaky-ci-node-24-node-core-integration-tests-suitesanrtestts-should) closes #20959 closes [JS-2524](https://linear.app/getsentry/issue/JS-2524) The ANR worker thread creates an InspectorSession and connects to the main thread's debugger. Previously, tests would start blocking work immediately, but the debugger session might not be fully initialized yet, causing stack traces to capture the wrong location (processTimers instead of longWork). This adds a `waitForDebuggerReady` helper to the test utils that polls `inspector.url()` to detect when the debugger is active, then waits 200ms for the async session setup to complete before starting the blocking work. First the LLM suggested to increase the timeout, but I didn't think that was a good solution, given that CI good have worse when it's busy. I tested that locally a lot of times and tried to slow down the process, seemed stable so far. Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 6d00aba commit ba1a270

16 files changed

Lines changed: 79 additions & 42 deletions

File tree

dev-packages/node-core-integration-tests/suites/anr/app-path.mjs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import * as crypto from 'crypto';
44
import * as path from 'path';
55
import * as url from 'url';
66
import { setupOtel } from '../../utils/setupOtel.js';
7+
import { waitForDebuggerReady } from '@sentry-internal/test-utils';
78

89
global._sentryDebugIds = { [new Error().stack]: 'aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaa' };
910

@@ -32,6 +33,6 @@ function longWork() {
3233
}
3334
}
3435

35-
setTimeout(() => {
36+
waitForDebuggerReady(() => {
3637
longWork();
37-
}, 1000);
38+
});

dev-packages/node-core-integration-tests/suites/anr/basic-multiple.mjs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as Sentry from '@sentry/node-core';
22
import * as assert from 'assert';
33
import * as crypto from 'crypto';
44
import { setupOtel } from '../../utils/setupOtel.js';
5+
import { waitForDebuggerReady } from '@sentry-internal/test-utils';
56

67
global._sentryDebugIds = { [new Error().stack]: 'aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaa' };
78

@@ -28,10 +29,11 @@ function longWork() {
2829
}
2930
}
3031

31-
setTimeout(() => {
32+
waitForDebuggerReady(() => {
3233
longWork();
33-
}, 1000);
3434

35-
setTimeout(() => {
36-
longWork();
37-
}, 4000);
35+
// Second blocking event for maxAnrEvents test
36+
setTimeout(() => {
37+
longWork();
38+
}, 2000);
39+
});

dev-packages/node-core-integration-tests/suites/anr/basic-session.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ const assert = require('assert');
33

44
const Sentry = require('@sentry/node-core');
55
const { setupOtel } = require('../../utils/setupOtel.js');
6+
const { waitForDebuggerReady } = require('@sentry-internal/test-utils');
67

78
setTimeout(() => {
89
process.exit();
@@ -27,6 +28,6 @@ function longWork() {
2728
}
2829
}
2930

30-
setTimeout(() => {
31+
waitForDebuggerReady(() => {
3132
longWork();
32-
}, 1000);
33+
});

dev-packages/node-core-integration-tests/suites/anr/basic.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ const assert = require('assert');
33

44
const Sentry = require('@sentry/node-core');
55
const { setupOtel } = require('../../utils/setupOtel.js');
6+
const { waitForDebuggerReady } = require('@sentry-internal/test-utils');
67

78
global._sentryDebugIds = { [new Error().stack]: 'aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaa' };
89

@@ -29,6 +30,6 @@ function longWork() {
2930
}
3031
}
3132

32-
setTimeout(() => {
33+
waitForDebuggerReady(() => {
3334
longWork();
34-
}, 1000);
35+
});

dev-packages/node-core-integration-tests/suites/anr/basic.mjs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as Sentry from '@sentry/node-core';
22
import * as assert from 'assert';
33
import * as crypto from 'crypto';
44
import { setupOtel } from '../../utils/setupOtel.js';
5+
import { waitForDebuggerReady } from '@sentry-internal/test-utils';
56

67
global._sentryDebugIds = { [new Error().stack]: 'aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaa' };
78

@@ -28,11 +29,11 @@ function longWork() {
2829
}
2930
}
3031

31-
setTimeout(() => {
32+
waitForDebuggerReady(() => {
3233
longWork();
33-
}, 1000);
3434

35-
// Ensure we only send one event even with multiple blocking events
36-
setTimeout(() => {
37-
longWork();
38-
}, 4000);
35+
// Ensure we only send one event even with multiple blocking events
36+
setTimeout(() => {
37+
longWork();
38+
}, 2000);
39+
});

dev-packages/node-core-integration-tests/suites/anr/forked.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ const assert = require('assert');
33

44
const Sentry = require('@sentry/node-core');
55
const { setupOtel } = require('../../utils/setupOtel.js');
6+
const { waitForDebuggerReady } = require('@sentry-internal/test-utils');
67

78
setTimeout(() => {
89
process.exit();
@@ -28,6 +29,6 @@ function longWork() {
2829
}
2930
}
3031

31-
setTimeout(() => {
32+
waitForDebuggerReady(() => {
3233
longWork();
33-
}, 1000);
34+
});

dev-packages/node-core-integration-tests/suites/anr/indefinite.mjs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as Sentry from '@sentry/node-core';
22
import * as assert from 'assert';
33
import * as crypto from 'crypto';
44
import { setupOtel } from '../../utils/setupOtel.js';
5+
import { waitForDebuggerReady } from '@sentry-internal/test-utils';
56

67
setTimeout(() => {
78
process.exit();
@@ -27,6 +28,6 @@ function longWork() {
2728
}
2829
}
2930

30-
setTimeout(() => {
31+
waitForDebuggerReady(() => {
3132
longWork();
32-
}, 1000);
33+
});

dev-packages/node-integration-tests/suites/anr/app-path.mjs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import * as assert from 'assert';
33
import * as crypto from 'crypto';
44
import * as path from 'path';
55
import * as url from 'url';
6+
import { waitForDebuggerReady } from '@sentry-internal/test-utils';
67

78
global._sentryDebugIds = { [new Error().stack]: 'aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaa' };
89

@@ -29,6 +30,6 @@ function longWork() {
2930
}
3031
}
3132

32-
setTimeout(() => {
33+
waitForDebuggerReady(() => {
3334
longWork();
34-
}, 1000);
35+
});

dev-packages/node-integration-tests/suites/anr/basic-multiple.mjs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as Sentry from '@sentry/node';
22
import * as assert from 'assert';
33
import * as crypto from 'crypto';
4+
import { waitForDebuggerReady } from '@sentry-internal/test-utils';
45

56
global._sentryDebugIds = { [new Error().stack]: 'aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaa' };
67

@@ -25,10 +26,11 @@ function longWork() {
2526
}
2627
}
2728

28-
setTimeout(() => {
29+
waitForDebuggerReady(() => {
2930
longWork();
30-
}, 1000);
3131

32-
setTimeout(() => {
33-
longWork();
34-
}, 4000);
32+
// Second blocking event for maxAnrEvents test
33+
setTimeout(() => {
34+
longWork();
35+
}, 2000);
36+
});

dev-packages/node-integration-tests/suites/anr/basic-session.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ const crypto = require('crypto');
22
const assert = require('assert');
33

44
const Sentry = require('@sentry/node');
5+
const { waitForDebuggerReady } = require('@sentry-internal/test-utils');
56

67
setTimeout(() => {
78
process.exit();
@@ -24,6 +25,6 @@ function longWork() {
2425
}
2526
}
2627

27-
setTimeout(() => {
28+
waitForDebuggerReady(() => {
2829
longWork();
29-
}, 1000);
30+
});

0 commit comments

Comments
 (0)