Skip to content

Commit 65b117c

Browse files
chargomeclaude
andcommitted
test(node): Port express tracing suites to span streaming
Rewrite the transaction assertions against span v2 containers. Status-code filtering is a no-op under streaming, so its scenario is removed and the 4xx routes are asserted on the main scenario instead. The isolationScope scenario switches from tags to scope attributes, and the tracesSampler matches on url.path since the initial name is just the method. Refs #24136 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
1 parent b7173ce commit 65b117c

18 files changed

Lines changed: 306 additions & 432 deletions

File tree

dev-packages/node-integration-tests/suites/express/ignore-layers-type/instrument.mjs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import * as Sentry from '@sentry/node';
22
import { loggingTransport } from '@sentry-internal/node-integration-tests';
33

44
Sentry.init({
5-
traceLifecycle: 'static',
65
dsn: 'https://public@dsn.ingest.sentry.io/1337',
76
release: '1.0',
87
tracesSampleRate: 1.0,

dev-packages/node-integration-tests/suites/express/ignore-layers-type/test.ts

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { afterAll, describe, expect } from 'vitest';
2-
import { assertSentryTransaction } from '../../../utils/assertions';
32
import { cleanupChildProcesses, createEsmAndCjsTests } from '../../../utils/runner';
43

54
describe('express ignoreLayersType', () => {
@@ -11,28 +10,26 @@ describe('express ignoreLayersType', () => {
1110
test('suppresses spans for layer types listed in ignoreLayersType', async () => {
1211
const runner = createRunner()
1312
.expect({
14-
transaction: transaction => {
15-
assertSentryTransaction(transaction, {
16-
transaction: 'GET /test/express',
17-
contexts: {
18-
trace: {
19-
op: 'http.server',
20-
status: 'ok',
21-
},
22-
},
13+
span: container => {
14+
expect(container.items.find(item => item.is_segment)).toMatchObject({
15+
name: 'GET /test/express',
16+
status: 'ok',
17+
attributes: expect.objectContaining({
18+
'sentry.op': { type: 'string', value: 'http.server' },
19+
}),
2320
});
24-
expect(transaction.spans).toContainEqual(
21+
expect(container.items).toContainEqual(
2522
expect.objectContaining({
26-
data: expect.objectContaining({
27-
'express.type': 'request_handler',
23+
attributes: expect.objectContaining({
24+
'express.type': { type: 'string', value: 'request_handler' },
2825
}),
2926
}),
3027
);
3128
// The cors() middleware span is suppressed by ignoreLayersType: ['middleware'].
32-
expect(transaction.spans).not.toContainEqual(
29+
expect(container.items).not.toContainEqual(
3330
expect.objectContaining({
34-
data: expect.objectContaining({
35-
'express.type': 'middleware',
31+
attributes: expect.objectContaining({
32+
'express.type': { type: 'string', value: 'middleware' },
3633
}),
3734
}),
3835
);

dev-packages/node-integration-tests/suites/express/multiple-routers/instrument.mjs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import * as Sentry from '@sentry/node';
22
import { loggingTransport } from '@sentry-internal/node-integration-tests';
33

44
Sentry.init({
5-
traceLifecycle: 'static',
65
dsn: 'https://public@dsn.ingest.sentry.io/1337',
76
release: '1.0',
87
tracesSampleRate: 1.0,

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

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { afterAll, describe } from 'vitest';
1+
import { afterAll, describe, expect } from 'vitest';
22
import { cleanupChildProcesses, createCjsTests } from '../../../utils/runner';
33

44
describe('express multiple routers', () => {
@@ -9,7 +9,7 @@ describe('express multiple routers', () => {
99
createCjsTests(__dirname, 'scenario-common-infix.mjs', 'instrument.mjs', (createRunner, test) => {
1010
test('should construct correct url with common infixes with multiple routers.', async () => {
1111
const runner = createRunner()
12-
.ignore('transaction')
12+
.ignore('span')
1313
.expect({ event: { message: 'Custom Message', transaction: 'GET /api2/v1/test' } })
1414
.start();
1515
runner.makeRequest('get', '/api2/v1/test');
@@ -20,7 +20,7 @@ describe('express multiple routers', () => {
2020
createCjsTests(__dirname, 'scenario-common-infix-parameterized.mjs', 'instrument.mjs', (createRunner, test) => {
2121
test('should construct correct url with common infixes with multiple parameterized routers.', async () => {
2222
const runner = createRunner()
23-
.ignore('transaction')
23+
.ignore('span')
2424
.expect({ event: { message: 'Custom Message', transaction: 'GET /api/v1/user/:userId' } })
2525
.start();
2626
runner.makeRequest('get', '/api/v1/user/3212');
@@ -31,7 +31,7 @@ describe('express multiple routers', () => {
3131
createCjsTests(__dirname, 'scenario-common-prefix.mjs', 'instrument.mjs', (createRunner, test) => {
3232
test('should construct correct urls with multiple routers.', async () => {
3333
const runner = createRunner()
34-
.ignore('transaction')
34+
.ignore('span')
3535
.expect({ event: { message: 'Custom Message', transaction: 'GET /api/v1/test' } })
3636
.start();
3737
runner.makeRequest('get', '/api/v1/test');
@@ -40,7 +40,7 @@ describe('express multiple routers', () => {
4040

4141
test('should construct correct urls with multiple parameterized routers.', async () => {
4242
const runner = createRunner()
43-
.ignore('transaction')
43+
.ignore('span')
4444
.expect({ event: { message: 'Custom Message', transaction: 'GET /api/v1/user/:userId' } })
4545
.start();
4646
runner.makeRequest('get', '/api/v1/user/1234/');
@@ -51,7 +51,7 @@ describe('express multiple routers', () => {
5151
createCjsTests(__dirname, 'scenario-common-prefix-reverse.mjs', 'instrument.mjs', (createRunner, test) => {
5252
test('should construct correct urls with multiple parameterized routers (use order reversed).', async () => {
5353
const runner = createRunner()
54-
.ignore('transaction')
54+
.ignore('span')
5555
.expect({ event: { message: 'Custom Message', transaction: 'GET /api/v1/user/:userId' } })
5656
.start();
5757
runner.makeRequest('get', '/api/v1/user/1234/');
@@ -62,7 +62,7 @@ describe('express multiple routers', () => {
6262
createCjsTests(__dirname, 'scenario-common-prefix-same-length.mjs', 'instrument.mjs', (createRunner, test) => {
6363
test('should construct correct url with multiple parameterized routers of the same length.', async () => {
6464
const runner = createRunner()
65-
.ignore('transaction')
65+
.ignore('span')
6666
.expect({ event: { message: 'Custom Message', transaction: 'GET /api/v1/:userId' } })
6767
.start();
6868
runner.makeRequest('get', '/api/v1/1234/');
@@ -76,11 +76,10 @@ describe('express multiple routers', () => {
7676
const runner = createRunner()
7777
.ignore('event')
7878
.expect({
79-
transaction: {
80-
transaction: 'GET /api/api/v1/sub-router/users/:userId/posts/:postId',
81-
transaction_info: {
82-
source: 'route',
83-
},
79+
span: container => {
80+
const serverSpan = container.items.find(item => item.is_segment);
81+
expect(serverSpan?.name).toBe('GET /api/api/v1/sub-router/users/:userId/posts/:postId');
82+
expect(serverSpan?.attributes['sentry.segment.name.source']).toEqual({ type: 'string', value: 'route' });
8483
},
8584
})
8685
.start();
@@ -92,11 +91,10 @@ describe('express multiple routers', () => {
9291
const runner = createRunner()
9392
.ignore('event')
9493
.expect({
95-
transaction: {
96-
transaction: 'GET /api/api/v1/sub-router/users/:userId/posts/:postId',
97-
transaction_info: {
98-
source: 'route',
99-
},
94+
span: container => {
95+
const serverSpan = container.items.find(item => item.is_segment);
96+
expect(serverSpan?.name).toBe('GET /api/api/v1/sub-router/users/:userId/posts/:postId');
97+
expect(serverSpan?.attributes['sentry.segment.name.source']).toEqual({ type: 'string', value: 'route' });
10098
},
10199
})
102100
.start();
@@ -108,11 +106,10 @@ describe('express multiple routers', () => {
108106
const runner = createRunner()
109107
.ignore('event')
110108
.expect({
111-
transaction: {
112-
transaction: 'GET /api/api/v1/sub-router/users/:userId/posts/:postId',
113-
transaction_info: {
114-
source: 'route',
115-
},
109+
span: container => {
110+
const serverSpan = container.items.find(item => item.is_segment);
111+
expect(serverSpan?.name).toBe('GET /api/api/v1/sub-router/users/:userId/posts/:postId');
112+
expect(serverSpan?.attributes['sentry.segment.name.source']).toEqual({ type: 'string', value: 'route' });
116113
},
117114
})
118115
.start();
@@ -129,11 +126,10 @@ describe('express multiple routers', () => {
129126
const runner = createRunner()
130127
.ignore('event')
131128
.expect({
132-
transaction: {
133-
transaction: 'GET /api/v1/users/:userId/posts/:postId',
134-
transaction_info: {
135-
source: 'route',
136-
},
129+
span: container => {
130+
const serverSpan = container.items.find(item => item.is_segment);
131+
expect(serverSpan?.name).toBe('GET /api/v1/users/:userId/posts/:postId');
132+
expect(serverSpan?.attributes['sentry.segment.name.source']).toEqual({ type: 'string', value: 'route' });
137133
},
138134
})
139135
.start();

dev-packages/node-integration-tests/suites/express/span-isolationScope/instrument.mjs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import * as Sentry from '@sentry/node';
22
import { loggingTransport } from '@sentry-internal/node-integration-tests';
33

44
Sentry.init({
5-
traceLifecycle: 'static',
65
dsn: 'https://public@dsn.ingest.sentry.io/1337',
76
release: '1.0',
87
tracesSampleRate: 1.0,

dev-packages/node-integration-tests/suites/express/span-isolationScope/scenario.mjs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,11 @@ import express from 'express';
44

55
const app = express();
66

7-
Sentry.setTag('global', 'tag');
7+
Sentry.setAttribute('global', 'attribute');
88

99
app.get('/test/isolationScope', (_req, res) => {
10-
// eslint-disable-next-line no-console
11-
console.log('This is a test log.');
12-
Sentry.addBreadcrumb({ message: 'manual breadcrumb' });
13-
Sentry.setTag('isolation-scope', 'tag');
10+
Sentry.setAttribute('isolation-scope', 'attribute');
11+
Sentry.setUser({ id: 'user-1' });
1412

1513
res.send({});
1614
});

dev-packages/node-integration-tests/suites/express/span-isolationScope/test.ts

Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -10,30 +10,17 @@ describe('express span isolationScope', () => {
1010
test('correctly applies isolation scope to span', async () => {
1111
const runner = createRunner()
1212
.expect({
13-
transaction: {
14-
transaction: 'GET /test/isolationScope',
15-
breadcrumbs: [
16-
{
17-
category: 'console',
18-
level: 'log',
19-
message: expect.stringMatching(/\{"port":(\d+)\}/),
20-
timestamp: expect.any(Number),
21-
},
22-
{
23-
category: 'console',
24-
level: 'log',
25-
message: 'This is a test log.',
26-
timestamp: expect.any(Number),
27-
},
28-
{
29-
message: 'manual breadcrumb',
30-
timestamp: expect.any(Number),
31-
},
32-
],
33-
tags: {
34-
global: 'tag',
35-
'isolation-scope': 'tag',
36-
},
13+
span: container => {
14+
const serverSpan = container.items.find(item => item.is_segment);
15+
16+
expect(serverSpan).toMatchObject({
17+
name: 'GET /test/isolationScope',
18+
attributes: expect.objectContaining({
19+
global: { type: 'string', value: 'attribute' },
20+
'isolation-scope': { type: 'string', value: 'attribute' },
21+
'user.id': { type: 'string', value: 'user-1' },
22+
}),
23+
});
3724
},
3825
})
3926
.start();

dev-packages/node-integration-tests/suites/express/tracing/instrument-filterStatusCode.mjs

Lines changed: 0 additions & 15 deletions
This file was deleted.

dev-packages/node-integration-tests/suites/express/tracing/instrument.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as Sentry from '@sentry/node';
22
import { loggingTransport } from '@sentry-internal/node-integration-tests';
33

44
Sentry.init({
5-
traceLifecycle: process.env.STREAMED === 'true' ? 'stream' : 'static',
5+
traceLifecycle: 'stream',
66
dsn: 'https://public@dsn.ingest.sentry.io/1337',
77
release: '1.0',
88
// disable attaching headers to /test/* endpoints

dev-packages/node-integration-tests/suites/express/tracing/scenario-filterStatusCode.mjs

Lines changed: 0 additions & 34 deletions
This file was deleted.

0 commit comments

Comments
 (0)