From e93206cded5dbc8685d6d99e52299f771c8bee1e Mon Sep 17 00:00:00 2001 From: Charly Gomez Date: Tue, 8 Sep 2026 10:34:36 +0200 Subject: [PATCH] test(node): Port express maxIncomingRequestBodySize suite to span streaming Assert the captured request body on the segment span's http.request.body.data attribute instead of the transaction's request.data. Refs #24136 Co-Authored-By: Claude Fable 5.1 --- .../instrument-always.mjs | 1 - .../instrument-default.mjs | 1 - .../instrument-medium.mjs | 1 - .../instrument-none.mjs | 1 - .../instrument-small.mjs | 1 - .../maxIncomingRequestBodySize/test.ts | 149 ++++++++++-------- 6 files changed, 83 insertions(+), 71 deletions(-) diff --git a/dev-packages/node-integration-tests/suites/express/with-http/maxIncomingRequestBodySize/instrument-always.mjs b/dev-packages/node-integration-tests/suites/express/with-http/maxIncomingRequestBodySize/instrument-always.mjs index 2ed2c4b03868..569fa14666b4 100644 --- a/dev-packages/node-integration-tests/suites/express/with-http/maxIncomingRequestBodySize/instrument-always.mjs +++ b/dev-packages/node-integration-tests/suites/express/with-http/maxIncomingRequestBodySize/instrument-always.mjs @@ -2,7 +2,6 @@ import * as Sentry from '@sentry/node'; import { loggingTransport } from '@sentry-internal/node-integration-tests'; Sentry.init({ - traceLifecycle: 'static', dsn: 'https://public@dsn.ingest.sentry.io/1337', release: '1.0', tracesSampleRate: 1.0, diff --git a/dev-packages/node-integration-tests/suites/express/with-http/maxIncomingRequestBodySize/instrument-default.mjs b/dev-packages/node-integration-tests/suites/express/with-http/maxIncomingRequestBodySize/instrument-default.mjs index 170ad6f6a702..46a27dd03b74 100644 --- a/dev-packages/node-integration-tests/suites/express/with-http/maxIncomingRequestBodySize/instrument-default.mjs +++ b/dev-packages/node-integration-tests/suites/express/with-http/maxIncomingRequestBodySize/instrument-default.mjs @@ -2,7 +2,6 @@ import * as Sentry from '@sentry/node'; import { loggingTransport } from '@sentry-internal/node-integration-tests'; Sentry.init({ - traceLifecycle: 'static', dsn: 'https://public@dsn.ingest.sentry.io/1337', release: '1.0', tracesSampleRate: 1.0, diff --git a/dev-packages/node-integration-tests/suites/express/with-http/maxIncomingRequestBodySize/instrument-medium.mjs b/dev-packages/node-integration-tests/suites/express/with-http/maxIncomingRequestBodySize/instrument-medium.mjs index 2ea1a18c449c..4fd83727c671 100644 --- a/dev-packages/node-integration-tests/suites/express/with-http/maxIncomingRequestBodySize/instrument-medium.mjs +++ b/dev-packages/node-integration-tests/suites/express/with-http/maxIncomingRequestBodySize/instrument-medium.mjs @@ -2,7 +2,6 @@ import * as Sentry from '@sentry/node'; import { loggingTransport } from '@sentry-internal/node-integration-tests'; Sentry.init({ - traceLifecycle: 'static', dsn: 'https://public@dsn.ingest.sentry.io/1337', release: '1.0', tracesSampleRate: 1.0, diff --git a/dev-packages/node-integration-tests/suites/express/with-http/maxIncomingRequestBodySize/instrument-none.mjs b/dev-packages/node-integration-tests/suites/express/with-http/maxIncomingRequestBodySize/instrument-none.mjs index b3c2c06d3dd9..18657af5d25e 100644 --- a/dev-packages/node-integration-tests/suites/express/with-http/maxIncomingRequestBodySize/instrument-none.mjs +++ b/dev-packages/node-integration-tests/suites/express/with-http/maxIncomingRequestBodySize/instrument-none.mjs @@ -2,7 +2,6 @@ import * as Sentry from '@sentry/node'; import { loggingTransport } from '@sentry-internal/node-integration-tests'; Sentry.init({ - traceLifecycle: 'static', dsn: 'https://public@dsn.ingest.sentry.io/1337', release: '1.0', tracesSampleRate: 1.0, diff --git a/dev-packages/node-integration-tests/suites/express/with-http/maxIncomingRequestBodySize/instrument-small.mjs b/dev-packages/node-integration-tests/suites/express/with-http/maxIncomingRequestBodySize/instrument-small.mjs index 2331b64953b4..cedd11b3d86a 100644 --- a/dev-packages/node-integration-tests/suites/express/with-http/maxIncomingRequestBodySize/instrument-small.mjs +++ b/dev-packages/node-integration-tests/suites/express/with-http/maxIncomingRequestBodySize/instrument-small.mjs @@ -2,7 +2,6 @@ import * as Sentry from '@sentry/node'; import { loggingTransport } from '@sentry-internal/node-integration-tests'; Sentry.init({ - traceLifecycle: 'static', dsn: 'https://public@dsn.ingest.sentry.io/1337', release: '1.0', tracesSampleRate: 1.0, diff --git a/dev-packages/node-integration-tests/suites/express/with-http/maxIncomingRequestBodySize/test.ts b/dev-packages/node-integration-tests/suites/express/with-http/maxIncomingRequestBodySize/test.ts index 2cc5595f4d20..7937dcdb026e 100644 --- a/dev-packages/node-integration-tests/suites/express/with-http/maxIncomingRequestBodySize/test.ts +++ b/dev-packages/node-integration-tests/suites/express/with-http/maxIncomingRequestBodySize/test.ts @@ -21,11 +21,13 @@ describe('express with httpIntegration and not defined maxRequestBodySize', () = test('captures medium request bodies with default setting (medium)', async () => { const runner = createRunner() .expect({ - transaction: { - transaction: 'POST /test-body-size', - request: { - data: JSON.stringify(generatePayload(MAX_MEDIUM)), - }, + span: container => { + expect(container.items.find(item => item.is_segment)).toMatchObject({ + name: 'POST /test-body-size', + attributes: expect.objectContaining({ + 'http.request.body.data': { type: 'string', value: JSON.stringify(generatePayload(MAX_MEDIUM)) }, + }), + }); }, }) .start(); @@ -41,11 +43,13 @@ describe('express with httpIntegration and not defined maxRequestBodySize', () = test('truncates large request bodies with default setting (medium)', async () => { const runner = createRunner() .expect({ - transaction: { - transaction: 'POST /test-body-size', - request: { - data: generatePayloadString(MAX_MEDIUM, true), - }, + span: container => { + expect(container.items.find(item => item.is_segment)).toMatchObject({ + name: 'POST /test-body-size', + attributes: expect.objectContaining({ + 'http.request.body.data': { type: 'string', value: generatePayloadString(MAX_MEDIUM, true) }, + }), + }); }, }) .start(); @@ -69,11 +73,13 @@ describe('express with httpIntegration, disabled httpBodies, and explicit maxReq test('captures request bodies because the explicit size overrides dataCollection.httpBodies', async () => { const runner = createRunner() .expect({ - transaction: { - transaction: 'POST /test-body-size', - request: { - data: JSON.stringify(generatePayload(MAX_SMALL)), - }, + span: container => { + expect(container.items.find(item => item.is_segment)).toMatchObject({ + name: 'POST /test-body-size', + attributes: expect.objectContaining({ + 'http.request.body.data': { type: 'string', value: JSON.stringify(generatePayload(MAX_SMALL)) }, + }), + }); }, }) .start(); @@ -97,11 +103,10 @@ describe('express with httpIntegration and maxRequestBodySize: "none"', () => { test('does not capture any request bodies with "none" setting', async () => { const runner = createRunner() .expect({ - transaction: { - transaction: 'POST /test-body-size', - request: expect.not.objectContaining({ - data: expect.any(String), - }), + span: container => { + const serverSpan = container.items.find(item => item.is_segment); + expect(serverSpan?.name).toBe('POST /test-body-size'); + expect(serverSpan?.attributes['http.request.body.data']).toBeUndefined(); }, }) .start(); @@ -117,19 +122,17 @@ describe('express with httpIntegration and maxRequestBodySize: "none"', () => { test('does not capture any request bodies with "none" setting and "ignoreRequestBody"', async () => { const runner = createRunner() .expect({ - transaction: { - transaction: 'POST /test-body-size', - request: expect.not.objectContaining({ - data: expect.any(String), - }), + span: container => { + const serverSpan = container.items.find(item => item.is_segment); + expect(serverSpan?.name).toBe('POST /test-body-size'); + expect(serverSpan?.attributes['http.request.body.data']).toBeUndefined(); }, }) .expect({ - transaction: { - transaction: 'POST /ignore-request-body', - request: expect.not.objectContaining({ - data: expect.any(String), - }), + span: container => { + const serverSpan = container.items.find(item => item.is_segment); + expect(serverSpan?.name).toBe('POST /ignore-request-body'); + expect(serverSpan?.attributes['http.request.body.data']).toBeUndefined(); }, }) .start(); @@ -158,11 +161,13 @@ describe('express with httpIntegration and maxRequestBodySize: "always"', () => test('captures maximum allowed request body length with "always" setting', async () => { const runner = createRunner() .expect({ - transaction: { - transaction: 'POST /test-body-size', - request: { - data: JSON.stringify(generatePayload(MAX_GENERAL)), - }, + span: container => { + expect(container.items.find(item => item.is_segment)).toMatchObject({ + name: 'POST /test-body-size', + attributes: expect.objectContaining({ + 'http.request.body.data': { type: 'string', value: JSON.stringify(generatePayload(MAX_GENERAL)) }, + }), + }); }, }) .start(); @@ -178,11 +183,13 @@ describe('express with httpIntegration and maxRequestBodySize: "always"', () => test('captures large request bodies with "always" setting but respects maximum size limit', async () => { const runner = createRunner() .expect({ - transaction: { - transaction: 'POST /test-body-size', - request: { - data: generatePayloadString(MAX_GENERAL, true), - }, + span: container => { + expect(container.items.find(item => item.is_segment)).toMatchObject({ + name: 'POST /test-body-size', + attributes: expect.objectContaining({ + 'http.request.body.data': { type: 'string', value: generatePayloadString(MAX_GENERAL, true) }, + }), + }); }, }) .start(); @@ -206,11 +213,13 @@ describe('express with httpIntegration and maxRequestBodySize: "small"', () => { test('keeps small request bodies with "small" setting', async () => { const runner = createRunner() .expect({ - transaction: { - transaction: 'POST /test-body-size', - request: { - data: JSON.stringify(generatePayload(MAX_SMALL)), - }, + span: container => { + expect(container.items.find(item => item.is_segment)).toMatchObject({ + name: 'POST /test-body-size', + attributes: expect.objectContaining({ + 'http.request.body.data': { type: 'string', value: JSON.stringify(generatePayload(MAX_SMALL)) }, + }), + }); }, }) .start(); @@ -226,11 +235,13 @@ describe('express with httpIntegration and maxRequestBodySize: "small"', () => { test('truncates too large request bodies with "small" setting', async () => { const runner = createRunner() .expect({ - transaction: { - transaction: 'POST /test-body-size', - request: { - data: generatePayloadString(MAX_SMALL, true), - }, + span: container => { + expect(container.items.find(item => item.is_segment)).toMatchObject({ + name: 'POST /test-body-size', + attributes: expect.objectContaining({ + 'http.request.body.data': { type: 'string', value: generatePayloadString(MAX_SMALL, true) }, + }), + }); }, }) .start(); @@ -246,12 +257,14 @@ describe('express with httpIntegration and maxRequestBodySize: "small"', () => { test('truncates too large non-ASCII request bodies with "small" setting', async () => { const runner = createRunner() .expect({ - transaction: { - transaction: 'POST /test-body-size', - request: { - // 250 emojis, each 4 bytes in UTF-8 (resulting in 1000 bytes --> MAX_SMALL) - data: generateEmojiPayloadString(250, true), - }, + span: container => { + expect(container.items.find(item => item.is_segment)).toMatchObject({ + name: 'POST /test-body-size', + attributes: expect.objectContaining({ + // 250 emojis, each 4 bytes in UTF-8 (resulting in 1000 bytes --> MAX_SMALL) + 'http.request.body.data': { type: 'string', value: generateEmojiPayloadString(250, true) }, + }), + }); }, }) .start(); @@ -275,11 +288,13 @@ describe('express with httpIntegration and maxRequestBodySize: "medium"', () => test('keeps medium request bodies with "medium" setting', async () => { const runner = createRunner() .expect({ - transaction: { - transaction: 'POST /test-body-size', - request: { - data: JSON.stringify(generatePayload(MAX_MEDIUM)), - }, + span: container => { + expect(container.items.find(item => item.is_segment)).toMatchObject({ + name: 'POST /test-body-size', + attributes: expect.objectContaining({ + 'http.request.body.data': { type: 'string', value: JSON.stringify(generatePayload(MAX_MEDIUM)) }, + }), + }); }, }) .start(); @@ -295,11 +310,13 @@ describe('express with httpIntegration and maxRequestBodySize: "medium"', () => test('truncates large request bodies with "medium" setting', async () => { const runner = createRunner() .expect({ - transaction: { - transaction: 'POST /test-body-size', - request: { - data: generatePayloadString(MAX_MEDIUM, true), - }, + span: container => { + expect(container.items.find(item => item.is_segment)).toMatchObject({ + name: 'POST /test-body-size', + attributes: expect.objectContaining({ + 'http.request.body.data': { type: 'string', value: generatePayloadString(MAX_MEDIUM, true) }, + }), + }); }, }) .start();