Skip to content

Commit 28bce1c

Browse files
authored
ref: Introduce test runner for node session health tests (#3728)
* ref: Introduce test runner for node session health tests * Make it work on Node 6
1 parent ac3cf20 commit 28bce1c

10 files changed

+111
-42
lines changed

packages/node/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,13 @@
6060
"test:watch": "jest --watch",
6161
"test:express": "node test/manual/express-scope-separation/start.js",
6262
"test:webpack": "cd test/manual/webpack-domain/ && yarn && node npm-build.js",
63-
"test:release-health": "node test/manual/release-health/single-session/healthy-session.js && node test/manual/release-health/single-session/caught-exception-errored-session.js && node test/manual/release-health/single-session/uncaught-exception-crashed-session.js && node test/manual/release-health/single-session/unhandled-rejection-crashed-session.js && node test/manual/release-health/session-aggregates/aggregates-disable-single-session.js && node test/manual/release-health/single-session/errors-in-session-capped-to-one.js & node test/manual/release-health/single-session/terminal-state-sessions-sent-once.js",
63+
"test:release-health": "node test/manual/release-health/runner.js",
6464
"pack": "npm pack",
6565
"circularDepCheck": "madge --circular src/index.ts"
6666
},
6767
"volta": {
68-
"extends": "../../package.json"
68+
"extends": "../../package.json",
69+
"node": "6.17.1"
6970
},
7071
"jest": {
7172
"collectCoverage": true,
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
const fs = require('fs');
2+
const path = require('path');
3+
const { spawn } = require('child_process');
4+
5+
const COLOR_RESET = '\x1b[0m';
6+
const COLORS = {
7+
green: '\x1b[32m',
8+
red: '\x1b[31m',
9+
yellow: '\x1b[33m',
10+
};
11+
12+
const colorize = (str, color) => {
13+
if (!(color in COLORS)) {
14+
throw new Error(`Unknown color. Available colors: ${Object.keys(COLORS).join(', ')}`);
15+
}
16+
17+
return `${COLORS[color]}${str}${COLOR_RESET}`;
18+
};
19+
20+
const scenariosDirs = ['session-aggregates', 'single-session'];
21+
const scenarios = [];
22+
23+
for (const dir of scenariosDirs) {
24+
const scenarioDir = path.resolve(__dirname, dir);
25+
const filenames = fs.readdirSync(scenarioDir);
26+
const paths = filenames.map(filename => [filename, path.resolve(scenarioDir, filename)]);
27+
scenarios.push(...paths);
28+
}
29+
30+
const processes = scenarios.map(([filename, filepath]) => {
31+
return new Promise(resolve => {
32+
const scenarioProcess = spawn('/usr/bin/env', ['node', filepath]);
33+
const output = [];
34+
const errors = [];
35+
36+
scenarioProcess.stdout.on('data', data => {
37+
output.push(data.toString());
38+
});
39+
40+
scenarioProcess.stderr.on('data', data => {
41+
errors.push(data.toString());
42+
});
43+
44+
scenarioProcess.on('exit', code => {
45+
if (code === 0) {
46+
console.log(colorize(`PASSED: ${filename}`, 'green'));
47+
} else {
48+
console.log(colorize(`FAILED: ${filename}`, 'red'));
49+
50+
if (output.length) {
51+
console.log(colorize(output.join('\n'), 'yellow'));
52+
}
53+
if (errors.length) {
54+
console.log(colorize(errors.join('\n'), 'yellow'));
55+
}
56+
}
57+
58+
resolve(code);
59+
});
60+
});
61+
});
62+
63+
Promise.all(processes).then(codes => {
64+
if (codes.some(code => code !== 0)) {
65+
process.exit(1);
66+
}
67+
});

packages/node/test/manual/release-health/session-aggregates/aggregates-disable-single-session.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ const Sentry = require('../../../../dist');
55
const { assertSessions, BaseDummyTransport } = require('../test-utils');
66

77
function cleanUpAndExitSuccessfully() {
8-
console.log('SUCCESS: Session Aggregates payload is correct!');
98
server.close();
109
clearInterval(flusher._intervalId);
1110
process.exit(0);

packages/node/test/manual/release-health/single-session/caught-exception-errored-session.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,25 @@ validateSessionCountFunction(sessionCounts);
1616
class DummyTransport extends BaseDummyTransport {
1717
sendSession(session) {
1818
sessionCounts.sessionCounter++;
19+
1920
if (sessionCounts.sessionCounter === 1) {
2021
assertSessions(constructStrippedSessionObject(session), {
2122
init: true,
2223
status: 'ok',
2324
errors: 1,
2425
release: '1.1',
2526
});
26-
} else if (sessionCounts.sessionCounter === 2) {
27+
}
28+
29+
if (sessionCounts.sessionCounter === 2) {
2730
assertSessions(constructStrippedSessionObject(session), {
2831
init: false,
2932
status: 'exited',
3033
errors: 1,
3134
release: '1.1',
3235
});
3336
}
37+
3438
return super.sendSession(session);
3539
}
3640
}

packages/node/test/manual/release-health/single-session/errors-in-session-capped-to-one.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,25 @@ validateSessionCountFunction(sessionCounts);
1616
class DummyTransport extends BaseDummyTransport {
1717
sendSession(session) {
1818
sessionCounts.sessionCounter++;
19+
1920
if (sessionCounts.sessionCounter === 1) {
2021
assertSessions(constructStrippedSessionObject(session), {
2122
init: true,
2223
status: 'ok',
2324
errors: 1,
2425
release: '1.1',
2526
});
26-
} else if (sessionCounts.sessionCounter === 2) {
27+
}
28+
29+
if (sessionCounts.sessionCounter === 2) {
2730
assertSessions(constructStrippedSessionObject(session), {
2831
init: false,
2932
status: 'exited',
3033
errors: 1,
3134
release: '1.1',
3235
});
3336
}
37+
3438
return super.sendSession(session);
3539
}
3640
}

packages/node/test/manual/release-health/single-session/healthy-session.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@ validateSessionCountFunction(sessionCounts);
1616
class DummyTransport extends BaseDummyTransport {
1717
sendSession(session) {
1818
sessionCounts.sessionCounter++;
19-
if (sessionCounts.sessionCounter === 1) {
20-
assertSessions(constructStrippedSessionObject(session), {
21-
init: true,
22-
status: 'exited',
23-
errors: 0,
24-
release: '1.1',
25-
});
26-
}
19+
20+
assertSessions(constructStrippedSessionObject(session), {
21+
init: true,
22+
status: 'exited',
23+
errors: 0,
24+
release: '1.1',
25+
});
26+
2727
return super.sendSession(session);
2828
}
2929
}

packages/node/test/manual/release-health/single-session/terminal-state-sessions-sent-once.js

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,13 @@ class DummyTransport extends BaseDummyTransport {
1717
sendSession(session) {
1818
sessionCounts.sessionCounter++;
1919

20-
if (sessionCounts.sessionCounter === 1) {
21-
assertSessions(constructStrippedSessionObject(session), {
22-
init: true,
23-
status: 'crashed',
24-
errors: 1,
25-
release: '1.1',
26-
});
27-
}
20+
assertSessions(constructStrippedSessionObject(session), {
21+
init: true,
22+
status: 'crashed',
23+
errors: 1,
24+
release: '1.1',
25+
});
26+
2827
return super.sendSession(session);
2928
}
3029
}

packages/node/test/manual/release-health/single-session/uncaught-exception-crashed-session.js

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
11
const Sentry = require('../../../../dist');
22
const { assertSessions, constructStrippedSessionObject, BaseDummyTransport } = require('../test-utils');
33

4-
process.on('exit', () => {
5-
if (process.exitCode === 0) {
6-
console.log('SUCCESS: All application mode sessions were sent to node transport as expected');
7-
}
8-
});
9-
104
class DummyTransport extends BaseDummyTransport {
115
sendSession(session) {
126
assertSessions(constructStrippedSessionObject(session), {
@@ -15,6 +9,8 @@ class DummyTransport extends BaseDummyTransport {
159
errors: 1,
1610
release: '1.1',
1711
});
12+
13+
// We need to explicitly exit process early here to allow for 0 exit code
1814
process.exit(0);
1915
}
2016
}
@@ -25,6 +21,7 @@ Sentry.init({
2521
transport: DummyTransport,
2622
autoSessionTracking: true,
2723
});
24+
2825
/**
2926
* The following code snippet will throw an exception of `mechanism.handled` equal to `false`, and so this session
3027
* is considered a Crashed Session.

packages/node/test/manual/release-health/single-session/unhandled-rejection-crashed-session.js

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,13 @@ class DummyTransport extends BaseDummyTransport {
1717
sendSession(session) {
1818
sessionCounts.sessionCounter++;
1919

20-
if (sessionCounts.sessionCounter === 1) {
21-
assertSessions(constructStrippedSessionObject(session), {
22-
init: true,
23-
status: 'crashed',
24-
errors: 1,
25-
release: '1.1',
26-
});
27-
}
20+
assertSessions(constructStrippedSessionObject(session), {
21+
init: true,
22+
status: 'crashed',
23+
errors: 1,
24+
release: '1.1',
25+
});
26+
2827
return super.sendSession(session);
2928
}
3029
}

packages/node/test/manual/release-health/test-utils.js

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
function assertSessions(actual, expected) {
2-
if (JSON.stringify(actual) !== JSON.stringify(expected)) {
3-
console.error('FAILED: Sessions do not match');
2+
actual = JSON.stringify(actual);
3+
expected = JSON.stringify(expected);
4+
if (actual !== expected) {
5+
process.stdout.write(`Expected Session:\n ${expected}\nActual Session:\n ${actual}`);
46
process.exit(1);
57
}
68
}
@@ -27,15 +29,12 @@ class BaseDummyTransport {
2729
}
2830

2931
function validateSessionCountFunction(sessionCounts) {
30-
process.on('exit', exitCode => {
32+
process.on('exit', () => {
3133
const { sessionCounter, expectedSessions } = sessionCounts;
3234
if (sessionCounter !== expectedSessions) {
33-
console.log(`FAIL: Expected ${expectedSessions} Sessions, Received ${sessionCounter}.`);
35+
process.stdout.write(`Expected Session Count: ${expectedSessions}\nActual Session Count: ${sessionCounter}`);
3436
process.exitCode = 1;
3537
}
36-
if ((exitCode === 0) & !process.exitCode) {
37-
console.log('SUCCESS: All application mode sessions were sent to node transport as expected');
38-
}
3938
});
4039
}
4140

0 commit comments

Comments
 (0)