Skip to content

Commit dac2aca

Browse files
committed
add node integration tests
1 parent b36d517 commit dac2aca

File tree

6 files changed

+287
-0
lines changed

6 files changed

+287
-0
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import * as Sentry from '@sentry/node-core';
2+
import { loggingTransport } from '@sentry-internal/node-integration-tests';
3+
import { setupOtel } from '../../../utils/setupOtel';
4+
5+
const client = Sentry.init({
6+
dsn: 'https://[email protected]/1337',
7+
release: '1.0.0',
8+
environment: 'test',
9+
_experiments: {
10+
enableTraceMetrics: true,
11+
},
12+
transport: loggingTransport,
13+
});
14+
15+
setupOtel(client);
16+
17+
async function run(): Promise<void> {
18+
Sentry.metrics.count('test.counter', 1, { attributes: { endpoint: '/api/test' } });
19+
20+
Sentry.metrics.gauge('test.gauge', 42, { unit: 'millisecond', attributes: { server: 'test-1' } });
21+
22+
Sentry.metrics.distribution('test.distribution', 200, { unit: 'second', attributes: { priority: 'high' } });
23+
24+
await Sentry.startSpan({ name: 'test-span', op: 'test' }, async () => {
25+
Sentry.metrics.count('test.span.counter', 1, { attributes: { operation: 'test' } });
26+
});
27+
28+
Sentry.setUser({ id: 'user-123', email: '[email protected]', username: 'testuser' });
29+
Sentry.metrics.count('test.user.counter', 1, { attributes: { action: 'click' } });
30+
31+
await Sentry.flush();
32+
}
33+
34+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
35+
void run();
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import { afterAll, describe, expect, test } from 'vitest';
2+
import { cleanupChildProcesses, createRunner } from '../../../utils/runner';
3+
4+
describe('metrics', () => {
5+
afterAll(() => {
6+
cleanupChildProcesses();
7+
});
8+
9+
test('should capture all metric types', async () => {
10+
const runner = createRunner(__dirname, 'scenario.ts')
11+
.unignore('metric')
12+
.expect({
13+
metric: {
14+
items: [
15+
{
16+
timestamp: expect.any(Number),
17+
trace_id: expect.any(String),
18+
name: 'test.counter',
19+
type: 'counter',
20+
value: 1,
21+
attributes: {
22+
endpoint: { value: '/api/test', type: 'string' },
23+
'sentry.release': { value: '1.0.0', type: 'string' },
24+
'sentry.environment': { value: 'test', type: 'string' },
25+
'sentry.sdk.name': { value: 'sentry.javascript.node-core', type: 'string' },
26+
'sentry.sdk.version': { value: expect.any(String), type: 'string' },
27+
},
28+
},
29+
{
30+
timestamp: expect.any(Number),
31+
trace_id: expect.any(String),
32+
name: 'test.gauge',
33+
type: 'gauge',
34+
unit: 'millisecond',
35+
value: 42,
36+
attributes: {
37+
server: { value: 'test-1', type: 'string' },
38+
'sentry.release': { value: '1.0.0', type: 'string' },
39+
'sentry.environment': { value: 'test', type: 'string' },
40+
'sentry.sdk.name': { value: 'sentry.javascript.node-core', type: 'string' },
41+
'sentry.sdk.version': { value: expect.any(String), type: 'string' },
42+
},
43+
},
44+
{
45+
timestamp: expect.any(Number),
46+
trace_id: expect.any(String),
47+
name: 'test.distribution',
48+
type: 'distribution',
49+
unit: 'second',
50+
value: 200,
51+
attributes: {
52+
priority: { value: 'high', type: 'string' },
53+
'sentry.release': { value: '1.0.0', type: 'string' },
54+
'sentry.environment': { value: 'test', type: 'string' },
55+
'sentry.sdk.name': { value: 'sentry.javascript.node-core', type: 'string' },
56+
'sentry.sdk.version': { value: expect.any(String), type: 'string' },
57+
},
58+
},
59+
{
60+
timestamp: expect.any(Number),
61+
trace_id: expect.any(String),
62+
name: 'test.span.counter',
63+
type: 'counter',
64+
value: 1,
65+
attributes: {
66+
operation: { value: 'test', type: 'string' },
67+
'sentry.release': { value: '1.0.0', type: 'string' },
68+
'sentry.environment': { value: 'test', type: 'string' },
69+
'sentry.sdk.name': { value: 'sentry.javascript.node-core', type: 'string' },
70+
'sentry.sdk.version': { value: expect.any(String), type: 'string' },
71+
},
72+
},
73+
{
74+
timestamp: expect.any(Number),
75+
trace_id: expect.any(String),
76+
name: 'test.user.counter',
77+
type: 'counter',
78+
value: 1,
79+
attributes: {
80+
action: { value: 'click', type: 'string' },
81+
'user.id': { value: 'user-123', type: 'string' },
82+
'user.email': { value: '[email protected]', type: 'string' },
83+
'user.name': { value: 'testuser', type: 'string' },
84+
'sentry.release': { value: '1.0.0', type: 'string' },
85+
'sentry.environment': { value: 'test', type: 'string' },
86+
'sentry.sdk.name': { value: 'sentry.javascript.node-core', type: 'string' },
87+
'sentry.sdk.version': { value: expect.any(String), type: 'string' },
88+
},
89+
},
90+
],
91+
},
92+
})
93+
.start();
94+
95+
await runner.completed();
96+
});
97+
});

dev-packages/node-core-integration-tests/utils/assertions.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import type {
44
Event,
55
SerializedCheckIn,
66
SerializedLogContainer,
7+
SerializedMetricContainer,
78
SerializedSession,
89
SessionAggregates,
910
TransactionEvent,
@@ -76,6 +77,15 @@ export function assertSentryLogContainer(
7677
});
7778
}
7879

80+
export function assertSentryMetricContainer(
81+
actual: SerializedMetricContainer,
82+
expected: Partial<SerializedMetricContainer>,
83+
): void {
84+
expect(actual).toMatchObject({
85+
...expected,
86+
});
87+
}
88+
7989
export function assertEnvelopeHeader(actual: Envelope[0], expected: Partial<Envelope[0]>): void {
8090
expect(actual).toEqual({
8191
event_id: expect.any(String),

dev-packages/node-core-integration-tests/utils/runner.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import type {
77
EventEnvelope,
88
SerializedCheckIn,
99
SerializedLogContainer,
10+
SerializedMetricContainer,
1011
SerializedSession,
1112
SessionAggregates,
1213
TransactionEvent,
@@ -22,6 +23,7 @@ import {
2223
assertSentryClientReport,
2324
assertSentryEvent,
2425
assertSentryLogContainer,
26+
assertSentryMetricContainer,
2527
assertSentrySession,
2628
assertSentrySessions,
2729
assertSentryTransaction,
@@ -122,6 +124,7 @@ type ExpectedSessions = Partial<SessionAggregates> | ((event: SessionAggregates)
122124
type ExpectedCheckIn = Partial<SerializedCheckIn> | ((event: SerializedCheckIn) => void);
123125
type ExpectedClientReport = Partial<ClientReport> | ((event: ClientReport) => void);
124126
type ExpectedLogContainer = Partial<SerializedLogContainer> | ((event: SerializedLogContainer) => void);
127+
type ExpectedMetricContainer = Partial<SerializedMetricContainer> | ((event: SerializedMetricContainer) => void);
125128

126129
type Expected =
127130
| {
@@ -144,6 +147,9 @@ type Expected =
144147
}
145148
| {
146149
log: ExpectedLogContainer;
150+
}
151+
| {
152+
metric: ExpectedMetricContainer;
147153
};
148154

149155
type ExpectedEnvelopeHeader =
@@ -403,6 +409,9 @@ export function createRunner(...paths: string[]) {
403409
} else if ('log' in expected) {
404410
expectLog(item[1] as SerializedLogContainer, expected.log);
405411
expectCallbackCalled();
412+
} else if ('metric' in expected) {
413+
expectMetric(item[1] as SerializedMetricContainer, expected.metric);
414+
expectCallbackCalled();
406415
} else {
407416
throw new Error(
408417
`Unhandled expected envelope item type: ${JSON.stringify(expected)}\nItem: ${JSON.stringify(item)}`,
@@ -649,6 +658,14 @@ function expectLog(item: SerializedLogContainer, expected: ExpectedLogContainer)
649658
}
650659
}
651660

661+
function expectMetric(item: SerializedMetricContainer, expected: ExpectedMetricContainer): void {
662+
if (typeof expected === 'function') {
663+
expected(item);
664+
} else {
665+
assertSentryMetricContainer(item, expected);
666+
}
667+
}
668+
652669
/**
653670
* Converts ESM import statements to CommonJS require statements
654671
* @param content The content of an ESM file
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import * as Sentry from '@sentry/node';
2+
import { loggingTransport } from '@sentry-internal/node-integration-tests';
3+
4+
Sentry.init({
5+
dsn: 'https://[email protected]/1337',
6+
release: '1.0.0',
7+
environment: 'test',
8+
_experiments: {
9+
enableTraceMetrics: true,
10+
},
11+
transport: loggingTransport,
12+
});
13+
14+
async function run(): Promise<void> {
15+
Sentry.metrics.count('test.counter', 1, { attributes: { endpoint: '/api/test' } });
16+
17+
Sentry.metrics.gauge('test.gauge', 42, { unit: 'millisecond', attributes: { server: 'test-1' } });
18+
19+
Sentry.metrics.distribution('test.distribution', 200, { unit: 'second', attributes: { priority: 'high' } });
20+
21+
await Sentry.startSpan({ name: 'test-span', op: 'test' }, async () => {
22+
Sentry.metrics.count('test.span.counter', 1, { attributes: { operation: 'test' } });
23+
});
24+
25+
Sentry.setUser({ id: 'user-123', email: '[email protected]', username: 'testuser' });
26+
Sentry.metrics.count('test.user.counter', 1, { attributes: { action: 'click' } });
27+
28+
await Sentry.flush();
29+
}
30+
31+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
32+
run();
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import { afterAll, describe, expect, test } from 'vitest';
2+
import { cleanupChildProcesses, createRunner } from '../../../utils/runner';
3+
4+
describe('metrics', () => {
5+
afterAll(() => {
6+
cleanupChildProcesses();
7+
});
8+
9+
test('should capture all metric types', async () => {
10+
const runner = createRunner(__dirname, 'scenario.ts')
11+
.expect({
12+
metric: {
13+
items: [
14+
{
15+
timestamp: expect.any(Number),
16+
trace_id: expect.any(String),
17+
name: 'test.counter',
18+
type: 'counter',
19+
value: 1,
20+
attributes: {
21+
endpoint: { value: '/api/test', type: 'string' },
22+
'sentry.release': { value: '1.0.0', type: 'string' },
23+
'sentry.environment': { value: 'test', type: 'string' },
24+
'sentry.sdk.name': { value: 'sentry.javascript.node', type: 'string' },
25+
'sentry.sdk.version': { value: expect.any(String), type: 'string' },
26+
},
27+
},
28+
{
29+
timestamp: expect.any(Number),
30+
trace_id: expect.any(String),
31+
name: 'test.gauge',
32+
type: 'gauge',
33+
unit: 'millisecond',
34+
value: 42,
35+
attributes: {
36+
server: { value: 'test-1', type: 'string' },
37+
'sentry.release': { value: '1.0.0', type: 'string' },
38+
'sentry.environment': { value: 'test', type: 'string' },
39+
'sentry.sdk.name': { value: 'sentry.javascript.node', type: 'string' },
40+
'sentry.sdk.version': { value: expect.any(String), type: 'string' },
41+
},
42+
},
43+
{
44+
timestamp: expect.any(Number),
45+
trace_id: expect.any(String),
46+
name: 'test.distribution',
47+
type: 'distribution',
48+
unit: 'second',
49+
value: 200,
50+
attributes: {
51+
priority: { value: 'high', type: 'string' },
52+
'sentry.release': { value: '1.0.0', type: 'string' },
53+
'sentry.environment': { value: 'test', type: 'string' },
54+
'sentry.sdk.name': { value: 'sentry.javascript.node', type: 'string' },
55+
'sentry.sdk.version': { value: expect.any(String), type: 'string' },
56+
},
57+
},
58+
{
59+
timestamp: expect.any(Number),
60+
trace_id: expect.any(String),
61+
name: 'test.span.counter',
62+
type: 'counter',
63+
value: 1,
64+
attributes: {
65+
operation: { value: 'test', type: 'string' },
66+
'sentry.release': { value: '1.0.0', type: 'string' },
67+
'sentry.environment': { value: 'test', type: 'string' },
68+
'sentry.sdk.name': { value: 'sentry.javascript.node', type: 'string' },
69+
'sentry.sdk.version': { value: expect.any(String), type: 'string' },
70+
},
71+
},
72+
{
73+
timestamp: expect.any(Number),
74+
trace_id: expect.any(String),
75+
name: 'test.user.counter',
76+
type: 'counter',
77+
value: 1,
78+
attributes: {
79+
action: { value: 'click', type: 'string' },
80+
'user.id': { value: 'user-123', type: 'string' },
81+
'user.email': { value: '[email protected]', type: 'string' },
82+
'user.name': { value: 'testuser', type: 'string' },
83+
'sentry.release': { value: '1.0.0', type: 'string' },
84+
'sentry.environment': { value: 'test', type: 'string' },
85+
'sentry.sdk.name': { value: 'sentry.javascript.node', type: 'string' },
86+
'sentry.sdk.version': { value: expect.any(String), type: 'string' },
87+
},
88+
},
89+
],
90+
},
91+
})
92+
.start();
93+
94+
await runner.completed();
95+
});
96+
});

0 commit comments

Comments
 (0)