Skip to content
Open
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
6 changes: 3 additions & 3 deletions dev-packages/cloudflare-integration-tests/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ type StartResult = {

/** Creates a test runner */
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
export function createRunner(...paths: string[]) {
export function createRunner({ signal }: { readonly signal?: AbortSignal }, ...paths: string[]) {
const testPath = join(...paths);

if (!existsSync(testPath)) {
Expand Down Expand Up @@ -130,7 +130,7 @@ export function createRunner(...paths: string[]) {
}
}

createBasicSentryServer(newEnvelope)
createBasicSentryServer(newEnvelope, { signal })
.then(([mockServerPort, mockServerClose]) => {
if (mockServerClose) {
CLEANUP_STEPS.add(() => {
Expand All @@ -155,7 +155,7 @@ export function createRunner(...paths: string[]) {
'--var',
`SENTRY_DSN:http://public@localhost:${mockServerPort}/1337`,
],
{ stdio },
{ stdio, signal },
);

CLEANUP_STEPS.add(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { expect, it } from 'vitest';
import { eventEnvelope } from '../../expect';
import { createRunner } from '../../runner';

it('Basic error in fetch handler', async () => {
const runner = createRunner(__dirname)
it('Basic error in fetch handler', async ({ signal }) => {
const runner = createRunner({ signal }, __dirname)
.expect(
eventEnvelope({
level: 'error',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { createRunner } from '../../../runner';
// want to test that the instrumentation does not break in our
// cloudflare SDK.

it('traces a basic message creation request', async () => {
const runner = createRunner(__dirname)
it('traces a basic message creation request', async ({ signal }) => {
const runner = createRunner({ signal }, __dirname)
.ignore('event')
.expect(envelope => {
const transactionEvent = envelope[1]?.[0]?.[1] as any;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { expect, it } from 'vitest';
import { createRunner } from '../../../runner';

it('traces a durable object method', async () => {
const runner = createRunner(__dirname)
it('traces a durable object method', async ({ signal }) => {
const runner = createRunner({ signal }, __dirname)
.expect(envelope => {
const transactionEvent = envelope[1]?.[0]?.[1];
expect(transactionEvent).toEqual(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { createRunner } from '../../../runner';
// want to test that the instrumentation does not break in our
// cloudflare SDK.

it('traces Google GenAI chat creation and message sending', async () => {
const runner = createRunner(__dirname)
it('traces Google GenAI chat creation and message sending', async ({ signal }) => {
const runner = createRunner({ signal }, __dirname)
.ignore('event')
.expect(envelope => {
const transactionEvent = envelope[1]?.[0]?.[1] as any;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import { createRunner } from '../../../runner';
// want to test that the instrumentation does not break in our
// cloudflare SDK.

it('traces a basic chat completion request', async () => {
const runner = createRunner(__dirname)
it('traces a basic chat completion request', async ({ signal }) => {
const runner = createRunner({ signal }, __dirname)
.ignore('event')
.expect(envelope => {
const transactionEvent = envelope[1]?.[0]?.[1];
const transactionEvent = envelope[1]?.[0]?.[1] as any;

expect(transactionEvent.transaction).toBe('GET /');
expect(transactionEvent.spans).toEqual(
Expand Down
14 changes: 10 additions & 4 deletions dev-packages/e2e-tests/registrySetup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,15 @@ function groupCIOutput(groupTitle: string, fn: () => void): void {
}
}

export function registrySetup(): void {
export function registrySetup(signal?: AbortSignal): void {
groupCIOutput('Test Registry Setup', () => {
// Stop test registry container (Verdaccio) if it was already running
childProcess.spawnSync('docker', ['stop', TEST_REGISTRY_CONTAINER_NAME], { stdio: 'ignore' });
console.log('Stopped previously running test registry');
const stop = (): void => {
childProcess.spawnSync('docker', ['stop', TEST_REGISTRY_CONTAINER_NAME], { stdio: 'ignore' });
console.log('Stopped previously running test registry');
};
stop();
signal?.addEventListener('abort', () => stop());

// Start test registry (Verdaccio)
const startRegistryProcessResult = childProcess.spawnSync(
Expand All @@ -38,7 +42,7 @@ export function registrySetup(): void {
`${__dirname}/verdaccio-config:/verdaccio/conf`,
`verdaccio/verdaccio:${VERDACCIO_VERSION}`,
],
{ encoding: 'utf8', stdio: 'inherit' },
{ encoding: 'utf8', stdio: 'inherit', signal },
);

if (startRegistryProcessResult.status !== 0) {
Expand All @@ -60,6 +64,7 @@ export function registrySetup(): void {
{
encoding: 'utf8',
stdio: 'inherit',
signal,
},
);

Expand All @@ -82,6 +87,7 @@ export function registrySetup(): void {
{
encoding: 'utf8',
stdio: 'inherit',
signal,
},
);

Expand Down
19 changes: 13 additions & 6 deletions dev-packages/e2e-tests/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ const DEFAULT_DSN = 'https://username@domain/123';
const DEFAULT_SENTRY_ORG_SLUG = 'sentry-javascript-sdks';
const DEFAULT_SENTRY_PROJECT = 'sentry-javascript-e2e-tests';

function asyncExec(command: string, options: { env: Record<string, string | undefined>; cwd: string }): Promise<void> {
function asyncExec(
command: string,
options: { env: Record<string, string | undefined>; cwd: string; signal: AbortSignal },
): Promise<void> {
return new Promise((resolve, reject) => {
const process = spawn(command, { ...options, shell: true });

Expand Down Expand Up @@ -41,6 +44,8 @@ async function run(): Promise<void> {
// Load environment variables from .env file locally
dotenv.config();

const abortController = new AbortController();

// Allow to run a single app only via `yarn test:run <app-name>`
const appName = process.argv[2] || '';

Expand All @@ -65,11 +70,11 @@ async function run(): Promise<void> {
console.log('');

if (!process.env.SKIP_REGISTRY) {
registrySetup();
registrySetup(abortController.signal);
}

await asyncExec('pnpm clean:test-applications', { env, cwd: __dirname });
await asyncExec('pnpm cache delete "@sentry/*"', { env, cwd: __dirname });
await asyncExec('pnpm clean:test-applications', { env, cwd: __dirname, signal: abortController.signal });
await asyncExec('pnpm cache delete "@sentry/*"', { env, cwd: __dirname, signal: abortController.signal });

const testAppPaths = appName ? [appName.trim()] : globSync('*', { cwd: `${__dirname}/test-applications/` });

Expand All @@ -84,15 +89,17 @@ async function run(): Promise<void> {
const cwd = tmpDirPath;

console.log(`Building ${testAppPath} in ${tmpDirPath}...`);
await asyncExec('volta run pnpm test:build', { env, cwd });
await asyncExec('volta run pnpm test:build', { env, cwd, signal: abortController.signal });

console.log(`Testing ${testAppPath}...`);
await asyncExec('volta run pnpm test:assert', { env, cwd });
await asyncExec('volta run pnpm test:assert', { env, cwd, signal: abortController.signal });

// clean up (although this is tmp, still nice to do)
await rm(tmpDirPath, { recursive: true });
}
abortController.abort();
} catch (error) {
abortController.abort(error);
console.error(error);
process.exit(1);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { Stack, CfnResource, StackProps } from 'aws-cdk-lib';
import { CfnResource, Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as path from 'node:path';
import * as fs from 'node:fs';
import * as os from 'node:os';
import * as dns from 'node:dns/promises';
import { platform } from 'node:process';
import { globSync } from 'glob';
import { execFileSync } from 'node:child_process';

Expand Down Expand Up @@ -123,10 +122,5 @@ export async function getHostIp() {
return host.address;
}

if (platform === 'darwin' || platform === 'win32') {
return 'host.docker.internal';
}

const host = await dns.lookup(os.hostname());
return host.address;
return 'host.docker.internal';
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { LocalLambdaStack, SAM_PORT, getHostIp } from '../src/stack';
import { writeFileSync } from 'node:fs';
import { spawn, execSync } from 'node:child_process';
import { LambdaClient } from '@aws-sdk/client-lambda';
import { platform } from 'node:process';

const DOCKER_NETWORK_NAME = 'lambda-test-network';
const SAM_TEMPLATE_FILE = 'sam.template.yml';
Expand All @@ -16,7 +17,7 @@ export const test = base.extend<{ testEnvironment: LocalLambdaStack; lambdaClien
async ({}, use) => {
console.log('[testEnvironment fixture] Setting up AWS Lambda test infrastructure');

execSync('docker network prune -f');
execSync(`docker network rm -f ${DOCKER_NETWORK_NAME} || /bin/true`);
execSync(`docker network create --driver bridge ${DOCKER_NETWORK_NAME}`);

const hostIp = await getHostIp();
Expand Down Expand Up @@ -44,6 +45,10 @@ export const test = base.extend<{ testEnvironment: LocalLambdaStack; lambdaClien
'--skip-pull-image',
];

if ('host.docker.internal' === hostIp && !['darwin', 'windows'].includes(platform)) {
args.push('--add-host', `${hostIp}:host-gateway`);
}

if (process.env.NODE_VERSION) {
args.push('--invoke-image', `public.ecr.aws/lambda/nodejs:${process.env.NODE_VERSION}`);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@ const EVENT_POLLING_TIMEOUT = 90_000;

test(
'Find symbolicated event on sentry',
async ({ expect }) => {
async ({ expect, skip }) => {
if (!authToken) {
skip('Auth token not set, skipping test');
}
const eventId = childProcess.execSync(`node ${path.join(__dirname, '..', 'dist', 'app.js')}`, {
encoding: 'utf-8',
timeout: 5_000,
});

console.log(`Polling for error eventId: ${eventId}`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import { createTestServer } from '../../../utils/server';
// This test requires Node.js 22+ because it depends on the 'http.client.request.created'
// diagnostic channel for baggage header propagation, which only exists since Node 22.12.0+ and 23.2.0+
conditionalTest({ min: 22 })('node >=22', () => {
test('adds current transaction name to baggage when the txn name is high-quality', async () => {
test('adds current transaction name to baggage when the txn name is high-quality', async ({ signal }) => {
expect.assertions(5);

let traceId: string | undefined;

const [SERVER_URL, closeTestServer] = await createTestServer()
const [SERVER_URL, closeTestServer] = await createTestServer({ signal })
.get('/api/v0', (headers: Record<string, string | string[] | undefined>) => {
const baggageItems = getBaggageHeaderItems(headers);
traceId = baggageItems.find(item => item.startsWith('sentry-trace_id='))?.split('=')[1] as string;
Expand Down Expand Up @@ -54,7 +54,7 @@ conditionalTest({ min: 22 })('node >=22', () => {
})
.start();

await createRunner(__dirname, 'scenario-headers.ts')
await createRunner({ signal }, __dirname, 'scenario-headers.ts')
.withEnv({ SERVER_URL })
.expect({
transaction: {},
Expand All @@ -65,10 +65,10 @@ conditionalTest({ min: 22 })('node >=22', () => {
});
});

test('adds current transaction name to trace envelope header when the txn name is high-quality', async () => {
test('adds current transaction name to trace envelope header when the txn name is high-quality', async ({ signal }) => {
expect.assertions(4);

await createRunner(__dirname, 'scenario-events.ts')
await createRunner({ signal }, __dirname, 'scenario-events.ts')
.expectHeader({
event: {
trace: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import { createTestServer } from '../../../../utils/server';
describe('outgoing fetch', () => {
createEsmAndCjsTests(__dirname, 'scenario.mjs', 'instrument.mjs', (createRunner, test) => {
conditionalTest({ min: 22 })('node >=22', () => {
test('outgoing fetch requests create breadcrumbs', async () => {
const [SERVER_URL, closeTestServer] = await createTestServer().start();
test('outgoing fetch requests create breadcrumbs', async ({ signal }) => {
const [SERVER_URL, closeTestServer] = await createTestServer({ signal }).start();

await createRunner()
await createRunner({ signal })
.withEnv({ SERVER_URL })
.expect({
event: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import { createTestServer } from '../../../../utils/server';

describe('outgoing fetch', () => {
createEsmAndCjsTests(__dirname, 'scenario.mjs', 'instrument.mjs', (createRunner, test) => {
test('outgoing fetch requests are correctly instrumented with tracing & spans are disabled', async () => {
test('outgoing fetch requests are correctly instrumented with tracing & spans are disabled', async ({ signal }) => {
expect.assertions(11);

const [SERVER_URL, closeTestServer] = await createTestServer()
const [SERVER_URL, closeTestServer] = await createTestServer({ signal })
.get('/api/v0', headers => {
expect(headers['sentry-trace']).toEqual(expect.stringMatching(/^([a-f0-9]{32})-([a-f0-9]{16})$/));
expect(headers['sentry-trace']).not.toEqual('00000000000000000000000000000000-0000000000000000');
Expand All @@ -28,7 +28,7 @@ describe('outgoing fetch', () => {
})
.start();

await createRunner()
await createRunner({ signal })
.withEnv({ SERVER_URL })
.expect({
event: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import { createTestServer } from '../../../../utils/server';

describe('outgoing fetch', () => {
createEsmAndCjsTests(__dirname, 'scenario.mjs', 'instrument.mjs', (createRunner, test) => {
test('outgoing fetch requests are correctly instrumented with tracing disabled', async () => {
test('outgoing fetch requests are correctly instrumented with tracing disabled', async ({ signal }) => {
expect.assertions(11);

const [SERVER_URL, closeTestServer] = await createTestServer()
const [SERVER_URL, closeTestServer] = await createTestServer({ signal })
.get('/api/v0', headers => {
expect(headers['sentry-trace']).toEqual(expect.stringMatching(/^([a-f0-9]{32})-([a-f0-9]{16})$/));
expect(headers['sentry-trace']).not.toEqual('00000000000000000000000000000000-0000000000000000');
Expand All @@ -28,7 +28,7 @@ describe('outgoing fetch', () => {
})
.start();

await createRunner()
await createRunner({ signal })
.withEnv({ SERVER_URL })
.expect({
event: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import { createTestServer } from '../../../../utils/server';

describe('outgoing fetch', () => {
createEsmAndCjsTests(__dirname, 'scenario.mjs', 'instrument.mjs', (createRunner, test) => {
test('outgoing sampled fetch requests without active span are correctly instrumented', async () => {
test('outgoing sampled fetch requests without active span are correctly instrumented', async ({ signal }) => {
expect.assertions(11);

const [SERVER_URL, closeTestServer] = await createTestServer()
const [SERVER_URL, closeTestServer] = await createTestServer({ signal })
.get('/api/v0', headers => {
expect(headers['baggage']).toEqual(expect.any(String));
expect(headers['sentry-trace']).toEqual(expect.stringMatching(/^([a-f0-9]{32})-([a-f0-9]{16})$/));
Expand All @@ -28,7 +28,7 @@ describe('outgoing fetch', () => {
})
.start();

await createRunner()
await createRunner({ signal })
.withEnv({ SERVER_URL })
.expect({
event: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import { createTestServer } from '../../../../utils/server';

describe('outgoing fetch', () => {
createEsmAndCjsTests(__dirname, 'scenario.mjs', 'instrument.mjs', (createRunner, test) => {
test('outgoing fetch requests are correctly instrumented when not sampled', async () => {
test('outgoing fetch requests are correctly instrumented when not sampled', async ({ signal }) => {
expect.assertions(11);

const [SERVER_URL, closeTestServer] = await createTestServer()
const [SERVER_URL, closeTestServer] = await createTestServer({ signal })
.get('/api/v0', headers => {
expect(headers['baggage']).toEqual(expect.any(String));
expect(headers['sentry-trace']).toEqual(expect.stringMatching(/^([a-f0-9]{32})-([a-f0-9]{16})-0$/));
Expand All @@ -28,7 +28,7 @@ describe('outgoing fetch', () => {
})
.start();

await createRunner()
await createRunner({ signal })
.withEnv({ SERVER_URL })
.expect({
event: {
Expand Down
Loading
Loading