dd-trace 5.16.0 → 5.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE-3rdparty.csv +1 -0
- package/ext/exporters.d.ts +1 -1
- package/index.d.ts +54 -1
- package/init.js +40 -1
- package/initialize.mjs +8 -5
- package/package.json +24 -20
- package/packages/datadog-core/src/storage/index.js +1 -10
- package/packages/datadog-esbuild/index.js +5 -1
- package/packages/datadog-instrumentations/src/aws-sdk.js +2 -1
- package/packages/datadog-instrumentations/src/cucumber.js +76 -34
- package/packages/datadog-instrumentations/src/helpers/hook.js +8 -3
- package/packages/datadog-instrumentations/src/helpers/hooks.js +3 -0
- package/packages/datadog-instrumentations/src/helpers/instrument.js +4 -3
- package/packages/datadog-instrumentations/src/helpers/register.js +56 -5
- package/packages/datadog-instrumentations/src/http/server.js +98 -0
- package/packages/datadog-instrumentations/src/mocha/main.js +12 -1
- package/packages/datadog-instrumentations/src/mocha/utils.js +58 -14
- package/packages/datadog-instrumentations/src/mocha/worker.js +1 -0
- package/packages/datadog-instrumentations/src/playwright.js +1 -1
- package/packages/datadog-instrumentations/src/undici.js +18 -0
- package/packages/datadog-instrumentations/src/vitest.js +303 -0
- package/packages/datadog-plugin-aws-sdk/src/base.js +8 -1
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +9 -3
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +6 -1
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +23 -5
- package/packages/datadog-plugin-child_process/src/index.js +1 -1
- package/packages/datadog-plugin-cucumber/src/index.js +24 -1
- package/packages/datadog-plugin-mocha/src/index.js +25 -4
- package/packages/datadog-plugin-openai/src/index.js +52 -30
- package/packages/datadog-plugin-openai/src/token-estimator.js +20 -0
- package/packages/datadog-plugin-undici/src/index.js +12 -0
- package/packages/datadog-plugin-vitest/src/index.js +156 -0
- package/packages/dd-trace/src/appsec/blocking.js +4 -0
- package/packages/dd-trace/src/appsec/channels.js +1 -0
- package/packages/dd-trace/src/appsec/iast/path-line.js +2 -19
- package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +4 -0
- package/packages/dd-trace/src/appsec/index.js +45 -11
- package/packages/dd-trace/src/appsec/rasp.js +32 -5
- package/packages/dd-trace/src/appsec/recommended.json +208 -3
- package/packages/dd-trace/src/appsec/remote_config/capabilities.js +1 -0
- package/packages/dd-trace/src/appsec/remote_config/index.js +2 -0
- package/packages/dd-trace/src/appsec/reporter.js +64 -20
- package/packages/dd-trace/src/appsec/sdk/track_event.js +3 -0
- package/packages/dd-trace/src/appsec/stack_trace.js +90 -0
- package/packages/dd-trace/src/appsec/standalone.js +130 -0
- package/packages/dd-trace/src/appsec/telemetry.js +33 -1
- package/packages/dd-trace/src/appsec/waf/index.js +2 -2
- package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +4 -2
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +4 -2
- package/packages/dd-trace/src/config.js +110 -40
- package/packages/dd-trace/src/constants.js +3 -1
- package/packages/dd-trace/src/datastreams/processor.js +2 -1
- package/packages/dd-trace/src/exporters/agent/index.js +2 -2
- package/packages/dd-trace/src/format.js +22 -2
- package/packages/dd-trace/src/opentelemetry/span.js +33 -7
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +12 -0
- package/packages/dd-trace/src/opentracing/span.js +42 -1
- package/packages/dd-trace/src/opentracing/tracer.js +2 -2
- package/packages/dd-trace/src/plugins/ci_plugin.js +7 -0
- package/packages/dd-trace/src/plugins/index.js +3 -0
- package/packages/dd-trace/src/plugins/util/test.js +5 -1
- package/packages/dd-trace/src/priority_sampler.js +2 -5
- package/packages/dd-trace/src/profiling/profiler.js +1 -1
- package/packages/dd-trace/src/proxy.js +3 -1
- package/packages/dd-trace/src/rate_limiter.js +2 -2
- package/packages/dd-trace/src/service-naming/schemas/v0/web.js +4 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/web.js +4 -0
- package/packages/dd-trace/src/span_stats.js +4 -3
- package/packages/dd-trace/src/tagger.js +10 -1
- package/packages/dd-trace/src/telemetry/init-telemetry.js +75 -0
- package/packages/dd-trace/src/tracer.js +2 -2
- package/packages/dd-trace/src/util.js +6 -1
- package/packages/datadog-core/src/storage/async_hooks.js +0 -49
package/LICENSE-3rdparty.csv
CHANGED
|
@@ -64,6 +64,7 @@ dev,sinon,BSD-3-Clause,Copyright 2010-2017 Christian Johansen
|
|
|
64
64
|
dev,sinon-chai,WTFPL and BSD-2-Clause,Copyright 2004 Sam Hocevar 2012–2017 Domenic Denicola
|
|
65
65
|
dev,tap,ISC,Copyright 2011-2022 Isaac Z. Schlueter and Contributors
|
|
66
66
|
dev,tape,MIT,Copyright James Halliday
|
|
67
|
+
dev,tiktoken,MIT,Copyright (c) 2022 OpenAI, Shantanu Jain
|
|
67
68
|
file,aws-lambda-nodejs-runtime-interface-client,Apache 2.0,Copyright 2019 Amazon.com Inc. or its affiliates. All Rights Reserved.
|
|
68
69
|
file,profile.proto,Apache license 2.0,Copyright 2016 Google Inc.
|
|
69
70
|
file,is-git-url,MIT,Copyright (c) 2017 Jon Schlinkert.
|
package/ext/exporters.d.ts
CHANGED
package/index.d.ts
CHANGED
|
@@ -197,6 +197,8 @@ interface Plugins {
|
|
|
197
197
|
"selenium": tracer.plugins.selenium;
|
|
198
198
|
"sharedb": tracer.plugins.sharedb;
|
|
199
199
|
"tedious": tracer.plugins.tedious;
|
|
200
|
+
"undici": tracer.plugins.undici;
|
|
201
|
+
"vitest": tracer.plugins.vitest;
|
|
200
202
|
"winston": tracer.plugins.winston;
|
|
201
203
|
}
|
|
202
204
|
|
|
@@ -555,6 +557,19 @@ declare namespace tracer {
|
|
|
555
557
|
*/
|
|
556
558
|
redactionValuePattern?: string
|
|
557
559
|
}
|
|
560
|
+
|
|
561
|
+
appsec?: {
|
|
562
|
+
/**
|
|
563
|
+
* Configuration of Standalone ASM mode
|
|
564
|
+
*/
|
|
565
|
+
standalone?: {
|
|
566
|
+
/**
|
|
567
|
+
* Whether to enable Standalone ASM.
|
|
568
|
+
* @default false
|
|
569
|
+
*/
|
|
570
|
+
enabled?: boolean
|
|
571
|
+
}
|
|
572
|
+
}
|
|
558
573
|
};
|
|
559
574
|
|
|
560
575
|
/**
|
|
@@ -699,6 +714,25 @@ declare namespace tracer {
|
|
|
699
714
|
* @default false
|
|
700
715
|
*/
|
|
701
716
|
enabled?: boolean
|
|
717
|
+
},
|
|
718
|
+
/**
|
|
719
|
+
* Configuration for stack trace reporting
|
|
720
|
+
*/
|
|
721
|
+
stackTrace?: {
|
|
722
|
+
/** Whether to enable stack trace reporting.
|
|
723
|
+
* @default true
|
|
724
|
+
*/
|
|
725
|
+
enabled?: boolean,
|
|
726
|
+
|
|
727
|
+
/** Specifies the maximum number of stack traces to be reported.
|
|
728
|
+
* @default 2
|
|
729
|
+
*/
|
|
730
|
+
maxStackTraces?: number,
|
|
731
|
+
|
|
732
|
+
/** Specifies the maximum depth of a stack trace to be reported.
|
|
733
|
+
* @default 32
|
|
734
|
+
*/
|
|
735
|
+
maxDepth?: number,
|
|
702
736
|
}
|
|
703
737
|
};
|
|
704
738
|
|
|
@@ -1189,6 +1223,13 @@ declare namespace tracer {
|
|
|
1189
1223
|
*/
|
|
1190
1224
|
splitByAwsService?: boolean;
|
|
1191
1225
|
|
|
1226
|
+
/**
|
|
1227
|
+
* Whether to inject all messages during batch AWS SQS, Kinesis, and SNS send operations. Normal
|
|
1228
|
+
* behavior is to inject the first message in batch send operations.
|
|
1229
|
+
* @default false
|
|
1230
|
+
*/
|
|
1231
|
+
batchPropagationEnabled?: boolean;
|
|
1232
|
+
|
|
1192
1233
|
/**
|
|
1193
1234
|
* Hooks to run before spans are finished.
|
|
1194
1235
|
*/
|
|
@@ -1523,7 +1564,7 @@ declare namespace tracer {
|
|
|
1523
1564
|
|
|
1524
1565
|
/**
|
|
1525
1566
|
* This plugin automatically instruments the
|
|
1526
|
-
* [jest](https://github.com/
|
|
1567
|
+
* [jest](https://github.com/jestjs/jest) module.
|
|
1527
1568
|
*/
|
|
1528
1569
|
interface jest extends Integration {}
|
|
1529
1570
|
|
|
@@ -1800,6 +1841,18 @@ declare namespace tracer {
|
|
|
1800
1841
|
*/
|
|
1801
1842
|
interface tedious extends Instrumentation {}
|
|
1802
1843
|
|
|
1844
|
+
/**
|
|
1845
|
+
* This plugin automatically instruments the
|
|
1846
|
+
* [undici](https://github.com/nodejs/undici) module.
|
|
1847
|
+
*/
|
|
1848
|
+
interface undici extends HttpClient {}
|
|
1849
|
+
|
|
1850
|
+
/**
|
|
1851
|
+
* This plugin automatically instruments the
|
|
1852
|
+
* [vitest](https://github.com/vitest-dev/vitest) module.
|
|
1853
|
+
*/
|
|
1854
|
+
interface vitest extends Integration {}
|
|
1855
|
+
|
|
1803
1856
|
/**
|
|
1804
1857
|
* This plugin patches the [winston](https://github.com/winstonjs/winston)
|
|
1805
1858
|
* to automatically inject trace identifiers in log records when the
|
package/init.js
CHANGED
|
@@ -2,8 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
const path = require('path')
|
|
4
4
|
const Module = require('module')
|
|
5
|
+
const telemetry = require('./packages/dd-trace/src/telemetry/init-telemetry')
|
|
6
|
+
const semver = require('semver')
|
|
7
|
+
|
|
8
|
+
function isTrue (envVar) {
|
|
9
|
+
return ['1', 'true', 'True'].includes(envVar)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// eslint-disable-next-line no-console
|
|
13
|
+
let log = { info: isTrue(process.env.DD_TRACE_DEBUG) ? console.log : () => {} }
|
|
14
|
+
if (semver.satisfies(process.versions.node, '>=16')) {
|
|
15
|
+
const Config = require('./packages/dd-trace/src/config')
|
|
16
|
+
log = require('./packages/dd-trace/src/log')
|
|
17
|
+
|
|
18
|
+
// eslint-disable-next-line no-new
|
|
19
|
+
new Config() // we need this to initialize the logger
|
|
20
|
+
}
|
|
5
21
|
|
|
6
22
|
let initBailout = false
|
|
23
|
+
let clobberBailout = false
|
|
24
|
+
const forced = isTrue(process.env.DD_INJECT_FORCE)
|
|
7
25
|
|
|
8
26
|
if (process.env.DD_INJECTION_ENABLED) {
|
|
9
27
|
// If we're running via single-step install, and we're not in the app's
|
|
@@ -19,13 +37,34 @@ if (process.env.DD_INJECTION_ENABLED) {
|
|
|
19
37
|
if (resolvedInApp) {
|
|
20
38
|
const ourselves = path.join(__dirname, 'index.js')
|
|
21
39
|
if (ourselves !== resolvedInApp) {
|
|
40
|
+
clobberBailout = true
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// If we're running via single-step install, and the runtime doesn't match
|
|
45
|
+
// the engines field in package.json, then we should not initialize the tracer.
|
|
46
|
+
if (!clobberBailout) {
|
|
47
|
+
const { engines } = require('./package.json')
|
|
48
|
+
const version = process.versions.node
|
|
49
|
+
if (!semver.satisfies(version, engines.node)) {
|
|
22
50
|
initBailout = true
|
|
51
|
+
telemetry([
|
|
52
|
+
{ name: 'abort', tags: ['reason:incompatible_runtime'] },
|
|
53
|
+
{ name: 'abort.runtime', tags: [] }
|
|
54
|
+
])
|
|
55
|
+
log.info('Aborting application instrumentation due to incompatible_runtime.')
|
|
56
|
+
log.info(`Found incompatible runtime nodejs ${version}, Supported runtimes: nodejs ${engines.node}.`)
|
|
57
|
+
if (forced) {
|
|
58
|
+
log.info('DD_INJECT_FORCE enabled, allowing unsupported runtimes and continuing.')
|
|
59
|
+
}
|
|
23
60
|
}
|
|
24
61
|
}
|
|
25
62
|
}
|
|
26
63
|
|
|
27
|
-
if (!initBailout) {
|
|
64
|
+
if (!clobberBailout && (!initBailout || forced)) {
|
|
28
65
|
const tracer = require('.')
|
|
29
66
|
tracer.init()
|
|
30
67
|
module.exports = tracer
|
|
68
|
+
telemetry('complete', [`injection_forced:${forced && initBailout ? 'true' : 'false'}`])
|
|
69
|
+
log.info('Application instrumentation bootstrapping complete')
|
|
31
70
|
}
|
package/initialize.mjs
CHANGED
|
@@ -44,9 +44,12 @@ export async function getSource (...args) {
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
if (isMainThread) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
register('
|
|
51
|
-
|
|
47
|
+
// Need this IIFE for versions of Node.js without top-level await.
|
|
48
|
+
(async () => {
|
|
49
|
+
await import('./init.js')
|
|
50
|
+
const { register } = await import('node:module')
|
|
51
|
+
if (register) {
|
|
52
|
+
register('./loader-hook.mjs', import.meta.url)
|
|
53
|
+
}
|
|
54
|
+
})()
|
|
52
55
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dd-trace",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.18.0",
|
|
4
4
|
"description": "Datadog APM tracing client for JavaScript",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"typings": "index.d.ts",
|
|
@@ -14,34 +14,37 @@
|
|
|
14
14
|
"type:test": "cd docs && yarn && yarn test",
|
|
15
15
|
"lint": "node scripts/check_licenses.js && eslint . && yarn audit --groups dependencies",
|
|
16
16
|
"services": "node ./scripts/install_plugin_modules && node packages/dd-trace/test/setup/services",
|
|
17
|
-
"test": "SERVICES=* yarn services && mocha --
|
|
18
|
-
"test:appsec": "mocha
|
|
17
|
+
"test": "SERVICES=* yarn services && mocha --expose-gc 'packages/dd-trace/test/setup/node.js' 'packages/*/test/**/*.spec.js'",
|
|
18
|
+
"test:appsec": "mocha -r \"packages/dd-trace/test/setup/mocha.js\" --exclude \"packages/dd-trace/test/appsec/**/*.plugin.spec.js\" \"packages/dd-trace/test/appsec/**/*.spec.js\"",
|
|
19
19
|
"test:appsec:ci": "nyc --no-clean --include \"packages/dd-trace/src/appsec/**/*.js\" --exclude \"packages/dd-trace/test/appsec/**/*.plugin.spec.js\" -- npm run test:appsec",
|
|
20
|
-
"test:appsec:plugins": "mocha
|
|
20
|
+
"test:appsec:plugins": "mocha -r \"packages/dd-trace/test/setup/mocha.js\" \"packages/dd-trace/test/appsec/**/*.@($(echo $PLUGINS)).plugin.spec.js\"",
|
|
21
21
|
"test:appsec:plugins:ci": "yarn services && nyc --no-clean --include \"packages/dd-trace/src/appsec/**/*.js\" -- npm run test:appsec:plugins",
|
|
22
22
|
"test:trace:core": "tap packages/dd-trace/test/*.spec.js \"packages/dd-trace/test/{ci-visibility,datastreams,encode,exporters,opentelemetry,opentracing,plugins,service-naming,telemetry}/**/*.spec.js\"",
|
|
23
23
|
"test:trace:core:ci": "npm run test:trace:core -- --coverage --nyc-arg=--include=\"packages/dd-trace/src/**/*.js\"",
|
|
24
|
-
"test:instrumentations": "mocha
|
|
24
|
+
"test:instrumentations": "mocha -r 'packages/dd-trace/test/setup/mocha.js' 'packages/datadog-instrumentations/test/**/*.spec.js'",
|
|
25
25
|
"test:instrumentations:ci": "nyc --no-clean --include 'packages/datadog-instrumentations/src/**/*.js' -- npm run test:instrumentations",
|
|
26
26
|
"test:core": "tap \"packages/datadog-core/test/**/*.spec.js\"",
|
|
27
27
|
"test:core:ci": "npm run test:core -- --coverage --nyc-arg=--include=\"packages/datadog-core/src/**/*.js\"",
|
|
28
|
-
"test:lambda": "mocha
|
|
28
|
+
"test:lambda": "mocha -r \"packages/dd-trace/test/setup/mocha.js\" \"packages/dd-trace/test/lambda/**/*.spec.js\"",
|
|
29
29
|
"test:lambda:ci": "nyc --no-clean --include \"packages/dd-trace/src/lambda/**/*.js\" -- npm run test:lambda",
|
|
30
|
-
"test:plugins": "mocha
|
|
30
|
+
"test:plugins": "mocha -r \"packages/dd-trace/test/setup/mocha.js\" \"packages/datadog-instrumentations/test/@($(echo $PLUGINS)).spec.js\" \"packages/datadog-plugin-@($(echo $PLUGINS))/test/**/*.spec.js\"",
|
|
31
31
|
"test:plugins:ci": "yarn services && nyc --no-clean --include \"packages/datadog-instrumentations/src/@($(echo $PLUGINS)).js\" --include \"packages/datadog-instrumentations/src/@($(echo $PLUGINS))/**/*.js\" --include \"packages/datadog-plugin-@($(echo $PLUGINS))/src/**/*.js\" -- npm run test:plugins",
|
|
32
32
|
"test:plugins:upstream": "node ./packages/dd-trace/test/plugins/suite.js",
|
|
33
33
|
"test:profiler": "tap \"packages/dd-trace/test/profiling/**/*.spec.js\"",
|
|
34
34
|
"test:profiler:ci": "npm run test:profiler -- --coverage --nyc-arg=--include=\"packages/dd-trace/src/profiling/**/*.js\"",
|
|
35
|
-
"test:integration": "mocha --
|
|
36
|
-
"test:integration:cucumber": "mocha --
|
|
37
|
-
"test:integration:cypress": "mocha --
|
|
38
|
-
"test:integration:
|
|
39
|
-
"test:integration:
|
|
40
|
-
"test:integration:
|
|
41
|
-
"test:integration:
|
|
42
|
-
"test:integration:
|
|
43
|
-
"test:
|
|
44
|
-
"test:
|
|
35
|
+
"test:integration": "mocha --timeout 60000 -r \"packages/dd-trace/test/setup/core.js\" \"integration-tests/*.spec.js\"",
|
|
36
|
+
"test:integration:cucumber": "mocha --timeout 60000 -r \"packages/dd-trace/test/setup/core.js\" \"integration-tests/cucumber/*.spec.js\"",
|
|
37
|
+
"test:integration:cypress": "mocha --timeout 60000 -r \"packages/dd-trace/test/setup/core.js\" \"integration-tests/cypress/*.spec.js\"",
|
|
38
|
+
"test:integration:jest": "mocha --timeout 60000 -r \"packages/dd-trace/test/setup/core.js\" \"integration-tests/jest/*.spec.js\"",
|
|
39
|
+
"test:integration:mocha": "mocha --timeout 60000 -r \"packages/dd-trace/test/setup/core.js\" \"integration-tests/mocha/*.spec.js\"",
|
|
40
|
+
"test:integration:playwright": "mocha --timeout 60000 -r \"packages/dd-trace/test/setup/core.js\" \"integration-tests/playwright/*.spec.js\"",
|
|
41
|
+
"test:integration:selenium": "mocha --timeout 60000 -r \"packages/dd-trace/test/setup/core.js\" \"integration-tests/selenium/*.spec.js\"",
|
|
42
|
+
"test:integration:vitest": "mocha --timeout 60000 -r \"packages/dd-trace/test/setup/core.js\" \"integration-tests/vitest/*.spec.js\"",
|
|
43
|
+
"test:integration:profiler": "mocha --timeout 180000 -r \"packages/dd-trace/test/setup/core.js\" \"integration-tests/profiler/*.spec.js\"",
|
|
44
|
+
"test:integration:serverless": "mocha --timeout 60000 -r \"packages/dd-trace/test/setup/core.js\" \"integration-tests/serverless/*.spec.js\"",
|
|
45
|
+
"test:integration:plugins": "mocha -r \"packages/dd-trace/test/setup/mocha.js\" \"packages/datadog-plugin-@($(echo $PLUGINS))/test/integration-test/**/*.spec.js\"",
|
|
46
|
+
"test:unit:plugins": "mocha -r \"packages/dd-trace/test/setup/mocha.js\" \"packages/datadog-instrumentations/test/@($(echo $PLUGINS)).spec.js\" \"packages/datadog-plugin-@($(echo $PLUGINS))/test/**/*.spec.js\" --exclude \"packages/datadog-plugin-@($(echo $PLUGINS))/test/integration-test/**/*.spec.js\"",
|
|
47
|
+
"test:shimmer": "mocha 'packages/datadog-shimmer/test/**/*.spec.js'",
|
|
45
48
|
"test:shimmer:ci": "nyc --no-clean --include 'packages/datadog-shimmer/src/**/*.js' -- npm run test:shimmer",
|
|
46
49
|
"leak:core": "node ./scripts/install_plugin_modules && (cd packages/memwatch && yarn) && NODE_PATH=./packages/memwatch/node_modules node --no-warnings ./node_modules/.bin/tape 'packages/dd-trace/test/leak/**/*.js'",
|
|
47
50
|
"leak:plugins": "yarn services && (cd packages/memwatch && yarn) && NODE_PATH=./packages/memwatch/node_modules node --no-warnings ./node_modules/.bin/tape \"packages/datadog-plugin-@($(echo $PLUGINS))/test/leak.js\""
|
|
@@ -72,7 +75,7 @@
|
|
|
72
75
|
"dependencies": {
|
|
73
76
|
"@datadog/native-appsec": "8.0.1",
|
|
74
77
|
"@datadog/native-iast-rewriter": "2.3.1",
|
|
75
|
-
"@datadog/native-iast-taint-tracking": "
|
|
78
|
+
"@datadog/native-iast-taint-tracking": "3.0.0",
|
|
76
79
|
"@datadog/native-metrics": "^2.0.0",
|
|
77
80
|
"@datadog/pprof": "5.3.0",
|
|
78
81
|
"@datadog/sketches-js": "^2.1.0",
|
|
@@ -81,7 +84,7 @@
|
|
|
81
84
|
"crypto-randomuuid": "^1.0.0",
|
|
82
85
|
"dc-polyfill": "^0.1.4",
|
|
83
86
|
"ignore": "^5.2.4",
|
|
84
|
-
"import-in-the-middle": "^1.
|
|
87
|
+
"import-in-the-middle": "^1.8.1",
|
|
85
88
|
"int64-buffer": "^0.1.9",
|
|
86
89
|
"istanbul-lib-coverage": "3.2.0",
|
|
87
90
|
"jest-docblock": "^29.7.0",
|
|
@@ -136,6 +139,7 @@
|
|
|
136
139
|
"sinon": "^15.2.0",
|
|
137
140
|
"sinon-chai": "^3.7.0",
|
|
138
141
|
"tap": "^16.3.7",
|
|
139
|
-
"tape": "^5.6.5"
|
|
142
|
+
"tape": "^5.6.5",
|
|
143
|
+
"tiktoken": "^1.0.15"
|
|
140
144
|
}
|
|
141
145
|
}
|
|
@@ -2,13 +2,4 @@
|
|
|
2
2
|
|
|
3
3
|
// TODO: default to AsyncLocalStorage when it supports triggerAsyncResource
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
// https://github.com/nodejs/node/pull/33801
|
|
8
|
-
const hasJavaScriptAsyncHooks = semver.satisfies(process.versions.node, '>=14.5')
|
|
9
|
-
|
|
10
|
-
if (hasJavaScriptAsyncHooks) {
|
|
11
|
-
module.exports = require('./async_resource')
|
|
12
|
-
} else {
|
|
13
|
-
module.exports = require('./async_hooks')
|
|
14
|
-
}
|
|
5
|
+
module.exports = require('./async_resource')
|
|
@@ -7,7 +7,11 @@ const hooks = require('../datadog-instrumentations/src/helpers/hooks.js')
|
|
|
7
7
|
const extractPackageAndModulePath = require('../datadog-instrumentations/src/utils/src/extract-package-and-module-path')
|
|
8
8
|
|
|
9
9
|
for (const hook of Object.values(hooks)) {
|
|
10
|
-
hook
|
|
10
|
+
if (typeof hook === 'object') {
|
|
11
|
+
hook.fn()
|
|
12
|
+
} else {
|
|
13
|
+
hook()
|
|
14
|
+
}
|
|
11
15
|
}
|
|
12
16
|
|
|
13
17
|
const modulesOfInterest = new Set()
|
|
@@ -20,7 +20,8 @@ function wrapRequest (send) {
|
|
|
20
20
|
|
|
21
21
|
return innerAr.runInAsyncScope(() => {
|
|
22
22
|
this.on('complete', innerAr.bind(response => {
|
|
23
|
-
|
|
23
|
+
const cbExists = typeof cb === 'function'
|
|
24
|
+
channel(`apm:aws:request:complete:${channelSuffix}`).publish({ response, cbExists })
|
|
24
25
|
}))
|
|
25
26
|
|
|
26
27
|
startCh.publish({
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
const { createCoverageMap } = require('istanbul-lib-coverage')
|
|
3
3
|
|
|
4
|
+
const { NUM_FAILED_TEST_RETRIES } = require('../../dd-trace/src/plugins/util/test')
|
|
4
5
|
const { addHook, channel, AsyncResource } = require('./helpers/instrument')
|
|
5
6
|
const shimmer = require('../../datadog-shimmer')
|
|
6
7
|
const log = require('../../dd-trace/src/log')
|
|
7
8
|
|
|
8
9
|
const testStartCh = channel('ci:cucumber:test:start')
|
|
10
|
+
const testRetryCh = channel('ci:cucumber:test:retry')
|
|
9
11
|
const testFinishCh = channel('ci:cucumber:test:finish') // used for test steps too
|
|
10
12
|
|
|
11
13
|
const testStepStartCh = channel('ci:cucumber:test-step:start')
|
|
@@ -47,6 +49,7 @@ const patched = new WeakSet()
|
|
|
47
49
|
|
|
48
50
|
const lastStatusByPickleId = new Map()
|
|
49
51
|
const numRetriesByPickleId = new Map()
|
|
52
|
+
const numAttemptToAsyncResource = new Map()
|
|
50
53
|
|
|
51
54
|
let pickleByFile = {}
|
|
52
55
|
const pickleResultByFile = {}
|
|
@@ -60,6 +63,7 @@ let isUnskippable = false
|
|
|
60
63
|
let isSuitesSkippingEnabled = false
|
|
61
64
|
let isEarlyFlakeDetectionEnabled = false
|
|
62
65
|
let earlyFlakeDetectionNumRetries = 0
|
|
66
|
+
let isFlakyTestRetriesEnabled = false
|
|
63
67
|
let knownTests = []
|
|
64
68
|
let skippedSuites = []
|
|
65
69
|
let isSuitesSkipped = false
|
|
@@ -162,47 +166,80 @@ function wrapRun (pl, isLatestVersion) {
|
|
|
162
166
|
return run.apply(this, arguments)
|
|
163
167
|
}
|
|
164
168
|
|
|
169
|
+
let numAttempt = 0
|
|
170
|
+
|
|
165
171
|
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
166
|
-
return asyncResource.runInAsyncScope(() => {
|
|
167
|
-
const testFileAbsolutePath = this.pickle.uri
|
|
168
172
|
|
|
169
|
-
|
|
173
|
+
numAttemptToAsyncResource.set(numAttempt, asyncResource)
|
|
170
174
|
|
|
171
|
-
|
|
172
|
-
testName: this.pickle.name,
|
|
173
|
-
testFileAbsolutePath,
|
|
174
|
-
testSourceLine,
|
|
175
|
-
isParallel: !!process.env.CUCUMBER_WORKER_ID
|
|
176
|
-
})
|
|
177
|
-
try {
|
|
178
|
-
const promise = run.apply(this, arguments)
|
|
179
|
-
promise.finally(() => {
|
|
180
|
-
const result = this.getWorstStepResult()
|
|
181
|
-
const { status, skipReason, errorMessage } = isLatestVersion
|
|
182
|
-
? getStatusFromResultLatest(result)
|
|
183
|
-
: getStatusFromResult(result)
|
|
175
|
+
const testFileAbsolutePath = this.pickle.uri
|
|
184
176
|
|
|
185
|
-
|
|
186
|
-
lastStatusByPickleId.get(this.pickle.id).push(status)
|
|
187
|
-
} else {
|
|
188
|
-
lastStatusByPickleId.set(this.pickle.id, [status])
|
|
189
|
-
}
|
|
190
|
-
let isNew = false
|
|
191
|
-
let isEfdRetry = false
|
|
192
|
-
if (isEarlyFlakeDetectionEnabled && status !== 'skip') {
|
|
193
|
-
const numRetries = numRetriesByPickleId.get(this.pickle.id)
|
|
177
|
+
const testSourceLine = this.gherkinDocument?.feature?.location?.line
|
|
194
178
|
|
|
195
|
-
|
|
196
|
-
|
|
179
|
+
const testStartPayload = {
|
|
180
|
+
testName: this.pickle.name,
|
|
181
|
+
testFileAbsolutePath,
|
|
182
|
+
testSourceLine,
|
|
183
|
+
isParallel: !!process.env.CUCUMBER_WORKER_ID
|
|
184
|
+
}
|
|
185
|
+
asyncResource.runInAsyncScope(() => {
|
|
186
|
+
testStartCh.publish(testStartPayload)
|
|
187
|
+
})
|
|
188
|
+
try {
|
|
189
|
+
this.eventBroadcaster.on('envelope', (testCase) => {
|
|
190
|
+
// Only supported from >=8.0.0
|
|
191
|
+
if (testCase?.testCaseFinished) {
|
|
192
|
+
const { testCaseFinished: { willBeRetried } } = testCase
|
|
193
|
+
if (willBeRetried) { // test case failed and will be retried
|
|
194
|
+
const failedAttemptAsyncResource = numAttemptToAsyncResource.get(numAttempt)
|
|
195
|
+
failedAttemptAsyncResource.runInAsyncScope(() => {
|
|
196
|
+
testRetryCh.publish(numAttempt++ > 0) // the current span will be finished and a new one will be created
|
|
197
|
+
})
|
|
198
|
+
|
|
199
|
+
const newAsyncResource = new AsyncResource('bound-anonymous-fn')
|
|
200
|
+
numAttemptToAsyncResource.set(numAttempt, newAsyncResource)
|
|
201
|
+
|
|
202
|
+
newAsyncResource.runInAsyncScope(() => {
|
|
203
|
+
testStartCh.publish(testStartPayload) // a new span will be created
|
|
204
|
+
})
|
|
197
205
|
}
|
|
198
|
-
|
|
206
|
+
}
|
|
207
|
+
})
|
|
208
|
+
let promise
|
|
209
|
+
|
|
210
|
+
asyncResource.runInAsyncScope(() => {
|
|
211
|
+
promise = run.apply(this, arguments)
|
|
212
|
+
})
|
|
213
|
+
promise.finally(() => {
|
|
214
|
+
const result = this.getWorstStepResult()
|
|
215
|
+
const { status, skipReason, errorMessage } = isLatestVersion
|
|
216
|
+
? getStatusFromResultLatest(result)
|
|
217
|
+
: getStatusFromResult(result)
|
|
218
|
+
|
|
219
|
+
if (lastStatusByPickleId.has(this.pickle.id)) {
|
|
220
|
+
lastStatusByPickleId.get(this.pickle.id).push(status)
|
|
221
|
+
} else {
|
|
222
|
+
lastStatusByPickleId.set(this.pickle.id, [status])
|
|
223
|
+
}
|
|
224
|
+
let isNew = false
|
|
225
|
+
let isEfdRetry = false
|
|
226
|
+
if (isEarlyFlakeDetectionEnabled && status !== 'skip') {
|
|
227
|
+
const numRetries = numRetriesByPickleId.get(this.pickle.id)
|
|
228
|
+
|
|
229
|
+
isNew = numRetries !== undefined
|
|
230
|
+
isEfdRetry = numRetries > 0
|
|
231
|
+
}
|
|
232
|
+
const attemptAsyncResource = numAttemptToAsyncResource.get(numAttempt)
|
|
233
|
+
|
|
234
|
+
attemptAsyncResource.runInAsyncScope(() => {
|
|
235
|
+
testFinishCh.publish({ status, skipReason, errorMessage, isNew, isEfdRetry, isFlakyRetry: numAttempt > 0 })
|
|
199
236
|
})
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
}
|
|
237
|
+
})
|
|
238
|
+
return promise
|
|
239
|
+
} catch (err) {
|
|
240
|
+
errorCh.publish(err)
|
|
241
|
+
throw err
|
|
242
|
+
}
|
|
206
243
|
})
|
|
207
244
|
shimmer.wrap(pl.prototype, 'runStep', runStep => function () {
|
|
208
245
|
if (!testStepStartCh.hasSubscribers) {
|
|
@@ -267,6 +304,7 @@ function getWrappedStart (start, frameworkVersion, isParallel = false) {
|
|
|
267
304
|
isEarlyFlakeDetectionEnabled = configurationResponse.libraryConfig?.isEarlyFlakeDetectionEnabled
|
|
268
305
|
earlyFlakeDetectionNumRetries = configurationResponse.libraryConfig?.earlyFlakeDetectionNumRetries
|
|
269
306
|
isSuitesSkippingEnabled = configurationResponse.libraryConfig?.isSuitesSkippingEnabled
|
|
307
|
+
isFlakyTestRetriesEnabled = configurationResponse.libraryConfig?.isFlakyTestRetriesEnabled
|
|
270
308
|
|
|
271
309
|
if (isEarlyFlakeDetectionEnabled) {
|
|
272
310
|
const knownTestsResponse = await getChannelPromise(knownTestsCh)
|
|
@@ -304,6 +342,10 @@ function getWrappedStart (start, frameworkVersion, isParallel = false) {
|
|
|
304
342
|
const processArgv = process.argv.slice(2).join(' ')
|
|
305
343
|
const command = process.env.npm_lifecycle_script || `cucumber-js ${processArgv}`
|
|
306
344
|
|
|
345
|
+
if (isFlakyTestRetriesEnabled && !this.options.retry) {
|
|
346
|
+
this.options.retry = NUM_FAILED_TEST_RETRIES
|
|
347
|
+
}
|
|
348
|
+
|
|
307
349
|
sessionAsyncResource.runInAsyncScope(() => {
|
|
308
350
|
sessionStartCh.publish({ command, frameworkVersion })
|
|
309
351
|
})
|
|
@@ -11,8 +11,13 @@ const ritm = require('../../../dd-trace/src/ritm')
|
|
|
11
11
|
* @param {string[]} modules list of modules to hook into
|
|
12
12
|
* @param {Function} onrequire callback to be executed upon encountering module
|
|
13
13
|
*/
|
|
14
|
-
function Hook (modules, onrequire) {
|
|
15
|
-
if (!(this instanceof Hook)) return new Hook(modules, onrequire)
|
|
14
|
+
function Hook (modules, hookOptions, onrequire) {
|
|
15
|
+
if (!(this instanceof Hook)) return new Hook(modules, hookOptions, onrequire)
|
|
16
|
+
|
|
17
|
+
if (typeof hookOptions === 'function') {
|
|
18
|
+
onrequire = hookOptions
|
|
19
|
+
hookOptions = {}
|
|
20
|
+
}
|
|
16
21
|
|
|
17
22
|
this._patched = Object.create(null)
|
|
18
23
|
|
|
@@ -28,7 +33,7 @@ function Hook (modules, onrequire) {
|
|
|
28
33
|
}
|
|
29
34
|
|
|
30
35
|
this._ritmHook = ritm(modules, {}, safeHook)
|
|
31
|
-
this._iitmHook = iitm(modules,
|
|
36
|
+
this._iitmHook = iitm(modules, hookOptions, (moduleExports, moduleName, moduleBaseDir) => {
|
|
32
37
|
// TODO: Move this logic to import-in-the-middle and only do it for CommonJS
|
|
33
38
|
// modules and not ESM. In the meantime, all the modules we instrument are
|
|
34
39
|
// CommonJS modules for which the default export is always moved to
|
|
@@ -23,6 +23,7 @@ module.exports = {
|
|
|
23
23
|
'@opentelemetry/sdk-trace-node': () => require('../otel-sdk-trace'),
|
|
24
24
|
'@redis/client': () => require('../redis'),
|
|
25
25
|
'@smithy/smithy-client': () => require('../aws-sdk'),
|
|
26
|
+
'@vitest/runner': { esmFirst: true, fn: () => require('../vitest') },
|
|
26
27
|
aerospike: () => require('../aerospike'),
|
|
27
28
|
amqp10: () => require('../amqp10'),
|
|
28
29
|
amqplib: () => require('../amqplib'),
|
|
@@ -109,6 +110,8 @@ module.exports = {
|
|
|
109
110
|
sequelize: () => require('../sequelize'),
|
|
110
111
|
sharedb: () => require('../sharedb'),
|
|
111
112
|
tedious: () => require('../tedious'),
|
|
113
|
+
undici: () => require('../undici'),
|
|
114
|
+
vitest: { esmFirst: true, fn: () => require('../vitest') },
|
|
112
115
|
when: () => require('../when'),
|
|
113
116
|
winston: () => require('../winston')
|
|
114
117
|
}
|
|
@@ -17,10 +17,11 @@ exports.channel = function (name) {
|
|
|
17
17
|
/**
|
|
18
18
|
* @param {string} args.name module name
|
|
19
19
|
* @param {string[]} args.versions array of semver range strings
|
|
20
|
-
* @param {string} args.file path to file within package to instrument
|
|
20
|
+
* @param {string} args.file path to file within package to instrument
|
|
21
|
+
* @param {string} args.filePattern pattern to match files within package to instrument
|
|
21
22
|
* @param Function hook
|
|
22
23
|
*/
|
|
23
|
-
exports.addHook = function addHook ({ name, versions, file }, hook) {
|
|
24
|
+
exports.addHook = function addHook ({ name, versions, file, filePattern }, hook) {
|
|
24
25
|
if (typeof name === 'string') {
|
|
25
26
|
name = [name]
|
|
26
27
|
}
|
|
@@ -29,7 +30,7 @@ exports.addHook = function addHook ({ name, versions, file }, hook) {
|
|
|
29
30
|
if (!instrumentations[val]) {
|
|
30
31
|
instrumentations[val] = []
|
|
31
32
|
}
|
|
32
|
-
instrumentations[val].push({ name: val, versions, file, hook })
|
|
33
|
+
instrumentations[val].push({ name: val, versions, file, filePattern, hook })
|
|
33
34
|
}
|
|
34
35
|
}
|
|
35
36
|
|