Skip to content

Commit 2e164e1

Browse files
authored
test(node): Add utility to test esm & cjs instrumentation (#16159)
Today, we do not have a lot of esm-specific node integration tests. Our tests make it possible to test ESM, but we only use it very rarely, sticking to cjs tests across the suite mostly. This means that we have a bunch of gaps around our ESM support. This PR introduces a new test utility to make it easier to test stuff in ESM and CJS: ```js createEsmAndCjsTests( __dirname, 'scenario.mjs', 'instrument.mjs', (createRunner, test) => { test('it works when importing the http module', async () => { const runner = createRunner(); // normal test as before }); }); ``` This has a few limitations based on how this works - we can make this more robust in the future, but for now it should be "OK": 1. It requires a .mjs based instrument file as well as an .mjs based scenario 2. No relative imports are supported (all content must be in these two files) 3. It simply regex replaces the esm imports with require for the CJS tests. not perfect, but it kind of works For tests that are known to fail on e.g. esm or cjs, you can configure `failsOnEsm: true`. In this case, it will fail if the test _does not fail_ (by using `test.fails()` to ensure test failure). This way we can ensure we find out if stuff starts to fail etc. To make this work, I had to re-write the test runner code a bit, because it had issues with vitest unhandled rejection handling. Due to the way we handled test completion with a promise, `test.fails` was not working as expected, because the test indeed succeeded when it failed, but the overall test run still failed because an unhandled rejection bubbled up. Now, this should work as expected... I re-wrote a few tests already to show how it works, plus added a new test that shows an ESM test failure when importing http module (😭 )
1 parent 2130d35 commit 2e164e1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+818
-703
lines changed

dev-packages/node-integration-tests/.eslintrc.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,11 @@ module.exports = {
1212
},
1313
},
1414
{
15-
files: ['suites/**/*.ts'],
15+
files: ['suites/**/*.ts', 'suites/**/*.mjs'],
1616
parserOptions: {
1717
project: ['tsconfig.test.json'],
1818
sourceType: 'module',
19+
ecmaVersion: 'latest',
1920
},
2021
rules: {
2122
'@typescript-eslint/typedef': 'off',
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
suites/**/tmp_*

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1+
import * as Sentry from '@sentry/node';
12
import * as assert from 'assert';
23
import * as crypto from 'crypto';
34
import * as path from 'path';
45
import * as url from 'url';
56

6-
import * as Sentry from '@sentry/node';
7-
87
global._sentryDebugIds = { [new Error().stack]: 'aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaa' };
98

109
const __dirname = path.dirname(url.fileURLToPath(import.meta.url));

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1+
import * as Sentry from '@sentry/node';
12
import * as assert from 'assert';
23
import * as crypto from 'crypto';
34

4-
import * as Sentry from '@sentry/node';
5-
65
global._sentryDebugIds = { [new Error().stack]: 'aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaa' };
76

87
setTimeout(() => {

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1+
import * as Sentry from '@sentry/node';
12
import * as assert from 'assert';
23
import * as crypto from 'crypto';
34

4-
import * as Sentry from '@sentry/node';
5-
65
global._sentryDebugIds = { [new Error().stack]: 'aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaa' };
76

87
setTimeout(() => {

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1+
import * as Sentry from '@sentry/node';
12
import * as assert from 'assert';
23
import * as crypto from 'crypto';
34

4-
import * as Sentry from '@sentry/node';
5-
65
setTimeout(() => {
76
process.exit();
87
}, 10000);

dev-packages/node-integration-tests/suites/anr/isolated.mjs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1+
import * as Sentry from '@sentry/node';
12
import * as assert from 'assert';
23
import * as crypto from 'crypto';
34

4-
import * as Sentry from '@sentry/node';
5-
65
setTimeout(() => {
76
process.exit();
87
}, 10000);

dev-packages/node-integration-tests/suites/anr/test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ const ANR_EVENT_WITH_DEBUG_META: Event = {
107107
},
108108
};
109109

110-
describe('should report ANR when event loop blocked', { timeout: 60_000 }, () => {
110+
describe('should report ANR when event loop blocked', { timeout: 90_000 }, () => {
111111
afterAll(() => {
112112
cleanupChildProcesses();
113113
});
Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1+
import * as Sentry from '@sentry/node';
2+
import { loggingTransport } from '@sentry-internal/node-integration-tests';
13
import { spawn } from 'child_process';
24
import { join } from 'path';
3-
import { loggingTransport } from '@sentry-internal/node-integration-tests';
4-
import * as Sentry from '@sentry/node';
55
import { Worker } from 'worker_threads';
66

77
const __dirname = new URL('.', import.meta.url).pathname;
@@ -13,16 +13,18 @@ Sentry.init({
1313
transport: loggingTransport,
1414
});
1515

16-
await new Promise(resolve => {
17-
const child = spawn('sleep', ['a']);
18-
child.on('error', resolve);
19-
child.on('exit', resolve);
20-
});
16+
(async () => {
17+
await new Promise(resolve => {
18+
const child = spawn('sleep', ['a']);
19+
child.on('error', resolve);
20+
child.on('exit', resolve);
21+
});
2122

22-
await new Promise(resolve => {
23-
const worker = new Worker(join(__dirname, 'worker.mjs'));
24-
worker.on('error', resolve);
25-
worker.on('exit', resolve);
26-
});
23+
await new Promise(resolve => {
24+
const worker = new Worker(join(__dirname, 'worker.mjs'));
25+
worker.on('error', resolve);
26+
worker.on('exit', resolve);
27+
});
2728

28-
throw new Error('This is a test error');
29+
throw new Error('This is a test error');
30+
})();

dev-packages/node-integration-tests/suites/child-process/fork.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ Sentry.init({
1010
transport: loggingTransport,
1111
});
1212

13-
// eslint-disable-next-line no-unused-vars
14-
const _child = fork(path.join(__dirname, 'child.mjs'));
13+
fork(path.join(__dirname, 'child.mjs'));
1514

1615
setTimeout(() => {
1716
throw new Error('Exiting main process');

0 commit comments

Comments
 (0)