From 3d42b386d4426b87fee4ab131b8592ad878a1f75 Mon Sep 17 00:00:00 2001 From: ishabi Date: Thu, 6 Nov 2025 12:58:04 +0100 Subject: [PATCH 1/7] Enable resource renaming tests for Node.js --- manifests/nodejs.yml | 8 ++++- tests/test_resource_renaming.py | 2 -- utils/_context/_scenarios/__init__.py | 4 +-- utils/build/docker/nodejs/express/app.js | 34 ++++++++++++------- .../docker/nodejs/express4-typescript/app.ts | 30 +++++++++++++--- utils/build/docker/nodejs/fastify/app.js | 21 +++++++++++- 6 files changed, 76 insertions(+), 23 deletions(-) diff --git a/manifests/nodejs.yml b/manifests/nodejs.yml index d56ced81c1f..1ceb62ba973 100644 --- a/manifests/nodejs.yml +++ b/manifests/nodejs.yml @@ -1484,7 +1484,13 @@ tests/: test_profiling.py: Test_Profile: *ref_5_16_0 #actual version unknown test_protobuf.py: missing_feature - test_resource_renaming.py: missing_feature + test_resource_renaming.py: + Test_Resource_Renaming_HTTP_Endpoint_Tag: + '*': *ref_5_77_0 + nextjs: missing_feature # Next.js have file based routing, resource renaming is supported if we are not able to get route from insturmantation that we can't reprocude it. + Test_Resource_Renaming_Stats_Aggregation_Keys: + '*': *ref_5_77_0 + nextjs: missing_feature test_sampling_rates.py: Test_SampleRateFunction: *ref_5_54_0 Test_SamplingDecisionAdded: *ref_5_17_0 # real version unknown diff --git a/tests/test_resource_renaming.py b/tests/test_resource_renaming.py index 9629ae75a3a..e40099d48a2 100644 --- a/tests/test_resource_renaming.py +++ b/tests/test_resource_renaming.py @@ -38,13 +38,11 @@ def test_http_endpoint_basic(self): def setup_http_endpoint_edge_cases(self): """Setup requests for edge case testing""" - self.r_root = weblog.get("/") self.r_long_path = weblog.get("/resource_renaming/a/b/c/d/e/f/g/h/i/j/k/l/m") self.r_empty_segments = weblog.get("/resource_renaming//double//slash") def test_http_endpoint_edge_cases(self): """Test that edge cases are handled correctly""" - assert get_endpoint_tag(self.r_root) == "/" assert get_endpoint_tag(self.r_long_path) == "/resource_renaming/a/b/c/d/e/f/g" assert get_endpoint_tag(self.r_empty_segments) == "/resource_renaming/double/slash" diff --git a/utils/_context/_scenarios/__init__.py b/utils/_context/_scenarios/__init__.py index f0340beae0c..aa2cc04112d 100644 --- a/utils/_context/_scenarios/__init__.py +++ b/utils/_context/_scenarios/__init__.py @@ -628,9 +628,9 @@ class _Scenarios: "DD_LOGS_INJECTION": "true", "DD_TRACE_RESOURCE_RENAMING_ENABLED": "true", "DD_TRACE_RESOURCE_RENAMING_ALWAYS_SIMPLIFIED_ENDPOINT": "true", - "DD_TRACE_COMPUTE_STATS": "true", + "DD_TRACE_STATS_COMPUTATION_ENABLED": "true", }, - appsec_enabled=False, + appsec_enabled=True, doc="", scenario_groups=[scenario_groups.tracing_config], ) diff --git a/utils/build/docker/nodejs/express/app.js b/utils/build/docker/nodejs/express/app.js index eb1a43499a4..7f288fef8e4 100644 --- a/utils/build/docker/nodejs/express/app.js +++ b/utils/build/docker/nodejs/express/app.js @@ -25,6 +25,7 @@ const api = require('@opentelemetry/api') const iast = require('./iast') const dsm = require('./dsm') const di = require('./debugger') +const { OpenFeature } = require('@openfeature/server-sdk') const { spawnSync } = require('child_process') @@ -666,18 +667,6 @@ app.get('/add_event', (req, res) => { require('./rasp')(app) -const startServer = () => { - return new Promise((resolve) => { - app.listen(7777, '0.0.0.0', () => { - tracer.trace('init.service', () => {}) - console.log('listening') - resolve() - }) - }) -} - -// apollo-server does not support Express 5 yet https://github.com/apollographql/apollo-server/issues/7928 -const { OpenFeature } = require('@openfeature/server-sdk') let openFeatureClient = null // Initialize OpenFeature provider if FFE is enabled @@ -724,12 +713,33 @@ app.post('/ffe', async (req, res) => { } }) +// apollo-server does not support Express 5 yet https://github.com/apollographql/apollo-server/issues/7928 const initGraphQL = () => { return graphQLEnabled ? require('./graphql')(app) : Promise.resolve() } +const startServer = () => { + return new Promise((resolve) => { + const server = http.createServer((req, res) => { + if (req.url.startsWith('/resource_renaming')) { + res.writeHead(200) + res.end('OK') + } else { + // Everything else goes to Express + app(req, res) + } + }) + + server.listen(7777, '0.0.0.0', () => { + tracer.trace('init.service', () => {}) + console.log('listening') + resolve() + }) + }) +} + initGraphQL() .then(startServer) .catch(error => { diff --git a/utils/build/docker/nodejs/express4-typescript/app.ts b/utils/build/docker/nodejs/express4-typescript/app.ts index cea47c9f8e6..26391c23b7c 100644 --- a/utils/build/docker/nodejs/express4-typescript/app.ts +++ b/utils/build/docker/nodejs/express4-typescript/app.ts @@ -412,9 +412,29 @@ app.get('/set_cookie', (req: Request, res: Response) => { require('./rasp')(app) -require('./graphql')(app).then(() => { - app.listen(7777, '0.0.0.0', () => { - tracer.trace('init.service', () => {}) - console.log('listening') +const startServer = () => { + return new Promise((resolve) => { + const server = http.createServer((req: http.IncomingMessage, res: http.ServerResponse) => { + if (req.url?.startsWith('/resource_renaming')) { + res.writeHead(200) + res.end('OK') + } else { + // Everything else goes to Express + app(req, res) + } + }) + + server.listen(7777, '0.0.0.0', () => { + tracer.trace('init.service', () => {}) + console.log('listening') + resolve(true) + }) + }) +} + +require('./graphql')(app) + .then(startServer) + .catch((error: Error) => { + console.error('Failed to start server:', error) + process.exit(1) }) -}) diff --git a/utils/build/docker/nodejs/fastify/app.js b/utils/build/docker/nodejs/fastify/app.js index 28b3241af80..85b457a350d 100644 --- a/utils/build/docker/nodejs/fastify/app.js +++ b/utils/build/docker/nodejs/fastify/app.js @@ -6,12 +6,31 @@ const tracer = require('dd-trace').init({ }) const { promisify } = require('util') -const fastify = require('fastify')({ logger: true }) const axios = require('axios') const crypto = require('crypto') const http = require('http') const winston = require('winston') +const server = http.createServer() + +const fastify = require('fastify')({ + logger: true, + serverFactory: (handler) => { + server.on('request', (req, res) => { + if (req.url.startsWith('/resource_renaming')) { + // Handle resource renaming with HTTP server directly + res.writeHead(200) + res.end('OK') + } else { + // Everything else goes to Fastify + handler(req, res) + } + }) + + return server + } +}) + const iast = require('./iast') const dsm = require('./dsm') const di = require('./debugger') From 388dabfe19baf933e3ddd6b2efe42a1c73759af7 Mon Sep 17 00:00:00 2001 From: ishabi Date: Fri, 7 Nov 2025 16:38:40 +0100 Subject: [PATCH 2/7] Empty From 7d5554ed4466167ec68f16796e4e92614aeee0a0 Mon Sep 17 00:00:00 2001 From: simon-id Date: Mon, 10 Nov 2025 09:45:50 +0100 Subject: [PATCH 3/7] empty commit From fdbb31d6ad81af380a5dd4a4b00a23df6dd0981e Mon Sep 17 00:00:00 2001 From: ishabi Date: Mon, 10 Nov 2025 11:34:59 +0100 Subject: [PATCH 4/7] linter --- manifests/nodejs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifests/nodejs.yml b/manifests/nodejs.yml index 904d48cfd1b..db15f45d1c0 100644 --- a/manifests/nodejs.yml +++ b/manifests/nodejs.yml @@ -1487,7 +1487,7 @@ tests/: test_resource_renaming.py: Test_Resource_Renaming_HTTP_Endpoint_Tag: '*': *ref_5_77_0 - nextjs: missing_feature # Next.js have file based routing, resource renaming is supported if we are not able to get route from insturmantation that we can't reprocude it. + nextjs: missing_feature # Next.js have file based routing, resource renaming is supported if we are not able to get route from insturmantation that we can't reprocude it. Test_Resource_Renaming_Stats_Aggregation_Keys: '*': *ref_5_77_0 nextjs: missing_feature From 611aa6cd814b29e0039d70e9fa4b86fde7f5e0a9 Mon Sep 17 00:00:00 2001 From: ishabi Date: Fri, 14 Nov 2025 16:04:41 +0100 Subject: [PATCH 5/7] update tests --- manifests/nodejs.yml | 5 +++-- tests/test_resource_renaming.py | 11 ++++++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/manifests/nodejs.yml b/manifests/nodejs.yml index db15f45d1c0..d285a00fcad 100644 --- a/manifests/nodejs.yml +++ b/manifests/nodejs.yml @@ -74,6 +74,7 @@ refs: - &ref_5_75_0 '>=5.75.0' - &ref_5_76_0 '>=5.76.0' - &ref_5_77_0 '>=5.77.0' + - &ref_5_79_0 '>=5.79.0' tests/: apm_tracing_e2e/: test_otel.py: @@ -1486,10 +1487,10 @@ tests/: test_protobuf.py: missing_feature test_resource_renaming.py: Test_Resource_Renaming_HTTP_Endpoint_Tag: - '*': *ref_5_77_0 + '*': *ref_5_79_0 nextjs: missing_feature # Next.js have file based routing, resource renaming is supported if we are not able to get route from insturmantation that we can't reprocude it. Test_Resource_Renaming_Stats_Aggregation_Keys: - '*': *ref_5_77_0 + '*': *ref_5_79_0 nextjs: missing_feature test_sampling_rates.py: Test_SampleRateFunction: *ref_5_54_0 diff --git a/tests/test_resource_renaming.py b/tests/test_resource_renaming.py index e40099d48a2..b479ab8b52d 100644 --- a/tests/test_resource_renaming.py +++ b/tests/test_resource_renaming.py @@ -1,4 +1,4 @@ -from utils import bug, scenarios, weblog, interfaces, features +from utils import bug, scenarios, weblog, interfaces, features, missing_feature, context from utils._weblog import HttpResponse @@ -36,6 +36,15 @@ def test_http_endpoint_basic(self): assert get_endpoint_tag(self.r_param_str) == "/resource_renaming/files/{param:str}" assert get_endpoint_tag(self.r_param_str_2) == "/resource_renaming/files/{param:str}" + def setup_http_endpoint_root(self): + """Setup requests for root endpoint testing""" + self.r_root = weblog.get("/") + + @missing_feature(context.weblog_variant == "fastify", reason="Fasitfy root route is always '/' not empty string") + def test_http_endpoint_root(self): + """Test that root endpoint is handled correctly""" + assert get_endpoint_tag(self.r_root) == "/" + def setup_http_endpoint_edge_cases(self): """Setup requests for edge case testing""" self.r_long_path = weblog.get("/resource_renaming/a/b/c/d/e/f/g/h/i/j/k/l/m") From 60d48a5c9681a1a29d67125e8ccfc49ac0f74262 Mon Sep 17 00:00:00 2001 From: ishabi Date: Mon, 17 Nov 2025 14:44:40 +0100 Subject: [PATCH 6/7] Fix duplicate scenario config --- utils/_context/_scenarios/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/_context/_scenarios/__init__.py b/utils/_context/_scenarios/__init__.py index 6f36511171b..23b48b3e4f2 100644 --- a/utils/_context/_scenarios/__init__.py +++ b/utils/_context/_scenarios/__init__.py @@ -630,7 +630,7 @@ class _Scenarios: "DD_TRACE_RESOURCE_RENAMING_ALWAYS_SIMPLIFIED_ENDPOINT": "true", "DD_TRACE_STATS_COMPUTATION_ENABLED": "true", }, - appsec_enabled=True, + appsec_enabled=False, doc="", scenario_groups=[scenario_groups.tracing_config], ) From 7f66b10c9dce14418ca3e26acafaba2fd88ac4db Mon Sep 17 00:00:00 2001 From: ishabi Date: Mon, 17 Nov 2025 15:20:30 +0100 Subject: [PATCH 7/7] update versions --- manifests/nodejs.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/manifests/nodejs.yml b/manifests/nodejs.yml index d3bacd3a67b..4b9e004f0ab 100644 --- a/manifests/nodejs.yml +++ b/manifests/nodejs.yml @@ -76,6 +76,7 @@ refs: - &ref_5_76_0 '>=5.76.0' - &ref_5_77_0 '>=5.77.0' - &ref_5_79_0 '>=5.79.0' + - &ref_5_80_0 '>=5.80.0' tests/: apm_tracing_e2e/: test_otel.py: @@ -1501,10 +1502,10 @@ tests/: test_protobuf.py: missing_feature test_resource_renaming.py: Test_Resource_Renaming_HTTP_Endpoint_Tag: - '*': *ref_5_79_0 + '*': *ref_5_80_0 nextjs: missing_feature # Next.js have file based routing, resource renaming is supported if we are not able to get route from insturmantation that we can't reprocude it. Test_Resource_Renaming_Stats_Aggregation_Keys: - '*': *ref_5_79_0 + '*': *ref_5_80_0 nextjs: missing_feature test_sampling_rates.py: Test_SampleRateFunction: *ref_5_54_0