From bed22b3291232ff25fc017f65a378df56950b217 Mon Sep 17 00:00:00 2001 From: Nicolas Hrubec Date: Fri, 14 Aug 2026 13:19:17 +0200 Subject: [PATCH] test(node): Remove dead Node 18 test gating Node 18 (and everything below 20.19) was dropped in v11, so the Node-version gates in the integration/unit tests can no longer branch: `max: 18` blocks never run, `min: 19/20` gates are always true, and the vercelai v6/v7 matrix no longer needs its Node 18 fork. Unwrap them to plain describe/test and drop the now-unused imports. Runtime `tracingChannel` guards in the instrumentations are intentionally left in place. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../suites/breadcrumbs/process-thread/test.ts | 5 ++- .../suites/child-process/test.ts | 5 ++- .../suites/esm/warn-esm/test.ts | 18 ---------- .../suites/pino/test.ts | 5 ++- .../suites/public-api/LocalVariables/test.ts | 19 ++++------- .../public-api/OnUncaughtException/test.ts | 33 +------------------ .../suites/tracing/fastify/test.ts | 11 +++---- .../suites/tracing/langchain/v1/test.ts | 7 ++-- .../suites/tracing/mongodb-v7/test.ts | 9 +++-- .../tracing/mongoose-tracing-channel/test.ts | 8 ++--- .../suites/tracing/mongoose-v9/test.ts | 7 ++-- .../tracing/mysql2-tracing-channel/test.ts | 6 ++-- .../orchestrion-lazy-registration/test.ts | 7 ++-- .../suites/tracing/prisma-orm-v7/test.ts | 6 ++-- .../suites/tracing/vercelai/v6_v7/test.ts | 14 +++----- .../node/test/integrations/context.test.ts | 5 --- 16 files changed, 42 insertions(+), 123 deletions(-) diff --git a/dev-packages/node-integration-tests/suites/breadcrumbs/process-thread/test.ts b/dev-packages/node-integration-tests/suites/breadcrumbs/process-thread/test.ts index a3ae49da4808..ce263fe21b59 100644 --- a/dev-packages/node-integration-tests/suites/breadcrumbs/process-thread/test.ts +++ b/dev-packages/node-integration-tests/suites/breadcrumbs/process-thread/test.ts @@ -1,6 +1,5 @@ import type { Event } from '@sentry/core'; -import { afterAll, expect, test } from 'vitest'; -import { conditionalTest } from '../../../utils'; +import { afterAll, describe, expect, test } from 'vitest'; import { cleanupChildProcesses, createRunner } from '../../../utils/runner'; const EVENT = { @@ -35,7 +34,7 @@ const EVENT = { ], }; -conditionalTest({ min: 20 })('should capture process and thread breadcrumbs', () => { +describe('should capture process and thread breadcrumbs', () => { afterAll(() => { cleanupChildProcesses(); }); diff --git a/dev-packages/node-integration-tests/suites/child-process/test.ts b/dev-packages/node-integration-tests/suites/child-process/test.ts index 1d04772c351e..ce78388c625d 100644 --- a/dev-packages/node-integration-tests/suites/child-process/test.ts +++ b/dev-packages/node-integration-tests/suites/child-process/test.ts @@ -1,6 +1,5 @@ import type { Event } from '@sentry/core'; import { afterAll, describe, expect, test } from 'vitest'; -import { conditionalTest } from '../../utils'; import { cleanupChildProcesses, createRunner } from '../../utils/runner'; const WORKER_EVENT: Event = { @@ -44,7 +43,7 @@ describe('should capture child process events', () => { cleanupChildProcesses(); }); - conditionalTest({ min: 20 })('worker', () => { + describe('worker', () => { test('ESM', async () => { await createRunner(__dirname, 'worker.mjs').expect({ event: WORKER_EVENT }).start().completed(); }); @@ -54,7 +53,7 @@ describe('should capture child process events', () => { }); }); - conditionalTest({ min: 20 })('fork', () => { + describe('fork', () => { test('ESM', async () => { await createRunner(__dirname, 'fork.mjs').expect({ event: CHILD_EVENT }).start().completed(); }); diff --git a/dev-packages/node-integration-tests/suites/esm/warn-esm/test.ts b/dev-packages/node-integration-tests/suites/esm/warn-esm/test.ts index 18eebdab6e85..5f52af14aaed 100644 --- a/dev-packages/node-integration-tests/suites/esm/warn-esm/test.ts +++ b/dev-packages/node-integration-tests/suites/esm/warn-esm/test.ts @@ -7,25 +7,7 @@ afterAll(() => { const esmWarning = `[Sentry] You are using Node.js v${process.versions.node} in ESM mode ("import syntax"). The Sentry Node.js SDK is not compatible with ESM in Node.js versions before 18.19.0 or before 20.6.0. Please either build your application with CommonJS ("require() syntax"), or upgrade your Node.js version.`; -test("warns if using ESM on Node.js versions that don't support `register()`", async () => { - const nodeMajorVersion = Number(process.versions.node.split('.')[0]); - if (nodeMajorVersion >= 18) { - return; - } - - const runner = createRunner(__dirname, 'server.mjs').ignore('event').start(); - - await runner.makeRequest('get', '/test/success'); - - expect(runner.getLogs()).toContain(esmWarning); -}); - test('does not warn if using ESM on Node.js versions that support `register()`', async () => { - const nodeMajorVersion = Number(process.versions.node.split('.')[0]); - if (nodeMajorVersion < 18) { - return; - } - const runner = createRunner(__dirname, 'server.mjs').ignore('event').start(); await runner.makeRequest('get', '/test/success'); diff --git a/dev-packages/node-integration-tests/suites/pino/test.ts b/dev-packages/node-integration-tests/suites/pino/test.ts index 9ed6f77e4175..b5ef17cca2a2 100644 --- a/dev-packages/node-integration-tests/suites/pino/test.ts +++ b/dev-packages/node-integration-tests/suites/pino/test.ts @@ -1,8 +1,7 @@ -import { afterAll, expect } from 'vitest'; -import { conditionalTest } from '../../utils'; +import { afterAll, describe, expect } from 'vitest'; import { cleanupChildProcesses, createEsmTests } from '../../utils/runner'; -conditionalTest({ min: 20 })('Pino integration', () => { +describe('Pino integration', () => { afterAll(() => { cleanupChildProcesses(); }); diff --git a/dev-packages/node-integration-tests/suites/public-api/LocalVariables/test.ts b/dev-packages/node-integration-tests/suites/public-api/LocalVariables/test.ts index 9acc9ea0d92a..fcb1c9dcfe72 100644 --- a/dev-packages/node-integration-tests/suites/public-api/LocalVariables/test.ts +++ b/dev-packages/node-integration-tests/suites/public-api/LocalVariables/test.ts @@ -1,7 +1,6 @@ import { mkdirSync, rmdirSync, unlinkSync, writeFileSync } from 'fs'; import * as path from 'path'; import { afterAll, beforeAll, describe, expect, test } from 'vitest'; -import { conditionalTest } from '../../../utils'; import { cleanupChildProcesses, createRunner } from '../../../utils/runner'; // This test takes some time because it connects the debugger etc. @@ -108,19 +107,15 @@ module.exports = { out_of_app_function };`, .completed(); }); - conditionalTest({ min: 19 })('Node v19+', () => { - test('Should not import inspector when not in use', async () => { - await createRunner(__dirname, 'deny-inspector.mjs').ensureNoErrorOutput().start().completed(); - }); + test('Should not import inspector when not in use', async () => { + await createRunner(__dirname, 'deny-inspector.mjs').ensureNoErrorOutput().start().completed(); }); - conditionalTest({ min: 20 })('Node v20+', () => { - test('Should retain original local variables when error is re-thrown', async () => { - await createRunner(__dirname, 'local-variables-rethrow.js') - .expect({ event: EXPECTED_LOCAL_VARIABLES_EVENT }) - .start() - .completed(); - }); + test('Should retain original local variables when error is re-thrown', async () => { + await createRunner(__dirname, 'local-variables-rethrow.js') + .expect({ event: EXPECTED_LOCAL_VARIABLES_EVENT }) + .start() + .completed(); }); test('Includes local variables for caught exceptions when enabled', async () => { diff --git a/dev-packages/node-integration-tests/suites/public-api/OnUncaughtException/test.ts b/dev-packages/node-integration-tests/suites/public-api/OnUncaughtException/test.ts index a7c8ce53e3b5..11cac0dbb128 100644 --- a/dev-packages/node-integration-tests/suites/public-api/OnUncaughtException/test.ts +++ b/dev-packages/node-integration-tests/suites/public-api/OnUncaughtException/test.ts @@ -1,7 +1,6 @@ import * as childProcess from 'child_process'; import * as path from 'path'; import { describe, expect, test } from 'vitest'; -import { conditionalTest } from '../../../utils'; import { createRunner } from '../../../utils/runner'; describe('OnUncaughtException integration', () => { @@ -103,37 +102,7 @@ describe('OnUncaughtException integration', () => { .completed(); }); - conditionalTest({ max: 18 })('Worker thread error handling Node 18', () => { - test('should capture uncaught worker thread errors - without childProcess integration', async () => { - await createRunner(__dirname, 'worker-thread/uncaught-worker.mjs') - .withInstrument(path.join(__dirname, 'worker-thread/instrument.mjs')) - .expect({ - event: { - level: 'fatal', - exception: { - values: [ - { - type: 'Error', - value: 'job failed', - mechanism: { - type: 'auto.node.onuncaughtexception', - handled: false, - }, - stacktrace: { - frames: expect.any(Array), - }, - }, - ], - }, - }, - }) - .start() - .completed(); - }); - }); - - // childProcessIntegration only exists in Node 20+ - conditionalTest({ min: 20 })('Worker thread error handling Node 20+', () => { + describe('Worker thread error handling', () => { test.each(['mjs', 'js'])('should not interfere with worker thread error handling ".%s"', async extension => { const runner = createRunner(__dirname, `worker-thread/caught-worker.${extension}`) .withFlags('--import', path.join(__dirname, `worker-thread/instrument.${extension}`)) diff --git a/dev-packages/node-integration-tests/suites/tracing/fastify/test.ts b/dev-packages/node-integration-tests/suites/tracing/fastify/test.ts index 0806abf3de72..445aed9abb9f 100644 --- a/dev-packages/node-integration-tests/suites/tracing/fastify/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/fastify/test.ts @@ -1,5 +1,4 @@ import { afterAll, describe, expect } from 'vitest'; -import { conditionalTest } from '../../../utils'; import { cleanupChildProcesses, createEsmAndCjsTests } from '../../../utils/runner'; describe('fastify auto-instrumentation', () => { @@ -7,8 +6,7 @@ describe('fastify auto-instrumentation', () => { cleanupChildProcesses(); }); - // Fastify v5 does not support Node 18 - conditionalTest({ min: 20 })('fastify v5', () => { + describe('fastify v5', () => { createEsmAndCjsTests(__dirname, 'scenario.mjs', 'instrument.mjs', (createRunner, test) => { test('creates transaction with fastify hook, request-handler and manual spans', async () => { const runner = createRunner() @@ -50,10 +48,9 @@ describe('fastify auto-instrumentation', () => { }); // Fastify v5 only publishes the `tracing:fastify.request.handler:error` diagnostics channel when - // `tracingChannel(...).hasSubscribers` is truthy. That aggregate getter does not exist on Node 18 - // (it was added in Node 20), so fastify takes the fast path and never publishes the channel there — - // making automatic error capture (without `setupFastifyErrorHandler`) impossible on Node 18. - conditionalTest({ min: 20 })('error capture via diagnostics channel', () => { + // `tracingChannel(...).hasSubscribers` is truthy, which is what enables automatic error capture + // without `setupFastifyErrorHandler`. + describe('error capture via diagnostics channel', () => { test('captures errors thrown in route handlers', async () => { const runner = createRunner() .ignore('transaction') diff --git a/dev-packages/node-integration-tests/suites/tracing/langchain/v1/test.ts b/dev-packages/node-integration-tests/suites/tracing/langchain/v1/test.ts index e0ea6e07992f..e605edc08173 100644 --- a/dev-packages/node-integration-tests/suites/tracing/langchain/v1/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/langchain/v1/test.ts @@ -1,4 +1,4 @@ -import { afterAll, expect } from 'vitest'; +import { afterAll, describe, expect } from 'vitest'; import { GEN_AI_INPUT_MESSAGES, GEN_AI_OPERATION_NAME, @@ -16,13 +16,10 @@ import { GEN_AI_USAGE_TOTAL_TOKENS, } from '@sentry/conventions/attributes'; import { GEN_AI_RESPONSE_STOP_REASON_ATTRIBUTE } from '../../../../../../packages/server-utils/src/ai/core/gen-ai-attributes'; -import { conditionalTest } from '../../../../utils'; import { cleanupChildProcesses, createEsmAndCjsTests } from '../../../../utils/runner'; import { createEsmTests } from '../../../../utils/runner/createEsmAndCjsTests'; -// LangChain v1 requires Node.js 20+ (dropped Node 18 support) -// See: https://docs.langchain.com/oss/javascript/migrate/langgraph-v1#dropped-node-18-support -conditionalTest({ min: 20 })('LangChain integration (v1)', () => { +describe('LangChain integration (v1)', () => { afterAll(() => { cleanupChildProcesses(); }); diff --git a/dev-packages/node-integration-tests/suites/tracing/mongodb-v7/test.ts b/dev-packages/node-integration-tests/suites/tracing/mongodb-v7/test.ts index 6579a1973ca8..8420890334b8 100644 --- a/dev-packages/node-integration-tests/suites/tracing/mongodb-v7/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/mongodb-v7/test.ts @@ -1,13 +1,12 @@ import type { TransactionEvent } from '@sentry/core'; import { MongoMemoryServer } from 'mongodb-memory-server-global'; -import { afterAll, beforeAll, expect } from 'vitest'; -import { conditionalTest, isOrchestrionEnabled } from '../../../utils'; +import { afterAll, beforeAll, describe, expect } from 'vitest'; +import { isOrchestrionEnabled } from '../../../utils'; import { cleanupChildProcesses, createEsmAndCjsTests } from '../../../utils/runner'; // Pins mongodb 7 so the >= 6.4 promise-based `Connection.prototype.command` -// band is exercised against a real mongodb. mongodb 7 requires Node >= 20.19, so this suite is -// skipped on older Node (on Node 18 the driver throws `ReferenceError: crypto is not defined`). -conditionalTest({ min: 20 })('MongoDB v7 auto-instrumentation', () => { +// band is exercised against a real mongodb. +describe('MongoDB v7 auto-instrumentation', () => { let mongoServer: MongoMemoryServer; beforeAll(async () => { diff --git a/dev-packages/node-integration-tests/suites/tracing/mongoose-tracing-channel/test.ts b/dev-packages/node-integration-tests/suites/tracing/mongoose-tracing-channel/test.ts index 2fcbda83375f..1e6523f9282b 100644 --- a/dev-packages/node-integration-tests/suites/tracing/mongoose-tracing-channel/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/mongoose-tracing-channel/test.ts @@ -1,14 +1,14 @@ import { MongoMemoryServer } from 'mongodb-memory-server-global'; -import { afterAll, beforeAll, expect } from 'vitest'; -import { conditionalTest, isOrchestrionEnabled } from '../../../utils'; +import { afterAll, beforeAll, describe, expect } from 'vitest'; +import { isOrchestrionEnabled } from '../../../utils'; import { cleanupChildProcesses, createEsmAndCjsTests } from '../../../utils/runner'; // mongoose >= 9.7.0 publishes its operations via `node:diagnostics_channel`, so the SDK subscribes // to those channels (`subscribeMongooseDiagnosticChannels`) instead of monkey-patching. This suite // pins `^9.7` and asserts the diagnostics-channel path: stable OTel DB semconv attributes, redacted // query text, span relationships, and that the legacy IITM patcher does NOT also fire (no double -// instrumentation). mongoose 9 requires Node >=20.19, so this suite is skipped on older Node. -conditionalTest({ min: 20 })('Mongoose tracing channel Test', () => { +// instrumentation). +describe('Mongoose tracing channel Test', () => { const driverOrigin = isOrchestrionEnabled() ? 'auto.db.mongo' : 'auto.db.otel.mongo'; let mongoServer: MongoMemoryServer; diff --git a/dev-packages/node-integration-tests/suites/tracing/mongoose-v9/test.ts b/dev-packages/node-integration-tests/suites/tracing/mongoose-v9/test.ts index acf1e75c96ac..122142c6b61d 100644 --- a/dev-packages/node-integration-tests/suites/tracing/mongoose-v9/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/mongoose-v9/test.ts @@ -1,13 +1,12 @@ import { MongoMemoryServer } from 'mongodb-memory-server-global'; -import { afterAll, beforeAll, expect } from 'vitest'; -import { conditionalTest, isOrchestrionEnabled } from '../../../utils'; +import { afterAll, beforeAll, describe, expect } from 'vitest'; +import { isOrchestrionEnabled } from '../../../utils'; import { cleanupChildProcesses, createEsmAndCjsTests } from '../../../utils/runner'; // Pins the highest mongoose 9 below 9.7, the top of the IITM patcher's `>=5.9.7 <9.7.0` range, so the // monkey-patch path is exercised against a real mongoose 9. mongoose >= 9.7 publishes via // diagnostics_channel and is covered by the `mongoose-tracing-channel` suite instead. -// mongoose 9 requires Node >=20.19, so this suite is skipped on older Node. -conditionalTest({ min: 20 })('Mongoose v9 Test', () => { +describe('Mongoose v9 Test', () => { const origin = isOrchestrionEnabled() ? 'auto.db.mongoose' : 'auto.db.otel.mongoose'; let mongoServer: MongoMemoryServer; diff --git a/dev-packages/node-integration-tests/suites/tracing/mysql2-tracing-channel/test.ts b/dev-packages/node-integration-tests/suites/tracing/mysql2-tracing-channel/test.ts index 7971974f9ca4..e3c9f31fe592 100644 --- a/dev-packages/node-integration-tests/suites/tracing/mysql2-tracing-channel/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/mysql2-tracing-channel/test.ts @@ -1,13 +1,11 @@ -import { afterAll, expect } from 'vitest'; -import { conditionalTest } from '../../../utils'; +import { afterAll, describe, expect } from 'vitest'; import { cleanupChildProcesses, createEsmAndCjsTests, describeWithDockerCompose } from '../../../utils/runner'; // mysql2 >= 3.20.0 publishes its operations via `node:diagnostics_channel`, so the SDK subscribes // to those channels (`subscribeMysql2DiagnosticChannels`) instead of monkey-patching. This suite // pins `^3.20.0` and asserts the diagnostics-channel path: stable OTel DB semconv attributes, // redacted query text, and that the legacy IITM patcher (gated to `< 3.20.0`) does NOT also fire. -// `TracingChannel` is only reliable on Node >= 20, so this suite is skipped on older Node. -conditionalTest({ min: 20 })('mysql2 tracing channel Test', () => { +describe('mysql2 tracing channel Test', () => { afterAll(() => { cleanupChildProcesses(); }); diff --git a/dev-packages/node-integration-tests/suites/tracing/orchestrion-lazy-registration/test.ts b/dev-packages/node-integration-tests/suites/tracing/orchestrion-lazy-registration/test.ts index 2a1fb02c8088..c715733a3993 100644 --- a/dev-packages/node-integration-tests/suites/tracing/orchestrion-lazy-registration/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/orchestrion-lazy-registration/test.ts @@ -1,15 +1,12 @@ import * as path from 'path'; -import { afterAll, test } from 'vitest'; -import { conditionalTest } from '../../../utils'; +import { afterAll, describe, test } from 'vitest'; import { cleanupChildProcesses, createRunner } from '../../../utils/runner'; afterAll(() => { cleanupChildProcesses(); }); -// The runtime module hook needs Node >= 18.19; gate on 20 to stay on the stable -// `Module.registerHooks` / `Channel.hasSubscribers` surface. -conditionalTest({ min: 20 })('orchestrion lazy channel registration', () => { +describe('orchestrion lazy channel registration', () => { // The scenario self-asserts (via `node:assert`) that a default channel // integration has NOT subscribed to its channel until the instrumented module // is loaded, then that it HAS once loaded. A violation throws, which diff --git a/dev-packages/node-integration-tests/suites/tracing/prisma-orm-v7/test.ts b/dev-packages/node-integration-tests/suites/tracing/prisma-orm-v7/test.ts index 2947fda3c045..9d7d98d48db1 100644 --- a/dev-packages/node-integration-tests/suites/tracing/prisma-orm-v7/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/prisma-orm-v7/test.ts @@ -1,13 +1,11 @@ -import { afterAll, expect } from 'vitest'; -import { conditionalTest } from '../../../utils'; +import { afterAll, describe, expect } from 'vitest'; import { cleanupChildProcesses, createEsmAndCjsTests, describeWithDockerCompose } from '../../../utils/runner'; afterAll(() => { cleanupChildProcesses(); }); -// Prisma 7 requires Node.js 20.19+ -conditionalTest({ min: 20 })('Prisma ORM v7 Tests', () => { +describe('Prisma ORM v7 Tests', () => { describeWithDockerCompose('Prisma ORM v7', { workingDirectory: [__dirname] }, () => { createEsmAndCjsTests( __dirname, diff --git a/dev-packages/node-integration-tests/suites/tracing/vercelai/v6_v7/test.ts b/dev-packages/node-integration-tests/suites/tracing/vercelai/v6_v7/test.ts index 7f18702d5621..1cb0f70595d6 100644 --- a/dev-packages/node-integration-tests/suites/tracing/vercelai/v6_v7/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/vercelai/v6_v7/test.ts @@ -1,4 +1,4 @@ -import { NODE_VERSION, type Event } from '@sentry/node'; +import type { Event } from '@sentry/node'; import { afterAll, describe, expect } from 'vitest'; import { GEN_AI_CONVERSATION_ID, @@ -25,14 +25,10 @@ import { GEN_AI_TOOL_CALL_ID_ATTRIBUTE } from '../../../../../../packages/server import { cleanupChildProcesses, createEsmAndCjsTests, createEsmTests } from '../../../../utils/runner'; import { isOrchestrionEnabled } from '../../../../utils'; -// On Node 18, we only test v6 as v7 is not supported -const matrix = - NODE_VERSION.major === 18 - ? ([['6', '^6.0.0']] as const) - : ([ - ['6', '^6.0.0'], - ['7', '^7.0.0'], - ] as const); +const matrix = [ + ['6', '^6.0.0'], + ['7', '^7.0.0'], +] as const; describe.each(matrix)('Vercel AI integration (version %s)', (version, vercelAiVersion) => { afterAll(() => { diff --git a/packages/node/test/integrations/context.test.ts b/packages/node/test/integrations/context.test.ts index 3bcc1af80589..0f2f2adb8510 100644 --- a/packages/node/test/integrations/context.test.ts +++ b/packages/node/test/integrations/context.test.ts @@ -24,11 +24,6 @@ describe('Context', () => { vi.clearAllMocks(); }); - conditionalTest({ max: 18 })('it does not return free_memory on older node versions', () => { - const appContext = getAppContext(); - expect(appContext.free_memory).toBeUndefined(); - }); - conditionalTest({ min: 22 })( 'returns free_memory if process.availableMemory is defined and returns a valid value', () => {