diff --git a/dev-packages/e2e-tests/test-applications/astro-7-orchestrion/.gitignore b/dev-packages/e2e-tests/test-applications/astro-7-orchestrion/.gitignore new file mode 100644 index 000000000000..a90494aee575 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/astro-7-orchestrion/.gitignore @@ -0,0 +1,26 @@ +# build output +dist/ +# generated types +.astro/ + +# dependencies +node_modules/ + +# logs +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* + + +# environment variables +.env +.env.production + +# macOS-specific files +.DS_Store + +# jetbrains setting folder +.idea/ + +test-results diff --git a/dev-packages/e2e-tests/test-applications/astro-7-orchestrion/AGENTS.md b/dev-packages/e2e-tests/test-applications/astro-7-orchestrion/AGENTS.md new file mode 100644 index 000000000000..c5ff42975b0b --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/astro-7-orchestrion/AGENTS.md @@ -0,0 +1,22 @@ +## Development + +When starting the dev server, use background mode: + +``` +astro dev --background +``` + +Manage the background server with `astro dev stop`, `astro dev status`, and `astro dev logs`. + +## Documentation + +Full documentation: https://docs.astro.build + +Consult these guides before working on related tasks: + +- [Adding pages, dynamic routes, or middleware](https://docs.astro.build/en/guides/routing/) +- [Working with Astro components](https://docs.astro.build/en/basics/astro-components/) +- [Using React, Vue, Svelte, or other framework components](https://docs.astro.build/en/guides/framework-components/) +- [Adding or managing content](https://docs.astro.build/en/guides/content-collections/) +- [Adding styles or using Tailwind](https://docs.astro.build/en/guides/styling/) +- [Supporting multiple languages](https://docs.astro.build/en/guides/internationalization/) diff --git a/dev-packages/e2e-tests/test-applications/astro-7-orchestrion/astro.config.mjs b/dev-packages/e2e-tests/test-applications/astro-7-orchestrion/astro.config.mjs new file mode 100644 index 000000000000..bca1420e1124 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/astro-7-orchestrion/astro.config.mjs @@ -0,0 +1,26 @@ +import node from '@astrojs/node'; +import sentry from '@sentry/astro'; +import { sentryOrchestrionPlugin } from '@sentry/server-utils/orchestrion/vite'; +// @ts-check +import { defineConfig } from 'astro/config'; + +// https://astro.build/config +export default defineConfig({ + integrations: [ + sentry({ + debug: true, + sourceMapsUploadOptions: { + enabled: false, + }, + }), + ], + output: 'server', + adapter: node({ + mode: 'standalone', + }), + vite: { + // Run the orchestrion code transform on the Vite SSR bundle so instrumented + // DB drivers get `diagnostics_channel` publishers injected at build time. + plugins: [sentryOrchestrionPlugin()], + }, +}); diff --git a/dev-packages/e2e-tests/test-applications/astro-7-orchestrion/docker-compose.yml b/dev-packages/e2e-tests/test-applications/astro-7-orchestrion/docker-compose.yml new file mode 100644 index 000000000000..9c965901f631 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/astro-7-orchestrion/docker-compose.yml @@ -0,0 +1,31 @@ +services: + db: + image: mysql:8.0 + restart: always + container_name: e2e-tests-astro-7-orchestrion-mysql + # The `mysql` 2.x driver doesn't speak MySQL 8's default + # `caching_sha2_password` auth, so force the legacy plugin. + command: ['--default-authentication-plugin=mysql_native_password'] + ports: + - '3306:3306' + environment: + MYSQL_ROOT_PASSWORD: docker + healthcheck: + test: ['CMD-SHELL', 'mysqladmin ping -h 127.0.0.1 -uroot -pdocker'] + interval: 2s + timeout: 3s + retries: 30 + start_period: 10s + + redis: + image: redis:7 + restart: always + container_name: e2e-tests-astro-7-orchestrion-redis + ports: + - '6379:6379' + healthcheck: + test: ['CMD', 'redis-cli', 'ping'] + interval: 2s + timeout: 3s + retries: 30 + start_period: 5s diff --git a/dev-packages/e2e-tests/test-applications/astro-7-orchestrion/global-setup.mjs b/dev-packages/e2e-tests/test-applications/astro-7-orchestrion/global-setup.mjs new file mode 100644 index 000000000000..cb48d539c466 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/astro-7-orchestrion/global-setup.mjs @@ -0,0 +1,14 @@ +import { execSync } from 'child_process'; +import { dirname } from 'path'; +import { fileURLToPath } from 'url'; + +const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default async function globalSetup() { + // Start MySQL + Redis via Docker Compose. `--wait` blocks until the + // healthchecks in docker-compose.yml pass, so the app can connect immediately. + execSync('docker compose up -d --wait', { + cwd: __dirname, + stdio: 'inherit', + }); +} diff --git a/dev-packages/e2e-tests/test-applications/astro-7-orchestrion/global-teardown.mjs b/dev-packages/e2e-tests/test-applications/astro-7-orchestrion/global-teardown.mjs new file mode 100644 index 000000000000..2742279431ad --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/astro-7-orchestrion/global-teardown.mjs @@ -0,0 +1,12 @@ +import { execSync } from 'child_process'; +import { dirname } from 'path'; +import { fileURLToPath } from 'url'; + +const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default async function globalTeardown() { + execSync('docker compose down --volumes', { + cwd: __dirname, + stdio: 'inherit', + }); +} diff --git a/dev-packages/e2e-tests/test-applications/astro-7-orchestrion/package.json b/dev-packages/e2e-tests/test-applications/astro-7-orchestrion/package.json new file mode 100644 index 000000000000..aeb882821dd2 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/astro-7-orchestrion/package.json @@ -0,0 +1,33 @@ +{ + "name": "astro-7-orchestrion", + "type": "module", + "version": "0.0.1", + "scripts": { + "dev": "astro dev", + "build": "astro build", + "preview": "astro preview", + "astro": "astro", + "start": "node ./dist/server/entry.mjs", + "test:build": "pnpm install && pnpm build", + "test:assert": "TEST_ENV=production playwright test" + }, + "//": "Need to use ioredis 5.10.1 because that's the last version before they support tracing channels", + "dependencies": { + "@astrojs/node": "^11.0.2", + "@playwright/test": "~1.56.0", + "@sentry-internal/test-utils": "link:../../../test-utils", + "@sentry/astro": "file:../../packed/sentry-astro-packed.tgz", + "@sentry/node": "file:../../packed/sentry-node-packed.tgz", + "@sentry/server-utils": "file:../../packed/sentry-server-utils-packed.tgz", + "astro": "^7.0.6", + "ioredis": "5.10.1", + "mysql": "^2.18.1" + }, + "devDependencies": { + "@apm-js-collab/code-transformer-bundler-plugins": "^0.5.0" + }, + "volta": { + "node": "22.22.0", + "extends": "../../package.json" + } +} diff --git a/dev-packages/e2e-tests/test-applications/astro-7-orchestrion/playwright.config.mjs b/dev-packages/e2e-tests/test-applications/astro-7-orchestrion/playwright.config.mjs new file mode 100644 index 000000000000..047fc701fa50 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/astro-7-orchestrion/playwright.config.mjs @@ -0,0 +1,11 @@ +import { getPlaywrightConfig } from '@sentry-internal/test-utils'; + +const config = getPlaywrightConfig({ + startCommand: 'pnpm start', +}); + +export default { + ...config, + globalSetup: './global-setup.mjs', + globalTeardown: './global-teardown.mjs', +}; diff --git a/dev-packages/e2e-tests/test-applications/astro-7-orchestrion/public/favicon.ico b/dev-packages/e2e-tests/test-applications/astro-7-orchestrion/public/favicon.ico new file mode 100644 index 000000000000..7f48a94d1607 Binary files /dev/null and b/dev-packages/e2e-tests/test-applications/astro-7-orchestrion/public/favicon.ico differ diff --git a/dev-packages/e2e-tests/test-applications/astro-7-orchestrion/public/favicon.svg b/dev-packages/e2e-tests/test-applications/astro-7-orchestrion/public/favicon.svg new file mode 100644 index 000000000000..f157bd1c5e28 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/astro-7-orchestrion/public/favicon.svg @@ -0,0 +1,9 @@ + diff --git a/dev-packages/e2e-tests/test-applications/astro-7-orchestrion/sentry.client.config.js b/dev-packages/e2e-tests/test-applications/astro-7-orchestrion/sentry.client.config.js new file mode 100644 index 000000000000..bc90470cef38 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/astro-7-orchestrion/sentry.client.config.js @@ -0,0 +1,9 @@ +import * as Sentry from '@sentry/astro'; + +Sentry.init({ + dsn: import.meta.env.PUBLIC_E2E_TEST_DSN, + environment: 'qa', + tracesSampleRate: 1.0, + tunnel: 'http://localhost:3031/', // proxy server + debug: true, +}); diff --git a/dev-packages/e2e-tests/test-applications/astro-7-orchestrion/sentry.server.config.js b/dev-packages/e2e-tests/test-applications/astro-7-orchestrion/sentry.server.config.js new file mode 100644 index 000000000000..7731c42d3f01 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/astro-7-orchestrion/sentry.server.config.js @@ -0,0 +1,15 @@ +import * as Sentry from '@sentry/astro'; +import { experimentalUseDiagnosticsChannelInjection } from '@sentry/node'; + +// Registers the diagnostics-channel subscribers that turn the build-time +// injected channel events (from the orchestrion Vite plugin) into Sentry spans. +// Must run before Sentry.init() +experimentalUseDiagnosticsChannelInjection(); + +Sentry.init({ + dsn: import.meta.env.PUBLIC_E2E_TEST_DSN, + environment: 'qa', + tracesSampleRate: 1.0, + tunnel: 'http://localhost:3031/', // proxy server + debug: true, +}); diff --git a/dev-packages/e2e-tests/test-applications/astro-7-orchestrion/src/pages/db-ioredis.astro b/dev-packages/e2e-tests/test-applications/astro-7-orchestrion/src/pages/db-ioredis.astro new file mode 100644 index 000000000000..d5ac5b586d47 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/astro-7-orchestrion/src/pages/db-ioredis.astro @@ -0,0 +1,31 @@ +--- +import Redis from 'ioredis'; + +export const prerender = false; + +const redis = new Redis({ + // Don't keep retrying forever if Redis goes away (e.g. on test teardown) + maxRetriesPerRequest: 1, + retryStrategy: () => null, +}); + +let value: string | null = null; + +try { + await redis.set('test-key', 'test-value'); + value = await redis.get('test-key'); +} finally { + redis.disconnect(); +} +--- + + +
+ +{value}
+ + diff --git a/dev-packages/e2e-tests/test-applications/astro-7-orchestrion/src/pages/db-mysql.astro b/dev-packages/e2e-tests/test-applications/astro-7-orchestrion/src/pages/db-mysql.astro new file mode 100644 index 000000000000..2272ebce10ad --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/astro-7-orchestrion/src/pages/db-mysql.astro @@ -0,0 +1,28 @@ +--- +import mysql from 'mysql'; + +export const prerender = false; + +const connection = mysql.createConnection({ + user: 'root', + password: 'docker', +}); + +await new Promise