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
|
@@ -18,8 +18,8 @@ addHook({ name: 'memcached', versions: ['>=2.2'] }, Memcached => {
|
|
|
18
18
|
|
|
19
19
|
const client = this
|
|
20
20
|
|
|
21
|
-
const wrappedQueryCompiler = function () {
|
|
22
|
-
const query = queryCompiler.apply(this,
|
|
21
|
+
const wrappedQueryCompiler = function (...args) {
|
|
22
|
+
const query = queryCompiler.apply(this, args)
|
|
23
23
|
|
|
24
24
|
const ctx = { client, server, query }
|
|
25
25
|
startCh.runStores(ctx, () => {
|
|
@@ -14,8 +14,8 @@ const versions = ['>=2.1 <=3.0.0']
|
|
|
14
14
|
const requestContexts = new WeakMap()
|
|
15
15
|
|
|
16
16
|
function wrapConfigProxyFactory (configProxyFactory) {
|
|
17
|
-
return function () {
|
|
18
|
-
const configProxy = configProxyFactory.apply(this,
|
|
17
|
+
return function (...args) {
|
|
18
|
+
const configProxy = configProxyFactory.apply(this, args)
|
|
19
19
|
|
|
20
20
|
return function (req, res, next) {
|
|
21
21
|
const ctx = { req, res }
|
|
@@ -20,9 +20,9 @@ addHook({
|
|
|
20
20
|
|
|
21
21
|
patched.add(mochaEach)
|
|
22
22
|
|
|
23
|
-
return shimmer.wrapFunction(mochaEach, mochaEach => function () {
|
|
24
|
-
const [params] =
|
|
25
|
-
const { it, ...rest } = mochaEach.apply(this,
|
|
23
|
+
return shimmer.wrapFunction(mochaEach, mochaEach => function (...args) {
|
|
24
|
+
const [params] = args
|
|
25
|
+
const { it, ...rest } = mochaEach.apply(this, args)
|
|
26
26
|
return {
|
|
27
27
|
it: function (title) {
|
|
28
28
|
parameterizedTestCh.publish({ title, params })
|
|
@@ -326,6 +326,7 @@ function getExecutionConfiguration (runner, isParallel, frameworkVersion, onFini
|
|
|
326
326
|
}
|
|
327
327
|
config.isEarlyFlakeDetectionEnabled = libraryConfig.isEarlyFlakeDetectionEnabled
|
|
328
328
|
config.earlyFlakeDetectionNumRetries = libraryConfig.earlyFlakeDetectionNumRetries
|
|
329
|
+
config.earlyFlakeDetectionSlowTestRetries = libraryConfig.earlyFlakeDetectionSlowTestRetries ?? {}
|
|
329
330
|
config.earlyFlakeDetectionFaultyThreshold = libraryConfig.earlyFlakeDetectionFaultyThreshold
|
|
330
331
|
config.isKnownTestsEnabled = libraryConfig.isKnownTestsEnabled
|
|
331
332
|
config.isTestManagementTestsEnabled = libraryConfig.isTestManagementEnabled
|
|
@@ -369,17 +370,17 @@ addHook({
|
|
|
369
370
|
}, (Mocha, frameworkVersion) => {
|
|
370
371
|
warnDeprecatedMochaVersion(frameworkVersion)
|
|
371
372
|
|
|
372
|
-
shimmer.wrap(Mocha.prototype, 'run', run => function () {
|
|
373
|
+
shimmer.wrap(Mocha.prototype, 'run', run => function (...args) {
|
|
373
374
|
// Workers do not need to request any data, just run the tests
|
|
374
375
|
if (!testFinishCh.hasSubscribers || getEnvironmentVariable('MOCHA_WORKER_ID') || this.options.parallel) {
|
|
375
|
-
return run.apply(this,
|
|
376
|
+
return run.apply(this, args)
|
|
376
377
|
}
|
|
377
378
|
|
|
378
379
|
// `options.delay` does not work in parallel mode, so we can't delay the execution this way
|
|
379
380
|
// This needs to be both here and in `runMocha` hook. Read the comment in `runMocha` hook for more info.
|
|
380
381
|
this.options.delay = true
|
|
381
382
|
|
|
382
|
-
const runner = run.apply(this,
|
|
383
|
+
const runner = run.apply(this, args)
|
|
383
384
|
|
|
384
385
|
// eslint-disable-next-line unicorn/no-array-for-each
|
|
385
386
|
this.files.forEach((path) => {
|
|
@@ -426,11 +427,11 @@ addHook({
|
|
|
426
427
|
file: 'lib/cli/run-helpers.js',
|
|
427
428
|
}, (run) => {
|
|
428
429
|
// `runMocha` is an async function
|
|
429
|
-
shimmer.wrap(run, 'runMocha', runMocha => function () {
|
|
430
|
+
shimmer.wrap(run, 'runMocha', runMocha => function (...args) {
|
|
430
431
|
if (!testFinishCh.hasSubscribers) {
|
|
431
|
-
return runMocha.apply(this,
|
|
432
|
+
return runMocha.apply(this, args)
|
|
432
433
|
}
|
|
433
|
-
const mocha =
|
|
434
|
+
const mocha = args[0]
|
|
434
435
|
|
|
435
436
|
/**
|
|
436
437
|
* This attaches `run` to the global context, which we'll call after
|
|
@@ -444,7 +445,7 @@ addHook({
|
|
|
444
445
|
mocha.options.delay = true
|
|
445
446
|
}
|
|
446
447
|
|
|
447
|
-
return runMocha.apply(this,
|
|
448
|
+
return runMocha.apply(this, args)
|
|
448
449
|
})
|
|
449
450
|
return run
|
|
450
451
|
})
|
|
@@ -462,12 +463,16 @@ addHook({
|
|
|
462
463
|
|
|
463
464
|
shimmer.wrap(Runner.prototype, 'runTests', runTests => getRunTestsWrapper(runTests, config))
|
|
464
465
|
|
|
465
|
-
shimmer.wrap(Runner.prototype, 'run', run => function () {
|
|
466
|
+
shimmer.wrap(Runner.prototype, 'run', run => function (...args) {
|
|
466
467
|
if (!testFinishCh.hasSubscribers) {
|
|
467
|
-
return run.apply(this,
|
|
468
|
+
return run.apply(this, args)
|
|
468
469
|
}
|
|
469
470
|
|
|
470
471
|
const { suitesByTestFile, numSuitesByTestFile } = getSuitesByTestFile(this.suite)
|
|
472
|
+
// Root-level tests (direct children of root, no describe wrapper) keyed by file.
|
|
473
|
+
// Populated during the root 'suite' event so the normal finish path can include them
|
|
474
|
+
// in mixed-file status calculation.
|
|
475
|
+
const rootTestsByFile = new Map()
|
|
471
476
|
|
|
472
477
|
this.once('start', getOnStartHandler(frameworkVersion))
|
|
473
478
|
|
|
@@ -488,6 +493,30 @@ addHook({
|
|
|
488
493
|
|
|
489
494
|
this.on('suite', function (suite) {
|
|
490
495
|
if (suite.root || !suite.tests.length) {
|
|
496
|
+
// This branch can be triggered when we have top level it(...) inside test files.
|
|
497
|
+
// In that case, they all (even if they are from different files) are going to be
|
|
498
|
+
// children of the root suite.
|
|
499
|
+
// Note: We could have suites that contain top level it(...) and also it(...) nested
|
|
500
|
+
// inside describe(...) ("mixed case"). Duplication is avoided by the context guard
|
|
501
|
+
// below. Since 'suite' fires for root first, in the mixed case the ctx is created
|
|
502
|
+
// here and the describe-based handler finds it already set.
|
|
503
|
+
if (suite.root && suite.tests.length > 0) {
|
|
504
|
+
const files = new Set(suite.tests.map(test => test.file).filter(Boolean))
|
|
505
|
+
for (const file of files) {
|
|
506
|
+
rootTestsByFile.set(file, suite.tests.filter(t => t.file === file))
|
|
507
|
+
if (testFileToSuiteCtx.get(file)) continue
|
|
508
|
+
const isUnskippable = unskippableSuites.includes(file)
|
|
509
|
+
isForcedToRun = isUnskippable && suitesToSkip.includes(getTestSuitePath(file, process.cwd()))
|
|
510
|
+
const ctx = {
|
|
511
|
+
testSuiteAbsolutePath: file,
|
|
512
|
+
isUnskippable,
|
|
513
|
+
isForcedToRun,
|
|
514
|
+
itrCorrelationId,
|
|
515
|
+
}
|
|
516
|
+
testFileToSuiteCtx.set(file, ctx)
|
|
517
|
+
testSuiteStartCh.runStores(ctx, () => {})
|
|
518
|
+
}
|
|
519
|
+
}
|
|
491
520
|
return
|
|
492
521
|
}
|
|
493
522
|
let ctx = testFileToSuiteCtx.get(suite.file)
|
|
@@ -507,6 +536,44 @@ addHook({
|
|
|
507
536
|
|
|
508
537
|
this.on('suite end', function (suite) {
|
|
509
538
|
if (suite.root) {
|
|
539
|
+
// Symmetric to the suite start fix
|
|
540
|
+
const fileToTests = new Map()
|
|
541
|
+
for (const test of suite.tests) {
|
|
542
|
+
if (!test.file) continue
|
|
543
|
+
if (!fileToTests.has(test.file)) fileToTests.set(test.file, [])
|
|
544
|
+
fileToTests.get(test.file).push(test)
|
|
545
|
+
}
|
|
546
|
+
for (const [file, tests] of fileToTests) {
|
|
547
|
+
// Mixed case: if a file appears in suitesByTestFile (pre-populated before the run),
|
|
548
|
+
// its numSuitesByTestFile counter hits zero when its last describe-based suite ends
|
|
549
|
+
// and the normal path below fires testSuiteFinishCh. Since root is last when
|
|
550
|
+
// 'suite end' fires, any such file has already been handled — skipping it here
|
|
551
|
+
// avoids duplication.
|
|
552
|
+
if (suitesByTestFile[file]) continue
|
|
553
|
+
let status = 'pass'
|
|
554
|
+
if (tests.every(test => test.isPending())) {
|
|
555
|
+
status = 'skip'
|
|
556
|
+
} else {
|
|
557
|
+
for (const test of tests) {
|
|
558
|
+
if (test.state === 'failed' || test.timedOut) {
|
|
559
|
+
status = 'fail'
|
|
560
|
+
break
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
if (global.__coverage__) {
|
|
565
|
+
const coverageFiles = getCoveredFilenamesFromCoverage(global.__coverage__)
|
|
566
|
+
testSuiteCodeCoverageCh.publish({ coverageFiles, suiteFile: file })
|
|
567
|
+
mergeCoverage(global.__coverage__, originalCoverageMap)
|
|
568
|
+
resetCoverage(global.__coverage__)
|
|
569
|
+
}
|
|
570
|
+
const ctx = testFileToSuiteCtx.get(file)
|
|
571
|
+
if (ctx) {
|
|
572
|
+
testSuiteFinishCh.publish({ status, ...ctx.currentStore }, () => {})
|
|
573
|
+
} else {
|
|
574
|
+
log.warn('No ctx found for suite', file)
|
|
575
|
+
}
|
|
576
|
+
}
|
|
510
577
|
return
|
|
511
578
|
}
|
|
512
579
|
const suitesInTestFile = suitesByTestFile[suite.file]
|
|
@@ -516,8 +583,9 @@ addHook({
|
|
|
516
583
|
return
|
|
517
584
|
}
|
|
518
585
|
|
|
586
|
+
const rootTests = rootTestsByFile.get(suite.file) || []
|
|
519
587
|
let status = 'pass'
|
|
520
|
-
if (suitesInTestFile.every(suite => suite.pending)) {
|
|
588
|
+
if (suitesInTestFile.every(suite => suite.pending) && rootTests.every(test => test.isPending())) {
|
|
521
589
|
status = 'skip'
|
|
522
590
|
} else {
|
|
523
591
|
// has to check every test in the test file
|
|
@@ -529,6 +597,11 @@ addHook({
|
|
|
529
597
|
}
|
|
530
598
|
})
|
|
531
599
|
})
|
|
600
|
+
for (const test of rootTests) {
|
|
601
|
+
if (test.state === 'failed' || test.timedOut) {
|
|
602
|
+
status = 'fail'
|
|
603
|
+
}
|
|
604
|
+
}
|
|
532
605
|
}
|
|
533
606
|
|
|
534
607
|
if (global.__coverage__) {
|
|
@@ -552,7 +625,7 @@ addHook({
|
|
|
552
625
|
}
|
|
553
626
|
})
|
|
554
627
|
|
|
555
|
-
return run.apply(this,
|
|
628
|
+
return run.apply(this, args)
|
|
556
629
|
})
|
|
557
630
|
|
|
558
631
|
return Runner
|
|
@@ -722,6 +795,7 @@ addHook({
|
|
|
722
795
|
if (config.knownTests?.mocha) {
|
|
723
796
|
const testSuiteKnownTests = config.knownTests.mocha[testPath] || []
|
|
724
797
|
newWorkerArgs._ddEfdNumRetries = config.earlyFlakeDetectionNumRetries
|
|
798
|
+
newWorkerArgs._ddEfdSlowTestRetries = config.earlyFlakeDetectionSlowTestRetries
|
|
725
799
|
newWorkerArgs._ddIsEfdEnabled = config.isEarlyFlakeDetectionEnabled
|
|
726
800
|
newWorkerArgs._ddIsKnownTestsEnabled = true
|
|
727
801
|
newWorkerArgs._ddKnownTests = {
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const { performance } = require('node:perf_hooks')
|
|
4
|
+
|
|
3
5
|
// Capture real timers at module load time, before any test can install fake timers.
|
|
4
6
|
const realSetTimeout = setTimeout
|
|
5
7
|
|
|
6
8
|
const {
|
|
7
9
|
getTestSuitePath,
|
|
8
10
|
DYNAMIC_NAME_RE,
|
|
11
|
+
getEfdRetryCount,
|
|
12
|
+
getMaxEfdRetryCount,
|
|
9
13
|
recordAttemptToFixExecution,
|
|
10
14
|
logAttemptToFixTestExecution,
|
|
11
15
|
} = require('../../../dd-trace/src/plugins/util/test')
|
|
@@ -35,6 +39,8 @@ const newTestsWithDynamicNames = new Set()
|
|
|
35
39
|
const testsAttemptToFix = new Set()
|
|
36
40
|
const testsQuarantined = new Set()
|
|
37
41
|
const testsStatuses = new Map()
|
|
42
|
+
const efdRetryCountByTestFullName = new Map()
|
|
43
|
+
const efdSlowAbortedTests = new Set()
|
|
38
44
|
const attemptToFixExecutions = new Map()
|
|
39
45
|
const loggedAttemptToFixTests = new Set()
|
|
40
46
|
|
|
@@ -70,11 +76,82 @@ function isNewTest (test, knownTests) {
|
|
|
70
76
|
return !testsForSuite.includes(testName)
|
|
71
77
|
}
|
|
72
78
|
|
|
73
|
-
function
|
|
79
|
+
function setEfdRetryCountForTest (test, duration, slowTestRetries) {
|
|
80
|
+
const testName = getTestFullName(test)
|
|
81
|
+
if (efdRetryCountByTestFullName.has(testName)) {
|
|
82
|
+
return
|
|
83
|
+
}
|
|
84
|
+
const retryCount = getEfdRetryCount(duration, slowTestRetries || {})
|
|
85
|
+
efdRetryCountByTestFullName.set(testName, retryCount)
|
|
86
|
+
if (retryCount === 0) {
|
|
87
|
+
efdSlowAbortedTests.add(testName)
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function wrapOriginalEfdTest (test, slowTestRetries) {
|
|
92
|
+
if (test._ddEfdDurationWrapped || typeof test.fn !== 'function') {
|
|
93
|
+
return
|
|
94
|
+
}
|
|
95
|
+
test._ddEfdDurationWrapped = true
|
|
96
|
+
const originalFn = test.fn
|
|
97
|
+
test.fn = shimmer.wrapFunction(originalFn, originalFn => function () {
|
|
98
|
+
const start = performance.now()
|
|
99
|
+
const recordDuration = () => {
|
|
100
|
+
setEfdRetryCountForTest(test, performance.now() - start, slowTestRetries)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (originalFn.length > 0) {
|
|
104
|
+
const args = Array.prototype.slice.call(arguments)
|
|
105
|
+
args[0] = shimmer.wrapFunction(args[0], done => function (...args) {
|
|
106
|
+
recordDuration()
|
|
107
|
+
return done.apply(this, args)
|
|
108
|
+
})
|
|
109
|
+
return originalFn.apply(this, args)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
try {
|
|
113
|
+
const result = originalFn.apply(this, arguments)
|
|
114
|
+
if (result?.then) {
|
|
115
|
+
return result.then(value => {
|
|
116
|
+
recordDuration()
|
|
117
|
+
return value
|
|
118
|
+
}, error => {
|
|
119
|
+
recordDuration()
|
|
120
|
+
throw error
|
|
121
|
+
})
|
|
122
|
+
}
|
|
123
|
+
recordDuration()
|
|
124
|
+
return result
|
|
125
|
+
} catch (error) {
|
|
126
|
+
recordDuration()
|
|
127
|
+
throw error
|
|
128
|
+
}
|
|
129
|
+
})
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function retryTest (test, numRetries, tags, slowTestRetries) {
|
|
74
133
|
const suite = test.parent
|
|
134
|
+
const isEfdRetry = tags.includes('_ddIsEfdRetry')
|
|
135
|
+
if (isEfdRetry) {
|
|
136
|
+
wrapOriginalEfdTest(test, slowTestRetries)
|
|
137
|
+
}
|
|
75
138
|
for (let retryIndex = 0; retryIndex < numRetries; retryIndex++) {
|
|
76
139
|
const clonedTest = test.clone()
|
|
77
140
|
suite.addTest(clonedTest)
|
|
141
|
+
if (isEfdRetry) {
|
|
142
|
+
clonedTest._ddEfdRetryIndex = retryIndex + 1
|
|
143
|
+
const originalFn = clonedTest.fn
|
|
144
|
+
if (typeof originalFn === 'function') {
|
|
145
|
+
clonedTest.fn = shimmer.wrapFunction(originalFn, originalFn => function (...args) {
|
|
146
|
+
const efdRetryCount = efdRetryCountByTestFullName.get(getTestFullName(clonedTest))
|
|
147
|
+
if (efdRetryCount !== undefined && clonedTest._ddEfdRetryIndex > efdRetryCount) {
|
|
148
|
+
clonedTest._ddShouldSkipEfdRetry = true
|
|
149
|
+
this.skip()
|
|
150
|
+
}
|
|
151
|
+
return originalFn.apply(this, args)
|
|
152
|
+
})
|
|
153
|
+
}
|
|
154
|
+
}
|
|
78
155
|
for (const tag of tags) {
|
|
79
156
|
if (tag) {
|
|
80
157
|
clonedTest[tag] = true
|
|
@@ -83,6 +160,14 @@ function retryTest (test, numRetries, tags) {
|
|
|
83
160
|
}
|
|
84
161
|
}
|
|
85
162
|
|
|
163
|
+
function getConfiguredEfdRetryCount (config) {
|
|
164
|
+
const { earlyFlakeDetectionSlowTestRetries } = config
|
|
165
|
+
if (!earlyFlakeDetectionSlowTestRetries || !Object.keys(earlyFlakeDetectionSlowTestRetries).length) {
|
|
166
|
+
return config.earlyFlakeDetectionNumRetries
|
|
167
|
+
}
|
|
168
|
+
return getMaxEfdRetryCount(earlyFlakeDetectionSlowTestRetries)
|
|
169
|
+
}
|
|
170
|
+
|
|
86
171
|
function getSuitesByTestFile (root) {
|
|
87
172
|
const suitesByTestFile = {}
|
|
88
173
|
function getSuites (suite) {
|
|
@@ -137,8 +222,7 @@ function getTestToContextKey (test) {
|
|
|
137
222
|
if (!wrappedFunctions.has(test.fn)) {
|
|
138
223
|
return test.fn
|
|
139
224
|
}
|
|
140
|
-
|
|
141
|
-
return originalFn
|
|
225
|
+
return originalFns.get(test.fn)
|
|
142
226
|
}
|
|
143
227
|
|
|
144
228
|
function getTestContext (test) {
|
|
@@ -147,9 +231,9 @@ function getTestContext (test) {
|
|
|
147
231
|
}
|
|
148
232
|
|
|
149
233
|
function runnableWrapper (RunnablePackage, libraryConfig) {
|
|
150
|
-
shimmer.wrap(RunnablePackage.prototype, 'run', run => function () {
|
|
234
|
+
shimmer.wrap(RunnablePackage.prototype, 'run', run => function (...args) {
|
|
151
235
|
if (!testFinishCh.hasSubscribers) {
|
|
152
|
-
return run.apply(this,
|
|
236
|
+
return run.apply(this, args)
|
|
153
237
|
}
|
|
154
238
|
if (libraryConfig?.isFlakyTestRetriesEnabled) {
|
|
155
239
|
this.retries(libraryConfig?.flakyTestRetriesCount)
|
|
@@ -175,8 +259,8 @@ function runnableWrapper (RunnablePackage, libraryConfig) {
|
|
|
175
259
|
|
|
176
260
|
if (ctx) {
|
|
177
261
|
// we bind the test fn to the correct context
|
|
178
|
-
const newFn = shimmer.wrapFunction(this.fn, originalFn => function () {
|
|
179
|
-
return testFnCh.runStores(ctx, () => originalFn.apply(this,
|
|
262
|
+
const newFn = shimmer.wrapFunction(this.fn, originalFn => function (...args) {
|
|
263
|
+
return testFnCh.runStores(ctx, () => originalFn.apply(this, args))
|
|
180
264
|
})
|
|
181
265
|
|
|
182
266
|
// we store the original function, not to lose it
|
|
@@ -187,7 +271,7 @@ function runnableWrapper (RunnablePackage, libraryConfig) {
|
|
|
187
271
|
}
|
|
188
272
|
}
|
|
189
273
|
|
|
190
|
-
return run.apply(this,
|
|
274
|
+
return run.apply(this, args)
|
|
191
275
|
})
|
|
192
276
|
return RunnablePackage
|
|
193
277
|
}
|
|
@@ -215,6 +299,17 @@ function getOnTestHandler (isMain) {
|
|
|
215
299
|
_ddIsModified: isModified,
|
|
216
300
|
} = test
|
|
217
301
|
|
|
302
|
+
test._ddStartTime = performance.now()
|
|
303
|
+
|
|
304
|
+
if (isEfdRetry) {
|
|
305
|
+
const efdRetryCount = efdRetryCountByTestFullName.get(getTestFullName(test))
|
|
306
|
+
if (efdRetryCount !== undefined && test._ddEfdRetryIndex > efdRetryCount) {
|
|
307
|
+
test.pending = true
|
|
308
|
+
test._ddShouldSkipEfdRetry = true
|
|
309
|
+
return
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
218
313
|
const testInfo = {
|
|
219
314
|
testName: test.fullTitle(),
|
|
220
315
|
testSuiteAbsolutePath,
|
|
@@ -273,6 +368,7 @@ function getFinalStatus ({
|
|
|
273
368
|
isAttemptToFix,
|
|
274
369
|
isLastAttemptToFix,
|
|
275
370
|
attemptToFixPassed,
|
|
371
|
+
hasPassedAnyEfdAttempt,
|
|
276
372
|
isQuarantined,
|
|
277
373
|
isDisabled,
|
|
278
374
|
}) {
|
|
@@ -301,7 +397,7 @@ function getFinalStatus ({
|
|
|
301
397
|
return hasFailedAllRetries ? 'fail' : 'pass'
|
|
302
398
|
}
|
|
303
399
|
if (isEfdRetry && isLastEfdRetry) {
|
|
304
|
-
return
|
|
400
|
+
return hasPassedAnyEfdAttempt ? 'pass' : 'fail'
|
|
305
401
|
}
|
|
306
402
|
if (isAttemptToFix && isLastAttemptToFix) {
|
|
307
403
|
return attemptToFixPassed ? 'pass' : 'fail'
|
|
@@ -314,6 +410,15 @@ function getTestFinishInfo (test, status, config, error) {
|
|
|
314
410
|
let attemptToFixFailed = false
|
|
315
411
|
|
|
316
412
|
const testName = getTestFullName(test)
|
|
413
|
+
if (
|
|
414
|
+
config.isEarlyFlakeDetectionEnabled &&
|
|
415
|
+
(test._ddIsNew || test._ddIsModified) &&
|
|
416
|
+
!test._ddIsEfdRetry &&
|
|
417
|
+
!efdRetryCountByTestFullName.has(testName)
|
|
418
|
+
) {
|
|
419
|
+
const duration = test.duration > 0 ? test.duration : performance.now() - test._ddStartTime
|
|
420
|
+
setEfdRetryCountForTest(test, duration, config.earlyFlakeDetectionSlowTestRetries)
|
|
421
|
+
}
|
|
317
422
|
|
|
318
423
|
if (testsStatuses.get(testName)) {
|
|
319
424
|
testsStatuses.get(testName).push(status)
|
|
@@ -323,12 +428,14 @@ function getTestFinishInfo (test, status, config, error) {
|
|
|
323
428
|
const testStatuses = testsStatuses.get(testName)
|
|
324
429
|
|
|
325
430
|
const isLastAttempt = testStatuses.length === config.testManagementAttemptToFixRetries + 1
|
|
326
|
-
const
|
|
431
|
+
const efdRetryCount = efdRetryCountByTestFullName.get(testName) ?? getConfiguredEfdRetryCount(config)
|
|
432
|
+
const isLastEfdRetry = testStatuses.length === efdRetryCount + 1
|
|
327
433
|
const isLastAtrAttempt = getIsLastRetry(test) || (config.isFlakyTestRetriesEnabled && status === 'pass')
|
|
328
434
|
|
|
329
435
|
// Needed for the getFinalStatus call. This is because EFD does NOT tag as
|
|
330
436
|
// EFD retry the first run of the test. It only tags as retries the clones
|
|
331
|
-
const isEfdRetry =
|
|
437
|
+
const isEfdRetry =
|
|
438
|
+
test._ddIsEfdRetry || ((test._ddIsNew || test._ddIsModified) && config.isEarlyFlakeDetectionEnabled)
|
|
332
439
|
|
|
333
440
|
if (test._ddIsAttemptToFix && isLastAttempt) {
|
|
334
441
|
if (testStatuses.includes('fail')) {
|
|
@@ -341,7 +448,7 @@ function getTestFinishInfo (test, status, config, error) {
|
|
|
341
448
|
}
|
|
342
449
|
}
|
|
343
450
|
|
|
344
|
-
if (test._ddIsEfdRetry && isLastEfdRetry &&
|
|
451
|
+
if (test._ddIsEfdRetry && efdRetryCount > 0 && isLastEfdRetry &&
|
|
345
452
|
testStatuses.every(status => status === 'fail')) {
|
|
346
453
|
hasFailedAllRetries = true
|
|
347
454
|
}
|
|
@@ -370,6 +477,7 @@ function getTestFinishInfo (test, status, config, error) {
|
|
|
370
477
|
isAttemptToFix: _ddIsAttemptToFix,
|
|
371
478
|
isLastAttemptToFix: isLastAttempt,
|
|
372
479
|
attemptToFixPassed,
|
|
480
|
+
hasPassedAnyEfdAttempt: testStatuses.includes('pass'),
|
|
373
481
|
isQuarantined: _ddIsQuarantined,
|
|
374
482
|
isDisabled: _ddIsDisabled,
|
|
375
483
|
})
|
|
@@ -391,11 +499,15 @@ function getTestFinishInfo (test, status, config, error) {
|
|
|
391
499
|
isAttemptToFixRetry,
|
|
392
500
|
isAtrRetry,
|
|
393
501
|
finalStatus,
|
|
502
|
+
earlyFlakeAbortReason: efdSlowAbortedTests.has(testName) ? 'slow' : undefined,
|
|
394
503
|
}
|
|
395
504
|
}
|
|
396
505
|
|
|
397
506
|
function getOnTestEndHandler (config) {
|
|
398
507
|
return async function (test) {
|
|
508
|
+
if (test._ddShouldSkipEfdRetry) {
|
|
509
|
+
return
|
|
510
|
+
}
|
|
399
511
|
const ctx = getTestContext(test)
|
|
400
512
|
const status = getTestStatus(test)
|
|
401
513
|
|
|
@@ -518,6 +630,9 @@ function getOnTestRetryHandler (config) {
|
|
|
518
630
|
|
|
519
631
|
function getOnPendingHandler () {
|
|
520
632
|
return function (test) {
|
|
633
|
+
if (test._ddShouldSkipEfdRetry) {
|
|
634
|
+
return
|
|
635
|
+
}
|
|
521
636
|
const testStartLine = testToStartLine.get(test)
|
|
522
637
|
const {
|
|
523
638
|
file: testSuiteAbsolutePath,
|
|
@@ -587,8 +702,9 @@ function getRunTestsWrapper (runTests, config) {
|
|
|
587
702
|
if (!test.isPending() && !test._ddIsAttemptToFix && config.isEarlyFlakeDetectionEnabled) {
|
|
588
703
|
retryTest(
|
|
589
704
|
test,
|
|
590
|
-
config
|
|
591
|
-
['_ddIsModified', '_ddIsEfdRetry']
|
|
705
|
+
getConfiguredEfdRetryCount(config),
|
|
706
|
+
['_ddIsModified', '_ddIsEfdRetry'],
|
|
707
|
+
config.earlyFlakeDetectionSlowTestRetries
|
|
592
708
|
)
|
|
593
709
|
}
|
|
594
710
|
}
|
|
@@ -606,8 +722,9 @@ function getRunTestsWrapper (runTests, config) {
|
|
|
606
722
|
if (config.isEarlyFlakeDetectionEnabled && !test._ddIsAttemptToFix && !test._ddIsModified) {
|
|
607
723
|
retryTest(
|
|
608
724
|
test,
|
|
609
|
-
config
|
|
610
|
-
['_ddIsNew', '_ddIsEfdRetry']
|
|
725
|
+
getConfiguredEfdRetryCount(config),
|
|
726
|
+
['_ddIsNew', '_ddIsEfdRetry'],
|
|
727
|
+
config.earlyFlakeDetectionSlowTestRetries
|
|
611
728
|
)
|
|
612
729
|
}
|
|
613
730
|
}
|
|
@@ -27,15 +27,17 @@ addHook({
|
|
|
27
27
|
versions: ['>=8.0.0'],
|
|
28
28
|
file: 'lib/mocha.js',
|
|
29
29
|
}, (Mocha) => {
|
|
30
|
-
shimmer.wrap(Mocha.prototype, 'run', run => function () {
|
|
30
|
+
shimmer.wrap(Mocha.prototype, 'run', run => function (...args) {
|
|
31
31
|
if (this.options._ddIsKnownTestsEnabled) {
|
|
32
32
|
config.isKnownTestsEnabled = true
|
|
33
33
|
config.isEarlyFlakeDetectionEnabled = this.options._ddIsEfdEnabled
|
|
34
34
|
config.knownTests = this.options._ddKnownTests
|
|
35
35
|
config.earlyFlakeDetectionNumRetries = this.options._ddEfdNumRetries
|
|
36
|
+
config.earlyFlakeDetectionSlowTestRetries = this.options._ddEfdSlowTestRetries ?? {}
|
|
36
37
|
delete this.options._ddIsEfdEnabled
|
|
37
38
|
delete this.options._ddKnownTests
|
|
38
39
|
delete this.options._ddEfdNumRetries
|
|
40
|
+
delete this.options._ddEfdSlowTestRetries
|
|
39
41
|
delete this.options._ddIsKnownTestsEnabled
|
|
40
42
|
}
|
|
41
43
|
if (this.options._ddIsImpactedTestsEnabled) {
|
|
@@ -58,7 +60,7 @@ addHook({
|
|
|
58
60
|
delete this.options._ddIsFlakyTestRetriesEnabled
|
|
59
61
|
delete this.options._ddFlakyTestRetriesCount
|
|
60
62
|
}
|
|
61
|
-
return run.apply(this,
|
|
63
|
+
return run.apply(this, args)
|
|
62
64
|
})
|
|
63
65
|
|
|
64
66
|
return Mocha
|
|
@@ -72,9 +74,9 @@ addHook({
|
|
|
72
74
|
}, function (Runner) {
|
|
73
75
|
shimmer.wrap(Runner.prototype, 'runTests', runTests => getRunTestsWrapper(runTests, config))
|
|
74
76
|
|
|
75
|
-
shimmer.wrap(Runner.prototype, 'run', run => function () {
|
|
77
|
+
shimmer.wrap(Runner.prototype, 'run', run => function (...args) {
|
|
76
78
|
if (!workerFinishCh.hasSubscribers) {
|
|
77
|
-
return run.apply(this,
|
|
79
|
+
return run.apply(this, args)
|
|
78
80
|
}
|
|
79
81
|
// We flush when the worker ends with its test file (a mocha instance in a worker runs a single test file)
|
|
80
82
|
this.once('end', () => {
|
|
@@ -93,7 +95,7 @@ addHook({
|
|
|
93
95
|
|
|
94
96
|
this.on('pending', getOnPendingHandler())
|
|
95
97
|
|
|
96
|
-
return run.apply(this,
|
|
98
|
+
return run.apply(this, args)
|
|
97
99
|
})
|
|
98
100
|
return Runner
|
|
99
101
|
})
|