dd-trace 5.101.0 → 5.103.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/ext/exporters.js +1 -0
- package/package.json +20 -17
- package/packages/datadog-esbuild/src/utils.js +2 -2
- package/packages/datadog-instrumentations/src/aerospike.js +2 -2
- package/packages/datadog-instrumentations/src/ai.js +9 -9
- package/packages/datadog-instrumentations/src/amqplib.js +6 -7
- package/packages/datadog-instrumentations/src/anthropic.js +10 -10
- package/packages/datadog-instrumentations/src/apollo-server-core.js +3 -3
- package/packages/datadog-instrumentations/src/apollo-server.js +5 -5
- package/packages/datadog-instrumentations/src/avsc.js +6 -6
- package/packages/datadog-instrumentations/src/aws-sdk.js +151 -67
- package/packages/datadog-instrumentations/src/azure-durable-functions.js +8 -8
- package/packages/datadog-instrumentations/src/bluebird.js +2 -2
- package/packages/datadog-instrumentations/src/body-parser.js +2 -2
- package/packages/datadog-instrumentations/src/cassandra-driver.js +7 -7
- package/packages/datadog-instrumentations/src/child_process.js +12 -12
- package/packages/datadog-instrumentations/src/confluentinc-kafka-javascript.js +41 -24
- package/packages/datadog-instrumentations/src/connect.js +7 -7
- package/packages/datadog-instrumentations/src/cookie-parser.js +4 -4
- package/packages/datadog-instrumentations/src/cookie.js +2 -2
- package/packages/datadog-instrumentations/src/couchbase.js +73 -238
- package/packages/datadog-instrumentations/src/crypto.js +4 -4
- package/packages/datadog-instrumentations/src/cucumber.js +78 -17
- package/packages/datadog-instrumentations/src/dns.js +0 -3
- package/packages/datadog-instrumentations/src/elasticsearch.js +8 -11
- package/packages/datadog-instrumentations/src/electron/preload.js +42 -0
- package/packages/datadog-instrumentations/src/electron.js +240 -0
- package/packages/datadog-instrumentations/src/express-mongo-sanitize.js +6 -6
- package/packages/datadog-instrumentations/src/express-session.js +4 -4
- package/packages/datadog-instrumentations/src/express.js +10 -11
- package/packages/datadog-instrumentations/src/fastify.js +2 -2
- package/packages/datadog-instrumentations/src/fetch.js +5 -5
- package/packages/datadog-instrumentations/src/fs.js +14 -14
- package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +5 -7
- package/packages/datadog-instrumentations/src/google-genai.js +4 -4
- package/packages/datadog-instrumentations/src/graphql.js +13 -12
- package/packages/datadog-instrumentations/src/grpc/server.js +2 -2
- package/packages/datadog-instrumentations/src/hapi.js +2 -2
- package/packages/datadog-instrumentations/src/helpers/callback-instrumentor.js +9 -9
- package/packages/datadog-instrumentations/src/helpers/hook.js +4 -1
- package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
- package/packages/datadog-instrumentations/src/helpers/instrument.js +2 -2
- package/packages/datadog-instrumentations/src/helpers/kafka.js +41 -0
- package/packages/datadog-instrumentations/src/helpers/promise.js +2 -2
- package/packages/datadog-instrumentations/src/hono.js +2 -2
- package/packages/datadog-instrumentations/src/http/client.js +6 -6
- package/packages/datadog-instrumentations/src/http/server.js +9 -9
- package/packages/datadog-instrumentations/src/ioredis.js +16 -12
- package/packages/datadog-instrumentations/src/jest.js +382 -81
- package/packages/datadog-instrumentations/src/kafkajs.js +165 -174
- package/packages/datadog-instrumentations/src/knex.js +17 -17
- package/packages/datadog-instrumentations/src/koa.js +12 -12
- package/packages/datadog-instrumentations/src/ldapjs.js +5 -5
- package/packages/datadog-instrumentations/src/light-my-request.js +2 -2
- package/packages/datadog-instrumentations/src/limitd-client.js +4 -4
- package/packages/datadog-instrumentations/src/lodash.js +4 -4
- package/packages/datadog-instrumentations/src/mariadb.js +13 -13
- package/packages/datadog-instrumentations/src/memcached.js +2 -2
- package/packages/datadog-instrumentations/src/microgateway-core.js +2 -2
- package/packages/datadog-instrumentations/src/mocha/common.js +3 -3
- package/packages/datadog-instrumentations/src/mocha/main.js +85 -11
- package/packages/datadog-instrumentations/src/mocha/utils.js +133 -16
- package/packages/datadog-instrumentations/src/mocha/worker.js +7 -5
- package/packages/datadog-instrumentations/src/mongodb-core.js +42 -30
- package/packages/datadog-instrumentations/src/mongodb.js +5 -5
- package/packages/datadog-instrumentations/src/mongoose.js +21 -21
- package/packages/datadog-instrumentations/src/mquery.js +5 -5
- package/packages/datadog-instrumentations/src/multer.js +4 -4
- package/packages/datadog-instrumentations/src/mysql.js +16 -16
- package/packages/datadog-instrumentations/src/mysql2.js +4 -4
- package/packages/datadog-instrumentations/src/net.js +14 -8
- package/packages/datadog-instrumentations/src/nyc.js +5 -5
- package/packages/datadog-instrumentations/src/openai.js +19 -19
- package/packages/datadog-instrumentations/src/oracledb.js +6 -6
- package/packages/datadog-instrumentations/src/passport-utils.js +5 -5
- package/packages/datadog-instrumentations/src/pg.js +39 -25
- package/packages/datadog-instrumentations/src/pino.js +6 -10
- package/packages/datadog-instrumentations/src/playwright.js +445 -68
- package/packages/datadog-instrumentations/src/protobufjs.js +16 -16
- package/packages/datadog-instrumentations/src/redis.js +20 -12
- package/packages/datadog-instrumentations/src/restify.js +2 -2
- package/packages/datadog-instrumentations/src/router.js +12 -12
- package/packages/datadog-instrumentations/src/stripe.js +12 -12
- package/packages/datadog-instrumentations/src/vitest.js +107 -26
- package/packages/datadog-instrumentations/src/winston.js +4 -4
- package/packages/datadog-instrumentations/src/ws.js +7 -7
- package/packages/datadog-plugin-apollo/src/gateway/request.js +1 -21
- package/packages/datadog-plugin-aws-sdk/src/base.js +70 -28
- package/packages/datadog-plugin-aws-sdk/src/services/cloudwatchlogs.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +20 -13
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +46 -36
- package/packages/datadog-plugin-aws-sdk/src/services/lambda.js +34 -23
- package/packages/datadog-plugin-aws-sdk/src/services/redshift.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/s3.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +14 -15
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +74 -55
- package/packages/datadog-plugin-aws-sdk/src/services/stepfunctions.js +20 -18
- package/packages/datadog-plugin-aws-sdk/src/util.js +22 -0
- package/packages/datadog-plugin-child_process/src/scrub-cmd-params.js +6 -6
- package/packages/datadog-plugin-couchbase/src/index.js +58 -52
- package/packages/datadog-plugin-cucumber/src/index.js +5 -0
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +215 -26
- package/packages/datadog-plugin-cypress/src/support.js +13 -1
- package/packages/datadog-plugin-electron/src/index.js +17 -0
- package/packages/datadog-plugin-electron/src/ipc.js +143 -0
- package/packages/datadog-plugin-electron/src/net.js +82 -0
- package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +1 -5
- package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +27 -18
- package/packages/datadog-plugin-google-cloud-pubsub/src/pubsub-push-subscription.js +3 -1
- package/packages/datadog-plugin-graphql/src/execute.js +6 -28
- package/packages/datadog-plugin-graphql/src/resolve.js +30 -35
- package/packages/datadog-plugin-graphql/src/tools/signature.js +32 -7
- package/packages/datadog-plugin-graphql/src/tools/transforms.js +118 -100
- package/packages/datadog-plugin-graphql/src/utils.js +29 -0
- package/packages/datadog-plugin-grpc/src/client.js +6 -7
- package/packages/datadog-plugin-grpc/src/util.js +57 -22
- package/packages/datadog-plugin-http/src/client.js +3 -7
- package/packages/datadog-plugin-jest/src/index.js +92 -50
- package/packages/datadog-plugin-jest/src/util.js +1 -2
- package/packages/datadog-plugin-mocha/src/index.js +5 -0
- package/packages/datadog-plugin-mongodb-core/src/index.js +36 -69
- package/packages/datadog-plugin-mysql/src/index.js +1 -1
- package/packages/datadog-plugin-openai/src/services.js +2 -1
- package/packages/datadog-plugin-openai/src/tracing.js +12 -23
- package/packages/datadog-plugin-pg/src/index.js +3 -3
- package/packages/datadog-plugin-playwright/src/index.js +5 -1
- package/packages/datadog-plugin-redis/src/index.js +18 -23
- package/packages/datadog-plugin-vitest/src/index.js +8 -1
- package/packages/datadog-shimmer/src/shimmer.js +7 -1
- package/packages/dd-trace/src/aiguard/index.js +3 -1
- package/packages/dd-trace/src/aiguard/sdk.js +36 -30
- package/packages/dd-trace/src/aiguard/tags.js +20 -11
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-password-rules.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secret-rules.js +81 -81
- package/packages/dd-trace/src/appsec/iast/security-controls/index.js +2 -2
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugins/kafka.js +2 -2
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +4 -4
- package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +2 -2
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +2 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/index.js +1 -3
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +83 -48
- package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +1 -1
- package/packages/dd-trace/src/appsec/index.js +21 -24
- package/packages/dd-trace/src/appsec/reporter.js +3 -1
- package/packages/dd-trace/src/appsec/rule_manager.js +4 -2
- package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +31 -16
- package/packages/dd-trace/src/azure_metadata.js +17 -6
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +4 -4
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +4 -2
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +6 -4
- package/packages/dd-trace/src/ci-visibility/requests/fs-cache.js +1 -1
- package/packages/dd-trace/src/config/defaults.js +3 -14
- package/packages/dd-trace/src/config/generated-config-types.d.ts +3 -1
- package/packages/dd-trace/src/config/git_properties.js +2 -2
- package/packages/dd-trace/src/config/helper.js +4 -0
- package/packages/dd-trace/src/config/index.js +2 -2
- package/packages/dd-trace/src/config/major-overrides.js +98 -0
- package/packages/dd-trace/src/config/parsers.js +7 -1
- package/packages/dd-trace/src/config/supported-configurations.json +51 -38
- package/packages/dd-trace/src/datastreams/checkpointer.js +2 -2
- package/packages/dd-trace/src/datastreams/index.js +2 -1
- package/packages/dd-trace/src/datastreams/manager.js +1 -1
- package/packages/dd-trace/src/datastreams/processor.js +3 -4
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +2 -2
- package/packages/dd-trace/src/debugger/devtools_client/snapshot-pruner.js +1 -0
- package/packages/dd-trace/src/debugger/devtools_client/source-maps.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/state.js +2 -1
- package/packages/dd-trace/src/debugger/index.js +7 -7
- package/packages/dd-trace/src/dogstatsd.js +2 -2
- package/packages/dd-trace/src/encode/0.4.js +748 -232
- package/packages/dd-trace/src/encode/0.5.js +47 -10
- package/packages/dd-trace/src/encode/agentless-json.js +1 -1
- package/packages/dd-trace/src/exporter.js +2 -0
- package/packages/dd-trace/src/exporters/agent/index.js +2 -1
- package/packages/dd-trace/src/exporters/agentless/index.js +3 -2
- package/packages/dd-trace/src/exporters/agentless/writer.js +2 -2
- package/packages/dd-trace/src/exporters/common/buffering-exporter.js +2 -1
- package/packages/dd-trace/src/exporters/common/request.js +1 -1
- package/packages/dd-trace/src/exporters/electron/index.js +49 -0
- package/packages/dd-trace/src/external-logger/src/index.js +2 -1
- package/packages/dd-trace/src/git_metadata.js +10 -8
- package/packages/dd-trace/src/lambda/handler-paths.js +52 -0
- package/packages/dd-trace/src/lambda/index.js +62 -14
- package/packages/dd-trace/src/lambda/runtime/patch.js +21 -46
- package/packages/dd-trace/src/llmobs/index.js +13 -2
- package/packages/dd-trace/src/llmobs/plugins/ai/util.js +1 -2
- package/packages/dd-trace/src/llmobs/plugins/bedrockruntime.js +45 -15
- package/packages/dd-trace/src/llmobs/plugins/genai/util.js +6 -3
- package/packages/dd-trace/src/llmobs/sdk.js +24 -26
- package/packages/dd-trace/src/llmobs/span_processor.js +25 -5
- package/packages/dd-trace/src/llmobs/util.js +1 -0
- package/packages/dd-trace/src/llmobs/writers/base.js +2 -1
- package/packages/dd-trace/src/msgpack/chunk.js +6 -3
- package/packages/dd-trace/src/openfeature/noop.js +40 -36
- package/packages/dd-trace/src/openfeature/writers/base.js +2 -1
- package/packages/dd-trace/src/openfeature/writers/exposures.js +33 -52
- package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +2 -1
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_transformer_base.js +1 -2
- package/packages/dd-trace/src/opentelemetry/tracer.js +0 -22
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +20 -9
- package/packages/dd-trace/src/opentracing/propagation/text_map_dsm.js +2 -11
- package/packages/dd-trace/src/payload-tagging/config/index.js +2 -2
- package/packages/dd-trace/src/plugins/ci_plugin.js +49 -4
- package/packages/dd-trace/src/plugins/database.js +54 -12
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/dd-trace/src/plugins/plugin.js +2 -4
- package/packages/dd-trace/src/plugins/util/ci.js +9 -9
- package/packages/dd-trace/src/plugins/util/git-cache.js +23 -23
- package/packages/dd-trace/src/plugins/util/stacktrace.js +2 -2
- package/packages/dd-trace/src/plugins/util/test.js +56 -12
- package/packages/dd-trace/src/plugins/util/url.js +1 -3
- package/packages/dd-trace/src/plugins/util/user-provided-git.js +18 -16
- package/packages/dd-trace/src/plugins/util/web.js +5 -7
- package/packages/dd-trace/src/priority_sampler.js +1 -1
- package/packages/dd-trace/src/profiling/profiler.js +1 -1
- package/packages/dd-trace/src/profiling/profilers/events.js +3 -23
- package/packages/dd-trace/src/profiling/profilers/wall.js +5 -6
- package/packages/dd-trace/src/profiling/ssi-heuristics.js +1 -1
- package/packages/dd-trace/src/rate_limiter.js +1 -1
- package/packages/dd-trace/src/remote_config/scheduler.js +1 -1
- package/packages/dd-trace/src/ritm.js +2 -1
- package/packages/dd-trace/src/runtime_metrics/index.js +2 -2
- package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +5 -8
- package/packages/dd-trace/src/scope.js +3 -10
- package/packages/dd-trace/src/serverless.js +6 -6
- package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +27 -1
- package/packages/dd-trace/src/service-naming/schemas/v0/web.js +4 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/messaging.js +24 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/web.js +4 -0
- package/packages/dd-trace/src/span_stats.js +1 -1
- package/packages/dd-trace/src/telemetry/dependencies.js +1 -1
- package/packages/dd-trace/src/telemetry/endpoints.js +1 -1
- package/packages/dd-trace/src/telemetry/telemetry.js +2 -2
- package/packages/dd-trace/src/tracer.js +7 -7
- package/packages/dd-trace/src/lambda/runtime/ritm.js +0 -133
|
@@ -16,7 +16,7 @@ class DSMTextMapPropagator {
|
|
|
16
16
|
inject (ctx, carrier) {
|
|
17
17
|
if (!this.config.dsmEnabled) return
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
DsmPathwayCodec.encode(ctx, carrier)
|
|
20
20
|
|
|
21
21
|
// eslint-disable-next-line eslint-rules/eslint-log-printf-style
|
|
22
22
|
log.debug(() => `Inject into carrier (DSM): ${JSON.stringify(pick(carrier, logKeys))}.`)
|
|
@@ -25,7 +25,7 @@ class DSMTextMapPropagator {
|
|
|
25
25
|
extract (carrier) {
|
|
26
26
|
if (!this.config.dsmEnabled) return
|
|
27
27
|
|
|
28
|
-
const dsmContext =
|
|
28
|
+
const dsmContext = DsmPathwayCodec.decode(carrier)
|
|
29
29
|
|
|
30
30
|
if (!dsmContext) return dsmContext
|
|
31
31
|
|
|
@@ -33,15 +33,6 @@ class DSMTextMapPropagator {
|
|
|
33
33
|
log.debug(() => `Extract from carrier (DSM): ${JSON.stringify(pick(carrier, logKeys))}.`)
|
|
34
34
|
return dsmContext
|
|
35
35
|
}
|
|
36
|
-
|
|
37
|
-
_injectDatadogDSMContext (ctx, carrier) {
|
|
38
|
-
DsmPathwayCodec.encode(ctx, carrier)
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
_extractDatadogDSMContext (carrier) {
|
|
42
|
-
const ctx = DsmPathwayCodec.decode(carrier)
|
|
43
|
-
return ctx
|
|
44
|
-
}
|
|
45
36
|
}
|
|
46
37
|
|
|
47
38
|
module.exports = DSMTextMapPropagator
|
|
@@ -30,8 +30,8 @@ function getSDKRules (sdk, requestInput, responseInput) {
|
|
|
30
30
|
* Appends input rules to all supported SDKs and returns a structure mapping SDK
|
|
31
31
|
* names to per-service rules.
|
|
32
32
|
*
|
|
33
|
-
* @param {string[]} [requestInput
|
|
34
|
-
* @param {string[]} [responseInput
|
|
33
|
+
* @param {string[]} [requestInput]
|
|
34
|
+
* @param {string[]} [responseInput]
|
|
35
35
|
* @returns {Record<string, SDKRules>}
|
|
36
36
|
*/
|
|
37
37
|
function appendRules (requestInput = [], responseInput = []) {
|
|
@@ -49,6 +49,7 @@ const {
|
|
|
49
49
|
getTestSuiteCommonTags,
|
|
50
50
|
TEST_STATUS,
|
|
51
51
|
TEST_SKIPPED_BY_ITR,
|
|
52
|
+
TEST_ITR_SKIPPING_ENABLED,
|
|
52
53
|
ITR_CORRELATION_ID,
|
|
53
54
|
TEST_SOURCE_FILE,
|
|
54
55
|
TEST_LEVEL_EVENT_TYPES,
|
|
@@ -64,7 +65,11 @@ const {
|
|
|
64
65
|
getModifiedFilesFromDiff,
|
|
65
66
|
getPullRequestBaseBranch,
|
|
66
67
|
getSessionRequestErrorTags,
|
|
67
|
-
|
|
68
|
+
DD_CI_LIBRARY_CONFIGURATION_ERROR_SETTINGS,
|
|
69
|
+
DD_CI_LIBRARY_CONFIGURATION_ERROR_SKIPPABLE_TESTS,
|
|
70
|
+
DD_CI_LIBRARY_CONFIGURATION_ERROR_KNOWN_TESTS,
|
|
71
|
+
DD_CI_LIBRARY_CONFIGURATION_ERROR_TEST_MANAGEMENT_TESTS,
|
|
72
|
+
getSessionItrSkippingEnabledTags,
|
|
68
73
|
TEST_IS_TEST_FRAMEWORK_WORKER,
|
|
69
74
|
TEST_IS_NEW,
|
|
70
75
|
TEST_IS_RUM_ACTIVE,
|
|
@@ -74,6 +79,7 @@ const {
|
|
|
74
79
|
TEST_IS_MODIFIED,
|
|
75
80
|
TEST_IS_RETRY,
|
|
76
81
|
TEST_RETRY_REASON,
|
|
82
|
+
DD_CAPABILITIES_TEST_IMPACT_ANALYSIS,
|
|
77
83
|
} = require('./util/test')
|
|
78
84
|
|
|
79
85
|
const FRAMEWORK_TO_TRIMMED_COMMAND = {
|
|
@@ -99,6 +105,21 @@ const TEST_FRAMEWORKS_TO_SKIP_GIT_METADATA_EXTRACTION = new Set([
|
|
|
99
105
|
'cucumber',
|
|
100
106
|
])
|
|
101
107
|
|
|
108
|
+
function setItrSkippingEnabledTagFromLibraryConfig (plugin, frameworkVersion) {
|
|
109
|
+
const libraryCapabilitiesTags = getLibraryCapabilitiesTags(plugin.constructor.id, frameworkVersion)
|
|
110
|
+
|
|
111
|
+
if (!libraryCapabilitiesTags[DD_CAPABILITIES_TEST_IMPACT_ANALYSIS] ||
|
|
112
|
+
!plugin.libraryConfig ||
|
|
113
|
+
!plugin.testSessionSpan ||
|
|
114
|
+
!plugin.testModuleSpan) {
|
|
115
|
+
return
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const skippingEnabled = plugin.libraryConfig.isSuitesSkippingEnabled ? 'true' : 'false'
|
|
119
|
+
plugin.testSessionSpan.setTag(TEST_ITR_SKIPPING_ENABLED, skippingEnabled)
|
|
120
|
+
plugin.testModuleSpan.setTag(TEST_ITR_SKIPPING_ENABLED, skippingEnabled)
|
|
121
|
+
}
|
|
122
|
+
|
|
102
123
|
function getTestSuiteLevelVisibilityTags (testSuiteSpan, testFramework) {
|
|
103
124
|
const testSuiteSpanContext = testSuiteSpan.context()
|
|
104
125
|
|
|
@@ -134,9 +155,10 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
134
155
|
this.tracer._exporter.getLibraryConfiguration(this.testConfiguration, (err, libraryConfig) => {
|
|
135
156
|
if (err) {
|
|
136
157
|
log.error('Library configuration could not be fetched. %s', err.message)
|
|
137
|
-
this._addRequestErrorTag(
|
|
158
|
+
this._addRequestErrorTag(DD_CI_LIBRARY_CONFIGURATION_ERROR_SETTINGS, err)
|
|
138
159
|
} else {
|
|
139
160
|
this.libraryConfig = libraryConfig
|
|
161
|
+
setItrSkippingEnabledTagFromLibraryConfig(this, frameworkVersion)
|
|
140
162
|
}
|
|
141
163
|
|
|
142
164
|
const requestErrorTags = this.testSessionSpan
|
|
@@ -165,6 +187,7 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
165
187
|
this.tracer._exporter.getSkippableSuites(this.testConfiguration, (err, skippableSuites, itrCorrelationId) => {
|
|
166
188
|
if (err) {
|
|
167
189
|
log.error('Skippable suites could not be fetched. %s', err.message)
|
|
190
|
+
this._addRequestErrorTag(DD_CI_LIBRARY_CONFIGURATION_ERROR_SKIPPABLE_TESTS, err)
|
|
168
191
|
} else {
|
|
169
192
|
this.itrCorrelationId = itrCorrelationId
|
|
170
193
|
}
|
|
@@ -225,6 +248,7 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
225
248
|
},
|
|
226
249
|
integrationName: this.constructor.id,
|
|
227
250
|
})
|
|
251
|
+
setItrSkippingEnabledTagFromLibraryConfig(this, frameworkVersion)
|
|
228
252
|
// only for vitest
|
|
229
253
|
// These are added for the worker threads to use
|
|
230
254
|
if (this.constructor.id === 'vitest') {
|
|
@@ -246,6 +270,7 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
246
270
|
const testSuiteMetadata = {
|
|
247
271
|
...getTestSuiteCommonTags(testCommand, frameworkVersion, testSuite, this.constructor.id),
|
|
248
272
|
...getSessionRequestErrorTags(this.testSessionSpan),
|
|
273
|
+
...getSessionItrSkippingEnabledTags(this.testSessionSpan),
|
|
249
274
|
}
|
|
250
275
|
if (this.itrCorrelationId) {
|
|
251
276
|
testSuiteMetadata[ITR_CORRELATION_ID] = this.itrCorrelationId
|
|
@@ -277,6 +302,7 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
277
302
|
this.tracer._exporter.getKnownTests(this.testConfiguration, (err, knownTests) => {
|
|
278
303
|
if (err) {
|
|
279
304
|
log.error('Known tests could not be fetched. %s', err.message)
|
|
305
|
+
this._addRequestErrorTag(DD_CI_LIBRARY_CONFIGURATION_ERROR_KNOWN_TESTS, err)
|
|
280
306
|
if (this.libraryConfig) {
|
|
281
307
|
this.libraryConfig.isEarlyFlakeDetectionEnabled = false
|
|
282
308
|
this.libraryConfig.isKnownTestsEnabled = false
|
|
@@ -297,6 +323,7 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
297
323
|
this.tracer._exporter.getTestManagementTests(this.testConfiguration, (err, testManagementTests) => {
|
|
298
324
|
if (err) {
|
|
299
325
|
log.error('Test management tests could not be fetched. %s', err.message)
|
|
326
|
+
this._addRequestErrorTag(DD_CI_LIBRARY_CONFIGURATION_ERROR_TEST_MANAGEMENT_TESTS, err)
|
|
300
327
|
if (this.libraryConfig) {
|
|
301
328
|
this.libraryConfig.isTestManagementEnabled = false
|
|
302
329
|
}
|
|
@@ -342,6 +369,9 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
342
369
|
|
|
343
370
|
if (span.name?.startsWith(`${this.constructor.id}.`)) {
|
|
344
371
|
span.meta[TEST_IS_TEST_FRAMEWORK_WORKER] = 'true'
|
|
372
|
+
if (span.name === `${this.constructor.id}.test` || span.name === `${this.constructor.id}.test_suite`) {
|
|
373
|
+
Object.assign(span.meta, getSessionItrSkippingEnabledTags(this.testSessionSpan))
|
|
374
|
+
}
|
|
345
375
|
// augment with git information (since it will not be available in the worker)
|
|
346
376
|
for (const key in this.testEnvironmentMetadata) {
|
|
347
377
|
// CAREFUL: this bypasses the metadata/metrics distinction
|
|
@@ -372,7 +402,8 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
372
402
|
|
|
373
403
|
// Jest and Vitest worker test spans are serialized in the worker and may not include
|
|
374
404
|
// request error tags; add them from the session span in the main process.
|
|
375
|
-
if ((span.name === 'jest.test' || span.name === 'vitest.test'
|
|
405
|
+
if ((span.name === 'jest.test' || span.name === 'vitest.test' || span.name === 'vitest.test_suite') &&
|
|
406
|
+
this.testSessionSpan) {
|
|
376
407
|
Object.assign(span.meta, getSessionRequestErrorTags(this.testSessionSpan))
|
|
377
408
|
}
|
|
378
409
|
}
|
|
@@ -449,13 +480,16 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
449
480
|
* Adds a hidden _dd tag to the test session span when a test-optimization request fails.
|
|
450
481
|
* If the session span does not exist yet (e.g. library-configuration failed before session:start),
|
|
451
482
|
* the tag is queued and applied when the span is created.
|
|
452
|
-
* @param {string} tag - Tag name (e.g.
|
|
483
|
+
* @param {string} tag - Tag name (e.g. DD_CI_LIBRARY_CONFIGURATION_ERROR_SETTINGS)
|
|
453
484
|
* @param {Error} err - Request error
|
|
454
485
|
*/
|
|
455
486
|
_addRequestErrorTag (tag, err) {
|
|
456
487
|
const value = 'true'
|
|
457
488
|
if (this.testSessionSpan) {
|
|
458
489
|
this.testSessionSpan.setTag(tag, value)
|
|
490
|
+
if (this.testModuleSpan) {
|
|
491
|
+
this.testModuleSpan.setTag(tag, value)
|
|
492
|
+
}
|
|
459
493
|
} else {
|
|
460
494
|
this._pendingRequestErrorTags.push({ tag, value })
|
|
461
495
|
}
|
|
@@ -469,6 +503,15 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
469
503
|
return getSessionRequestErrorTags(this.testSessionSpan)
|
|
470
504
|
}
|
|
471
505
|
|
|
506
|
+
/**
|
|
507
|
+
* Returns ITR skipping-enabled tags from the test session span for propagation to child events.
|
|
508
|
+
*
|
|
509
|
+
* @returns {Record<string, string>}
|
|
510
|
+
*/
|
|
511
|
+
getSessionItrSkippingEnabledTags () {
|
|
512
|
+
return getSessionItrSkippingEnabledTags(this.testSessionSpan)
|
|
513
|
+
}
|
|
514
|
+
|
|
472
515
|
/**
|
|
473
516
|
* @param {import('../config/config-base')} config - Tracer configuration
|
|
474
517
|
* @param {boolean} shouldGetEnvironmentData - Whether to get environment data
|
|
@@ -596,6 +639,8 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
596
639
|
}
|
|
597
640
|
}
|
|
598
641
|
|
|
642
|
+
Object.assign(testTags, getSessionItrSkippingEnabledTags(this.testSessionSpan))
|
|
643
|
+
|
|
599
644
|
this.telemetry.ciVisEvent(TELEMETRY_EVENT_CREATED, 'test', { hasCodeOwners: !!codeOwners })
|
|
600
645
|
|
|
601
646
|
const testSpan = this.tracer
|
|
@@ -1,13 +1,47 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const { LRUCache } = require('../../../../vendor/dist/lru-cache')
|
|
3
4
|
const { PEER_SERVICE_KEY, PEER_SERVICE_SOURCE_KEY } = require('../constants')
|
|
4
5
|
const propagationHash = require('../propagation-hash')
|
|
5
6
|
const StoragePlugin = require('./storage')
|
|
6
7
|
|
|
8
|
+
// Unreserved RFC 3986 set that `encodeURIComponent` leaves untouched (a conservative subset:
|
|
9
|
+
// `! * ' ( )` are also untouched but rarely appear in db / host / service names so we skip them).
|
|
10
|
+
const SAFE_ENCODE_RE = /^[\w\-.~]*$/
|
|
11
|
+
|
|
12
|
+
// Cap `#dbmPrefixCache` so a high-cardinality `db.name` (MongoDB sets it to
|
|
13
|
+
// `${database}.${collection}`) cannot grow the map without bound. Steady-state working sets
|
|
14
|
+
// fit well below the cap; cache misses cost a few hundred nanoseconds, so an evicted entry
|
|
15
|
+
// rebuilds cheaply on the next query.
|
|
16
|
+
const DBM_PREFIX_CACHE_MAX = 256
|
|
17
|
+
|
|
7
18
|
class DatabasePlugin extends StoragePlugin {
|
|
8
19
|
static operation = 'query'
|
|
9
20
|
static peerServicePrecursors = ['db.name']
|
|
10
21
|
|
|
22
|
+
// dde / ddps / ddpv are tracer-process constants. They are baked in at `configure()` time as
|
|
23
|
+
// two pre-templated fragments — `dbmEnvFragment` splices between dddbs and ddh; `dbmEndFragment`
|
|
24
|
+
// trails ddh — so per-query work shrinks to encoding dddb / dddbs / ddh and concatenating.
|
|
25
|
+
#dbmEnvFragment
|
|
26
|
+
#dbmEndFragment
|
|
27
|
+
// Cache the rendered prefix per `${db.name}\0${out.host}\0${dbmService}`. The triple is
|
|
28
|
+
// connection-stable for a real workload, so the steady state is one `LRUCache.get` plus the
|
|
29
|
+
// optional per-call `,ddprs='...'` suffix.
|
|
30
|
+
#dbmPrefixCache = new LRUCache({ max: DBM_PREFIX_CACHE_MAX })
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @override
|
|
34
|
+
* @param {boolean | import('../config/config-base') & {enabled: boolean}} config
|
|
35
|
+
*/
|
|
36
|
+
configure (config) {
|
|
37
|
+
super.configure(config)
|
|
38
|
+
// Match the previous shape exactly: `dde` is `encode`d; `ddps` / `ddpv` are template-literal
|
|
39
|
+
// coerced so `undefined` renders as the literal `'undefined'` the way the original did.
|
|
40
|
+
this.#dbmEnvFragment = `,dde='${encode(this.tracer._env)}',`
|
|
41
|
+
this.#dbmEndFragment = `,ddps='${this.tracer._service ?? ''}',ddpv='${this.tracer._version}'`
|
|
42
|
+
this.#dbmPrefixCache.clear()
|
|
43
|
+
}
|
|
44
|
+
|
|
11
45
|
/**
|
|
12
46
|
* @param {string} serviceName
|
|
13
47
|
* @param {import('../../../..').Span} span
|
|
@@ -16,20 +50,21 @@ class DatabasePlugin extends StoragePlugin {
|
|
|
16
50
|
*/
|
|
17
51
|
#createDBMPropagationCommentService (serviceName, span, peerData) {
|
|
18
52
|
const spanTags = span.context()._tags
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
53
|
+
const dddb = spanTags['db.name']
|
|
54
|
+
const ddh = spanTags['out.host']
|
|
55
|
+
const cacheKey = `${dddb ?? ''}\0${ddh ?? ''}\0${serviceName ?? ''}`
|
|
56
|
+
|
|
57
|
+
let prefix = this.#dbmPrefixCache.get(cacheKey)
|
|
58
|
+
if (prefix === undefined) {
|
|
59
|
+
prefix = `dddb='${encode(dddb)}',dddbs='${encode(serviceName)}'${this.#dbmEnvFragment}` +
|
|
60
|
+
`ddh='${encode(ddh)}'${this.#dbmEndFragment}`
|
|
61
|
+
this.#dbmPrefixCache.set(cacheKey, prefix)
|
|
62
|
+
}
|
|
28
63
|
|
|
29
64
|
if (peerData !== undefined && peerData[PEER_SERVICE_SOURCE_KEY] === PEER_SERVICE_KEY) {
|
|
30
|
-
|
|
65
|
+
return `${prefix},ddprs='${encode(peerData[PEER_SERVICE_KEY])}'`
|
|
31
66
|
}
|
|
32
|
-
return
|
|
67
|
+
return prefix
|
|
33
68
|
}
|
|
34
69
|
|
|
35
70
|
/**
|
|
@@ -118,6 +153,13 @@ class DatabasePlugin extends StoragePlugin {
|
|
|
118
153
|
}
|
|
119
154
|
}
|
|
120
155
|
|
|
121
|
-
|
|
156
|
+
/**
|
|
157
|
+
* @param {string | number | undefined | null} value
|
|
158
|
+
* @returns {string}
|
|
159
|
+
*/
|
|
160
|
+
function encode (value) {
|
|
161
|
+
if (!value) return ''
|
|
162
|
+
return SAFE_ENCODE_RE.test(value) ? value : encodeURIComponent(value)
|
|
163
|
+
}
|
|
122
164
|
|
|
123
165
|
module.exports = DatabasePlugin
|
|
@@ -49,6 +49,7 @@ const plugins = {
|
|
|
49
49
|
get dns () { return require('../../../datadog-plugin-dns/src') },
|
|
50
50
|
get 'dd-trace-api' () { return require('../../../datadog-plugin-dd-trace-api/src') },
|
|
51
51
|
get elasticsearch () { return require('../../../datadog-plugin-elasticsearch/src') },
|
|
52
|
+
get electron () { return require('../../../datadog-plugin-electron/src') },
|
|
52
53
|
get express () { return require('../../../datadog-plugin-express/src') },
|
|
53
54
|
get fastify () { return require('../../../datadog-plugin-fastify/src') },
|
|
54
55
|
get 'find-my-way' () { return require('../../../datadog-plugin-find-my-way/src') },
|
|
@@ -160,14 +160,12 @@ module.exports = class Plugin {
|
|
|
160
160
|
/**
|
|
161
161
|
* Enable or disable the plugin and (re)apply its configuration.
|
|
162
162
|
*
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
* @param {boolean | import('../config/config-base') & {enabled: boolean}} config Either a boolean to
|
|
163
|
+
* @param {boolean | Record<string, unknown> & {enabled: boolean}} config Either a boolean to
|
|
166
164
|
* enable/disable or a configuration object containing at least `{ enabled: boolean }`.
|
|
167
165
|
*/
|
|
168
166
|
configure (config) {
|
|
169
167
|
if (typeof config === 'boolean') {
|
|
170
|
-
config =
|
|
168
|
+
config = { enabled: config }
|
|
171
169
|
}
|
|
172
170
|
this.config = config
|
|
173
171
|
if (config.enabled) {
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
const { readFileSync, readdirSync, existsSync } = require('fs')
|
|
4
4
|
const path = require('path')
|
|
5
|
-
const
|
|
5
|
+
const getConfig = require('../../config')
|
|
6
|
+
const { getEnvironmentVariable, getEnvironmentVariables } = require('../../config/helper')
|
|
6
7
|
const {
|
|
7
8
|
GIT_BRANCH,
|
|
8
9
|
GIT_COMMIT_SHA,
|
|
@@ -217,7 +218,7 @@ const githubWellKnownDiagnosticDirPatternsWin = ['C:/actions-runner/*/_diag', 'C
|
|
|
217
218
|
const githubJobIDRegex = /"job":\s*{[\s\S]*?"v"\s*:\s*(\d+)(?:\.0)?/
|
|
218
219
|
|
|
219
220
|
function getJobIDFromDiagFile () {
|
|
220
|
-
const runnerTemp =
|
|
221
|
+
const runnerTemp = getEnvironmentVariable('RUNNER_TEMP')
|
|
221
222
|
if (!runnerTemp || !existsSync(runnerTemp)) { return null }
|
|
222
223
|
|
|
223
224
|
const isWin = process.platform === 'win32'
|
|
@@ -298,7 +299,7 @@ module.exports = {
|
|
|
298
299
|
CHANGE_ID,
|
|
299
300
|
CHANGE_TARGET,
|
|
300
301
|
} = env
|
|
301
|
-
const DD_CUSTOM_TRACE_ID =
|
|
302
|
+
const { DD_CUSTOM_TRACE_ID, DD_CUSTOM_PARENT_ID } = getConfig()
|
|
302
303
|
|
|
303
304
|
tags = {
|
|
304
305
|
[CI_PIPELINE_ID]: BUILD_TAG,
|
|
@@ -308,7 +309,7 @@ module.exports = {
|
|
|
308
309
|
[GIT_COMMIT_SHA]: JENKINS_GIT_COMMIT,
|
|
309
310
|
[GIT_REPOSITORY_URL]: JENKINS_GIT_REPOSITORY_URL || JENKINS_GIT_REPOSITORY_URL_1,
|
|
310
311
|
[CI_WORKSPACE_PATH]: WORKSPACE,
|
|
311
|
-
[CI_ENV_VARS]: JSON.stringify({ DD_CUSTOM_TRACE_ID }),
|
|
312
|
+
[CI_ENV_VARS]: JSON.stringify({ DD_CUSTOM_TRACE_ID, DD_CUSTOM_PARENT_ID }),
|
|
312
313
|
[CI_NODE_NAME]: NODE_NAME,
|
|
313
314
|
[PR_NUMBER]: CHANGE_ID,
|
|
314
315
|
[GIT_PULL_REQUEST_BASE_BRANCH]: CHANGE_TARGET,
|
|
@@ -650,7 +651,7 @@ module.exports = {
|
|
|
650
651
|
[GIT_TAG]: BITBUCKET_TAG,
|
|
651
652
|
[GIT_REPOSITORY_URL]: BITBUCKET_GIT_SSH_ORIGIN || BITBUCKET_GIT_HTTP_ORIGIN,
|
|
652
653
|
[CI_WORKSPACE_PATH]: BITBUCKET_CLONE_DIR,
|
|
653
|
-
[CI_PIPELINE_ID]: BITBUCKET_PIPELINE_UUID && BITBUCKET_PIPELINE_UUID.replaceAll(/{
|
|
654
|
+
[CI_PIPELINE_ID]: BITBUCKET_PIPELINE_UUID && BITBUCKET_PIPELINE_UUID.replaceAll(/[{}]/gm, ''),
|
|
654
655
|
[GIT_PULL_REQUEST_BASE_BRANCH]: BITBUCKET_PR_DESTINATION_BRANCH,
|
|
655
656
|
[PR_NUMBER]: BITBUCKET_PR_ID,
|
|
656
657
|
}
|
|
@@ -738,11 +739,11 @@ module.exports = {
|
|
|
738
739
|
}),
|
|
739
740
|
[CI_NODE_NAME]: BUILDKITE_AGENT_ID,
|
|
740
741
|
[CI_NODE_LABELS]: JSON.stringify(extraTags),
|
|
741
|
-
[PR_NUMBER]: BUILDKITE_PULL_REQUEST,
|
|
742
742
|
[CI_JOB_ID]: BUILDKITE_JOB_ID,
|
|
743
743
|
}
|
|
744
744
|
|
|
745
|
-
if (BUILDKITE_PULL_REQUEST) {
|
|
745
|
+
if (BUILDKITE_PULL_REQUEST && BUILDKITE_PULL_REQUEST !== 'false') {
|
|
746
|
+
tags[PR_NUMBER] = BUILDKITE_PULL_REQUEST
|
|
746
747
|
tags[GIT_PULL_REQUEST_BASE_BRANCH] = BUILDKITE_PULL_REQUEST_BASE_BRANCH
|
|
747
748
|
}
|
|
748
749
|
}
|
|
@@ -868,8 +869,7 @@ module.exports = {
|
|
|
868
869
|
}
|
|
869
870
|
|
|
870
871
|
if (env.CODEBUILD_INITIATOR?.startsWith('codepipeline/')) {
|
|
871
|
-
const DD_ACTION_EXECUTION_ID =
|
|
872
|
-
const DD_PIPELINE_EXECUTION_ID = getValueFromEnvSources('DD_PIPELINE_EXECUTION_ID')
|
|
872
|
+
const { DD_ACTION_EXECUTION_ID, DD_PIPELINE_EXECUTION_ID } = getConfig()
|
|
873
873
|
tags = {
|
|
874
874
|
[CI_PROVIDER_NAME]: 'awscodepipeline',
|
|
875
875
|
[CI_PIPELINE_ID]: DD_PIPELINE_EXECUTION_ID,
|
|
@@ -7,24 +7,31 @@ const crypto = require('crypto')
|
|
|
7
7
|
const cp = require('child_process')
|
|
8
8
|
|
|
9
9
|
const log = require('../../log')
|
|
10
|
-
const
|
|
11
|
-
const { isTrue } = require('../../util')
|
|
10
|
+
const getConfig = require('../../config')
|
|
12
11
|
|
|
13
|
-
let isGitEnabled
|
|
14
|
-
|
|
15
|
-
path.join(os.tmpdir(), 'dd-trace-git-cache')
|
|
12
|
+
let isGitEnabled
|
|
13
|
+
let gitCacheDir
|
|
16
14
|
|
|
17
15
|
function ensureCacheDir () {
|
|
16
|
+
if (isGitEnabled === undefined) {
|
|
17
|
+
const config = getConfig()
|
|
18
|
+
isGitEnabled = config.DD_EXPERIMENTAL_TEST_OPT_GIT_CACHE_ENABLED
|
|
19
|
+
// TODO: Move the default to config/index.js applyCalculated
|
|
20
|
+
// when using the config singleton.
|
|
21
|
+
gitCacheDir = config.DD_EXPERIMENTAL_TEST_OPT_GIT_CACHE_DIR ||
|
|
22
|
+
path.join(os.tmpdir(), 'dd-trace-git-cache')
|
|
23
|
+
}
|
|
24
|
+
|
|
18
25
|
if (!isGitEnabled) return false
|
|
19
26
|
|
|
20
27
|
try {
|
|
21
|
-
if (fs.existsSync(
|
|
22
|
-
const stats = fs.statSync(
|
|
28
|
+
if (fs.existsSync(gitCacheDir)) {
|
|
29
|
+
const stats = fs.statSync(gitCacheDir)
|
|
23
30
|
if (!stats.isDirectory()) {
|
|
24
|
-
throw new Error(`Cache directory path exists but is not a directory: ${
|
|
31
|
+
throw new Error(`Cache directory path exists but is not a directory: ${gitCacheDir}`)
|
|
25
32
|
}
|
|
26
33
|
} else {
|
|
27
|
-
fs.mkdirSync(
|
|
34
|
+
fs.mkdirSync(gitCacheDir, { recursive: true })
|
|
28
35
|
}
|
|
29
36
|
return true
|
|
30
37
|
} catch (err) {
|
|
@@ -34,9 +41,6 @@ function ensureCacheDir () {
|
|
|
34
41
|
}
|
|
35
42
|
}
|
|
36
43
|
|
|
37
|
-
// Initialize cache directory at module load time
|
|
38
|
-
ensureCacheDir()
|
|
39
|
-
|
|
40
44
|
function getCacheKey (cmd, flags) {
|
|
41
45
|
// Create a hash of the command and flags to use as cache key
|
|
42
46
|
const commandString = `${cmd} ${flags.join(' ')}`
|
|
@@ -44,30 +48,26 @@ function getCacheKey (cmd, flags) {
|
|
|
44
48
|
}
|
|
45
49
|
|
|
46
50
|
function getCacheFilePath (cacheKey) {
|
|
47
|
-
|
|
51
|
+
ensureCacheDir()
|
|
52
|
+
return path.join(gitCacheDir, `${cacheKey}.cache`)
|
|
48
53
|
}
|
|
49
54
|
|
|
50
55
|
function getCache (cacheKey) {
|
|
51
|
-
if (!
|
|
56
|
+
if (!ensureCacheDir()) return null
|
|
52
57
|
|
|
53
58
|
try {
|
|
54
59
|
const cacheFilePath = getCacheFilePath(cacheKey)
|
|
55
60
|
if (!fs.existsSync(cacheFilePath)) {
|
|
56
|
-
return
|
|
61
|
+
return
|
|
57
62
|
}
|
|
58
63
|
|
|
59
|
-
|
|
60
|
-
return content
|
|
64
|
+
return fs.readFileSync(cacheFilePath, 'utf8')
|
|
61
65
|
} catch (err) {
|
|
62
66
|
log.error('Failed to read git cache', err)
|
|
63
|
-
return null
|
|
64
67
|
}
|
|
65
68
|
}
|
|
66
69
|
|
|
67
70
|
function setCache (cacheKey, result) {
|
|
68
|
-
if (!isGitEnabled) return
|
|
69
|
-
|
|
70
|
-
// Ensure cache directory exists
|
|
71
71
|
if (!ensureCacheDir()) return
|
|
72
72
|
|
|
73
73
|
try {
|
|
@@ -82,12 +82,12 @@ function cachedExec (cmd, flags, options) {
|
|
|
82
82
|
if (options === undefined) {
|
|
83
83
|
options = { stdio: 'pipe' }
|
|
84
84
|
}
|
|
85
|
-
if (!
|
|
85
|
+
if (!ensureCacheDir()) {
|
|
86
86
|
return cp.execFileSync(cmd, flags, options)
|
|
87
87
|
}
|
|
88
88
|
const cacheKey = getCacheKey(cmd, flags)
|
|
89
89
|
const cachedResult = getCache(cacheKey)
|
|
90
|
-
if (cachedResult !==
|
|
90
|
+
if (cachedResult !== undefined) {
|
|
91
91
|
if (cachedResult.startsWith('__GIT_COMMAND_FAILED__')) {
|
|
92
92
|
let error
|
|
93
93
|
try {
|
|
@@ -14,7 +14,7 @@ const NODE_MODULES_PATTERN_START = `node_modules${sep}`
|
|
|
14
14
|
* In production, these frames are already filtered by isNodeModulesFrame.
|
|
15
15
|
*/
|
|
16
16
|
const SHOULD_FILTER_DD_TRACE_INSTRUMENTAION = __filename.endsWith(
|
|
17
|
-
join(
|
|
17
|
+
join('packages', 'dd-trace', 'src', 'plugins', 'util', 'stacktrace.js')
|
|
18
18
|
)
|
|
19
19
|
|
|
20
20
|
module.exports = {
|
|
@@ -46,7 +46,7 @@ function getCallSites (constructorOpt) {
|
|
|
46
46
|
* Get stack trace of user-land frames.
|
|
47
47
|
*
|
|
48
48
|
* @param {string} stack - The stack trace to parse
|
|
49
|
-
* @param {number} [limit
|
|
49
|
+
* @param {number} [limit] - The maximum number of frames to return
|
|
50
50
|
* @returns {StackFrame[]} - A list of stack frames from user-land code
|
|
51
51
|
*/
|
|
52
52
|
function parseUserLandFrames (stack, limit = Infinity) {
|
|
@@ -163,8 +163,12 @@ const DD_CAPABILITIES_TEST_MANAGEMENT_DISABLE = '_dd.library_capabilities.test_m
|
|
|
163
163
|
const DD_CAPABILITIES_TEST_MANAGEMENT_ATTEMPT_TO_FIX = '_dd.library_capabilities.test_management.attempt_to_fix'
|
|
164
164
|
const DD_CAPABILITIES_FAILED_TEST_REPLAY = '_dd.library_capabilities.failed_test_replay'
|
|
165
165
|
|
|
166
|
-
// Library configuration request error
|
|
167
|
-
const
|
|
166
|
+
// Library configuration request error tags
|
|
167
|
+
const DD_CI_LIBRARY_CONFIGURATION_ERROR_SETTINGS = '_dd.ci.library_configuration_error.settings'
|
|
168
|
+
const DD_CI_LIBRARY_CONFIGURATION_ERROR_SKIPPABLE_TESTS = '_dd.ci.library_configuration_error.skippable_tests'
|
|
169
|
+
const DD_CI_LIBRARY_CONFIGURATION_ERROR_KNOWN_TESTS = '_dd.ci.library_configuration_error.known_tests'
|
|
170
|
+
const DD_CI_LIBRARY_CONFIGURATION_ERROR_TEST_MANAGEMENT_TESTS =
|
|
171
|
+
'_dd.ci.library_configuration_error.test_management_tests'
|
|
168
172
|
|
|
169
173
|
const UNSUPPORTED_TIA_FRAMEWORKS = new Set(['playwright', 'vitest'])
|
|
170
174
|
const MINIMUM_FRAMEWORK_VERSION_FOR_EFD = {
|
|
@@ -230,10 +234,34 @@ const BASE_LIKE_BRANCH_FILTER = /^(main|master|preprod|prod|dev|development|trun
|
|
|
230
234
|
*/
|
|
231
235
|
function getSessionRequestErrorTags (sessionSpan) {
|
|
232
236
|
const tags = sessionSpan?.context()._tags
|
|
237
|
+
const sessionRequestErrorTags = {}
|
|
233
238
|
if (!tags || typeof tags !== 'object') return {}
|
|
234
|
-
if (tags[
|
|
239
|
+
if (tags[DD_CI_LIBRARY_CONFIGURATION_ERROR_SETTINGS] === 'true') {
|
|
240
|
+
sessionRequestErrorTags[DD_CI_LIBRARY_CONFIGURATION_ERROR_SETTINGS] = 'true'
|
|
241
|
+
}
|
|
242
|
+
if (tags[DD_CI_LIBRARY_CONFIGURATION_ERROR_SKIPPABLE_TESTS] === 'true') {
|
|
243
|
+
sessionRequestErrorTags[DD_CI_LIBRARY_CONFIGURATION_ERROR_SKIPPABLE_TESTS] = 'true'
|
|
244
|
+
}
|
|
245
|
+
if (tags[DD_CI_LIBRARY_CONFIGURATION_ERROR_KNOWN_TESTS] === 'true') {
|
|
246
|
+
sessionRequestErrorTags[DD_CI_LIBRARY_CONFIGURATION_ERROR_KNOWN_TESTS] = 'true'
|
|
247
|
+
}
|
|
248
|
+
if (tags[DD_CI_LIBRARY_CONFIGURATION_ERROR_TEST_MANAGEMENT_TESTS] === 'true') {
|
|
249
|
+
sessionRequestErrorTags[DD_CI_LIBRARY_CONFIGURATION_ERROR_TEST_MANAGEMENT_TESTS] = 'true'
|
|
250
|
+
}
|
|
251
|
+
return sessionRequestErrorTags
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Returns ITR skipping-enabled tags from a test session span for propagation to child events.
|
|
256
|
+
* @param {{ context: () => { _tags?: Record<string, string> } } | undefined} sessionSpan
|
|
257
|
+
* @returns {Record<string, string>}
|
|
258
|
+
*/
|
|
259
|
+
function getSessionItrSkippingEnabledTags (sessionSpan) {
|
|
260
|
+
const tags = sessionSpan?.context()._tags
|
|
261
|
+
if (!tags || typeof tags !== 'object') return {}
|
|
262
|
+
if (tags[TEST_ITR_SKIPPING_ENABLED] !== undefined) {
|
|
235
263
|
return {
|
|
236
|
-
[
|
|
264
|
+
[TEST_ITR_SKIPPING_ENABLED]: tags[TEST_ITR_SKIPPING_ENABLED],
|
|
237
265
|
}
|
|
238
266
|
}
|
|
239
267
|
return {}
|
|
@@ -318,6 +346,7 @@ module.exports = {
|
|
|
318
346
|
parseAnnotations,
|
|
319
347
|
getIsFaultyEarlyFlakeDetection,
|
|
320
348
|
getEfdRetryCount,
|
|
349
|
+
getMaxEfdRetryCount,
|
|
321
350
|
TEST_BROWSER_DRIVER,
|
|
322
351
|
TEST_BROWSER_DRIVER_VERSION,
|
|
323
352
|
TEST_BROWSER_NAME,
|
|
@@ -349,7 +378,11 @@ module.exports = {
|
|
|
349
378
|
TEST_MANAGEMENT_ATTEMPT_TO_FIX_PASSED,
|
|
350
379
|
getLibraryCapabilitiesTags,
|
|
351
380
|
getSessionRequestErrorTags,
|
|
352
|
-
|
|
381
|
+
DD_CI_LIBRARY_CONFIGURATION_ERROR_SETTINGS,
|
|
382
|
+
DD_CI_LIBRARY_CONFIGURATION_ERROR_SKIPPABLE_TESTS,
|
|
383
|
+
DD_CI_LIBRARY_CONFIGURATION_ERROR_KNOWN_TESTS,
|
|
384
|
+
DD_CI_LIBRARY_CONFIGURATION_ERROR_TEST_MANAGEMENT_TESTS,
|
|
385
|
+
getSessionItrSkippingEnabledTags,
|
|
353
386
|
checkShaDiscrepancies,
|
|
354
387
|
getPullRequestDiff,
|
|
355
388
|
getPullRequestBaseBranch,
|
|
@@ -922,9 +955,7 @@ function getCoveredFilenamesFromCoverage (coverage) {
|
|
|
922
955
|
.filter(filename => {
|
|
923
956
|
const fileCoverage = coverageMap.fileCoverageFor(filename)
|
|
924
957
|
const lineCoverage = fileCoverage.getLineCoverage()
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
return isAnyLineExecuted
|
|
958
|
+
return Object.entries(lineCoverage).some(([, numExecutions]) => !!numExecutions)
|
|
928
959
|
})
|
|
929
960
|
}
|
|
930
961
|
|
|
@@ -1045,6 +1076,22 @@ function getEfdRetryCount (durationMs, slowTestRetries) {
|
|
|
1045
1076
|
return 0 // ≥ 5 min — abort
|
|
1046
1077
|
}
|
|
1047
1078
|
|
|
1079
|
+
/**
|
|
1080
|
+
* Returns the maximum retry count configured by the backend for EFD.
|
|
1081
|
+
*
|
|
1082
|
+
* @param {Record<string, number>} slowTestRetries e.g. { '5s': 10, '10s': 5, '30s': 3, '5m': 2 }
|
|
1083
|
+
* @returns {number}
|
|
1084
|
+
*/
|
|
1085
|
+
function getMaxEfdRetryCount (slowTestRetries) {
|
|
1086
|
+
let maxRetries = 0
|
|
1087
|
+
for (const retryCount of Object.values(slowTestRetries || {})) {
|
|
1088
|
+
if (retryCount > maxRetries) {
|
|
1089
|
+
maxRetries = retryCount
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
return maxRetries
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1048
1095
|
function getIsFaultyEarlyFlakeDetection (projectSuites, testsBySuiteName, faultyThresholdPercentage) {
|
|
1049
1096
|
let newSuites = 0
|
|
1050
1097
|
for (const suite of projectSuites) {
|
|
@@ -1276,10 +1323,7 @@ function getPullRequestBaseBranch (pullRequestBaseBranch) {
|
|
|
1276
1323
|
let bestScore = Infinity
|
|
1277
1324
|
for (const branch of Object.keys(metrics)) {
|
|
1278
1325
|
const score = metrics[branch].ahead
|
|
1279
|
-
if (score < bestScore) {
|
|
1280
|
-
bestScore = score
|
|
1281
|
-
bestBranch = branch
|
|
1282
|
-
} else if (score === bestScore && isDefaultBranch(branch)) {
|
|
1326
|
+
if (score < bestScore || score === bestScore && isDefaultBranch(branch)) {
|
|
1283
1327
|
bestScore = score
|
|
1284
1328
|
bestBranch = branch
|
|
1285
1329
|
}
|
|
@@ -108,11 +108,9 @@ function calculateHttpEndpoint (url) {
|
|
|
108
108
|
return element
|
|
109
109
|
})
|
|
110
110
|
|
|
111
|
-
|
|
111
|
+
return normalizedElements.length > 0
|
|
112
112
|
? '/' + normalizedElements.join('/')
|
|
113
113
|
: '/'
|
|
114
|
-
|
|
115
|
-
return endpoint
|
|
116
114
|
}
|
|
117
115
|
|
|
118
116
|
function filterSensitiveInfoFromRepository (repositoryUrl) {
|