From 9df76df11e36b2e57a48a82aa97a873c77183395 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Fri, 2 Aug 2024 13:05:55 +0000 Subject: [PATCH 1/4] test(e2e): Unflake NestJS e2e tests --- .../nestjs-basic/src/instrument.ts | 4 ++ .../nestjs-basic/start-event-proxy.mjs | 2 +- .../nestjs-basic/tests/cron-decorator.test.ts | 6 +-- .../nestjs-basic/tests/errors.test.ts | 20 ++++----- .../nestjs-basic/tests/span-decorator.test.ts | 12 +++--- .../nestjs-basic/tests/transactions.test.ts | 42 ++++++++++--------- .../src/instrument.ts | 4 ++ .../start-event-proxy.mjs | 2 +- .../tests/propagation.test.ts | 40 +++++++++--------- .../nestjs-with-submodules/src/instrument.ts | 4 ++ .../start-event-proxy.mjs | 2 +- .../tests/errors.test.ts | 34 +++++++-------- .../tests/transactions.test.ts | 2 +- 13 files changed, 94 insertions(+), 80 deletions(-) diff --git a/dev-packages/e2e-tests/test-applications/nestjs-basic/src/instrument.ts b/dev-packages/e2e-tests/test-applications/nestjs-basic/src/instrument.ts index f1f4de865435..4f16ebb36d11 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-basic/src/instrument.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-basic/src/instrument.ts @@ -5,4 +5,8 @@ Sentry.init({ dsn: process.env.E2E_TEST_DSN, tunnel: `http://localhost:3031/`, // proxy server tracesSampleRate: 1, + transportOptions: { + // We expect the app to send a lot of events in a short time + bufferSize: 1000, + }, }); diff --git a/dev-packages/e2e-tests/test-applications/nestjs-basic/start-event-proxy.mjs b/dev-packages/e2e-tests/test-applications/nestjs-basic/start-event-proxy.mjs index e9917b9273da..a8ca8dcf1b3a 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-basic/start-event-proxy.mjs +++ b/dev-packages/e2e-tests/test-applications/nestjs-basic/start-event-proxy.mjs @@ -2,5 +2,5 @@ import { startEventProxyServer } from '@sentry-internal/test-utils'; startEventProxyServer({ port: 3031, - proxyServerName: 'nestjs', + proxyServerName: 'nestjs-basic', }); diff --git a/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/cron-decorator.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/cron-decorator.test.ts index c13623337343..7d04928a5272 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/cron-decorator.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/cron-decorator.test.ts @@ -1,8 +1,8 @@ import { expect, test } from '@playwright/test'; import { waitForEnvelopeItem } from '@sentry-internal/test-utils'; -test('Cron job triggers send of in_progress envelope', async ({ baseURL }) => { - const inProgressEnvelopePromise = waitForEnvelopeItem('nestjs', envelope => { +test('Cron job triggers send of in_progress envelope', async ({ request }) => { + const inProgressEnvelopePromise = waitForEnvelopeItem('nestjs-basic', envelope => { return envelope[0].type === 'check_in'; }); @@ -30,5 +30,5 @@ test('Cron job triggers send of in_progress envelope', async ({ baseURL }) => { ); // kill cron so tests don't get stuck - await fetch(`${baseURL}/kill-test-cron`); + await request.get('/kill-test-cron'); }); diff --git a/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/errors.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/errors.test.ts index dad5d391bdde..06bffc5b4e7e 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/errors.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/errors.test.ts @@ -1,12 +1,12 @@ import { expect, test } from '@playwright/test'; import { waitForError, waitForTransaction } from '@sentry-internal/test-utils'; -test('Sends exception to Sentry', async ({ baseURL }) => { - const errorEventPromise = waitForError('nestjs', event => { +test('Sends exception to Sentry', async ({ request }) => { + const errorEventPromise = waitForError('nestjs-basic', event => { return !event.type && event.exception?.values?.[0]?.value === 'This is an exception with id 123'; }); - const response = await fetch(`${baseURL}/test-exception/123`); + const response = await request.get('/test-exception/123'); expect(response.status).toBe(500); const errorEvent = await errorEventPromise; @@ -29,10 +29,10 @@ test('Sends exception to Sentry', async ({ baseURL }) => { }); }); -test('Does not send HttpExceptions to Sentry', async ({ baseURL }) => { +test('Does not send HttpExceptions to Sentry', async ({ request }) => { let errorEventOccurred = false; - waitForError('nestjs', event => { + waitForError('nestjs-basic', event => { if (!event.type && event.exception?.values?.[0]?.value === 'This is an expected 400 exception with id 123') { errorEventOccurred = true; } @@ -40,7 +40,7 @@ test('Does not send HttpExceptions to Sentry', async ({ baseURL }) => { return event?.transaction === 'GET /test-expected-400-exception/:id'; }); - waitForError('nestjs', event => { + waitForError('nestjs-basic', event => { if (!event.type && event.exception?.values?.[0]?.value === 'This is an expected 500 exception with id 123') { errorEventOccurred = true; } @@ -48,18 +48,18 @@ test('Does not send HttpExceptions to Sentry', async ({ baseURL }) => { return event?.transaction === 'GET /test-expected-500-exception/:id'; }); - const transactionEventPromise400 = waitForTransaction('nestjs', transactionEvent => { + const transactionEventPromise400 = waitForTransaction('nestjs-basic', transactionEvent => { return transactionEvent?.transaction === 'GET /test-expected-400-exception/:id'; }); - const transactionEventPromise500 = waitForTransaction('nestjs', transactionEvent => { + const transactionEventPromise500 = waitForTransaction('nestjs-basic', transactionEvent => { return transactionEvent?.transaction === 'GET /test-expected-500-exception/:id'; }); - const response400 = await fetch(`${baseURL}/test-expected-400-exception/123`); + const response400 = await request.get('/test-expected-400-exception/123'); expect(response400.status).toBe(400); - const response500 = await fetch(`${baseURL}/test-expected-500-exception/123`); + const response500 = await request.get('/test-expected-500-exception/123'); expect(response500.status).toBe(500); await transactionEventPromise400; diff --git a/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/span-decorator.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/span-decorator.test.ts index 28c925727d89..d7479325ab8b 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/span-decorator.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/span-decorator.test.ts @@ -1,15 +1,15 @@ import { expect, test } from '@playwright/test'; import { waitForTransaction } from '@sentry-internal/test-utils'; -test('Transaction includes span and correct value for decorated async function', async ({ baseURL }) => { - const transactionEventPromise = waitForTransaction('nestjs', transactionEvent => { +test('Transaction includes span and correct value for decorated async function', async ({ request }) => { + const transactionEventPromise = waitForTransaction('nestjs-basic', transactionEvent => { return ( transactionEvent?.contexts?.trace?.op === 'http.server' && transactionEvent?.transaction === 'GET /test-span-decorator-async' ); }); - const response = await fetch(`${baseURL}/test-span-decorator-async`); + const response = await request.get(`/test-span-decorator-async`); const body = await response.json(); expect(body.result).toEqual('test'); @@ -36,15 +36,15 @@ test('Transaction includes span and correct value for decorated async function', ); }); -test('Transaction includes span and correct value for decorated sync function', async ({ baseURL }) => { - const transactionEventPromise = waitForTransaction('nestjs', transactionEvent => { +test('Transaction includes span and correct value for decorated sync function', async ({ request }) => { + const transactionEventPromise = waitForTransaction('nestjs-basic', transactionEvent => { return ( transactionEvent?.contexts?.trace?.op === 'http.server' && transactionEvent?.transaction === 'GET /test-span-decorator-sync' ); }); - const response = await fetch(`${baseURL}/test-span-decorator-sync`); + const response = await request.get('/test-span-decorator-sync'); const body = await response.json(); expect(body.result).toEqual('test'); diff --git a/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/transactions.test.ts index 78b3e0d3102a..a954ce1b87fe 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/transactions.test.ts @@ -1,15 +1,15 @@ import { expect, test } from '@playwright/test'; import { waitForTransaction } from '@sentry-internal/test-utils'; -test('Sends an API route transaction', async ({ baseURL }) => { - const pageloadTransactionEventPromise = waitForTransaction('nestjs', transactionEvent => { +test('Sends an API route transaction', async ({ request }) => { + const pageloadTransactionEventPromise = waitForTransaction('nestjs-basic', transactionEvent => { return ( transactionEvent?.contexts?.trace?.op === 'http.server' && transactionEvent?.transaction === 'GET /test-transaction' ); }); - await fetch(`${baseURL}/test-transaction`); + await request.get('/test-transaction'); const transactionEvent = await pageloadTransactionEventPromise; @@ -123,16 +123,16 @@ test('Sends an API route transaction', async ({ baseURL }) => { }); test('API route transaction includes nest middleware span. Spans created in and after middleware are nested correctly', async ({ - baseURL, + request, }) => { - const pageloadTransactionEventPromise = waitForTransaction('nestjs', transactionEvent => { + const pageloadTransactionEventPromise = waitForTransaction('nestjs-basic', transactionEvent => { return ( transactionEvent?.contexts?.trace?.op === 'http.server' && transactionEvent?.transaction === 'GET /test-middleware-instrumentation' ); }); - const response = await fetch(`${baseURL}/test-middleware-instrumentation`); + const response = await request.get('/test-middleware-instrumentation'); expect(response.status).toBe(200); const transactionEvent = await pageloadTransactionEventPromise; @@ -203,16 +203,16 @@ test('API route transaction includes nest middleware span. Spans created in and }); test('API route transaction includes nest guard span and span started in guard is nested correctly', async ({ - baseURL, + request, }) => { - const transactionEventPromise = waitForTransaction('nestjs', transactionEvent => { + const transactionEventPromise = waitForTransaction('nestjs-basic', transactionEvent => { return ( transactionEvent?.contexts?.trace?.op === 'http.server' && transactionEvent?.transaction === 'GET /test-guard-instrumentation' ); }); - const response = await fetch(`${baseURL}/test-guard-instrumentation`); + const response = await request.get('/test-guard-instrumentation'); expect(response.status).toBe(200); const transactionEvent = await transactionEventPromise; @@ -267,15 +267,16 @@ test('API route transaction includes nest guard span and span started in guard i expect(testGuardSpan.parent_span_id).toBe(exampleGuardSpanId); }); -test('API route transaction includes nest pipe span for valid request', async ({ baseURL }) => { - const transactionEventPromise = waitForTransaction('nestjs', transactionEvent => { +test('API route transaction includes nest pipe span for valid request', async ({ request }) => { + const transactionEventPromise = waitForTransaction('nestjs-basic', transactionEvent => { return ( transactionEvent?.contexts?.trace?.op === 'http.server' && - transactionEvent?.transaction === 'GET /test-pipe-instrumentation/:id' + transactionEvent?.transaction === 'GET /test-pipe-instrumentation/:id' && + transactionEvent?.request?.url?.includes('/test-pipe-instrumentation/123') ); }); - const response = await fetch(`${baseURL}/test-pipe-instrumentation/123`); + const response = await request.get('/test-pipe-instrumentation/123'); expect(response.status).toBe(200); const transactionEvent = await transactionEventPromise; @@ -303,15 +304,16 @@ test('API route transaction includes nest pipe span for valid request', async ({ ); }); -test('API route transaction includes nest pipe span for invalid request', async ({ baseURL }) => { - const transactionEventPromise = waitForTransaction('nestjs', transactionEvent => { +test('API route transaction includes nest pipe span for invalid request', async ({ request }) => { + const transactionEventPromise = waitForTransaction('nestjs-basic', transactionEvent => { return ( transactionEvent?.contexts?.trace?.op === 'http.server' && - transactionEvent?.transaction === 'GET /test-pipe-instrumentation/:id' + transactionEvent?.transaction === 'GET /test-pipe-instrumentation/:id' && + transactionEvent?.request?.url?.includes('/test-pipe-instrumentation/abc') ); }); - const response = await fetch(`${baseURL}/test-pipe-instrumentation/abc`); + const response = await request.get('/test-pipe-instrumentation/abc'); expect(response.status).toBe(400); const transactionEvent = await transactionEventPromise; @@ -340,16 +342,16 @@ test('API route transaction includes nest pipe span for invalid request', async }); test('API route transaction includes nest interceptor span. Spans created in and after interceptor are nested correctly', async ({ - baseURL, + request, }) => { - const pageloadTransactionEventPromise = waitForTransaction('nestjs', transactionEvent => { + const pageloadTransactionEventPromise = waitForTransaction('nestjs-basic', transactionEvent => { return ( transactionEvent?.contexts?.trace?.op === 'http.server' && transactionEvent?.transaction === 'GET /test-interceptor-instrumentation' ); }); - const response = await fetch(`${baseURL}/test-interceptor-instrumentation`); + const response = await request.get('/test-interceptor-instrumentation'); expect(response.status).toBe(200); const transactionEvent = await pageloadTransactionEventPromise; diff --git a/dev-packages/e2e-tests/test-applications/nestjs-distributed-tracing/src/instrument.ts b/dev-packages/e2e-tests/test-applications/nestjs-distributed-tracing/src/instrument.ts index b5ca047e497c..1cf7b8ee1f76 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-distributed-tracing/src/instrument.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-distributed-tracing/src/instrument.ts @@ -6,4 +6,8 @@ Sentry.init({ tunnel: `http://localhost:3031/`, // proxy server tracesSampleRate: 1, tracePropagationTargets: ['http://localhost:3030', '/external-allowed'], + transportOptions: { + // We expect the app to send a lot of events in a short time + bufferSize: 1000, + }, }); diff --git a/dev-packages/e2e-tests/test-applications/nestjs-distributed-tracing/start-event-proxy.mjs b/dev-packages/e2e-tests/test-applications/nestjs-distributed-tracing/start-event-proxy.mjs index e9917b9273da..5ba2a78c585c 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-distributed-tracing/start-event-proxy.mjs +++ b/dev-packages/e2e-tests/test-applications/nestjs-distributed-tracing/start-event-proxy.mjs @@ -2,5 +2,5 @@ import { startEventProxyServer } from '@sentry-internal/test-utils'; startEventProxyServer({ port: 3031, - proxyServerName: 'nestjs', + proxyServerName: 'nestjs-distributed-tracing', }); diff --git a/dev-packages/e2e-tests/test-applications/nestjs-distributed-tracing/tests/propagation.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-distributed-tracing/tests/propagation.test.ts index 2922435c542b..1fe3167bad99 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-distributed-tracing/tests/propagation.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-distributed-tracing/tests/propagation.test.ts @@ -3,24 +3,24 @@ import { expect, test } from '@playwright/test'; import { waitForTransaction } from '@sentry-internal/test-utils'; import { SpanJSON } from '@sentry/types'; -test('Propagates trace for outgoing http requests', async ({ baseURL }) => { +test('Propagates trace for outgoing http requests', async ({ request }) => { const id = crypto.randomUUID(); - const inboundTransactionPromise = waitForTransaction('nestjs', transactionEvent => { + const inboundTransactionPromise = waitForTransaction('nestjs-distributed-tracing', transactionEvent => { return ( transactionEvent.contexts?.trace?.op === 'http.server' && transactionEvent.contexts?.trace?.data?.['http.target'] === `/test-inbound-headers/${id}` ); }); - const outboundTransactionPromise = waitForTransaction('nestjs', transactionEvent => { + const outboundTransactionPromise = waitForTransaction('nestjs-distributed-tracing', transactionEvent => { return ( transactionEvent.contexts?.trace?.op === 'http.server' && transactionEvent.contexts?.trace?.data?.['http.target'] === `/test-outgoing-http/${id}` ); }); - const response = await fetch(`${baseURL}/test-outgoing-http/${id}`); + const response = await request.get(`/test-outgoing-http/${id}`); const data = await response.json(); const inboundTransaction = await inboundTransactionPromise; @@ -118,24 +118,24 @@ test('Propagates trace for outgoing http requests', async ({ baseURL }) => { }); }); -test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => { +test('Propagates trace for outgoing fetch requests', async ({ request }) => { const id = crypto.randomUUID(); - const inboundTransactionPromise = waitForTransaction('nestjs', transactionEvent => { + const inboundTransactionPromise = waitForTransaction('nestjs-distributed-tracing', transactionEvent => { return ( transactionEvent?.contexts?.trace?.op === 'http.server' && transactionEvent.contexts?.trace?.data?.['http.target'] === `/test-inbound-headers/${id}` ); }); - const outboundTransactionPromise = waitForTransaction('nestjs', transactionEvent => { + const outboundTransactionPromise = waitForTransaction('nestjs-distributed-tracing', transactionEvent => { return ( transactionEvent?.contexts?.trace?.op === 'http.server' && transactionEvent.contexts?.trace?.data?.['http.target'] === `/test-outgoing-fetch/${id}` ); }); - const response = await fetch(`${baseURL}/test-outgoing-fetch/${id}`); + const response = await request.get(`/test-outgoing-fetch/${id}`); const data = await response.json(); const inboundTransaction = await inboundTransactionPromise; @@ -233,15 +233,15 @@ test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => { }); }); -test('Propagates trace for outgoing external http requests', async ({ baseURL }) => { - const inboundTransactionPromise = waitForTransaction('nestjs', transactionEvent => { +test('Propagates trace for outgoing external http requests', async ({ request }) => { + const inboundTransactionPromise = waitForTransaction('nestjs-distributed-tracing', transactionEvent => { return ( transactionEvent?.contexts?.trace?.op === 'http.server' && transactionEvent.contexts?.trace?.data?.['http.target'] === `/test-outgoing-http-external-allowed` ); }); - const response = await fetch(`${baseURL}/test-outgoing-http-external-allowed`); + const response = await request.get(`/test-outgoing-http-external-allowed`); const data = await response.json(); const inboundTransaction = await inboundTransactionPromise; @@ -270,15 +270,15 @@ test('Propagates trace for outgoing external http requests', async ({ baseURL }) ); }); -test('Does not propagate outgoing http requests not covered by tracePropagationTargets', async ({ baseURL }) => { - const inboundTransactionPromise = waitForTransaction('nestjs', transactionEvent => { +test('Does not propagate outgoing http requests not covered by tracePropagationTargets', async ({ request }) => { + const inboundTransactionPromise = waitForTransaction('nestjs-distributed-tracing', transactionEvent => { return ( transactionEvent?.contexts?.trace?.op === 'http.server' && transactionEvent.contexts?.trace?.data?.['http.target'] === `/test-outgoing-http-external-disallowed` ); }); - const response = await fetch(`${baseURL}/test-outgoing-http-external-disallowed`); + const response = await request.get(`/test-outgoing-http-external-disallowed`); const data = await response.json(); const inboundTransaction = await inboundTransactionPromise; @@ -294,15 +294,15 @@ test('Does not propagate outgoing http requests not covered by tracePropagationT expect(data.headers?.baggage).toBeUndefined(); }); -test('Propagates trace for outgoing external fetch requests', async ({ baseURL }) => { - const inboundTransactionPromise = waitForTransaction('nestjs', transactionEvent => { +test('Propagates trace for outgoing external fetch requests', async ({ request }) => { + const inboundTransactionPromise = waitForTransaction('nestjs-distributed-tracing', transactionEvent => { return ( transactionEvent?.contexts?.trace?.op === 'http.server' && transactionEvent.contexts?.trace?.data?.['http.target'] === `/test-outgoing-fetch-external-allowed` ); }); - const response = await fetch(`${baseURL}/test-outgoing-fetch-external-allowed`); + const response = await request.get(`/test-outgoing-fetch-external-allowed`); const data = await response.json(); const inboundTransaction = await inboundTransactionPromise; @@ -331,15 +331,15 @@ test('Propagates trace for outgoing external fetch requests', async ({ baseURL } ); }); -test('Does not propagate outgoing fetch requests not covered by tracePropagationTargets', async ({ baseURL }) => { - const inboundTransactionPromise = waitForTransaction('nestjs', transactionEvent => { +test('Does not propagate outgoing fetch requests not covered by tracePropagationTargets', async ({ request }) => { + const inboundTransactionPromise = waitForTransaction('nestjs-distributed-tracing', transactionEvent => { return ( transactionEvent?.contexts?.trace?.op === 'http.server' && transactionEvent.contexts?.trace?.data?.['http.target'] === `/test-outgoing-fetch-external-disallowed` ); }); - const response = await fetch(`${baseURL}/test-outgoing-fetch-external-disallowed`); + const response = await request.get(`/test-outgoing-fetch-external-disallowed`); const data = await response.json(); const inboundTransaction = await inboundTransactionPromise; diff --git a/dev-packages/e2e-tests/test-applications/nestjs-with-submodules/src/instrument.ts b/dev-packages/e2e-tests/test-applications/nestjs-with-submodules/src/instrument.ts index f1f4de865435..4f16ebb36d11 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-with-submodules/src/instrument.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-with-submodules/src/instrument.ts @@ -5,4 +5,8 @@ Sentry.init({ dsn: process.env.E2E_TEST_DSN, tunnel: `http://localhost:3031/`, // proxy server tracesSampleRate: 1, + transportOptions: { + // We expect the app to send a lot of events in a short time + bufferSize: 1000, + }, }); diff --git a/dev-packages/e2e-tests/test-applications/nestjs-with-submodules/start-event-proxy.mjs b/dev-packages/e2e-tests/test-applications/nestjs-with-submodules/start-event-proxy.mjs index e9917b9273da..6ec54bc59e4f 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-with-submodules/start-event-proxy.mjs +++ b/dev-packages/e2e-tests/test-applications/nestjs-with-submodules/start-event-proxy.mjs @@ -2,5 +2,5 @@ import { startEventProxyServer } from '@sentry-internal/test-utils'; startEventProxyServer({ port: 3031, - proxyServerName: 'nestjs', + proxyServerName: 'nestjs-with-submodules', }); diff --git a/dev-packages/e2e-tests/test-applications/nestjs-with-submodules/tests/errors.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-with-submodules/tests/errors.test.ts index 8d5885f146df..d7e1ab7e9a73 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-with-submodules/tests/errors.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-with-submodules/tests/errors.test.ts @@ -1,12 +1,12 @@ import { expect, test } from '@playwright/test'; import { waitForError, waitForTransaction } from '@sentry-internal/test-utils'; -test('Sends unexpected exception to Sentry if thrown in module with global filter', async ({ baseURL }) => { - const errorEventPromise = waitForError('nestjs', event => { +test('Sends unexpected exception to Sentry if thrown in module with global filter', async ({ request }) => { + const errorEventPromise = waitForError('nestjs-with-submodules', event => { return !event.type && event.exception?.values?.[0]?.value === 'This is an uncaught exception!'; }); - const response = await fetch(`${baseURL}/example-module/unexpected-exception`); + const response = await request.get(`/example-module/unexpected-exception`); expect(response.status).toBe(500); const errorEvent = await errorEventPromise; @@ -30,13 +30,13 @@ test('Sends unexpected exception to Sentry if thrown in module with global filte }); test('Sends unexpected exception to Sentry if thrown in module that was registered before Sentry', async ({ - baseURL, + request, }) => { - const errorEventPromise = waitForError('nestjs', event => { + const errorEventPromise = waitForError('nestjs-with-submodules', event => { return !event.type && event.exception?.values?.[0]?.value === 'This is an uncaught exception!'; }); - const response = await fetch(`${baseURL}/example-module-wrong-order/unexpected-exception`); + const response = await request.get(`/example-module-wrong-order/unexpected-exception`); expect(response.status).toBe(500); const errorEvent = await errorEventPromise; @@ -60,11 +60,11 @@ test('Sends unexpected exception to Sentry if thrown in module that was register }); test('Does not send exception to Sentry if user-defined global exception filter already catches the exception', async ({ - baseURL, + request, }) => { let errorEventOccurred = false; - waitForError('nestjs', event => { + waitForError('nestjs-with-submodules', event => { if (!event.type && event.exception?.values?.[0]?.value === 'Something went wrong in the example module!') { errorEventOccurred = true; } @@ -72,11 +72,11 @@ test('Does not send exception to Sentry if user-defined global exception filter return event?.transaction === 'GET /example-module/expected-exception'; }); - const transactionEventPromise = waitForTransaction('nestjs', transactionEvent => { + const transactionEventPromise = waitForTransaction('nestjs-with-submodules', transactionEvent => { return transactionEvent?.transaction === 'GET /example-module/expected-exception'; }); - const response = await fetch(`${baseURL}/example-module/expected-exception`); + const response = await request.get(`/example-module/expected-exception`); expect(response.status).toBe(400); await transactionEventPromise; @@ -87,11 +87,11 @@ test('Does not send exception to Sentry if user-defined global exception filter }); test('Does not send exception to Sentry if user-defined local exception filter already catches the exception', async ({ - baseURL, + request, }) => { let errorEventOccurred = false; - waitForError('nestjs', event => { + waitForError('nestjs-with-submodules', event => { if ( !event.type && event.exception?.values?.[0]?.value === 'Something went wrong in the example module with local filter!' @@ -102,11 +102,11 @@ test('Does not send exception to Sentry if user-defined local exception filter a return event?.transaction === 'GET /example-module-local-filter/expected-exception'; }); - const transactionEventPromise = waitForTransaction('nestjs', transactionEvent => { + const transactionEventPromise = waitForTransaction('nestjs-with-submodules', transactionEvent => { return transactionEvent?.transaction === 'GET /example-module-local-filter/expected-exception'; }); - const response = await fetch(`${baseURL}/example-module-local-filter/expected-exception`); + const response = await request.get(`/example-module-local-filter/expected-exception`); expect(response.status).toBe(400); await transactionEventPromise; @@ -117,13 +117,13 @@ test('Does not send exception to Sentry if user-defined local exception filter a }); test('Does not handle expected exception if exception is thrown in module registered before Sentry', async ({ - baseURL, + request, }) => { - const errorEventPromise = waitForError('nestjs', event => { + const errorEventPromise = waitForError('nestjs-with-submodules', event => { return !event.type && event.exception?.values?.[0]?.value === 'Something went wrong in the example module!'; }); - const response = await fetch(`${baseURL}/example-module-wrong-order/expected-exception`); + const response = await request.get(`/example-module-wrong-order/expected-exception`); expect(response.status).toBe(500); // should be 400 // should never arrive, but does because the exception is not handled properly diff --git a/dev-packages/e2e-tests/test-applications/nestjs-with-submodules/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-with-submodules/tests/transactions.test.ts index 25375f5fd962..887284585ae1 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-with-submodules/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-with-submodules/tests/transactions.test.ts @@ -2,7 +2,7 @@ import { expect, test } from '@playwright/test'; import { waitForTransaction } from '@sentry-internal/test-utils'; test('Sends an API route transaction from module', async ({ baseURL }) => { - const pageloadTransactionEventPromise = waitForTransaction('nestjs', transactionEvent => { + const pageloadTransactionEventPromise = waitForTransaction('nestjs-with-submodules', transactionEvent => { return ( transactionEvent?.contexts?.trace?.op === 'http.server' && transactionEvent?.transaction === 'GET /example-module/transaction' From b04cee9681af57b9a321ece33977de9bb5d2de79 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Fri, 2 Aug 2024 13:47:28 +0000 Subject: [PATCH 2/4] screw the fetch thing --- .../nestjs-basic/tests/cron-decorator.test.ts | 4 +-- .../nestjs-basic/tests/errors.test.ts | 10 +++---- .../nestjs-basic/tests/span-decorator.test.ts | 4 +-- .../nestjs-basic/tests/transactions.test.ts | 24 ++++++++-------- .../tests/propagation.test.ts | 28 +++++++++---------- .../tests/errors.test.ts | 20 ++++++------- 6 files changed, 45 insertions(+), 45 deletions(-) diff --git a/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/cron-decorator.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/cron-decorator.test.ts index 7d04928a5272..e9fa54c69164 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/cron-decorator.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/cron-decorator.test.ts @@ -1,7 +1,7 @@ import { expect, test } from '@playwright/test'; import { waitForEnvelopeItem } from '@sentry-internal/test-utils'; -test('Cron job triggers send of in_progress envelope', async ({ request }) => { +test('Cron job triggers send of in_progress envelope', async ({ baseURL }) => { const inProgressEnvelopePromise = waitForEnvelopeItem('nestjs-basic', envelope => { return envelope[0].type === 'check_in'; }); @@ -30,5 +30,5 @@ test('Cron job triggers send of in_progress envelope', async ({ request }) => { ); // kill cron so tests don't get stuck - await request.get('/kill-test-cron'); + await fetch(`${baseURL}/kill-test-cron`); }); diff --git a/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/errors.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/errors.test.ts index 06bffc5b4e7e..cffc5f4946a3 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/errors.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/errors.test.ts @@ -1,12 +1,12 @@ import { expect, test } from '@playwright/test'; import { waitForError, waitForTransaction } from '@sentry-internal/test-utils'; -test('Sends exception to Sentry', async ({ request }) => { +test('Sends exception to Sentry', async ({ baseURL }) => { const errorEventPromise = waitForError('nestjs-basic', event => { return !event.type && event.exception?.values?.[0]?.value === 'This is an exception with id 123'; }); - const response = await request.get('/test-exception/123'); + const response = await fetch(`${baseURL}/test-exception/123`); expect(response.status).toBe(500); const errorEvent = await errorEventPromise; @@ -29,7 +29,7 @@ test('Sends exception to Sentry', async ({ request }) => { }); }); -test('Does not send HttpExceptions to Sentry', async ({ request }) => { +test('Does not send HttpExceptions to Sentry', async ({ baseURL }) => { let errorEventOccurred = false; waitForError('nestjs-basic', event => { @@ -56,10 +56,10 @@ test('Does not send HttpExceptions to Sentry', async ({ request }) => { return transactionEvent?.transaction === 'GET /test-expected-500-exception/:id'; }); - const response400 = await request.get('/test-expected-400-exception/123'); + const response400 = await fetch(`${baseURL}/test-expected-400-exception/123`); expect(response400.status).toBe(400); - const response500 = await request.get('/test-expected-500-exception/123'); + const response500 = await fetch(`${baseURL}/test-expected-500-exception/123`); expect(response500.status).toBe(500); await transactionEventPromise400; diff --git a/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/span-decorator.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/span-decorator.test.ts index d7479325ab8b..6a58f5324767 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/span-decorator.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/span-decorator.test.ts @@ -36,7 +36,7 @@ test('Transaction includes span and correct value for decorated async function', ); }); -test('Transaction includes span and correct value for decorated sync function', async ({ request }) => { +test('Transaction includes span and correct value for decorated sync function', async ({ baseURL }) => { const transactionEventPromise = waitForTransaction('nestjs-basic', transactionEvent => { return ( transactionEvent?.contexts?.trace?.op === 'http.server' && @@ -44,7 +44,7 @@ test('Transaction includes span and correct value for decorated sync function', ); }); - const response = await request.get('/test-span-decorator-sync'); + const response = await fetch(`${baseURL}/test-span-decorator-sync`); const body = await response.json(); expect(body.result).toEqual('test'); diff --git a/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/transactions.test.ts index a954ce1b87fe..555b6357ade8 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/transactions.test.ts @@ -1,7 +1,7 @@ import { expect, test } from '@playwright/test'; import { waitForTransaction } from '@sentry-internal/test-utils'; -test('Sends an API route transaction', async ({ request }) => { +test('Sends an API route transaction', async ({ baseURL }) => { const pageloadTransactionEventPromise = waitForTransaction('nestjs-basic', transactionEvent => { return ( transactionEvent?.contexts?.trace?.op === 'http.server' && @@ -9,7 +9,7 @@ test('Sends an API route transaction', async ({ request }) => { ); }); - await request.get('/test-transaction'); + await fetch(`${baseURL}/test-transaction`); const transactionEvent = await pageloadTransactionEventPromise; @@ -123,7 +123,7 @@ test('Sends an API route transaction', async ({ request }) => { }); test('API route transaction includes nest middleware span. Spans created in and after middleware are nested correctly', async ({ - request, + baseURL, }) => { const pageloadTransactionEventPromise = waitForTransaction('nestjs-basic', transactionEvent => { return ( @@ -132,7 +132,7 @@ test('API route transaction includes nest middleware span. Spans created in and ); }); - const response = await request.get('/test-middleware-instrumentation'); + const response = await fetch(`${baseURL}/test-middleware-instrumentation`); expect(response.status).toBe(200); const transactionEvent = await pageloadTransactionEventPromise; @@ -203,7 +203,7 @@ test('API route transaction includes nest middleware span. Spans created in and }); test('API route transaction includes nest guard span and span started in guard is nested correctly', async ({ - request, + baseURL, }) => { const transactionEventPromise = waitForTransaction('nestjs-basic', transactionEvent => { return ( @@ -212,7 +212,7 @@ test('API route transaction includes nest guard span and span started in guard i ); }); - const response = await request.get('/test-guard-instrumentation'); + const response = await fetch(`${baseURL}/test-guard-instrumentation`); expect(response.status).toBe(200); const transactionEvent = await transactionEventPromise; @@ -267,7 +267,7 @@ test('API route transaction includes nest guard span and span started in guard i expect(testGuardSpan.parent_span_id).toBe(exampleGuardSpanId); }); -test('API route transaction includes nest pipe span for valid request', async ({ request }) => { +test('API route transaction includes nest pipe span for valid request', async ({ baseURL }) => { const transactionEventPromise = waitForTransaction('nestjs-basic', transactionEvent => { return ( transactionEvent?.contexts?.trace?.op === 'http.server' && @@ -276,7 +276,7 @@ test('API route transaction includes nest pipe span for valid request', async ({ ); }); - const response = await request.get('/test-pipe-instrumentation/123'); + const response = await fetch(`${baseURL}/test-pipe-instrumentation/123`); expect(response.status).toBe(200); const transactionEvent = await transactionEventPromise; @@ -304,7 +304,7 @@ test('API route transaction includes nest pipe span for valid request', async ({ ); }); -test('API route transaction includes nest pipe span for invalid request', async ({ request }) => { +test('API route transaction includes nest pipe span for invalid request', async ({ baseURL }) => { const transactionEventPromise = waitForTransaction('nestjs-basic', transactionEvent => { return ( transactionEvent?.contexts?.trace?.op === 'http.server' && @@ -313,7 +313,7 @@ test('API route transaction includes nest pipe span for invalid request', async ); }); - const response = await request.get('/test-pipe-instrumentation/abc'); + const response = await fetch(`${baseURL}/test-pipe-instrumentation/abc`); expect(response.status).toBe(400); const transactionEvent = await transactionEventPromise; @@ -342,7 +342,7 @@ test('API route transaction includes nest pipe span for invalid request', async }); test('API route transaction includes nest interceptor span. Spans created in and after interceptor are nested correctly', async ({ - request, + baseURL, }) => { const pageloadTransactionEventPromise = waitForTransaction('nestjs-basic', transactionEvent => { return ( @@ -351,7 +351,7 @@ test('API route transaction includes nest interceptor span. Spans created in and ); }); - const response = await request.get('/test-interceptor-instrumentation'); + const response = await fetch(`${baseURL}/test-interceptor-instrumentation`); expect(response.status).toBe(200); const transactionEvent = await pageloadTransactionEventPromise; diff --git a/dev-packages/e2e-tests/test-applications/nestjs-distributed-tracing/tests/propagation.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-distributed-tracing/tests/propagation.test.ts index 1fe3167bad99..d928deac08fd 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-distributed-tracing/tests/propagation.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-distributed-tracing/tests/propagation.test.ts @@ -3,7 +3,7 @@ import { expect, test } from '@playwright/test'; import { waitForTransaction } from '@sentry-internal/test-utils'; import { SpanJSON } from '@sentry/types'; -test('Propagates trace for outgoing http requests', async ({ request }) => { +test('Propagates trace for outgoing http requests', async ({ baseURL }) => { const id = crypto.randomUUID(); const inboundTransactionPromise = waitForTransaction('nestjs-distributed-tracing', transactionEvent => { @@ -20,7 +20,7 @@ test('Propagates trace for outgoing http requests', async ({ request }) => { ); }); - const response = await request.get(`/test-outgoing-http/${id}`); + const response = await fetch(`${baseURL}/test-outgoing-http/${id}`); const data = await response.json(); const inboundTransaction = await inboundTransactionPromise; @@ -66,7 +66,7 @@ test('Propagates trace for outgoing http requests', async ({ request }) => { 'http.method': 'GET', 'http.scheme': 'http', 'http.target': `/test-outgoing-http/${id}`, - 'http.user_agent': 'node', + 'http.user_agent': expect.any(String), 'http.flavor': '1.1', 'net.transport': 'ip_tcp', 'net.host.ip': expect.any(String), @@ -118,7 +118,7 @@ test('Propagates trace for outgoing http requests', async ({ request }) => { }); }); -test('Propagates trace for outgoing fetch requests', async ({ request }) => { +test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => { const id = crypto.randomUUID(); const inboundTransactionPromise = waitForTransaction('nestjs-distributed-tracing', transactionEvent => { @@ -135,7 +135,7 @@ test('Propagates trace for outgoing fetch requests', async ({ request }) => { ); }); - const response = await request.get(`/test-outgoing-fetch/${id}`); + const response = await fetch(`${baseURL}/test-outgoing-fetch/${id}`); const data = await response.json(); const inboundTransaction = await inboundTransactionPromise; @@ -181,7 +181,7 @@ test('Propagates trace for outgoing fetch requests', async ({ request }) => { 'http.method': 'GET', 'http.scheme': 'http', 'http.target': `/test-outgoing-fetch/${id}`, - 'http.user_agent': 'node', + 'http.user_agent': expect.any(String), 'http.flavor': '1.1', 'net.transport': 'ip_tcp', 'net.host.ip': expect.any(String), @@ -233,7 +233,7 @@ test('Propagates trace for outgoing fetch requests', async ({ request }) => { }); }); -test('Propagates trace for outgoing external http requests', async ({ request }) => { +test('Propagates trace for outgoing external http requests', async ({ baseURL }) => { const inboundTransactionPromise = waitForTransaction('nestjs-distributed-tracing', transactionEvent => { return ( transactionEvent?.contexts?.trace?.op === 'http.server' && @@ -241,7 +241,7 @@ test('Propagates trace for outgoing external http requests', async ({ request }) ); }); - const response = await request.get(`/test-outgoing-http-external-allowed`); + const response = await fetch(`${baseURL}/test-outgoing-http-external-allowed`); const data = await response.json(); const inboundTransaction = await inboundTransactionPromise; @@ -270,7 +270,7 @@ test('Propagates trace for outgoing external http requests', async ({ request }) ); }); -test('Does not propagate outgoing http requests not covered by tracePropagationTargets', async ({ request }) => { +test('Does not propagate outgoing http requests not covered by tracePropagationTargets', async ({ baseURL }) => { const inboundTransactionPromise = waitForTransaction('nestjs-distributed-tracing', transactionEvent => { return ( transactionEvent?.contexts?.trace?.op === 'http.server' && @@ -278,7 +278,7 @@ test('Does not propagate outgoing http requests not covered by tracePropagationT ); }); - const response = await request.get(`/test-outgoing-http-external-disallowed`); + const response = await fetch(`${baseURL}/test-outgoing-http-external-disallowed`); const data = await response.json(); const inboundTransaction = await inboundTransactionPromise; @@ -294,7 +294,7 @@ test('Does not propagate outgoing http requests not covered by tracePropagationT expect(data.headers?.baggage).toBeUndefined(); }); -test('Propagates trace for outgoing external fetch requests', async ({ request }) => { +test('Propagates trace for outgoing external fetch requests', async ({ baseURL }) => { const inboundTransactionPromise = waitForTransaction('nestjs-distributed-tracing', transactionEvent => { return ( transactionEvent?.contexts?.trace?.op === 'http.server' && @@ -302,7 +302,7 @@ test('Propagates trace for outgoing external fetch requests', async ({ request } ); }); - const response = await request.get(`/test-outgoing-fetch-external-allowed`); + const response = await fetch(`${baseURL}/test-outgoing-fetch-external-allowed`); const data = await response.json(); const inboundTransaction = await inboundTransactionPromise; @@ -331,7 +331,7 @@ test('Propagates trace for outgoing external fetch requests', async ({ request } ); }); -test('Does not propagate outgoing fetch requests not covered by tracePropagationTargets', async ({ request }) => { +test('Does not propagate outgoing fetch requests not covered by tracePropagationTargets', async ({ baseURL }) => { const inboundTransactionPromise = waitForTransaction('nestjs-distributed-tracing', transactionEvent => { return ( transactionEvent?.contexts?.trace?.op === 'http.server' && @@ -339,7 +339,7 @@ test('Does not propagate outgoing fetch requests not covered by tracePropagation ); }); - const response = await request.get(`/test-outgoing-fetch-external-disallowed`); + const response = await fetch(`${baseURL}/test-outgoing-fetch-external-disallowed`); const data = await response.json(); const inboundTransaction = await inboundTransactionPromise; diff --git a/dev-packages/e2e-tests/test-applications/nestjs-with-submodules/tests/errors.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-with-submodules/tests/errors.test.ts index d7e1ab7e9a73..87b828dc8501 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-with-submodules/tests/errors.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-with-submodules/tests/errors.test.ts @@ -1,12 +1,12 @@ import { expect, test } from '@playwright/test'; import { waitForError, waitForTransaction } from '@sentry-internal/test-utils'; -test('Sends unexpected exception to Sentry if thrown in module with global filter', async ({ request }) => { +test('Sends unexpected exception to Sentry if thrown in module with global filter', async ({ baseURL }) => { const errorEventPromise = waitForError('nestjs-with-submodules', event => { return !event.type && event.exception?.values?.[0]?.value === 'This is an uncaught exception!'; }); - const response = await request.get(`/example-module/unexpected-exception`); + const response = await fetch(`${baseURL}/example-module/unexpected-exception`); expect(response.status).toBe(500); const errorEvent = await errorEventPromise; @@ -30,13 +30,13 @@ test('Sends unexpected exception to Sentry if thrown in module with global filte }); test('Sends unexpected exception to Sentry if thrown in module that was registered before Sentry', async ({ - request, + baseURL, }) => { const errorEventPromise = waitForError('nestjs-with-submodules', event => { return !event.type && event.exception?.values?.[0]?.value === 'This is an uncaught exception!'; }); - const response = await request.get(`/example-module-wrong-order/unexpected-exception`); + const response = await fetch(`${baseURL}/example-module-wrong-order/unexpected-exception`); expect(response.status).toBe(500); const errorEvent = await errorEventPromise; @@ -60,7 +60,7 @@ test('Sends unexpected exception to Sentry if thrown in module that was register }); test('Does not send exception to Sentry if user-defined global exception filter already catches the exception', async ({ - request, + baseURL, }) => { let errorEventOccurred = false; @@ -76,7 +76,7 @@ test('Does not send exception to Sentry if user-defined global exception filter return transactionEvent?.transaction === 'GET /example-module/expected-exception'; }); - const response = await request.get(`/example-module/expected-exception`); + const response = await fetch(`${baseURL}/example-module/expected-exception`); expect(response.status).toBe(400); await transactionEventPromise; @@ -87,7 +87,7 @@ test('Does not send exception to Sentry if user-defined global exception filter }); test('Does not send exception to Sentry if user-defined local exception filter already catches the exception', async ({ - request, + baseURL, }) => { let errorEventOccurred = false; @@ -106,7 +106,7 @@ test('Does not send exception to Sentry if user-defined local exception filter a return transactionEvent?.transaction === 'GET /example-module-local-filter/expected-exception'; }); - const response = await request.get(`/example-module-local-filter/expected-exception`); + const response = await fetch(`${baseURL}/example-module-local-filter/expected-exception`); expect(response.status).toBe(400); await transactionEventPromise; @@ -117,13 +117,13 @@ test('Does not send exception to Sentry if user-defined local exception filter a }); test('Does not handle expected exception if exception is thrown in module registered before Sentry', async ({ - request, + baseURL, }) => { const errorEventPromise = waitForError('nestjs-with-submodules', event => { return !event.type && event.exception?.values?.[0]?.value === 'Something went wrong in the example module!'; }); - const response = await request.get(`/example-module-wrong-order/expected-exception`); + const response = await fetch(`${baseURL}/example-module-wrong-order/expected-exception`); expect(response.status).toBe(500); // should be 400 // should never arrive, but does because the exception is not handled properly From 1f128455ccd21d3649fc0692a3cd432e0fbec465 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Fri, 2 Aug 2024 14:14:57 +0000 Subject: [PATCH 3/4] review --- .../nestjs-basic/tests/span-decorator.test.ts | 4 ++-- .../node-nestjs-basic/src/instrument.ts | 4 ++++ .../node-nestjs-basic/start-event-proxy.mjs | 2 +- .../tests/cron-decorator.test.ts | 2 +- .../node-nestjs-basic/tests/errors.test.ts | 10 +++++----- .../tests/span-decorator.test.ts | 4 ++-- .../node-nestjs-basic/tests/transactions.test.ts | 12 ++++++------ .../src/instrument.ts | 4 ++++ .../start-event-proxy.mjs | 2 +- .../tests/propagation.test.ts | 16 ++++++++-------- 10 files changed, 34 insertions(+), 26 deletions(-) diff --git a/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/span-decorator.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/span-decorator.test.ts index 6a58f5324767..4b3ea2c0ba40 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/span-decorator.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/span-decorator.test.ts @@ -1,7 +1,7 @@ import { expect, test } from '@playwright/test'; import { waitForTransaction } from '@sentry-internal/test-utils'; -test('Transaction includes span and correct value for decorated async function', async ({ request }) => { +test('Transaction includes span and correct value for decorated async function', async ({ baseURL }) => { const transactionEventPromise = waitForTransaction('nestjs-basic', transactionEvent => { return ( transactionEvent?.contexts?.trace?.op === 'http.server' && @@ -9,7 +9,7 @@ test('Transaction includes span and correct value for decorated async function', ); }); - const response = await request.get(`/test-span-decorator-async`); + const response = await fetch(`${baseURL}/test-span-decorator-async`); const body = await response.json(); expect(body.result).toEqual('test'); diff --git a/dev-packages/e2e-tests/test-applications/node-nestjs-basic/src/instrument.ts b/dev-packages/e2e-tests/test-applications/node-nestjs-basic/src/instrument.ts index f1f4de865435..4f16ebb36d11 100644 --- a/dev-packages/e2e-tests/test-applications/node-nestjs-basic/src/instrument.ts +++ b/dev-packages/e2e-tests/test-applications/node-nestjs-basic/src/instrument.ts @@ -5,4 +5,8 @@ Sentry.init({ dsn: process.env.E2E_TEST_DSN, tunnel: `http://localhost:3031/`, // proxy server tracesSampleRate: 1, + transportOptions: { + // We expect the app to send a lot of events in a short time + bufferSize: 1000, + }, }); diff --git a/dev-packages/e2e-tests/test-applications/node-nestjs-basic/start-event-proxy.mjs b/dev-packages/e2e-tests/test-applications/node-nestjs-basic/start-event-proxy.mjs index e9917b9273da..a521d4f7d4fc 100644 --- a/dev-packages/e2e-tests/test-applications/node-nestjs-basic/start-event-proxy.mjs +++ b/dev-packages/e2e-tests/test-applications/node-nestjs-basic/start-event-proxy.mjs @@ -2,5 +2,5 @@ import { startEventProxyServer } from '@sentry-internal/test-utils'; startEventProxyServer({ port: 3031, - proxyServerName: 'nestjs', + proxyServerName: 'node-nestjs-basic', }); diff --git a/dev-packages/e2e-tests/test-applications/node-nestjs-basic/tests/cron-decorator.test.ts b/dev-packages/e2e-tests/test-applications/node-nestjs-basic/tests/cron-decorator.test.ts index c13623337343..0b73ea513f0b 100644 --- a/dev-packages/e2e-tests/test-applications/node-nestjs-basic/tests/cron-decorator.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-nestjs-basic/tests/cron-decorator.test.ts @@ -2,7 +2,7 @@ import { expect, test } from '@playwright/test'; import { waitForEnvelopeItem } from '@sentry-internal/test-utils'; test('Cron job triggers send of in_progress envelope', async ({ baseURL }) => { - const inProgressEnvelopePromise = waitForEnvelopeItem('nestjs', envelope => { + const inProgressEnvelopePromise = waitForEnvelopeItem('node-nestjs-basic', envelope => { return envelope[0].type === 'check_in'; }); diff --git a/dev-packages/e2e-tests/test-applications/node-nestjs-basic/tests/errors.test.ts b/dev-packages/e2e-tests/test-applications/node-nestjs-basic/tests/errors.test.ts index dad5d391bdde..11eafc38f430 100644 --- a/dev-packages/e2e-tests/test-applications/node-nestjs-basic/tests/errors.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-nestjs-basic/tests/errors.test.ts @@ -2,7 +2,7 @@ import { expect, test } from '@playwright/test'; import { waitForError, waitForTransaction } from '@sentry-internal/test-utils'; test('Sends exception to Sentry', async ({ baseURL }) => { - const errorEventPromise = waitForError('nestjs', event => { + const errorEventPromise = waitForError('node-nestjs-basic', event => { return !event.type && event.exception?.values?.[0]?.value === 'This is an exception with id 123'; }); @@ -32,7 +32,7 @@ test('Sends exception to Sentry', async ({ baseURL }) => { test('Does not send HttpExceptions to Sentry', async ({ baseURL }) => { let errorEventOccurred = false; - waitForError('nestjs', event => { + waitForError('node-nestjs-basic', event => { if (!event.type && event.exception?.values?.[0]?.value === 'This is an expected 400 exception with id 123') { errorEventOccurred = true; } @@ -40,7 +40,7 @@ test('Does not send HttpExceptions to Sentry', async ({ baseURL }) => { return event?.transaction === 'GET /test-expected-400-exception/:id'; }); - waitForError('nestjs', event => { + waitForError('node-nestjs-basic', event => { if (!event.type && event.exception?.values?.[0]?.value === 'This is an expected 500 exception with id 123') { errorEventOccurred = true; } @@ -48,11 +48,11 @@ test('Does not send HttpExceptions to Sentry', async ({ baseURL }) => { return event?.transaction === 'GET /test-expected-500-exception/:id'; }); - const transactionEventPromise400 = waitForTransaction('nestjs', transactionEvent => { + const transactionEventPromise400 = waitForTransaction('node-nestjs-basic', transactionEvent => { return transactionEvent?.transaction === 'GET /test-expected-400-exception/:id'; }); - const transactionEventPromise500 = waitForTransaction('nestjs', transactionEvent => { + const transactionEventPromise500 = waitForTransaction('node-nestjs-basic', transactionEvent => { return transactionEvent?.transaction === 'GET /test-expected-500-exception/:id'; }); diff --git a/dev-packages/e2e-tests/test-applications/node-nestjs-basic/tests/span-decorator.test.ts b/dev-packages/e2e-tests/test-applications/node-nestjs-basic/tests/span-decorator.test.ts index 28c925727d89..831dfd4400dc 100644 --- a/dev-packages/e2e-tests/test-applications/node-nestjs-basic/tests/span-decorator.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-nestjs-basic/tests/span-decorator.test.ts @@ -2,7 +2,7 @@ import { expect, test } from '@playwright/test'; import { waitForTransaction } from '@sentry-internal/test-utils'; test('Transaction includes span and correct value for decorated async function', async ({ baseURL }) => { - const transactionEventPromise = waitForTransaction('nestjs', transactionEvent => { + const transactionEventPromise = waitForTransaction('node-nestjs-basic', transactionEvent => { return ( transactionEvent?.contexts?.trace?.op === 'http.server' && transactionEvent?.transaction === 'GET /test-span-decorator-async' @@ -37,7 +37,7 @@ test('Transaction includes span and correct value for decorated async function', }); test('Transaction includes span and correct value for decorated sync function', async ({ baseURL }) => { - const transactionEventPromise = waitForTransaction('nestjs', transactionEvent => { + const transactionEventPromise = waitForTransaction('node-nestjs-basic', transactionEvent => { return ( transactionEvent?.contexts?.trace?.op === 'http.server' && transactionEvent?.transaction === 'GET /test-span-decorator-sync' diff --git a/dev-packages/e2e-tests/test-applications/node-nestjs-basic/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/node-nestjs-basic/tests/transactions.test.ts index 62c882eb7f4b..cb04bc06839e 100644 --- a/dev-packages/e2e-tests/test-applications/node-nestjs-basic/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-nestjs-basic/tests/transactions.test.ts @@ -2,7 +2,7 @@ import { expect, test } from '@playwright/test'; import { waitForTransaction } from '@sentry-internal/test-utils'; test('Sends an API route transaction', async ({ baseURL }) => { - const pageloadTransactionEventPromise = waitForTransaction('nestjs', transactionEvent => { + const pageloadTransactionEventPromise = waitForTransaction('node-nestjs-basic', transactionEvent => { return ( transactionEvent?.contexts?.trace?.op === 'http.server' && transactionEvent?.transaction === 'GET /test-transaction' @@ -125,7 +125,7 @@ test('Sends an API route transaction', async ({ baseURL }) => { test('API route transaction includes nest middleware span. Spans created in and after middleware are nested correctly', async ({ baseURL, }) => { - const transactionEventPromise = waitForTransaction('nestjs', transactionEvent => { + const transactionEventPromise = waitForTransaction('node-nestjs-basic', transactionEvent => { return ( transactionEvent?.contexts?.trace?.op === 'http.server' && transactionEvent?.transaction === 'GET /test-middleware-instrumentation' @@ -205,7 +205,7 @@ test('API route transaction includes nest middleware span. Spans created in and test('API route transaction includes nest guard span and span started in guard is nested correctly', async ({ baseURL, }) => { - const transactionEventPromise = waitForTransaction('nestjs', transactionEvent => { + const transactionEventPromise = waitForTransaction('node-nestjs-basic', transactionEvent => { return ( transactionEvent?.contexts?.trace?.op === 'http.server' && transactionEvent?.transaction === 'GET /test-guard-instrumentation' @@ -268,7 +268,7 @@ test('API route transaction includes nest guard span and span started in guard i }); test('API route transaction includes nest pipe span for valid request', async ({ baseURL }) => { - const transactionEventPromise = waitForTransaction('nestjs', transactionEvent => { + const transactionEventPromise = waitForTransaction('node-nestjs-basic', transactionEvent => { return ( transactionEvent?.contexts?.trace?.op === 'http.server' && transactionEvent?.transaction === 'GET /test-pipe-instrumentation/:id' @@ -304,7 +304,7 @@ test('API route transaction includes nest pipe span for valid request', async ({ }); test('API route transaction includes nest pipe span for invalid request', async ({ baseURL }) => { - const transactionEventPromise = waitForTransaction('nestjs', transactionEvent => { + const transactionEventPromise = waitForTransaction('node-nestjs-basic', transactionEvent => { return ( transactionEvent?.contexts?.trace?.op === 'http.server' && transactionEvent?.transaction === 'GET /test-pipe-instrumentation/:id' @@ -342,7 +342,7 @@ test('API route transaction includes nest pipe span for invalid request', async test('API route transaction includes nest interceptor span. Spans created in and after interceptor are nested correctly', async ({ baseURL, }) => { - const pageloadTransactionEventPromise = waitForTransaction('nestjs', transactionEvent => { + const pageloadTransactionEventPromise = waitForTransaction('node-nestjs-basic', transactionEvent => { return ( transactionEvent?.contexts?.trace?.op === 'http.server' && transactionEvent?.transaction === 'GET /test-interceptor-instrumentation' diff --git a/dev-packages/e2e-tests/test-applications/node-nestjs-distributed-tracing/src/instrument.ts b/dev-packages/e2e-tests/test-applications/node-nestjs-distributed-tracing/src/instrument.ts index b5ca047e497c..1cf7b8ee1f76 100644 --- a/dev-packages/e2e-tests/test-applications/node-nestjs-distributed-tracing/src/instrument.ts +++ b/dev-packages/e2e-tests/test-applications/node-nestjs-distributed-tracing/src/instrument.ts @@ -6,4 +6,8 @@ Sentry.init({ tunnel: `http://localhost:3031/`, // proxy server tracesSampleRate: 1, tracePropagationTargets: ['http://localhost:3030', '/external-allowed'], + transportOptions: { + // We expect the app to send a lot of events in a short time + bufferSize: 1000, + }, }); diff --git a/dev-packages/e2e-tests/test-applications/node-nestjs-distributed-tracing/start-event-proxy.mjs b/dev-packages/e2e-tests/test-applications/node-nestjs-distributed-tracing/start-event-proxy.mjs index e9917b9273da..1db7d30f8680 100644 --- a/dev-packages/e2e-tests/test-applications/node-nestjs-distributed-tracing/start-event-proxy.mjs +++ b/dev-packages/e2e-tests/test-applications/node-nestjs-distributed-tracing/start-event-proxy.mjs @@ -2,5 +2,5 @@ import { startEventProxyServer } from '@sentry-internal/test-utils'; startEventProxyServer({ port: 3031, - proxyServerName: 'nestjs', + proxyServerName: 'node-nestjs-distributed-tracing', }); diff --git a/dev-packages/e2e-tests/test-applications/node-nestjs-distributed-tracing/tests/propagation.test.ts b/dev-packages/e2e-tests/test-applications/node-nestjs-distributed-tracing/tests/propagation.test.ts index 2922435c542b..49b827ca7e27 100644 --- a/dev-packages/e2e-tests/test-applications/node-nestjs-distributed-tracing/tests/propagation.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-nestjs-distributed-tracing/tests/propagation.test.ts @@ -6,14 +6,14 @@ import { SpanJSON } from '@sentry/types'; test('Propagates trace for outgoing http requests', async ({ baseURL }) => { const id = crypto.randomUUID(); - const inboundTransactionPromise = waitForTransaction('nestjs', transactionEvent => { + const inboundTransactionPromise = waitForTransaction('node-nestjs-distributed-tracing', transactionEvent => { return ( transactionEvent.contexts?.trace?.op === 'http.server' && transactionEvent.contexts?.trace?.data?.['http.target'] === `/test-inbound-headers/${id}` ); }); - const outboundTransactionPromise = waitForTransaction('nestjs', transactionEvent => { + const outboundTransactionPromise = waitForTransaction('node-nestjs-distributed-tracing', transactionEvent => { return ( transactionEvent.contexts?.trace?.op === 'http.server' && transactionEvent.contexts?.trace?.data?.['http.target'] === `/test-outgoing-http/${id}` @@ -121,14 +121,14 @@ test('Propagates trace for outgoing http requests', async ({ baseURL }) => { test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => { const id = crypto.randomUUID(); - const inboundTransactionPromise = waitForTransaction('nestjs', transactionEvent => { + const inboundTransactionPromise = waitForTransaction('node-nestjs-distributed-tracing', transactionEvent => { return ( transactionEvent?.contexts?.trace?.op === 'http.server' && transactionEvent.contexts?.trace?.data?.['http.target'] === `/test-inbound-headers/${id}` ); }); - const outboundTransactionPromise = waitForTransaction('nestjs', transactionEvent => { + const outboundTransactionPromise = waitForTransaction('node-nestjs-distributed-tracing', transactionEvent => { return ( transactionEvent?.contexts?.trace?.op === 'http.server' && transactionEvent.contexts?.trace?.data?.['http.target'] === `/test-outgoing-fetch/${id}` @@ -234,7 +234,7 @@ test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => { }); test('Propagates trace for outgoing external http requests', async ({ baseURL }) => { - const inboundTransactionPromise = waitForTransaction('nestjs', transactionEvent => { + const inboundTransactionPromise = waitForTransaction('node-nestjs-distributed-tracing', transactionEvent => { return ( transactionEvent?.contexts?.trace?.op === 'http.server' && transactionEvent.contexts?.trace?.data?.['http.target'] === `/test-outgoing-http-external-allowed` @@ -271,7 +271,7 @@ test('Propagates trace for outgoing external http requests', async ({ baseURL }) }); test('Does not propagate outgoing http requests not covered by tracePropagationTargets', async ({ baseURL }) => { - const inboundTransactionPromise = waitForTransaction('nestjs', transactionEvent => { + const inboundTransactionPromise = waitForTransaction('node-nestjs-distributed-tracing', transactionEvent => { return ( transactionEvent?.contexts?.trace?.op === 'http.server' && transactionEvent.contexts?.trace?.data?.['http.target'] === `/test-outgoing-http-external-disallowed` @@ -295,7 +295,7 @@ test('Does not propagate outgoing http requests not covered by tracePropagationT }); test('Propagates trace for outgoing external fetch requests', async ({ baseURL }) => { - const inboundTransactionPromise = waitForTransaction('nestjs', transactionEvent => { + const inboundTransactionPromise = waitForTransaction('node-nestjs-distributed-tracing', transactionEvent => { return ( transactionEvent?.contexts?.trace?.op === 'http.server' && transactionEvent.contexts?.trace?.data?.['http.target'] === `/test-outgoing-fetch-external-allowed` @@ -332,7 +332,7 @@ test('Propagates trace for outgoing external fetch requests', async ({ baseURL } }); test('Does not propagate outgoing fetch requests not covered by tracePropagationTargets', async ({ baseURL }) => { - const inboundTransactionPromise = waitForTransaction('nestjs', transactionEvent => { + const inboundTransactionPromise = waitForTransaction('node-nestjs-distributed-tracing', transactionEvent => { return ( transactionEvent?.contexts?.trace?.op === 'http.server' && transactionEvent.contexts?.trace?.data?.['http.target'] === `/test-outgoing-fetch-external-disallowed` From 6b0268368bea7be9f2af3ab3ee32c9f65caa0393 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Mon, 5 Aug 2024 08:24:11 +0000 Subject: [PATCH 4/4] nanosecond check? --- .../test-utils/src/event-proxy-server.ts | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/dev-packages/test-utils/src/event-proxy-server.ts b/dev-packages/test-utils/src/event-proxy-server.ts index 01395202d990..58c39de95c8c 100644 --- a/dev-packages/test-utils/src/event-proxy-server.ts +++ b/dev-packages/test-utils/src/event-proxy-server.ts @@ -90,7 +90,7 @@ export async function startProxyServer( const callback: OnRequest = onRequest || (async (eventCallbackListeners, proxyRequest, proxyRequestBody, eventBuffer) => { - eventBuffer.push({ data: proxyRequestBody, timestamp: Date.now() }); + eventBuffer.push({ data: proxyRequestBody, timestamp: getNanosecondTimestamp() }); eventCallbackListeners.forEach(listener => { listener(proxyRequestBody); @@ -234,7 +234,7 @@ export async function startEventProxyServer(options: EventProxyServerOptions): P const dataString = Buffer.from(JSON.stringify(data)).toString('base64'); - eventBuffer.push({ data: dataString, timestamp: Date.now() }); + eventBuffer.push({ data: dataString, timestamp: getNanosecondTimestamp() }); eventCallbackListeners.forEach(listener => { listener(dataString); @@ -259,7 +259,7 @@ export async function waitForPlainRequest( return new Promise((resolve, reject) => { const request = http.request( - `http://localhost:${eventCallbackServerPort}/?timestamp=${Date.now()}`, + `http://localhost:${eventCallbackServerPort}/?timestamp=${getNanosecondTimestamp()}`, {}, response => { let eventContents = ''; @@ -289,7 +289,7 @@ export async function waitForPlainRequest( export async function waitForRequest( proxyServerName: string, callback: (eventData: SentryRequestCallbackData) => Promise | boolean, - timestamp: number = Date.now(), + timestamp: number = getNanosecondTimestamp(), ): Promise { const eventCallbackServerPort = await retrieveCallbackServerPort(proxyServerName); @@ -345,7 +345,7 @@ export async function waitForRequest( export function waitForEnvelopeItem( proxyServerName: string, callback: (envelopeItem: EnvelopeItem) => Promise | boolean, - timestamp: number = Date.now(), + timestamp: number = getNanosecondTimestamp(), ): Promise { return new Promise((resolve, reject) => { waitForRequest( @@ -370,7 +370,7 @@ export function waitForError( proxyServerName: string, callback: (errorEvent: Event) => Promise | boolean, ): Promise { - const timestamp = Date.now(); + const timestamp = getNanosecondTimestamp(); return new Promise((resolve, reject) => { waitForEnvelopeItem( proxyServerName, @@ -392,7 +392,7 @@ export function waitForSession( proxyServerName: string, callback: (session: SerializedSession) => Promise | boolean, ): Promise { - const timestamp = Date.now(); + const timestamp = getNanosecondTimestamp(); return new Promise((resolve, reject) => { waitForEnvelopeItem( proxyServerName, @@ -414,7 +414,7 @@ export function waitForTransaction( proxyServerName: string, callback: (transactionEvent: Event) => Promise | boolean, ): Promise { - const timestamp = Date.now(); + const timestamp = getNanosecondTimestamp(); return new Promise((resolve, reject) => { waitForEnvelopeItem( proxyServerName, @@ -448,3 +448,12 @@ async function retrieveCallbackServerPort(serverName: string): Promise { throw e; } } + +/** + * We do nanosecond checking because the waitFor* calls and the fetch requests may come very shortly after one another. + */ +function getNanosecondTimestamp(): number { + const NS_PER_SEC = 1e9; + const [seconds, nanoseconds] = process.hrtime(); + return seconds * NS_PER_SEC + nanoseconds; +}