Skip to content

Commit a55e4d5

Browse files
authored
test: Fix node-integration-test timeouts & cleanup (#13280)
This PR streamlines and fixes some timing/cleanup issues we had in integration tests, which sometimes lead to issues. One problem was introduced here: #13253 This change lead to the server being shut down (because `done` is called) before the HTTP requests are finished, leading to error logs. Another problem was that in some cases we had leaking processes, where we did not properly close servers we started - this was everywhere we used `createTestServer`. I also moved some code from the node-integration-tests package to the remix package, that was only used there (and not properly depended/imported on). For future debugging, this was shown by running tests with `--detectOpenHandles`.
1 parent 88fef5b commit a55e4d5

File tree

38 files changed

+369
-324
lines changed

38 files changed

+369
-324
lines changed

dev-packages/node-integration-tests/README.md

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,6 @@ requests, and assertions. Test server, interceptors and assertions are all run o
3838

3939
`utils/` contains helpers and Sentry-specific assertions that can be used in (`test.ts`).
4040

41-
`TestEnv` class contains methods to create and execute requests on a test server instance. `TestEnv.init()` which starts
42-
a test server and returns a `TestEnv` instance must be called by each test. The test server is automatically shut down
43-
after each test, if a data collection helper method such as `getEnvelopeRequest` and `getAPIResponse` is used. Tests
44-
that do not use those helper methods will need to end the server manually.
45-
46-
`TestEnv` instance has two public properties: `url` and `server`. The `url` property is the base URL for the server. The
47-
`http.Server` instance is used to finish the server eventually.
48-
4941
Nock interceptors are internally used to capture envelope requests by `getEnvelopeRequest` and
5042
`getMultipleEnvelopeRequest` helpers. After capturing required requests, the interceptors are removed. Nock can manually
5143
be used inside the test cases to intercept requests but should be removed before the test ends, as not to cause

dev-packages/node-integration-tests/jest.setup.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
const { cleanupChildProcesses } = require('./utils/runner');
22

3-
// Increases test timeout from 5s to 45s
4-
jest.setTimeout(45000);
3+
// Default timeout: 15s
4+
jest.setTimeout(15000);
55

66
afterEach(() => {
77
cleanupChildProcesses();

dev-packages/node-integration-tests/suites/express/multiple-init/server.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,19 @@ app.get('/test/error/:id', (req, res) => {
5454

5555
setTimeout(() => {
5656
// We flush to ensure we are sending exceptions in a certain order
57-
Sentry.flush(3000).then(
57+
Sentry.flush(1000).then(
5858
() => {
59+
// We send this so we can wait for this, to know the test is ended & server can be closed
60+
if (id === '3') {
61+
Sentry.captureException(new Error('Final exception was captured'));
62+
}
5963
res.send({});
6064
},
6165
() => {
6266
res.send({});
6367
},
6468
);
65-
}, 1000);
69+
}, 1);
6670
});
6771

6872
Sentry.setupExpressErrorHandler(app);

dev-packages/node-integration-tests/suites/express/multiple-init/test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,17 @@ test('allows to call init multiple times', done => {
4848
},
4949
},
5050
})
51+
.expect({
52+
event: {
53+
exception: {
54+
values: [
55+
{
56+
value: 'Final exception was captured',
57+
},
58+
],
59+
},
60+
},
61+
})
5162
.start(done);
5263

5364
runner

dev-packages/node-integration-tests/suites/public-api/LocalVariables/test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ import * as path from 'path';
33
import { conditionalTest } from '../../../utils';
44
import { cleanupChildProcesses, createRunner } from '../../../utils/runner';
55

6+
// This test takes some time because it connects the debugger etc.
7+
// So we increase the timeout here
8+
jest.setTimeout(45_000);
9+
610
const EXPECTED_LOCAL_VARIABLES_EVENT = {
711
exception: {
812
values: [

dev-packages/node-integration-tests/suites/tracing/connect/scenario.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Sentry.init({
1313
const connect = require('connect');
1414
const http = require('http');
1515

16-
const init = async () => {
16+
const run = async () => {
1717
const app = connect();
1818

1919
app.use('/', function (req, res, next) {
@@ -34,4 +34,4 @@ const init = async () => {
3434
sendPortToRunner(port);
3535
};
3636

37-
init();
37+
run();

dev-packages/node-integration-tests/suites/tracing/connect/test.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import { cleanupChildProcesses, createRunner } from '../../../utils/runner';
22

3-
jest.setTimeout(20000);
4-
53
describe('connect auto-instrumentation', () => {
64
afterAll(async () => {
75
cleanupChildProcesses();

dev-packages/node-integration-tests/suites/tracing/hapi/scenario.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const Boom = require('@hapi/boom');
1313

1414
const port = 5999;
1515

16-
const init = async () => {
16+
const run = async () => {
1717
const server = Hapi.server({
1818
host: 'localhost',
1919
port,
@@ -65,4 +65,4 @@ const init = async () => {
6565
sendPortToRunner(port);
6666
};
6767

68-
init();
68+
run();

dev-packages/node-integration-tests/suites/tracing/hapi/test.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import { cleanupChildProcesses, createRunner } from '../../../utils/runner';
22

3-
jest.setTimeout(20000);
4-
53
describe('hapi auto-instrumentation', () => {
64
afterAll(async () => {
75
cleanupChildProcesses();

dev-packages/node-integration-tests/suites/tracing/mongodb/test.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ import { MongoMemoryServer } from 'mongodb-memory-server-global';
22

33
import { cleanupChildProcesses, createRunner } from '../../../utils/runner';
44

5-
jest.setTimeout(20000);
6-
75
describe('MongoDB experimental Test', () => {
86
let mongoServer: MongoMemoryServer;
97

dev-packages/node-integration-tests/suites/tracing/mongoose/test.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ import { MongoMemoryServer } from 'mongodb-memory-server-global';
22

33
import { cleanupChildProcesses, createRunner } from '../../../utils/runner';
44

5-
jest.setTimeout(20000);
6-
75
describe('Mongoose experimental Test', () => {
86
let mongoServer: MongoMemoryServer;
97

dev-packages/node-integration-tests/suites/tracing/mysql2/test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import { cleanupChildProcesses, createRunner } from '../../../utils/runner';
22

3+
// When running docker compose, we need a larger timeout, as this takes some time...
4+
jest.setTimeout(75000);
5+
36
describe('mysql2 auto instrumentation', () => {
47
afterAll(() => {
58
cleanupChildProcesses();

dev-packages/node-integration-tests/suites/tracing/nestjs-errors-no-express/scenario.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class AppController {
4747
})
4848
class AppModule {}
4949

50-
async function init(): Promise<void> {
50+
async function run(): Promise<void> {
5151
const app = await NestFactory.create(AppModule);
5252
const { httpAdapter } = app.get(HttpAdapterHost);
5353
Sentry.setupNestErrorHandler(app, new BaseExceptionFilter(httpAdapter));
@@ -56,4 +56,4 @@ async function init(): Promise<void> {
5656
}
5757

5858
// eslint-disable-next-line @typescript-eslint/no-floating-promises
59-
init();
59+
run();

dev-packages/node-integration-tests/suites/tracing/nestjs-errors-no-express/test.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import { conditionalTest } from '../../../utils';
22
import { cleanupChildProcesses, createRunner } from '../../../utils/runner';
33

4-
jest.setTimeout(20000);
5-
64
const { TS_VERSION } = process.env;
75
const isOldTS = TS_VERSION && TS_VERSION.startsWith('3.');
86

dev-packages/node-integration-tests/suites/tracing/nestjs-errors/scenario.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class AppController {
4545
})
4646
class AppModule {}
4747

48-
async function init(): Promise<void> {
48+
async function run(): Promise<void> {
4949
const app = await NestFactory.create(AppModule);
5050
const { httpAdapter } = app.get(HttpAdapterHost);
5151
Sentry.setupNestErrorHandler(app, new BaseExceptionFilter(httpAdapter));
@@ -54,4 +54,4 @@ async function init(): Promise<void> {
5454
}
5555

5656
// eslint-disable-next-line @typescript-eslint/no-floating-promises
57-
init();
57+
run();

dev-packages/node-integration-tests/suites/tracing/nestjs-errors/test.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import { conditionalTest } from '../../../utils';
22
import { cleanupChildProcesses, createRunner } from '../../../utils/runner';
33

4-
jest.setTimeout(20000);
5-
64
const { TS_VERSION } = process.env;
75
const isOldTS = TS_VERSION && TS_VERSION.startsWith('3.');
86

dev-packages/node-integration-tests/suites/tracing/nestjs-no-express/scenario.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class AppController {
4747
})
4848
class AppModule {}
4949

50-
async function init(): Promise<void> {
50+
async function run(): Promise<void> {
5151
const app = await NestFactory.create(AppModule);
5252
const { httpAdapter } = app.get(HttpAdapterHost);
5353
Sentry.setupNestErrorHandler(app, new BaseExceptionFilter(httpAdapter));
@@ -56,4 +56,4 @@ async function init(): Promise<void> {
5656
}
5757

5858
// eslint-disable-next-line @typescript-eslint/no-floating-promises
59-
init();
59+
run();

dev-packages/node-integration-tests/suites/tracing/nestjs-no-express/test.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import { conditionalTest } from '../../../utils';
22
import { cleanupChildProcesses, createRunner } from '../../../utils/runner';
33

4-
jest.setTimeout(20000);
5-
64
const { TS_VERSION } = process.env;
75
const isOldTS = TS_VERSION && TS_VERSION.startsWith('3.');
86

dev-packages/node-integration-tests/suites/tracing/nestjs/scenario.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,11 @@ class AppController {
4545
})
4646
class AppModule {}
4747

48-
async function init(): Promise<void> {
48+
async function run(): Promise<void> {
4949
const app = await NestFactory.create(AppModule);
5050
await app.listen(port);
5151
sendPortToRunner(port);
5252
}
5353

5454
// eslint-disable-next-line @typescript-eslint/no-floating-promises
55-
init();
55+
run();

dev-packages/node-integration-tests/suites/tracing/nestjs/test.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import { conditionalTest } from '../../../utils';
22
import { cleanupChildProcesses, createRunner } from '../../../utils/runner';
33

4-
jest.setTimeout(20000);
5-
64
const { TS_VERSION } = process.env;
75
const isOldTS = TS_VERSION && TS_VERSION.startsWith('3.');
86

dev-packages/node-integration-tests/suites/tracing/postgres/test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import { createRunner } from '../../../utils/runner';
22

3+
// When running docker compose, we need a larger timeout, as this takes some time...
4+
jest.setTimeout(75000);
5+
36
describe('postgres auto instrumentation', () => {
47
test('should auto-instrument `pg` package', done => {
58
const EXPECTED_TRANSACTION = {

dev-packages/node-integration-tests/suites/tracing/redis-cache/test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import { cleanupChildProcesses, createRunner } from '../../../utils/runner';
22

3+
// When running docker compose, we need a larger timeout, as this takes some time...
4+
jest.setTimeout(75000);
5+
36
describe('redis cache auto instrumentation', () => {
47
afterAll(() => {
58
cleanupChildProcesses();

dev-packages/node-integration-tests/suites/tracing/redis/test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import { cleanupChildProcesses, createRunner } from '../../../utils/runner';
22

3+
// When running docker compose, we need a larger timeout, as this takes some time...
4+
jest.setTimeout(75000);
5+
36
describe('redis auto instrumentation', () => {
47
afterAll(() => {
58
cleanupChildProcesses();

dev-packages/node-integration-tests/suites/tracing/requests/fetch-breadcrumbs/test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ conditionalTest({ min: 18 })('outgoing fetch', () => {
66
test('outgoing fetch requests create breadcrumbs', done => {
77
createTestServer(done)
88
.start()
9-
.then(SERVER_URL => {
9+
.then(([SERVER_URL, closeTestServer]) => {
1010
createRunner(__dirname, 'scenario.ts')
1111
.withEnv({ SERVER_URL })
1212
.ensureNoErrorOutput()
@@ -72,7 +72,7 @@ conditionalTest({ min: 18 })('outgoing fetch', () => {
7272
},
7373
},
7474
})
75-
.start(done);
75+
.start(closeTestServer);
7676
});
7777
});
7878
});

dev-packages/node-integration-tests/suites/tracing/requests/fetch-no-tracing/test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ conditionalTest({ min: 18 })('outgoing fetch', () => {
2626
expect(headers['sentry-trace']).toBeUndefined();
2727
})
2828
.start()
29-
.then(SERVER_URL => {
29+
.then(([SERVER_URL, closeTestServer]) => {
3030
createRunner(__dirname, 'scenario.ts')
3131
.withEnv({ SERVER_URL })
3232
.ensureNoErrorOutput()
@@ -42,7 +42,7 @@ conditionalTest({ min: 18 })('outgoing fetch', () => {
4242
},
4343
},
4444
})
45-
.start(done);
45+
.start(closeTestServer);
4646
});
4747
});
4848
});

dev-packages/node-integration-tests/suites/tracing/requests/fetch-sampled-no-active-span/test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ conditionalTest({ min: 18 })('outgoing fetch', () => {
2626
expect(headers['sentry-trace']).toBeUndefined();
2727
})
2828
.start()
29-
.then(SERVER_URL => {
29+
.then(([SERVER_URL, closeTestServer]) => {
3030
createRunner(__dirname, 'scenario.ts')
3131
.withEnv({ SERVER_URL })
3232
.expect({
@@ -41,7 +41,7 @@ conditionalTest({ min: 18 })('outgoing fetch', () => {
4141
},
4242
},
4343
})
44-
.start(done);
44+
.start(closeTestServer);
4545
});
4646
});
4747
});

dev-packages/node-integration-tests/suites/tracing/requests/fetch-unsampled/test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ conditionalTest({ min: 18 })('outgoing fetch', () => {
2626
expect(headers['sentry-trace']).toBeUndefined();
2727
})
2828
.start()
29-
.then(SERVER_URL => {
29+
.then(([SERVER_URL, closeTestServer]) => {
3030
createRunner(__dirname, 'scenario.ts')
3131
.withEnv({ SERVER_URL })
3232
.expect({
@@ -41,7 +41,7 @@ conditionalTest({ min: 18 })('outgoing fetch', () => {
4141
},
4242
},
4343
})
44-
.start(done);
44+
.start(closeTestServer);
4545
});
4646
});
4747
});

dev-packages/node-integration-tests/suites/tracing/requests/http-breadcrumbs/test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { createTestServer } from '../../../../utils/server';
44
test('outgoing http requests create breadcrumbs', done => {
55
createTestServer(done)
66
.start()
7-
.then(SERVER_URL => {
7+
.then(([SERVER_URL, closeTestServer]) => {
88
createRunner(__dirname, 'scenario.ts')
99
.withEnv({ SERVER_URL })
1010
.ensureNoErrorOutput()
@@ -70,6 +70,6 @@ test('outgoing http requests create breadcrumbs', done => {
7070
},
7171
},
7272
})
73-
.start(done);
73+
.start(closeTestServer);
7474
});
7575
});

dev-packages/node-integration-tests/suites/tracing/requests/http-no-tracing/test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ test('outgoing http requests are correctly instrumented with tracing disabled',
2424
expect(headers['sentry-trace']).toBeUndefined();
2525
})
2626
.start()
27-
.then(SERVER_URL => {
27+
.then(([SERVER_URL, closeTestServer]) => {
2828
createRunner(__dirname, 'scenario.ts')
2929
.withEnv({ SERVER_URL })
3030
.ensureNoErrorOutput()
@@ -40,6 +40,6 @@ test('outgoing http requests are correctly instrumented with tracing disabled',
4040
},
4141
},
4242
})
43-
.start(done);
43+
.start(closeTestServer);
4444
});
4545
});

dev-packages/node-integration-tests/suites/tracing/requests/http-sampled-no-active-span/test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ test('outgoing sampled http requests without active span are correctly instrumen
2424
expect(headers['sentry-trace']).toBeUndefined();
2525
})
2626
.start()
27-
.then(SERVER_URL => {
27+
.then(([SERVER_URL, closeTestServer]) => {
2828
createRunner(__dirname, 'scenario.ts')
2929
.withEnv({ SERVER_URL })
3030
.expect({
@@ -39,6 +39,6 @@ test('outgoing sampled http requests without active span are correctly instrumen
3939
},
4040
},
4141
})
42-
.start(done);
42+
.start(closeTestServer);
4343
});
4444
});

0 commit comments

Comments
 (0)