Skip to content

ref(tests): Add TestEnv class to Node integration tests. #5633

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Aug 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/node-integration-tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ A custom server configuration can be used, supplying a script that exports a val

`utils/` contains helpers and Sentry-specific assertions that can be used in (`test.ts`).

`runServer` utility function returns an object containing `url` and [`http.Server`](https://nodejs.org/dist/latest-v16.x/docs/api/http.html#class-httpserver) instance for the created server. The `url` property is the base URL for the server. The `http.Server` instance is used to finish the server eventually.
`TestEnv` class contains methods to create and execute requests on a test server instance. `TestEnv.init()` which starts a test server and returns a `TestEnv` instance must be called by each test. The test server is automatically shut down after each test, if a data collection helper method such as `getEnvelopeRequest` and `getAPIResponse` is used. Tests that do not use those helper methods will need to end the server manually.

The responsibility of ending the server is delegated to the test case. Data collection helpers such as `getEnvelopeRequest` and `getAPIResponse` expect the server instance to be available and finish it before their resolution. Tests that do not use those helpers will need to end the server manually.
`TestEnv` instance has two public properties: `url` and `server`. The `url` property is the base URL for the server. The `http.Server` instance is used to finish the server eventually.

Nock interceptors are internally used to capture envelope requests by `getEnvelopeRequest` and `getMultipleEnvelopeRequest` helpers. After capturing required requests, the interceptors are removed. Nock can manually be used inside the test cases to intercept requests but should be removed before the test ends, as not to cause flakiness.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { assertSentryEvent, getEnvelopeRequest, runServer } from '../../../utils/index';
import { assertSentryEvent, TestEnv } from '../../../utils/index';

test('should capture and send Express controller error.', async () => {
const { url, server } = await runServer(__dirname, `${__dirname}/server.ts`);
const event = await getEnvelopeRequest({ url: `${url}/express`, server });
const env = await TestEnv.init(__dirname, `${__dirname}/server.ts`);
const event = await env.getEnvelopeRequest({ url: `${env.url}/express` });

expect((event[2] as any).exception.values[0].stacktrace.frames.length).toBeGreaterThan(0);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
import * as path from 'path';

import { getAPIResponse, runServer } from '../../../../utils/index';
import { TestEnv } from '../../../../utils/index';
import { TestAPIResponse } from '../server';

test('Should not overwrite baggage if the incoming request already has Sentry baggage data.', async () => {
const { url, server } = await runServer(__dirname, `${path.resolve(__dirname, '..')}/server.ts`);

const response = (await getAPIResponse(
{ url: `${url}/express`, server },
{
baggage: 'sentry-release=2.0.0,sentry-environment=myEnv',
},
)) as TestAPIResponse;
const env = await TestEnv.init(__dirname, `${path.resolve(__dirname, '..')}/server.ts`);
const response = (await env.getAPIResponse(`${env.url}/express`, {
baggage: 'sentry-release=2.0.0,sentry-environment=myEnv',
})) as TestAPIResponse;

expect(response).toBeDefined();
expect(response).toMatchObject({
Expand All @@ -23,15 +19,12 @@ test('Should not overwrite baggage if the incoming request already has Sentry ba
});

test('Should propagate sentry trace baggage data from an incoming to an outgoing request.', async () => {
const { url, server } = await runServer(__dirname, `${path.resolve(__dirname, '..')}/server.ts`);
const env = await TestEnv.init(__dirname, `${path.resolve(__dirname, '..')}/server.ts`);

const response = (await getAPIResponse(
{ url: `${url}/express`, server },
{
'sentry-trace': '',
baggage: 'sentry-release=2.0.0,sentry-environment=myEnv,dogs=great',
},
)) as TestAPIResponse;
const response = (await env.getAPIResponse(`${env.url}/express`, {
'sentry-trace': '',
baggage: 'sentry-release=2.0.0,sentry-environment=myEnv,dogs=great',
})) as TestAPIResponse;

expect(response).toBeDefined();
expect(response).toMatchObject({
Expand All @@ -43,14 +36,11 @@ test('Should propagate sentry trace baggage data from an incoming to an outgoing
});

test('Should propagate empty baggage if sentry-trace header is present in incoming request but no baggage header', async () => {
const { url, server } = await runServer(__dirname, `${path.resolve(__dirname, '..')}/server.ts`);
const env = await TestEnv.init(__dirname, `${path.resolve(__dirname, '..')}/server.ts`);

const response = (await getAPIResponse(
{ url: `${url}/express`, server },
{
'sentry-trace': '',
},
)) as TestAPIResponse;
const response = (await env.getAPIResponse(`${env.url}/express`, {
'sentry-trace': '',
})) as TestAPIResponse;

expect(response).toBeDefined();
expect(response).toMatchObject({
Expand All @@ -62,15 +52,12 @@ test('Should propagate empty baggage if sentry-trace header is present in incomi
});

test('Should propagate empty sentry and ignore original 3rd party baggage entries if sentry-trace header is present', async () => {
const { url, server } = await runServer(__dirname, `${path.resolve(__dirname, '..')}/server.ts`);
const env = await TestEnv.init(__dirname, `${path.resolve(__dirname, '..')}/server.ts`);

const response = (await getAPIResponse(
{ url: `${url}/express`, server },
{
'sentry-trace': '',
baggage: 'foo=bar',
},
)) as TestAPIResponse;
const response = (await env.getAPIResponse(`${env.url}/express`, {
'sentry-trace': '',
baggage: 'foo=bar',
})) as TestAPIResponse;

expect(response).toBeDefined();
expect(response).toMatchObject({
Expand All @@ -82,9 +69,9 @@ test('Should propagate empty sentry and ignore original 3rd party baggage entrie
});

test('Should populate and propagate sentry baggage if sentry-trace header does not exist', async () => {
const { url, server } = await runServer(__dirname, `${path.resolve(__dirname, '..')}/server.ts`);
const env = await TestEnv.init(__dirname, `${path.resolve(__dirname, '..')}/server.ts`);

const response = (await getAPIResponse({ url: `${url}/express`, server }, {})) as TestAPIResponse;
const response = (await env.getAPIResponse(`${env.url}/express`, {})) as TestAPIResponse;

expect(response).toBeDefined();
expect(response).toMatchObject({
Expand All @@ -99,14 +86,11 @@ test('Should populate and propagate sentry baggage if sentry-trace header does n
});

test('Should populate Sentry and ignore 3rd party content if sentry-trace header does not exist', async () => {
const { url, server } = await runServer(__dirname, `${path.resolve(__dirname, '..')}/server.ts`);
const env = await TestEnv.init(__dirname, `${path.resolve(__dirname, '..')}/server.ts`);

const response = (await getAPIResponse(
{ url: `${url}/express`, server },
{
baggage: 'foo=bar,bar=baz',
},
)) as TestAPIResponse;
const response = (await env.getAPIResponse(`${env.url}/express`, {
baggage: 'foo=bar,bar=baz',
})) as TestAPIResponse;

expect(response).toBeDefined();
expect(response).toMatchObject({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import * as path from 'path';

import { getAPIResponse, runServer } from '../../../../utils/index';
import { TestEnv } from '../../../../utils/index';
import { TestAPIResponse } from '../server';

test('Does not include transaction name if transaction source is not set', async () => {
const { url, server } = await runServer(__dirname, `${path.resolve(__dirname, '.')}/server.ts`);
const env = await TestEnv.init(__dirname, `${path.resolve(__dirname, '.')}/server.ts`);

const response = (await getAPIResponse({ url: `${url}/express`, server })) as TestAPIResponse;
const response = (await env.getAPIResponse(`${env.url}/express`)) as TestAPIResponse;
const baggageString = response.test_data.baggage;

expect(response).toBeDefined();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import * as path from 'path';

import { getAPIResponse, runServer } from '../../../../utils/index';
import { TestEnv } from '../../../../utils/index';
import { TestAPIResponse } from '../server';

test('should attach a `baggage` header to an outgoing request.', async () => {
const { url, server } = await runServer(__dirname, `${path.resolve(__dirname, '.')}/server.ts`);
const env = await TestEnv.init(__dirname, `${path.resolve(__dirname, '.')}/server.ts`);

const response = (await getAPIResponse({ url: `${url}/express`, server })) as TestAPIResponse;
const response = (await env.getAPIResponse(`${env.url}/express`)) as TestAPIResponse;

expect(response).toBeDefined();
expect(response).toMatchObject({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
import * as path from 'path';

import { getAPIResponse, runServer } from '../../../../utils/index';
import { TestEnv } from '../../../../utils/index';
import { TestAPIResponse } from '../server';

test('should ignore sentry-values in `baggage` header of a third party vendor and overwrite them with incoming DSC', async () => {
const { url, server } = await runServer(__dirname, `${path.resolve(__dirname, '.')}/server.ts`);
const env = await TestEnv.init(__dirname, `${path.resolve(__dirname, '.')}/server.ts`);

const response = (await getAPIResponse(
{ url: `${url}/express`, server },
{
'sentry-trace': '',
baggage: 'sentry-release=2.1.0,sentry-environment=myEnv',
},
)) as TestAPIResponse;
const response = (await env.getAPIResponse(`${env.url}/express`, {
'sentry-trace': '',
baggage: 'sentry-release=2.1.0,sentry-environment=myEnv',
})) as TestAPIResponse;

expect(response).toBeDefined();
expect(response).toMatchObject({
Expand All @@ -24,9 +21,9 @@ test('should ignore sentry-values in `baggage` header of a third party vendor an
});

test('should ignore sentry-values in `baggage` header of a third party vendor and overwrite them with new DSC', async () => {
const { url, server } = await runServer(__dirname, `${path.resolve(__dirname, '.')}/server.ts`);
const env = await TestEnv.init(__dirname, `${path.resolve(__dirname, '.')}/server.ts`);

const response = (await getAPIResponse({ url: `${url}/express`, server }, {})) as TestAPIResponse;
const response = (await env.getAPIResponse(`${env.url}/express`, {})) as TestAPIResponse;

expect(response).toBeDefined();
expect(response).toMatchObject({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
import * as path from 'path';

import { getAPIResponse, runServer } from '../../../../utils/index';
import { TestEnv } from '../../../../utils/index';
import { TestAPIResponse } from '../server';

test('should merge `baggage` header of a third party vendor with the Sentry DSC baggage items', async () => {
const { url, server } = await runServer(__dirname, `${path.resolve(__dirname, '.')}/server.ts`);
const env = await TestEnv.init(__dirname, `${path.resolve(__dirname, '.')}/server.ts`);

const response = (await getAPIResponse(
{ url: `${url}/express`, server },
{
'sentry-trace': '',
baggage: 'sentry-release=2.0.0,sentry-environment=myEnv',
},
)) as TestAPIResponse;
const response = (await env.getAPIResponse(`${env.url}/express`, {
'sentry-trace': '',
baggage: 'sentry-release=2.0.0,sentry-environment=myEnv',
})) as TestAPIResponse;

expect(response).toBeDefined();
expect(response).toMatchObject({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import * as path from 'path';

import { getAPIResponse, runServer } from '../../../../utils/index';
import { TestEnv } from '../../../../utils/index';
import { TestAPIResponse } from '../server';

test('Includes transaction in baggage if the transaction name is parameterized', async () => {
const { url, server } = await runServer(__dirname, `${path.resolve(__dirname, '.')}/server.ts`);
const env = await TestEnv.init(__dirname, `${path.resolve(__dirname, '.')}/server.ts`);

const response = (await getAPIResponse({ url: `${url}/express`, server })) as TestAPIResponse;
const response = (await env.getAPIResponse(`${env.url}/express`)) as TestAPIResponse;

expect(response).toBeDefined();
expect(response).toMatchObject({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
import { TRACEPARENT_REGEXP } from '@sentry/utils';
import * as path from 'path';

import { getAPIResponse, runServer } from '../../../../utils/index';
import { TestEnv } from '../../../../utils/index';
import { TestAPIResponse } from '../server';

test('Should assign `sentry-trace` header which sets parent trace id of an outgoing request.', async () => {
const { url, server } = await runServer(__dirname, `${path.resolve(__dirname, '..')}/server.ts`);
const env = await TestEnv.init(__dirname, `${path.resolve(__dirname, '..')}/server.ts`);

const response = (await getAPIResponse(
{ url: `${url}/express`, server },
{
'sentry-trace': '12312012123120121231201212312012-1121201211212012-0',
},
)) as TestAPIResponse;
const response = (await env.getAPIResponse(`${env.url}/express`, {
'sentry-trace': '12312012123120121231201212312012-1121201211212012-0',
})) as TestAPIResponse;

expect(response).toBeDefined();
expect(response).toMatchObject({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { TRACEPARENT_REGEXP } from '@sentry/utils';
import * as path from 'path';

import { getAPIResponse, runServer } from '../../../../utils/index';
import { TestEnv } from '../../../../utils/index';
import { TestAPIResponse } from '../server';

test('should attach a `sentry-trace` header to an outgoing request.', async () => {
const { url, server } = await runServer(__dirname, `${path.resolve(__dirname, '..')}/server.ts`);
const env = await TestEnv.init(__dirname, `${path.resolve(__dirname, '..')}/server.ts`);

const response = (await getAPIResponse({ url: `${url}/express`, server })) as TestAPIResponse;
const response = (await env.getAPIResponse(`${env.url}/express`)) as TestAPIResponse;

expect(response).toBeDefined();
expect(response).toMatchObject({
Expand Down
18 changes: 9 additions & 9 deletions packages/node-integration-tests/suites/express/tracing/test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { assertSentryTransaction, getEnvelopeRequest, runServer } from '../../../utils/index';
import { assertSentryTransaction, TestEnv } from '../../../utils/index';

test('should create and send transactions for Express routes and spans for middlewares.', async () => {
const { url, server } = await runServer(__dirname, `${__dirname}/server.ts`);
const envelope = await getEnvelopeRequest({ url: `${url}/express`, server }, { envelopeType: 'transaction' });
const env = await TestEnv.init(__dirname, `${__dirname}/server.ts`);
const envelope = await env.getEnvelopeRequest({ url: `${env.url}/express`, envelopeType: 'transaction' });

expect(envelope).toHaveLength(3);

Expand All @@ -29,8 +29,8 @@ test('should create and send transactions for Express routes and spans for middl
});

test('should set a correct transaction name for routes specified in RegEx', async () => {
const { url, server } = await runServer(__dirname, `${__dirname}/server.ts`);
const envelope = await getEnvelopeRequest({ url: `${url}/regex`, server }, { envelopeType: 'transaction' });
const env = await TestEnv.init(__dirname, `${__dirname}/server.ts`);
const envelope = await env.getEnvelopeRequest({ url: `${env.url}/regex`, envelopeType: 'transaction' });

expect(envelope).toHaveLength(3);

Expand All @@ -57,8 +57,8 @@ test('should set a correct transaction name for routes specified in RegEx', asyn
test.each([['array1'], ['array5']])(
'should set a correct transaction name for routes consisting of arrays of routes',
async segment => {
const { url, server } = await runServer(__dirname, `${__dirname}/server.ts`);
const envelope = await getEnvelopeRequest({ url: `${url}/${segment}`, server }, { envelopeType: 'transaction' });
const env = await TestEnv.init(__dirname, `${__dirname}/server.ts`);
const envelope = await env.getEnvelopeRequest({ url: `${env.url}/${segment}`, envelopeType: 'transaction' });

expect(envelope).toHaveLength(3);

Expand Down Expand Up @@ -93,8 +93,8 @@ test.each([
['arr/requiredPath/optionalPath/'],
['arr/requiredPath/optionalPath/lastParam'],
])('should handle more complex regexes in route arrays correctly', async segment => {
const { url, server } = await runServer(__dirname, `${__dirname}/server.ts`);
const envelope = await getEnvelopeRequest({ url: `${url}/${segment}`, server }, { envelopeType: 'transaction' });
const env = await TestEnv.init(__dirname, `${__dirname}/server.ts`);
const envelope = await env.getEnvelopeRequest({ url: `${env.url}/${segment}`, envelopeType: 'transaction' });

expect(envelope).toHaveLength(3);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { assertSentryEvent, getEnvelopeRequest, runServer } from '../../../../utils';
import { assertSentryEvent, TestEnv } from '../../../../utils';

test('should add an empty breadcrumb, when an empty object is given', async () => {
const config = await runServer(__dirname);
const envelope = await getEnvelopeRequest(config);
const env = await TestEnv.init(__dirname);
const envelope = await env.getEnvelopeRequest();

expect(envelope).toHaveLength(3);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { assertSentryEvent, getEnvelopeRequest, runServer } from '../../../../utils';
import { assertSentryEvent, TestEnv } from '../../../../utils';

test('should add multiple breadcrumbs', async () => {
const config = await runServer(__dirname);
const events = await getEnvelopeRequest(config);
const env = await TestEnv.init(__dirname);
const events = await env.getEnvelopeRequest();

assertSentryEvent(events[2], {
message: 'test_multi_breadcrumbs',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { assertSentryEvent, getEnvelopeRequest, runServer } from '../../../../utils';
import { assertSentryEvent, TestEnv } from '../../../../utils';

test('should add a simple breadcrumb', async () => {
const config = await runServer(__dirname);
const event = await getEnvelopeRequest(config);
const env = await TestEnv.init(__dirname);
const event = await env.getEnvelopeRequest();

assertSentryEvent(event[2], {
message: 'test_simple',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { assertSentryEvent, getMultipleEnvelopeRequest, runServer } from '../../../../utils';
import { assertSentryEvent, TestEnv } from '../../../../utils';

test('should work inside catch block', async () => {
const config = await runServer(__dirname);
const events = await getMultipleEnvelopeRequest(config, { count: 1 });
const env = await TestEnv.init(__dirname);
const event = await env.getEnvelopeRequest();

assertSentryEvent(events[0][2], {
assertSentryEvent(event[2], {
exception: {
values: [
{
Expand Down
Loading