From 21a79c00cbdec3c574d2f47dac60d563f490ece9 Mon Sep 17 00:00:00 2001 From: s1gr1d <32902192+s1gr1d@users.noreply.github.com> Date: Mon, 20 Apr 2026 13:35:44 +0200 Subject: [PATCH] test(node): Refactor integration tests for `honoIntegration` --- .../suites/tracing/hono/test.ts | 358 ++++++------------ 1 file changed, 122 insertions(+), 236 deletions(-) diff --git a/dev-packages/node-integration-tests/suites/tracing/hono/test.ts b/dev-packages/node-integration-tests/suites/tracing/hono/test.ts index 67d0ff8b56fb..484e7c948407 100644 --- a/dev-packages/node-integration-tests/suites/tracing/hono/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/hono/test.ts @@ -1,251 +1,137 @@ -import { afterAll, describe, expect } from 'vitest'; +import { afterAll, expect } from 'vitest'; import { cleanupChildProcesses, createEsmAndCjsTests } from '../../../utils/runner'; -describe('hono tracing', () => { - afterAll(() => { - cleanupChildProcesses(); +const ROUTES = ['/sync', '/async'] as const; +const METHODS = ['get', 'post', 'put', 'delete', 'patch'] as const; +const PATHS = ['/', '/all', '/on'] as const; + +type Method = (typeof METHODS)[number]; + +function verifyHonoSpan(name: string, type: 'middleware' | 'request_handler') { + return expect.objectContaining({ + data: expect.objectContaining({ + 'hono.name': name, + 'hono.type': type, + }), + description: name, + op: type === 'request_handler' ? 'request_handler.hono' : 'middleware.hono', + origin: 'auto.http.otel.hono', }); +} - createEsmAndCjsTests(__dirname, 'scenario.mjs', 'instrument.mjs', (createRunner, test) => { - describe.each(['/sync', '/async'] as const)('when using %s route', route => { - describe.each(['get', 'post', 'put', 'delete', 'patch'] as const)('when using %s method', method => { - describe.each(['/', '/all', '/on'])('when using %s path', path => { - test('should handle transaction', async () => { - const runner = createRunner() - .expect({ - transaction: { - transaction: `${method.toUpperCase()} ${route}${path === '/' ? '' : path}`, - spans: expect.arrayContaining([ - expect.objectContaining({ - data: expect.objectContaining({ - 'hono.name': 'sentryRequestMiddleware', - 'hono.type': 'middleware', - }), - description: 'sentryRequestMiddleware', - op: 'middleware.hono', - origin: 'auto.http.otel.hono', - }), - expect.objectContaining({ - data: expect.objectContaining({ - 'hono.name': 'sentryErrorMiddleware', - 'hono.type': 'middleware', - }), - description: 'sentryErrorMiddleware', - op: 'middleware.hono', - origin: 'auto.http.otel.hono', - }), - expect.objectContaining({ - data: expect.objectContaining({ - 'hono.name': 'global', - 'hono.type': 'middleware', - }), - description: 'global', - op: 'middleware.hono', - origin: 'auto.http.otel.hono', - }), - expect.objectContaining({ - data: expect.objectContaining({ - 'hono.name': 'base', - 'hono.type': 'middleware', - }), - description: 'base', - op: 'middleware.hono', - origin: 'auto.http.otel.hono', - }), - expect.objectContaining({ - data: expect.objectContaining({ - 'hono.name': `${route}${path === '/' ? '' : path}`, - 'hono.type': 'request_handler', - }), - description: `${route}${path === '/' ? '' : path}`, - op: 'request_handler.hono', - origin: 'auto.http.otel.hono', - }), - ]), - }, - }) - .start(); - runner.makeRequest(method, `${route}${path === '/' ? '' : path}`); - await runner.completed(); - }); +function baseSpans() { + return [ + verifyHonoSpan('sentryRequestMiddleware', 'middleware'), + verifyHonoSpan('sentryErrorMiddleware', 'middleware'), + verifyHonoSpan('global', 'middleware'), + verifyHonoSpan('base', 'middleware'), + ]; +} + +afterAll(() => { + cleanupChildProcesses(); +}); - test('should handle transaction with anonymous middleware', async () => { - const runner = createRunner() - .expect({ - transaction: { - transaction: `${method.toUpperCase()} ${route}${path === '/' ? '' : path}/middleware`, - spans: expect.arrayContaining([ - expect.objectContaining({ - data: expect.objectContaining({ - 'hono.name': 'sentryRequestMiddleware', - 'hono.type': 'middleware', - }), - description: 'sentryRequestMiddleware', - op: 'middleware.hono', - origin: 'auto.http.otel.hono', - }), - expect.objectContaining({ - data: expect.objectContaining({ - 'hono.name': 'sentryErrorMiddleware', - 'hono.type': 'middleware', - }), - description: 'sentryErrorMiddleware', - op: 'middleware.hono', - origin: 'auto.http.otel.hono', - }), - expect.objectContaining({ - data: expect.objectContaining({ - 'hono.name': 'global', - 'hono.type': 'middleware', - }), - description: 'global', - op: 'middleware.hono', - origin: 'auto.http.otel.hono', - }), - expect.objectContaining({ - data: expect.objectContaining({ - 'hono.name': 'base', - 'hono.type': 'middleware', - }), - description: 'base', - op: 'middleware.hono', - origin: 'auto.http.otel.hono', - }), - expect.objectContaining({ - data: expect.objectContaining({ - 'hono.name': 'anonymous', - 'hono.type': 'middleware', - }), - description: 'anonymous', - op: 'middleware.hono', - origin: 'auto.http.otel.hono', - }), - expect.objectContaining({ - data: expect.objectContaining({ - 'hono.name': `${route}${path === '/' ? '' : path}/middleware`, - 'hono.type': 'request_handler', - }), - description: `${route}${path === '/' ? '' : path}/middleware`, - op: 'request_handler.hono', - origin: 'auto.http.otel.hono', - }), - ]), - }, - }) - .start(); - runner.makeRequest(method, `${route}${path === '/' ? '' : path}/middleware`); - await runner.completed(); +createEsmAndCjsTests(__dirname, 'scenario.mjs', 'instrument.mjs', (createRunner, test) => { + test('should handle transactions for all route/method/path combinations', async () => { + const runner = createRunner(); + const requests: Array<{ method: Method; url: string }> = []; + + for (const route of ROUTES) { + for (const method of METHODS) { + for (const path of PATHS) { + const pathSuffix = path === '/' ? '' : path; + const fullPath = `${route}${pathSuffix}`; + + runner.expect({ + transaction: { + transaction: `${method.toUpperCase()} ${fullPath}`, + spans: expect.arrayContaining([...baseSpans(), verifyHonoSpan(fullPath, 'request_handler')]), + }, }); + requests.push({ method, url: fullPath }); - test('should handle transaction with separate middleware', async () => { - const runner = createRunner() - .expect({ - transaction: { - transaction: `${method.toUpperCase()} ${route}${path === '/' ? '' : path}/middleware/separately`, - spans: expect.arrayContaining([ - expect.objectContaining({ - data: expect.objectContaining({ - 'hono.name': 'sentryRequestMiddleware', - 'hono.type': 'middleware', - }), - description: 'sentryRequestMiddleware', - op: 'middleware.hono', - origin: 'auto.http.otel.hono', - }), - expect.objectContaining({ - data: expect.objectContaining({ - 'hono.name': 'sentryErrorMiddleware', - 'hono.type': 'middleware', - }), - description: 'sentryErrorMiddleware', - op: 'middleware.hono', - origin: 'auto.http.otel.hono', - }), - expect.objectContaining({ - data: expect.objectContaining({ - 'hono.name': 'global', - 'hono.type': 'middleware', - }), - description: 'global', - op: 'middleware.hono', - origin: 'auto.http.otel.hono', - }), - expect.objectContaining({ - data: expect.objectContaining({ - 'hono.name': 'base', - 'hono.type': 'middleware', - }), - description: 'base', - op: 'middleware.hono', - origin: 'auto.http.otel.hono', - }), - expect.objectContaining({ - data: expect.objectContaining({ - 'hono.name': 'anonymous', - 'hono.type': 'middleware', - }), - description: 'anonymous', - op: 'middleware.hono', - origin: 'auto.http.otel.hono', - }), - expect.objectContaining({ - data: expect.objectContaining({ - 'hono.name': `${route}${path === '/' ? '' : path}/middleware/separately`, - 'hono.type': 'request_handler', - }), - description: `${route}${path === '/' ? '' : path}/middleware/separately`, - op: 'request_handler.hono', - origin: 'auto.http.otel.hono', - }), - ]), - }, - }) - .start(); - runner.makeRequest(method, `${route}${path === '/' ? '' : path}/middleware/separately`); - await runner.completed(); + runner.expect({ + transaction: { + transaction: `${method.toUpperCase()} ${fullPath}/middleware`, + spans: expect.arrayContaining([ + ...baseSpans(), + verifyHonoSpan('anonymous', 'middleware'), + verifyHonoSpan(`${fullPath}/middleware`, 'request_handler'), + ]), + }, }); + requests.push({ method, url: `${fullPath}/middleware` }); - test('should handle returned errors for %s path', async () => { - const runner = createRunner() - .ignore('transaction') - .expect({ - event: { - exception: { - values: [ - { - mechanism: { - type: 'auto.middleware.hono', - handled: false, - }, - type: 'Error', - value: 'response 500', - }, - ], - }, - }, - }) - .start(); - runner.makeRequest(method, `${route}${path === '/' ? '' : path}/500`, { expectError: true }); - await runner.completed(); + runner.expect({ + transaction: { + transaction: `${method.toUpperCase()} ${fullPath}/middleware/separately`, + spans: expect.arrayContaining([ + ...baseSpans(), + verifyHonoSpan('anonymous', 'middleware'), + verifyHonoSpan(`${fullPath}/middleware/separately`, 'request_handler'), + ]), + }, }); + requests.push({ method, url: `${fullPath}/middleware/separately` }); + } + } + } + + const started = runner.start(); + for (const req of requests) { + await started.makeRequest(req.method, req.url); + } + await started.completed(); + }, 60_000); + + test('should capture 500 errors for all route/method/path combinations', async () => { + const runner = createRunner().ignore('transaction'); + const requests: Array<{ method: Method; url: string }> = []; - test.each(['/401', '/402', '/403', '/does-not-exist'])( - 'should ignores error %s path by default', - async (subPath: string) => { - const runner = createRunner() - .expect({ - transaction: { - transaction: `${method.toUpperCase()} ${route}`, + for (const route of ROUTES) { + for (const method of METHODS) { + for (const path of PATHS) { + const pathSuffix = path === '/' ? '' : path; + + runner.expect({ + event: { + exception: { + values: [ + { + mechanism: { + type: 'auto.middleware.hono', + handled: false, + }, + type: 'Error', + value: 'response 500', }, - }) - .start(); - runner.makeRequest(method, `${route}${path === '/' ? '' : path}${subPath}`, { expectError: true }); - runner.makeRequest(method, route); - await runner.completed(); + ], + }, }, - ); - }); - }); - }); + }); + requests.push({ method, url: `${route}${pathSuffix}/500` }); + } + } + } + + const started = runner.start(); + for (const req of requests) { + await started.makeRequest(req.method, req.url, { expectError: true }); + } + await started.completed(); + }, 60_000); + + test.each(['/401', '/402', '/403', '/does-not-exist'])('should not capture %s errors', async (subPath: string) => { + const runner = createRunner() + .expect({ + transaction: { + transaction: 'GET /sync', + }, + }) + .start(); + runner.makeRequest('get', `/sync${subPath}`, { expectError: true }); + runner.makeRequest('get', '/sync'); + await runner.completed(); }); });