@depup/dd-trace 5.90.0-depup.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 +6 -0
- package/LICENSE-3rdparty.csv +102 -0
- package/LICENSE.Apache +200 -0
- package/LICENSE.BSD3 +29 -0
- package/README.md +25 -0
- package/changes.json +5 -0
- package/ci/cypress/after-run.js +3 -0
- package/ci/cypress/after-spec.js +3 -0
- package/ci/cypress/plugin.js +13 -0
- package/ci/cypress/polyfills.js +25 -0
- package/ci/cypress/support.js +3 -0
- package/ci/init.js +86 -0
- package/esbuild.js +3 -0
- package/ext/exporters.d.ts +14 -0
- package/ext/exporters.js +13 -0
- package/ext/formats.d.ts +11 -0
- package/ext/formats.js +9 -0
- package/ext/index.d.ts +8 -0
- package/ext/index.js +17 -0
- package/ext/kinds.d.ts +9 -0
- package/ext/kinds.js +9 -0
- package/ext/priority.d.ts +8 -0
- package/ext/priority.js +8 -0
- package/ext/scopes.d.ts +9 -0
- package/ext/scopes.js +9 -0
- package/ext/tags.d.ts +26 -0
- package/ext/tags.js +40 -0
- package/ext/types.d.ts +7 -0
- package/ext/types.js +7 -0
- package/index.d.ts +3811 -0
- package/index.js +3 -0
- package/init.js +7 -0
- package/initialize.mjs +85 -0
- package/loader-hook.mjs +77 -0
- package/package.json +215 -0
- package/packages/datadog-code-origin/index.js +66 -0
- package/packages/datadog-core/index.js +5 -0
- package/packages/datadog-core/src/storage.js +132 -0
- package/packages/datadog-core/src/utils/src/kebabcase.js +14 -0
- package/packages/datadog-core/src/utils/src/parse-tags.js +33 -0
- package/packages/datadog-core/src/utils/src/pick.js +11 -0
- package/packages/datadog-core/src/utils/src/set.js +18 -0
- package/packages/datadog-core/src/utils/src/uniq.js +5 -0
- package/packages/datadog-esbuild/index.js +403 -0
- package/packages/datadog-esbuild/src/log.js +32 -0
- package/packages/datadog-esbuild/src/utils.js +218 -0
- package/packages/datadog-instrumentations/index.js +5 -0
- package/packages/datadog-instrumentations/src/aerospike.js +48 -0
- package/packages/datadog-instrumentations/src/ai.js +119 -0
- package/packages/datadog-instrumentations/src/amqp10.js +73 -0
- package/packages/datadog-instrumentations/src/amqplib.js +146 -0
- package/packages/datadog-instrumentations/src/anthropic.js +127 -0
- package/packages/datadog-instrumentations/src/apollo-server-core.js +40 -0
- package/packages/datadog-instrumentations/src/apollo-server.js +135 -0
- package/packages/datadog-instrumentations/src/apollo.js +101 -0
- package/packages/datadog-instrumentations/src/avsc.js +39 -0
- package/packages/datadog-instrumentations/src/aws-sdk.js +264 -0
- package/packages/datadog-instrumentations/src/azure-durable-functions.js +75 -0
- package/packages/datadog-instrumentations/src/azure-event-hubs.js +38 -0
- package/packages/datadog-instrumentations/src/azure-functions.js +56 -0
- package/packages/datadog-instrumentations/src/azure-service-bus.js +71 -0
- package/packages/datadog-instrumentations/src/bluebird.js +26 -0
- package/packages/datadog-instrumentations/src/body-parser.js +44 -0
- package/packages/datadog-instrumentations/src/bullmq.js +11 -0
- package/packages/datadog-instrumentations/src/bunyan.js +22 -0
- package/packages/datadog-instrumentations/src/cassandra-driver.js +179 -0
- package/packages/datadog-instrumentations/src/child_process.js +246 -0
- package/packages/datadog-instrumentations/src/confluentinc-kafka-javascript.js +421 -0
- package/packages/datadog-instrumentations/src/connect.js +118 -0
- package/packages/datadog-instrumentations/src/cookie-parser.js +36 -0
- package/packages/datadog-instrumentations/src/cookie.js +21 -0
- package/packages/datadog-instrumentations/src/couchbase.js +324 -0
- package/packages/datadog-instrumentations/src/crypto.js +33 -0
- package/packages/datadog-instrumentations/src/cucumber.js +1096 -0
- package/packages/datadog-instrumentations/src/cypress.js +11 -0
- package/packages/datadog-instrumentations/src/dd-trace-api.js +7 -0
- package/packages/datadog-instrumentations/src/dns.js +98 -0
- package/packages/datadog-instrumentations/src/elasticsearch.js +129 -0
- package/packages/datadog-instrumentations/src/express-mongo-sanitize.js +45 -0
- package/packages/datadog-instrumentations/src/express-session.js +41 -0
- package/packages/datadog-instrumentations/src/express.js +253 -0
- package/packages/datadog-instrumentations/src/fastify.js +300 -0
- package/packages/datadog-instrumentations/src/fetch.js +33 -0
- package/packages/datadog-instrumentations/src/find-my-way.js +31 -0
- package/packages/datadog-instrumentations/src/fs.js +372 -0
- package/packages/datadog-instrumentations/src/generic-pool.js +48 -0
- package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +287 -0
- package/packages/datadog-instrumentations/src/google-cloud-vertexai.js +101 -0
- package/packages/datadog-instrumentations/src/google-genai.js +120 -0
- package/packages/datadog-instrumentations/src/graphql.js +382 -0
- package/packages/datadog-instrumentations/src/grpc/client.js +258 -0
- package/packages/datadog-instrumentations/src/grpc/server.js +154 -0
- package/packages/datadog-instrumentations/src/grpc/types.js +10 -0
- package/packages/datadog-instrumentations/src/grpc.js +4 -0
- package/packages/datadog-instrumentations/src/handlebars.js +40 -0
- package/packages/datadog-instrumentations/src/hapi.js +178 -0
- package/packages/datadog-instrumentations/src/helpers/bundler-register.js +68 -0
- package/packages/datadog-instrumentations/src/helpers/check-require-cache.js +103 -0
- package/packages/datadog-instrumentations/src/helpers/extract-package-and-module-path.js +42 -0
- package/packages/datadog-instrumentations/src/helpers/fetch.js +26 -0
- package/packages/datadog-instrumentations/src/helpers/hook.js +75 -0
- package/packages/datadog-instrumentations/src/helpers/hooks.js +151 -0
- package/packages/datadog-instrumentations/src/helpers/instrument.js +57 -0
- package/packages/datadog-instrumentations/src/helpers/instrumentations.js +8 -0
- package/packages/datadog-instrumentations/src/helpers/promise.js +29 -0
- package/packages/datadog-instrumentations/src/helpers/register.js +242 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +70 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/ai.js +103 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/bullmq.js +108 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +7 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/langchain.js +237 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/loader.js +9 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/loader.mjs +11 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/orchestrion/compiler.js +74 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/orchestrion/index.js +43 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/orchestrion/matcher.js +49 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/orchestrion/transformer.js +121 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/orchestrion/transforms.js +322 -0
- package/packages/datadog-instrumentations/src/helpers/router-helper.js +238 -0
- package/packages/datadog-instrumentations/src/helpers/shared-utils.js +9 -0
- package/packages/datadog-instrumentations/src/hono.js +150 -0
- package/packages/datadog-instrumentations/src/http/client.js +315 -0
- package/packages/datadog-instrumentations/src/http/server.js +223 -0
- package/packages/datadog-instrumentations/src/http.js +4 -0
- package/packages/datadog-instrumentations/src/http2/client.js +76 -0
- package/packages/datadog-instrumentations/src/http2/server.js +64 -0
- package/packages/datadog-instrumentations/src/http2.js +4 -0
- package/packages/datadog-instrumentations/src/ioredis.js +57 -0
- package/packages/datadog-instrumentations/src/iovalkey.js +47 -0
- package/packages/datadog-instrumentations/src/jest.js +1895 -0
- package/packages/datadog-instrumentations/src/kafkajs.js +266 -0
- package/packages/datadog-instrumentations/src/knex.js +86 -0
- package/packages/datadog-instrumentations/src/koa.js +173 -0
- package/packages/datadog-instrumentations/src/langchain.js +7 -0
- package/packages/datadog-instrumentations/src/ldapjs.js +101 -0
- package/packages/datadog-instrumentations/src/light-my-request.js +93 -0
- package/packages/datadog-instrumentations/src/limitd-client.js +22 -0
- package/packages/datadog-instrumentations/src/lodash.js +30 -0
- package/packages/datadog-instrumentations/src/mariadb.js +186 -0
- package/packages/datadog-instrumentations/src/memcached.js +45 -0
- package/packages/datadog-instrumentations/src/microgateway-core.js +69 -0
- package/packages/datadog-instrumentations/src/mocha/common.js +50 -0
- package/packages/datadog-instrumentations/src/mocha/main.js +753 -0
- package/packages/datadog-instrumentations/src/mocha/utils.js +526 -0
- package/packages/datadog-instrumentations/src/mocha/worker.js +104 -0
- package/packages/datadog-instrumentations/src/mocha.js +13 -0
- package/packages/datadog-instrumentations/src/moleculer/client.js +44 -0
- package/packages/datadog-instrumentations/src/moleculer/server.js +58 -0
- package/packages/datadog-instrumentations/src/moleculer.js +4 -0
- package/packages/datadog-instrumentations/src/mongodb-core.js +213 -0
- package/packages/datadog-instrumentations/src/mongodb.js +59 -0
- package/packages/datadog-instrumentations/src/mongoose.js +179 -0
- package/packages/datadog-instrumentations/src/mquery.js +65 -0
- package/packages/datadog-instrumentations/src/multer.js +37 -0
- package/packages/datadog-instrumentations/src/mysql.js +105 -0
- package/packages/datadog-instrumentations/src/mysql2.js +380 -0
- package/packages/datadog-instrumentations/src/net.js +143 -0
- package/packages/datadog-instrumentations/src/next.js +320 -0
- package/packages/datadog-instrumentations/src/node-serialize.js +22 -0
- package/packages/datadog-instrumentations/src/nyc.js +59 -0
- package/packages/datadog-instrumentations/src/openai.js +326 -0
- package/packages/datadog-instrumentations/src/opensearch.js +11 -0
- package/packages/datadog-instrumentations/src/oracledb.js +162 -0
- package/packages/datadog-instrumentations/src/orchestrion-config/index.js +86 -0
- package/packages/datadog-instrumentations/src/otel-sdk-trace.js +24 -0
- package/packages/datadog-instrumentations/src/passport-http.js +10 -0
- package/packages/datadog-instrumentations/src/passport-local.js +10 -0
- package/packages/datadog-instrumentations/src/passport-utils.js +61 -0
- package/packages/datadog-instrumentations/src/passport.js +45 -0
- package/packages/datadog-instrumentations/src/pg.js +201 -0
- package/packages/datadog-instrumentations/src/pino.js +117 -0
- package/packages/datadog-instrumentations/src/playwright.js +1383 -0
- package/packages/datadog-instrumentations/src/prisma.js +272 -0
- package/packages/datadog-instrumentations/src/process.js +29 -0
- package/packages/datadog-instrumentations/src/promise-js.js +15 -0
- package/packages/datadog-instrumentations/src/promise.js +14 -0
- package/packages/datadog-instrumentations/src/protobufjs.js +128 -0
- package/packages/datadog-instrumentations/src/pug.js +23 -0
- package/packages/datadog-instrumentations/src/q.js +21 -0
- package/packages/datadog-instrumentations/src/redis.js +161 -0
- package/packages/datadog-instrumentations/src/restify.js +89 -0
- package/packages/datadog-instrumentations/src/rhea.js +237 -0
- package/packages/datadog-instrumentations/src/router.js +326 -0
- package/packages/datadog-instrumentations/src/selenium.js +80 -0
- package/packages/datadog-instrumentations/src/sequelize.js +45 -0
- package/packages/datadog-instrumentations/src/sharedb.js +72 -0
- package/packages/datadog-instrumentations/src/stripe.js +92 -0
- package/packages/datadog-instrumentations/src/tedious.js +63 -0
- package/packages/datadog-instrumentations/src/undici.js +29 -0
- package/packages/datadog-instrumentations/src/url.js +80 -0
- package/packages/datadog-instrumentations/src/vitest.js +1116 -0
- package/packages/datadog-instrumentations/src/vm.js +49 -0
- package/packages/datadog-instrumentations/src/when.js +14 -0
- package/packages/datadog-instrumentations/src/winston.js +78 -0
- package/packages/datadog-instrumentations/src/ws.js +264 -0
- package/packages/datadog-plugin-aerospike/src/index.js +113 -0
- package/packages/datadog-plugin-ai/src/index.js +17 -0
- package/packages/datadog-plugin-ai/src/tracing.js +33 -0
- package/packages/datadog-plugin-ai/src/utils.js +28 -0
- package/packages/datadog-plugin-amqp10/src/consumer.js +34 -0
- package/packages/datadog-plugin-amqp10/src/index.js +17 -0
- package/packages/datadog-plugin-amqp10/src/producer.js +37 -0
- package/packages/datadog-plugin-amqp10/src/util.js +15 -0
- package/packages/datadog-plugin-amqplib/src/client.js +44 -0
- package/packages/datadog-plugin-amqplib/src/consumer.js +57 -0
- package/packages/datadog-plugin-amqplib/src/index.js +20 -0
- package/packages/datadog-plugin-amqplib/src/producer.js +63 -0
- package/packages/datadog-plugin-amqplib/src/util.js +14 -0
- package/packages/datadog-plugin-anthropic/src/index.js +17 -0
- package/packages/datadog-plugin-anthropic/src/tracing.js +30 -0
- package/packages/datadog-plugin-apollo/src/gateway/execute.js +18 -0
- package/packages/datadog-plugin-apollo/src/gateway/fetch.js +39 -0
- package/packages/datadog-plugin-apollo/src/gateway/index.js +36 -0
- package/packages/datadog-plugin-apollo/src/gateway/plan.js +18 -0
- package/packages/datadog-plugin-apollo/src/gateway/postprocessing.js +15 -0
- package/packages/datadog-plugin-apollo/src/gateway/request.js +122 -0
- package/packages/datadog-plugin-apollo/src/gateway/validate.js +23 -0
- package/packages/datadog-plugin-apollo/src/index.js +43 -0
- package/packages/datadog-plugin-avsc/src/index.js +11 -0
- package/packages/datadog-plugin-avsc/src/schema_iterator.js +176 -0
- package/packages/datadog-plugin-aws-sdk/src/base.js +335 -0
- package/packages/datadog-plugin-aws-sdk/src/index.js +26 -0
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/index.js +16 -0
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/tracing.js +31 -0
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +487 -0
- package/packages/datadog-plugin-aws-sdk/src/services/cloudwatchlogs.js +19 -0
- package/packages/datadog-plugin-aws-sdk/src/services/default.js +7 -0
- package/packages/datadog-plugin-aws-sdk/src/services/dynamodb.js +197 -0
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +53 -0
- package/packages/datadog-plugin-aws-sdk/src/services/index.js +16 -0
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +214 -0
- package/packages/datadog-plugin-aws-sdk/src/services/lambda.js +67 -0
- package/packages/datadog-plugin-aws-sdk/src/services/redshift.js +19 -0
- package/packages/datadog-plugin-aws-sdk/src/services/s3.js +55 -0
- package/packages/datadog-plugin-aws-sdk/src/services/sfn.js +7 -0
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +125 -0
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +298 -0
- package/packages/datadog-plugin-aws-sdk/src/services/states.js +7 -0
- package/packages/datadog-plugin-aws-sdk/src/services/stepfunctions.js +64 -0
- package/packages/datadog-plugin-aws-sdk/src/util.js +151 -0
- package/packages/datadog-plugin-azure-durable-functions/src/index.js +49 -0
- package/packages/datadog-plugin-azure-event-hubs/src/index.js +15 -0
- package/packages/datadog-plugin-azure-event-hubs/src/producer.js +96 -0
- package/packages/datadog-plugin-azure-functions/src/index.js +171 -0
- package/packages/datadog-plugin-azure-service-bus/src/index.js +15 -0
- package/packages/datadog-plugin-azure-service-bus/src/producer.js +97 -0
- package/packages/datadog-plugin-bullmq/src/consumer.js +82 -0
- package/packages/datadog-plugin-bullmq/src/index.js +18 -0
- package/packages/datadog-plugin-bullmq/src/producer.js +207 -0
- package/packages/datadog-plugin-bunyan/src/index.js +8 -0
- package/packages/datadog-plugin-cassandra-driver/src/index.js +47 -0
- package/packages/datadog-plugin-child_process/src/index.js +111 -0
- package/packages/datadog-plugin-child_process/src/scrub-cmd-params.js +127 -0
- package/packages/datadog-plugin-confluentinc-kafka-javascript/src/batch-consumer.js +9 -0
- package/packages/datadog-plugin-confluentinc-kafka-javascript/src/consumer.js +9 -0
- package/packages/datadog-plugin-confluentinc-kafka-javascript/src/index.js +25 -0
- package/packages/datadog-plugin-confluentinc-kafka-javascript/src/producer.js +9 -0
- package/packages/datadog-plugin-connect/src/index.js +17 -0
- package/packages/datadog-plugin-couchbase/src/index.js +94 -0
- package/packages/datadog-plugin-cucumber/src/index.js +461 -0
- package/packages/datadog-plugin-cypress/src/after-run.js +5 -0
- package/packages/datadog-plugin-cypress/src/after-spec.js +5 -0
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +1089 -0
- package/packages/datadog-plugin-cypress/src/index.js +11 -0
- package/packages/datadog-plugin-cypress/src/plugin.js +57 -0
- package/packages/datadog-plugin-cypress/src/source-map-utils.js +297 -0
- package/packages/datadog-plugin-cypress/src/support.js +303 -0
- package/packages/datadog-plugin-dd-trace-api/src/index.js +117 -0
- package/packages/datadog-plugin-dns/src/index.js +23 -0
- package/packages/datadog-plugin-dns/src/lookup.js +45 -0
- package/packages/datadog-plugin-dns/src/lookup_service.js +28 -0
- package/packages/datadog-plugin-dns/src/resolve.js +27 -0
- package/packages/datadog-plugin-dns/src/reverse.js +25 -0
- package/packages/datadog-plugin-elasticsearch/src/index.js +49 -0
- package/packages/datadog-plugin-express/src/code_origin.js +47 -0
- package/packages/datadog-plugin-express/src/index.js +17 -0
- package/packages/datadog-plugin-express/src/tracing.js +17 -0
- package/packages/datadog-plugin-fastify/src/code_origin.js +41 -0
- package/packages/datadog-plugin-fastify/src/index.js +17 -0
- package/packages/datadog-plugin-fastify/src/tracing.js +34 -0
- package/packages/datadog-plugin-fetch/src/index.js +40 -0
- package/packages/datadog-plugin-find-my-way/src/index.js +18 -0
- package/packages/datadog-plugin-fs/src/index.js +52 -0
- package/packages/datadog-plugin-google-cloud-pubsub/src/client.js +39 -0
- package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +212 -0
- package/packages/datadog-plugin-google-cloud-pubsub/src/index.js +19 -0
- package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +191 -0
- package/packages/datadog-plugin-google-cloud-pubsub/src/pubsub-push-subscription.js +217 -0
- package/packages/datadog-plugin-google-cloud-vertexai/src/index.js +17 -0
- package/packages/datadog-plugin-google-cloud-vertexai/src/tracing.js +49 -0
- package/packages/datadog-plugin-google-cloud-vertexai/src/utils.js +21 -0
- package/packages/datadog-plugin-google-genai/src/index.js +17 -0
- package/packages/datadog-plugin-google-genai/src/tracing.js +41 -0
- package/packages/datadog-plugin-graphql/src/execute.js +88 -0
- package/packages/datadog-plugin-graphql/src/index.js +72 -0
- package/packages/datadog-plugin-graphql/src/parse.js +35 -0
- package/packages/datadog-plugin-graphql/src/resolve.js +191 -0
- package/packages/datadog-plugin-graphql/src/tools/index.js +6 -0
- package/packages/datadog-plugin-graphql/src/tools/signature.js +9 -0
- package/packages/datadog-plugin-graphql/src/tools/transforms.js +108 -0
- package/packages/datadog-plugin-graphql/src/utils.js +49 -0
- package/packages/datadog-plugin-graphql/src/validate.js +40 -0
- package/packages/datadog-plugin-grpc/src/client.js +129 -0
- package/packages/datadog-plugin-grpc/src/index.js +17 -0
- package/packages/datadog-plugin-grpc/src/server.js +112 -0
- package/packages/datadog-plugin-grpc/src/util.js +66 -0
- package/packages/datadog-plugin-hapi/src/index.js +39 -0
- package/packages/datadog-plugin-hono/src/index.js +26 -0
- package/packages/datadog-plugin-http/src/client.js +244 -0
- package/packages/datadog-plugin-http/src/index.js +37 -0
- package/packages/datadog-plugin-http/src/server.js +92 -0
- package/packages/datadog-plugin-http2/src/client.js +217 -0
- package/packages/datadog-plugin-http2/src/index.js +17 -0
- package/packages/datadog-plugin-http2/src/server.js +73 -0
- package/packages/datadog-plugin-ioredis/src/index.js +9 -0
- package/packages/datadog-plugin-iovalkey/src/index.js +16 -0
- package/packages/datadog-plugin-jest/src/index.js +558 -0
- package/packages/datadog-plugin-jest/src/util.js +176 -0
- package/packages/datadog-plugin-kafkajs/src/batch-consumer.js +28 -0
- package/packages/datadog-plugin-kafkajs/src/consumer.js +128 -0
- package/packages/datadog-plugin-kafkajs/src/index.js +19 -0
- package/packages/datadog-plugin-kafkajs/src/producer.js +129 -0
- package/packages/datadog-plugin-kafkajs/src/utils.js +27 -0
- package/packages/datadog-plugin-koa/src/index.js +22 -0
- package/packages/datadog-plugin-langchain/src/handlers/default.js +11 -0
- package/packages/datadog-plugin-langchain/src/handlers/embedding.js +18 -0
- package/packages/datadog-plugin-langchain/src/handlers/language_models.js +18 -0
- package/packages/datadog-plugin-langchain/src/index.js +26 -0
- package/packages/datadog-plugin-langchain/src/tokens.js +35 -0
- package/packages/datadog-plugin-langchain/src/tracing.js +155 -0
- package/packages/datadog-plugin-mariadb/src/index.js +21 -0
- package/packages/datadog-plugin-memcached/src/index.js +54 -0
- package/packages/datadog-plugin-microgateway-core/src/index.js +26 -0
- package/packages/datadog-plugin-mocha/src/index.js +480 -0
- package/packages/datadog-plugin-moleculer/src/client.js +42 -0
- package/packages/datadog-plugin-moleculer/src/index.js +19 -0
- package/packages/datadog-plugin-moleculer/src/server.js +30 -0
- package/packages/datadog-plugin-moleculer/src/util.js +21 -0
- package/packages/datadog-plugin-mongodb-core/src/index.js +215 -0
- package/packages/datadog-plugin-mongoose/src/index.js +20 -0
- package/packages/datadog-plugin-mysql/src/index.js +42 -0
- package/packages/datadog-plugin-mysql2/src/index.js +25 -0
- package/packages/datadog-plugin-net/src/index.js +23 -0
- package/packages/datadog-plugin-net/src/ipc.js +23 -0
- package/packages/datadog-plugin-net/src/tcp.js +53 -0
- package/packages/datadog-plugin-next/src/index.js +155 -0
- package/packages/datadog-plugin-nyc/src/index.js +95 -0
- package/packages/datadog-plugin-openai/src/index.js +17 -0
- package/packages/datadog-plugin-openai/src/services.js +48 -0
- package/packages/datadog-plugin-openai/src/stream-helpers.js +159 -0
- package/packages/datadog-plugin-openai/src/token-estimator.js +20 -0
- package/packages/datadog-plugin-openai/src/tracing.js +723 -0
- package/packages/datadog-plugin-opensearch/src/index.js +9 -0
- package/packages/datadog-plugin-oracledb/src/connection-parser.js +37 -0
- package/packages/datadog-plugin-oracledb/src/index.js +44 -0
- package/packages/datadog-plugin-pg/src/index.js +41 -0
- package/packages/datadog-plugin-pino/src/index.js +9 -0
- package/packages/datadog-plugin-playwright/src/index.js +497 -0
- package/packages/datadog-plugin-prisma/src/datadog-tracing-helper.js +118 -0
- package/packages/datadog-plugin-prisma/src/index.js +144 -0
- package/packages/datadog-plugin-protobufjs/src/index.js +12 -0
- package/packages/datadog-plugin-protobufjs/src/schema_iterator.js +181 -0
- package/packages/datadog-plugin-redis/src/index.js +95 -0
- package/packages/datadog-plugin-restify/src/index.js +29 -0
- package/packages/datadog-plugin-rhea/src/consumer.js +68 -0
- package/packages/datadog-plugin-rhea/src/index.js +17 -0
- package/packages/datadog-plugin-rhea/src/producer.js +54 -0
- package/packages/datadog-plugin-router/src/index.js +170 -0
- package/packages/datadog-plugin-selenium/src/index.js +66 -0
- package/packages/datadog-plugin-sharedb/src/index.js +68 -0
- package/packages/datadog-plugin-tedious/src/index.js +36 -0
- package/packages/datadog-plugin-undici/src/index.js +313 -0
- package/packages/datadog-plugin-vitest/src/index.js +444 -0
- package/packages/datadog-plugin-web/src/index.js +18 -0
- package/packages/datadog-plugin-winston/src/index.js +8 -0
- package/packages/datadog-plugin-ws/src/close.js +121 -0
- package/packages/datadog-plugin-ws/src/index.js +30 -0
- package/packages/datadog-plugin-ws/src/producer.js +99 -0
- package/packages/datadog-plugin-ws/src/receiver.js +110 -0
- package/packages/datadog-plugin-ws/src/server.js +106 -0
- package/packages/datadog-plugin-ws/src/util.js +139 -0
- package/packages/datadog-shimmer/index.js +3 -0
- package/packages/datadog-shimmer/src/shimmer.js +279 -0
- package/packages/dd-trace/index.js +36 -0
- package/packages/dd-trace/src/agent/info.js +57 -0
- package/packages/dd-trace/src/agent/url.js +28 -0
- package/packages/dd-trace/src/aiguard/client.js +25 -0
- package/packages/dd-trace/src/aiguard/noop.js +9 -0
- package/packages/dd-trace/src/aiguard/sdk.js +223 -0
- package/packages/dd-trace/src/aiguard/tags.js +14 -0
- package/packages/dd-trace/src/analytics_sampler.js +15 -0
- package/packages/dd-trace/src/appsec/activation.js +29 -0
- package/packages/dd-trace/src/appsec/addresses.js +51 -0
- package/packages/dd-trace/src/appsec/api_security_sampler.js +117 -0
- package/packages/dd-trace/src/appsec/blocked_templates.js +14 -0
- package/packages/dd-trace/src/appsec/blocking.js +196 -0
- package/packages/dd-trace/src/appsec/channels.js +50 -0
- package/packages/dd-trace/src/appsec/downstream_requests.js +302 -0
- package/packages/dd-trace/src/appsec/graphql.js +166 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +24 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/code-injection-analyzer.js +36 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/command-injection-analyzer.js +15 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/cookie-analyzer.js +62 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-base-analyzer.js +72 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-password-analyzer.js +18 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-password-rules.js +11 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-rule-type.js +6 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secret-analyzer.js +15 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secret-rules.js +741 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/hsts-header-missing-analyzer.js +44 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/index.js +23 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/injection-analyzer.js +42 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/insecure-cookie-analyzer.js +12 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/ldap-injection-analyzer.js +22 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/missing-header-analyzer.js +82 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/no-httponly-cookie-analyzer.js +12 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/no-samesite-cookie-analyzer.js +12 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/nosql-injection-mongodb-analyzer.js +192 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/path-traversal-analyzer.js +108 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/set-cookies-header-interceptor.js +58 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/sql-injection-analyzer.js +102 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/ssrf-analyzer.js +37 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/stored-injection-analyzer.js +11 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/template-injection-analyzer.js +18 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/untrusted-deserialization-analyzer.js +16 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/unvalidated-redirect-analyzer.js +64 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/vulnerability-analyzer.js +181 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/weak-cipher-analyzer.js +31 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/weak-hash-analyzer.js +64 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/weak-randomness-analyzer.js +19 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/xcontenttype-header-missing-analyzer.js +19 -0
- package/packages/dd-trace/src/appsec/iast/context/context-plugin.js +89 -0
- package/packages/dd-trace/src/appsec/iast/context/kafka-ctx-plugin.js +14 -0
- package/packages/dd-trace/src/appsec/iast/iast-context.js +75 -0
- package/packages/dd-trace/src/appsec/iast/iast-plugin.js +230 -0
- package/packages/dd-trace/src/appsec/iast/index.js +126 -0
- package/packages/dd-trace/src/appsec/iast/overhead-controller.js +209 -0
- package/packages/dd-trace/src/appsec/iast/path-line.js +116 -0
- package/packages/dd-trace/src/appsec/iast/security-controls/index.js +179 -0
- package/packages/dd-trace/src/appsec/iast/security-controls/parser.js +128 -0
- package/packages/dd-trace/src/appsec/iast/tags.js +7 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/constants.js +6 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/csi-methods.js +24 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/filter.js +16 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/index.js +36 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/operations-taint-object.js +88 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/operations.js +108 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +293 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugins/kafka.js +46 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter-esm.mjs +76 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter-telemetry.js +13 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +266 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/secure-marks-generator.js +13 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/secure-marks.js +30 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/source-types.js +15 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +258 -0
- package/packages/dd-trace/src/appsec/iast/telemetry/iast-metric.js +113 -0
- package/packages/dd-trace/src/appsec/iast/telemetry/index.js +41 -0
- package/packages/dd-trace/src/appsec/iast/telemetry/namespaces.js +112 -0
- package/packages/dd-trace/src/appsec/iast/telemetry/span-tags.js +54 -0
- package/packages/dd-trace/src/appsec/iast/telemetry/verbosity.js +41 -0
- package/packages/dd-trace/src/appsec/iast/utils.js +24 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/constants.js +7 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/range-utils.js +36 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/command-sensitive-analyzer.js +22 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/hardcoded-password-analyzer.js +13 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/json-sensitive-analyzer.js +12 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/ldap-sensitive-analyzer.js +28 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/sql-sensitive-analyzer.js +112 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/tainted-range-based-sensitive-analyzer.js +25 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/url-sensitive-analyzer.js +40 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +294 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/index.js +126 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +168 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities.js +24 -0
- package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +169 -0
- package/packages/dd-trace/src/appsec/index.js +560 -0
- package/packages/dd-trace/src/appsec/rasp/command_injection.js +56 -0
- package/packages/dd-trace/src/appsec/rasp/fs-plugin.js +103 -0
- package/packages/dd-trace/src/appsec/rasp/index.js +140 -0
- package/packages/dd-trace/src/appsec/rasp/lfi.js +129 -0
- package/packages/dd-trace/src/appsec/rasp/sql_injection.js +108 -0
- package/packages/dd-trace/src/appsec/rasp/ssrf.js +102 -0
- package/packages/dd-trace/src/appsec/rasp/utils.js +85 -0
- package/packages/dd-trace/src/appsec/rc-products.js +10 -0
- package/packages/dd-trace/src/appsec/recommended.json +10731 -0
- package/packages/dd-trace/src/appsec/remote_config.js +177 -0
- package/packages/dd-trace/src/appsec/reporter.js +599 -0
- package/packages/dd-trace/src/appsec/rule_manager.js +168 -0
- package/packages/dd-trace/src/appsec/sdk/index.js +63 -0
- package/packages/dd-trace/src/appsec/sdk/noop.js +27 -0
- package/packages/dd-trace/src/appsec/sdk/set_user.js +44 -0
- package/packages/dd-trace/src/appsec/sdk/track_event.js +230 -0
- package/packages/dd-trace/src/appsec/sdk/user_blocking.js +60 -0
- package/packages/dd-trace/src/appsec/sdk/utils.js +29 -0
- package/packages/dd-trace/src/appsec/stack_trace.js +117 -0
- package/packages/dd-trace/src/appsec/telemetry/common.js +28 -0
- package/packages/dd-trace/src/appsec/telemetry/index.js +184 -0
- package/packages/dd-trace/src/appsec/telemetry/rasp.js +103 -0
- package/packages/dd-trace/src/appsec/telemetry/user.js +32 -0
- package/packages/dd-trace/src/appsec/telemetry/waf.js +143 -0
- package/packages/dd-trace/src/appsec/user_tracking.js +190 -0
- package/packages/dd-trace/src/appsec/waf/diagnostics.js +15 -0
- package/packages/dd-trace/src/appsec/waf/index.js +149 -0
- package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +188 -0
- package/packages/dd-trace/src/appsec/waf/waf_manager.js +98 -0
- package/packages/dd-trace/src/azure_metadata.js +137 -0
- package/packages/dd-trace/src/baggage.js +72 -0
- package/packages/dd-trace/src/ci-visibility/coverage-report-discovery.js +82 -0
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +159 -0
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +156 -0
- package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +111 -0
- package/packages/dd-trace/src/ci-visibility/encode/json-encoder.js +27 -0
- package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +104 -0
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +78 -0
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +56 -0
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/index.js +52 -0
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +83 -0
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +420 -0
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +317 -0
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +114 -0
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/writer.js +76 -0
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +120 -0
- package/packages/dd-trace/src/ci-visibility/log-submission/log-submission-plugin.js +54 -0
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +156 -0
- package/packages/dd-trace/src/ci-visibility/requests/request.js +236 -0
- package/packages/dd-trace/src/ci-visibility/requests/upload-coverage-report.js +107 -0
- package/packages/dd-trace/src/ci-visibility/telemetry.js +204 -0
- package/packages/dd-trace/src/ci-visibility/test-api-manual/test-api-manual-plugin.js +63 -0
- package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +121 -0
- package/packages/dd-trace/src/ci-visibility/test-optimization-cache.js +61 -0
- package/packages/dd-trace/src/config/defaults.js +174 -0
- package/packages/dd-trace/src/config/git_properties.js +120 -0
- package/packages/dd-trace/src/config/helper.js +214 -0
- package/packages/dd-trace/src/config/index.js +1676 -0
- package/packages/dd-trace/src/config/remote_config.js +203 -0
- package/packages/dd-trace/src/config/stable.js +93 -0
- package/packages/dd-trace/src/config/supported-configurations.json +4136 -0
- package/packages/dd-trace/src/constants.js +61 -0
- package/packages/dd-trace/src/crashtracking/crashtracker.js +120 -0
- package/packages/dd-trace/src/crashtracking/index.js +15 -0
- package/packages/dd-trace/src/crashtracking/noop.js +11 -0
- package/packages/dd-trace/src/datastreams/checkpointer.js +80 -0
- package/packages/dd-trace/src/datastreams/context.js +20 -0
- package/packages/dd-trace/src/datastreams/encoding.js +99 -0
- package/packages/dd-trace/src/datastreams/fnv.js +25 -0
- package/packages/dd-trace/src/datastreams/index.js +129 -0
- package/packages/dd-trace/src/datastreams/manager.js +36 -0
- package/packages/dd-trace/src/datastreams/pathway.js +187 -0
- package/packages/dd-trace/src/datastreams/processor.js +494 -0
- package/packages/dd-trace/src/datastreams/schemas/schema.js +10 -0
- package/packages/dd-trace/src/datastreams/schemas/schema_builder.js +140 -0
- package/packages/dd-trace/src/datastreams/schemas/schema_sampler.js +27 -0
- package/packages/dd-trace/src/datastreams/size.js +53 -0
- package/packages/dd-trace/src/datastreams/writer.js +70 -0
- package/packages/dd-trace/src/debugger/config.js +18 -0
- package/packages/dd-trace/src/debugger/constants.js +7 -0
- package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +320 -0
- package/packages/dd-trace/src/debugger/devtools_client/condition.js +294 -0
- package/packages/dd-trace/src/debugger/devtools_client/config.js +23 -0
- package/packages/dd-trace/src/debugger/devtools_client/defaults.js +7 -0
- package/packages/dd-trace/src/debugger/devtools_client/index.js +336 -0
- package/packages/dd-trace/src/debugger/devtools_client/inspector_promises_polyfill.js +27 -0
- package/packages/dd-trace/src/debugger/devtools_client/json-buffer.js +41 -0
- package/packages/dd-trace/src/debugger/devtools_client/log.js +30 -0
- package/packages/dd-trace/src/debugger/devtools_client/remote_config.js +106 -0
- package/packages/dd-trace/src/debugger/devtools_client/send.js +138 -0
- package/packages/dd-trace/src/debugger/devtools_client/session.js +17 -0
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +336 -0
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/constants.js +25 -0
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +215 -0
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +349 -0
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/redaction.js +112 -0
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/symbols.js +8 -0
- package/packages/dd-trace/src/debugger/devtools_client/snapshot-pruner.js +404 -0
- package/packages/dd-trace/src/debugger/devtools_client/source-maps.js +72 -0
- package/packages/dd-trace/src/debugger/devtools_client/state.js +238 -0
- package/packages/dd-trace/src/debugger/devtools_client/status.js +123 -0
- package/packages/dd-trace/src/debugger/index.js +259 -0
- package/packages/dd-trace/src/dogstatsd.js +412 -0
- package/packages/dd-trace/src/encode/0.4.js +425 -0
- package/packages/dd-trace/src/encode/0.5.js +77 -0
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +361 -0
- package/packages/dd-trace/src/encode/agentless-json.js +200 -0
- package/packages/dd-trace/src/encode/coverage-ci-visibility.js +131 -0
- package/packages/dd-trace/src/encode/span-stats.js +136 -0
- package/packages/dd-trace/src/encode/tags-processors.js +91 -0
- package/packages/dd-trace/src/exporter.js +32 -0
- package/packages/dd-trace/src/exporters/agent/index.js +65 -0
- package/packages/dd-trace/src/exporters/agent/writer.js +110 -0
- package/packages/dd-trace/src/exporters/agentless/index.js +132 -0
- package/packages/dd-trace/src/exporters/agentless/writer.js +201 -0
- package/packages/dd-trace/src/exporters/common/agents.js +42 -0
- package/packages/dd-trace/src/exporters/common/buffering-exporter.js +62 -0
- package/packages/dd-trace/src/exporters/common/docker.js +52 -0
- package/packages/dd-trace/src/exporters/common/form-data.js +59 -0
- package/packages/dd-trace/src/exporters/common/request.js +190 -0
- package/packages/dd-trace/src/exporters/common/url-to-http-options-polyfill.js +31 -0
- package/packages/dd-trace/src/exporters/common/util.js +13 -0
- package/packages/dd-trace/src/exporters/common/writer.js +49 -0
- package/packages/dd-trace/src/exporters/log/index.js +52 -0
- package/packages/dd-trace/src/exporters/span-stats/index.js +20 -0
- package/packages/dd-trace/src/exporters/span-stats/writer.js +54 -0
- package/packages/dd-trace/src/external-logger/src/index.js +139 -0
- package/packages/dd-trace/src/flare/file.js +40 -0
- package/packages/dd-trace/src/flare/index.js +101 -0
- package/packages/dd-trace/src/git_metadata_tagger.js +19 -0
- package/packages/dd-trace/src/guardrails/index.js +76 -0
- package/packages/dd-trace/src/guardrails/log.js +32 -0
- package/packages/dd-trace/src/guardrails/telemetry.js +92 -0
- package/packages/dd-trace/src/guardrails/util.js +8 -0
- package/packages/dd-trace/src/heap_snapshots.js +58 -0
- package/packages/dd-trace/src/histogram.js +35 -0
- package/packages/dd-trace/src/id.js +247 -0
- package/packages/dd-trace/src/iitm.js +15 -0
- package/packages/dd-trace/src/index.js +15 -0
- package/packages/dd-trace/src/lambda/context.js +27 -0
- package/packages/dd-trace/src/lambda/handler.js +87 -0
- package/packages/dd-trace/src/lambda/index.js +17 -0
- package/packages/dd-trace/src/lambda/runtime/errors.js +20 -0
- package/packages/dd-trace/src/lambda/runtime/patch.js +77 -0
- package/packages/dd-trace/src/lambda/runtime/ritm.js +133 -0
- package/packages/dd-trace/src/llmobs/constants/tags.js +55 -0
- package/packages/dd-trace/src/llmobs/constants/text.js +6 -0
- package/packages/dd-trace/src/llmobs/constants/writers.js +17 -0
- package/packages/dd-trace/src/llmobs/index.js +149 -0
- package/packages/dd-trace/src/llmobs/noop.js +88 -0
- package/packages/dd-trace/src/llmobs/plugins/ai/index.js +399 -0
- package/packages/dd-trace/src/llmobs/plugins/ai/util.js +218 -0
- package/packages/dd-trace/src/llmobs/plugins/anthropic.js +288 -0
- package/packages/dd-trace/src/llmobs/plugins/base.js +96 -0
- package/packages/dd-trace/src/llmobs/plugins/bedrockruntime.js +137 -0
- package/packages/dd-trace/src/llmobs/plugins/genai/index.js +104 -0
- package/packages/dd-trace/src/llmobs/plugins/genai/util.js +486 -0
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chain.js +20 -0
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chat_model.js +111 -0
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/embedding.js +42 -0
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/index.js +106 -0
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/llm.js +32 -0
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/tool.js +15 -0
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/vectorstore.js +36 -0
- package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +214 -0
- package/packages/dd-trace/src/llmobs/plugins/openai/constants.js +16 -0
- package/packages/dd-trace/src/llmobs/plugins/openai/index.js +501 -0
- package/packages/dd-trace/src/llmobs/plugins/openai/utils.js +126 -0
- package/packages/dd-trace/src/llmobs/plugins/vertexai.js +195 -0
- package/packages/dd-trace/src/llmobs/sdk.js +578 -0
- package/packages/dd-trace/src/llmobs/span_processor.js +311 -0
- package/packages/dd-trace/src/llmobs/storage.js +6 -0
- package/packages/dd-trace/src/llmobs/tagger.js +648 -0
- package/packages/dd-trace/src/llmobs/telemetry.js +174 -0
- package/packages/dd-trace/src/llmobs/util.js +182 -0
- package/packages/dd-trace/src/llmobs/writers/base.js +242 -0
- package/packages/dd-trace/src/llmobs/writers/evaluations.js +32 -0
- package/packages/dd-trace/src/llmobs/writers/spans.js +69 -0
- package/packages/dd-trace/src/llmobs/writers/util.js +54 -0
- package/packages/dd-trace/src/log/channels.js +78 -0
- package/packages/dd-trace/src/log/index.js +157 -0
- package/packages/dd-trace/src/log/log.js +76 -0
- package/packages/dd-trace/src/log/utils.js +16 -0
- package/packages/dd-trace/src/log/writer.js +72 -0
- package/packages/dd-trace/src/msgpack/chunk.js +69 -0
- package/packages/dd-trace/src/msgpack/encoder.js +308 -0
- package/packages/dd-trace/src/msgpack/index.js +6 -0
- package/packages/dd-trace/src/noop/dogstatsd.js +19 -0
- package/packages/dd-trace/src/noop/proxy.js +106 -0
- package/packages/dd-trace/src/noop/scope.js +19 -0
- package/packages/dd-trace/src/noop/span.js +50 -0
- package/packages/dd-trace/src/noop/span_context.js +16 -0
- package/packages/dd-trace/src/noop/tracer.js +47 -0
- package/packages/dd-trace/src/openfeature/constants/constants.js +51 -0
- package/packages/dd-trace/src/openfeature/flagging_provider.js +47 -0
- package/packages/dd-trace/src/openfeature/index.js +77 -0
- package/packages/dd-trace/src/openfeature/noop.js +101 -0
- package/packages/dd-trace/src/openfeature/remote_config.js +31 -0
- package/packages/dd-trace/src/openfeature/writers/base.js +174 -0
- package/packages/dd-trace/src/openfeature/writers/exposures.js +173 -0
- package/packages/dd-trace/src/openfeature/writers/util.js +38 -0
- package/packages/dd-trace/src/opentelemetry/context_manager.js +91 -0
- package/packages/dd-trace/src/opentelemetry/logs/batch_log_processor.js +100 -0
- package/packages/dd-trace/src/opentelemetry/logs/index.js +87 -0
- package/packages/dd-trace/src/opentelemetry/logs/logger.js +83 -0
- package/packages/dd-trace/src/opentelemetry/logs/logger_provider.js +126 -0
- package/packages/dd-trace/src/opentelemetry/logs/otlp_http_log_exporter.js +55 -0
- package/packages/dd-trace/src/opentelemetry/logs/otlp_transformer.js +245 -0
- package/packages/dd-trace/src/opentelemetry/metrics/constants.js +34 -0
- package/packages/dd-trace/src/opentelemetry/metrics/index.js +81 -0
- package/packages/dd-trace/src/opentelemetry/metrics/instruments.js +225 -0
- package/packages/dd-trace/src/opentelemetry/metrics/meter.js +171 -0
- package/packages/dd-trace/src/opentelemetry/metrics/meter_provider.js +54 -0
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_http_metric_exporter.js +62 -0
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_transformer.js +251 -0
- package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +557 -0
- package/packages/dd-trace/src/opentelemetry/otlp/common.proto +116 -0
- package/packages/dd-trace/src/opentelemetry/otlp/logs.proto +226 -0
- package/packages/dd-trace/src/opentelemetry/otlp/logs_service.proto +78 -0
- package/packages/dd-trace/src/opentelemetry/otlp/metrics.proto +720 -0
- package/packages/dd-trace/src/opentelemetry/otlp/metrics_service.proto +78 -0
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_http_exporter_base.js +168 -0
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_transformer_base.js +181 -0
- package/packages/dd-trace/src/opentelemetry/otlp/protobuf_loader.js +66 -0
- package/packages/dd-trace/src/opentelemetry/otlp/resource.proto +45 -0
- package/packages/dd-trace/src/opentelemetry/sampler.js +18 -0
- package/packages/dd-trace/src/opentelemetry/span.js +317 -0
- package/packages/dd-trace/src/opentelemetry/span_context.js +44 -0
- package/packages/dd-trace/src/opentelemetry/span_processor.js +50 -0
- package/packages/dd-trace/src/opentelemetry/tracer.js +226 -0
- package/packages/dd-trace/src/opentelemetry/tracer_provider.js +80 -0
- package/packages/dd-trace/src/opentracing/propagation/binary.js +11 -0
- package/packages/dd-trace/src/opentracing/propagation/http.js +7 -0
- package/packages/dd-trace/src/opentracing/propagation/log.js +54 -0
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +818 -0
- package/packages/dd-trace/src/opentracing/propagation/text_map_dsm.js +47 -0
- package/packages/dd-trace/src/opentracing/propagation/tracestate.js +103 -0
- package/packages/dd-trace/src/opentracing/span.js +412 -0
- package/packages/dd-trace/src/opentracing/span_context.js +75 -0
- package/packages/dd-trace/src/opentracing/tracer.js +145 -0
- package/packages/dd-trace/src/payload-tagging/config/aws.json +106 -0
- package/packages/dd-trace/src/payload-tagging/config/index.js +44 -0
- package/packages/dd-trace/src/payload-tagging/index.js +110 -0
- package/packages/dd-trace/src/payload-tagging/tagging.js +94 -0
- package/packages/dd-trace/src/pkg.js +44 -0
- package/packages/dd-trace/src/plugin_manager.js +219 -0
- package/packages/dd-trace/src/plugins/apollo.js +59 -0
- package/packages/dd-trace/src/plugins/cache.js +16 -0
- package/packages/dd-trace/src/plugins/ci_plugin.js +786 -0
- package/packages/dd-trace/src/plugins/client.js +11 -0
- package/packages/dd-trace/src/plugins/composite.js +29 -0
- package/packages/dd-trace/src/plugins/consumer.js +21 -0
- package/packages/dd-trace/src/plugins/database.js +123 -0
- package/packages/dd-trace/src/plugins/inbound.js +11 -0
- package/packages/dd-trace/src/plugins/index.js +117 -0
- package/packages/dd-trace/src/plugins/log_plugin.js +54 -0
- package/packages/dd-trace/src/plugins/outbound.js +159 -0
- package/packages/dd-trace/src/plugins/plugin.js +195 -0
- package/packages/dd-trace/src/plugins/producer.js +27 -0
- package/packages/dd-trace/src/plugins/schema.js +35 -0
- package/packages/dd-trace/src/plugins/server.js +11 -0
- package/packages/dd-trace/src/plugins/storage.js +23 -0
- package/packages/dd-trace/src/plugins/structured_log_plugin.js +9 -0
- package/packages/dd-trace/src/plugins/tracing.js +222 -0
- package/packages/dd-trace/src/plugins/util/ci.js +843 -0
- package/packages/dd-trace/src/plugins/util/env.js +31 -0
- package/packages/dd-trace/src/plugins/util/git-cache.js +129 -0
- package/packages/dd-trace/src/plugins/util/git.js +613 -0
- package/packages/dd-trace/src/plugins/util/inferred_proxy.js +157 -0
- package/packages/dd-trace/src/plugins/util/ip_extractor.js +139 -0
- package/packages/dd-trace/src/plugins/util/llm.js +54 -0
- package/packages/dd-trace/src/plugins/util/stacktrace.js +244 -0
- package/packages/dd-trace/src/plugins/util/tags.js +81 -0
- package/packages/dd-trace/src/plugins/util/test.js +1202 -0
- package/packages/dd-trace/src/plugins/util/url.js +146 -0
- package/packages/dd-trace/src/plugins/util/urlfilter.js +32 -0
- package/packages/dd-trace/src/plugins/util/user-provided-git.js +91 -0
- package/packages/dd-trace/src/plugins/util/web.js +631 -0
- package/packages/dd-trace/src/priority_sampler.js +374 -0
- package/packages/dd-trace/src/process-tags/index.js +83 -0
- package/packages/dd-trace/src/profiler.js +17 -0
- package/packages/dd-trace/src/profiling/config.js +473 -0
- package/packages/dd-trace/src/profiling/constants.js +15 -0
- package/packages/dd-trace/src/profiling/exporter_cli.js +74 -0
- package/packages/dd-trace/src/profiling/exporters/agent.js +199 -0
- package/packages/dd-trace/src/profiling/exporters/event_serializer.js +91 -0
- package/packages/dd-trace/src/profiling/exporters/file.js +35 -0
- package/packages/dd-trace/src/profiling/index.js +20 -0
- package/packages/dd-trace/src/profiling/libuv-size.js +49 -0
- package/packages/dd-trace/src/profiling/loggers/console.js +41 -0
- package/packages/dd-trace/src/profiling/profiler.js +430 -0
- package/packages/dd-trace/src/profiling/profilers/event_plugins/dns.js +11 -0
- package/packages/dd-trace/src/profiling/profilers/event_plugins/dns_lookup.js +16 -0
- package/packages/dd-trace/src/profiling/profilers/event_plugins/dns_lookupservice.js +16 -0
- package/packages/dd-trace/src/profiling/profilers/event_plugins/dns_resolve.js +24 -0
- package/packages/dd-trace/src/profiling/profilers/event_plugins/dns_reverse.js +16 -0
- package/packages/dd-trace/src/profiling/profilers/event_plugins/event.js +66 -0
- package/packages/dd-trace/src/profiling/profilers/event_plugins/fs.js +45 -0
- package/packages/dd-trace/src/profiling/profilers/event_plugins/net.js +20 -0
- package/packages/dd-trace/src/profiling/profilers/events.js +466 -0
- package/packages/dd-trace/src/profiling/profilers/poisson.js +105 -0
- package/packages/dd-trace/src/profiling/profilers/shared.js +55 -0
- package/packages/dd-trace/src/profiling/profilers/space.js +77 -0
- package/packages/dd-trace/src/profiling/profilers/wall.js +434 -0
- package/packages/dd-trace/src/profiling/ssi-heuristics.js +84 -0
- package/packages/dd-trace/src/profiling/tagger.js +40 -0
- package/packages/dd-trace/src/profiling/webspan-utils.js +25 -0
- package/packages/dd-trace/src/propagation-hash/index.js +145 -0
- package/packages/dd-trace/src/proxy.js +351 -0
- package/packages/dd-trace/src/random_sampler.js +40 -0
- package/packages/dd-trace/src/rate_limiter.js +82 -0
- package/packages/dd-trace/src/remote_config/apply_states.js +7 -0
- package/packages/dd-trace/src/remote_config/capabilities.js +47 -0
- package/packages/dd-trace/src/remote_config/index.js +574 -0
- package/packages/dd-trace/src/remote_config/scheduler.js +30 -0
- package/packages/dd-trace/src/require-package-json.js +33 -0
- package/packages/dd-trace/src/ritm.js +211 -0
- package/packages/dd-trace/src/runtime_metrics/index.js +34 -0
- package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +373 -0
- package/packages/dd-trace/src/sampler.js +63 -0
- package/packages/dd-trace/src/sampling_rule.js +267 -0
- package/packages/dd-trace/src/scope.js +63 -0
- package/packages/dd-trace/src/serverless.js +52 -0
- package/packages/dd-trace/src/service-naming/extra-services.js +24 -0
- package/packages/dd-trace/src/service-naming/index.js +75 -0
- package/packages/dd-trace/src/service-naming/schemas/definition.js +19 -0
- package/packages/dd-trace/src/service-naming/schemas/util.js +25 -0
- package/packages/dd-trace/src/service-naming/schemas/v0/graphql.js +14 -0
- package/packages/dd-trace/src/service-naming/schemas/v0/index.js +11 -0
- package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +102 -0
- package/packages/dd-trace/src/service-naming/schemas/v0/serverless.js +18 -0
- package/packages/dd-trace/src/service-naming/schemas/v0/storage.js +118 -0
- package/packages/dd-trace/src/service-naming/schemas/v0/web.js +92 -0
- package/packages/dd-trace/src/service-naming/schemas/v0/websocket.js +30 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/graphql.js +14 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/index.js +11 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/messaging.js +90 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/serverless.js +18 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/storage.js +86 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/web.js +92 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/websocket.js +30 -0
- package/packages/dd-trace/src/span_format.js +264 -0
- package/packages/dd-trace/src/span_processor.js +171 -0
- package/packages/dd-trace/src/span_sampler.js +58 -0
- package/packages/dd-trace/src/span_stats.js +227 -0
- package/packages/dd-trace/src/spanleak.js +97 -0
- package/packages/dd-trace/src/standalone/index.js +70 -0
- package/packages/dd-trace/src/standalone/product.js +36 -0
- package/packages/dd-trace/src/standalone/tracesource.js +36 -0
- package/packages/dd-trace/src/standalone/tracesource_priority_sampler.js +59 -0
- package/packages/dd-trace/src/startup-log.js +146 -0
- package/packages/dd-trace/src/tagger.js +58 -0
- package/packages/dd-trace/src/telemetry/dependencies.js +174 -0
- package/packages/dd-trace/src/telemetry/endpoints.js +212 -0
- package/packages/dd-trace/src/telemetry/index.js +26 -0
- package/packages/dd-trace/src/telemetry/logs/index.js +90 -0
- package/packages/dd-trace/src/telemetry/logs/log-collector.js +128 -0
- package/packages/dd-trace/src/telemetry/metrics.js +288 -0
- package/packages/dd-trace/src/telemetry/send-data.js +225 -0
- package/packages/dd-trace/src/telemetry/telemetry.js +535 -0
- package/packages/dd-trace/src/tracer.js +171 -0
- package/packages/dd-trace/src/tracer_metadata.js +29 -0
- package/packages/dd-trace/src/util.js +94 -0
- package/register.js +8 -0
- package/scripts/preinstall.js +34 -0
- package/vendor/dist/@datadog/sketches-js/LICENSE +39 -0
- package/vendor/dist/@datadog/sketches-js/index.js +1 -0
- package/vendor/dist/@datadog/source-map/LICENSE +28 -0
- package/vendor/dist/@datadog/source-map/index.js +1 -0
- package/vendor/dist/@isaacs/ttlcache/LICENSE +55 -0
- package/vendor/dist/@isaacs/ttlcache/index.js +1 -0
- package/vendor/dist/@opentelemetry/core/LICENSE +201 -0
- package/vendor/dist/@opentelemetry/core/index.js +1 -0
- package/vendor/dist/@opentelemetry/resources/LICENSE +201 -0
- package/vendor/dist/@opentelemetry/resources/index.js +1 -0
- package/vendor/dist/astring/LICENSE +19 -0
- package/vendor/dist/astring/index.js +1 -0
- package/vendor/dist/crypto-randomuuid/index.js +1 -0
- package/vendor/dist/escape-string-regexp/LICENSE +9 -0
- package/vendor/dist/escape-string-regexp/index.js +1 -0
- package/vendor/dist/esquery/LICENSE +24 -0
- package/vendor/dist/esquery/index.js +1 -0
- package/vendor/dist/ignore/LICENSE +21 -0
- package/vendor/dist/ignore/index.js +1 -0
- package/vendor/dist/istanbul-lib-coverage/LICENSE +24 -0
- package/vendor/dist/istanbul-lib-coverage/index.js +1 -0
- package/vendor/dist/jest-docblock/LICENSE +21 -0
- package/vendor/dist/jest-docblock/index.js +1 -0
- package/vendor/dist/jsonpath-plus/LICENSE +22 -0
- package/vendor/dist/jsonpath-plus/index.js +1 -0
- package/vendor/dist/limiter/LICENSE +19 -0
- package/vendor/dist/limiter/index.js +1 -0
- package/vendor/dist/lodash.sortby/LICENSE +47 -0
- package/vendor/dist/lodash.sortby/index.js +1 -0
- package/vendor/dist/lru-cache/LICENSE +15 -0
- package/vendor/dist/lru-cache/index.js +1 -0
- package/vendor/dist/meriyah/LICENSE +7 -0
- package/vendor/dist/meriyah/index.js +1 -0
- package/vendor/dist/module-details-from-path/LICENSE +21 -0
- package/vendor/dist/module-details-from-path/index.js +1 -0
- package/vendor/dist/mutexify/promise/LICENSE +21 -0
- package/vendor/dist/mutexify/promise/index.js +1 -0
- package/vendor/dist/opentracing/LICENSE +201 -0
- package/vendor/dist/opentracing/binary_carrier.d.ts +11 -0
- package/vendor/dist/opentracing/constants.d.ts +61 -0
- package/vendor/dist/opentracing/examples/demo/demo.d.ts +2 -0
- package/vendor/dist/opentracing/ext/tags.d.ts +90 -0
- package/vendor/dist/opentracing/functions.d.ts +20 -0
- package/vendor/dist/opentracing/global_tracer.d.ts +14 -0
- package/vendor/dist/opentracing/index.d.ts +12 -0
- package/vendor/dist/opentracing/index.js +1 -0
- package/vendor/dist/opentracing/mock_tracer/index.d.ts +5 -0
- package/vendor/dist/opentracing/mock_tracer/mock_context.d.ts +13 -0
- package/vendor/dist/opentracing/mock_tracer/mock_report.d.ts +16 -0
- package/vendor/dist/opentracing/mock_tracer/mock_span.d.ts +50 -0
- package/vendor/dist/opentracing/mock_tracer/mock_tracer.d.ts +26 -0
- package/vendor/dist/opentracing/noop.d.ts +8 -0
- package/vendor/dist/opentracing/reference.d.ts +33 -0
- package/vendor/dist/opentracing/span.d.ts +147 -0
- package/vendor/dist/opentracing/span_context.d.ts +26 -0
- package/vendor/dist/opentracing/test/api_compatibility.d.ts +16 -0
- package/vendor/dist/opentracing/test/mocktracer_implemenation.d.ts +3 -0
- package/vendor/dist/opentracing/test/noop_implementation.d.ts +4 -0
- package/vendor/dist/opentracing/test/opentracing_api.d.ts +3 -0
- package/vendor/dist/opentracing/test/unittest.d.ts +2 -0
- package/vendor/dist/opentracing/tracer.d.ts +127 -0
- package/vendor/dist/path-to-regexp/LICENSE +21 -0
- package/vendor/dist/path-to-regexp/index.js +1 -0
- package/vendor/dist/pprof-format/LICENSE +8 -0
- package/vendor/dist/pprof-format/index.js +1 -0
- package/vendor/dist/protobufjs/LICENSE +39 -0
- package/vendor/dist/protobufjs/index.js +1 -0
- package/vendor/dist/protobufjs/minimal/LICENSE +39 -0
- package/vendor/dist/protobufjs/minimal/index.js +1 -0
- package/vendor/dist/retry/LICENSE +21 -0
- package/vendor/dist/retry/index.js +1 -0
- package/vendor/dist/rfdc/LICENSE +15 -0
- package/vendor/dist/rfdc/index.js +1 -0
- package/vendor/dist/semifies/LICENSE +201 -0
- package/vendor/dist/semifies/index.js +1 -0
- package/vendor/dist/shell-quote/LICENSE +24 -0
- package/vendor/dist/shell-quote/index.js +1 -0
- package/vendor/dist/source-map/LICENSE +28 -0
- package/vendor/dist/source-map/index.js +1 -0
- package/vendor/dist/source-map/lib/util/LICENSE +28 -0
- package/vendor/dist/source-map/lib/util/index.js +1 -0
- package/vendor/dist/source-map/mappings.wasm +0 -0
- package/vendor/dist/tlhunter-sorted-set/LICENSE +21 -0
- package/vendor/dist/tlhunter-sorted-set/index.js +1 -0
- package/vendor/dist/ttl-set/LICENSE +21 -0
- package/vendor/dist/ttl-set/index.js +1 -0
- package/version.js +18 -0
|
@@ -0,0 +1,1895 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const path = require('path')
|
|
4
|
+
const shimmer = require('../../datadog-shimmer')
|
|
5
|
+
const log = require('../../dd-trace/src/log')
|
|
6
|
+
const {
|
|
7
|
+
getCoveredFilenamesFromCoverage,
|
|
8
|
+
JEST_WORKER_TRACE_PAYLOAD_CODE,
|
|
9
|
+
JEST_WORKER_COVERAGE_PAYLOAD_CODE,
|
|
10
|
+
JEST_WORKER_TELEMETRY_PAYLOAD_CODE,
|
|
11
|
+
getTestLineStart,
|
|
12
|
+
getTestSuitePath,
|
|
13
|
+
getTestParametersString,
|
|
14
|
+
getIsFaultyEarlyFlakeDetection,
|
|
15
|
+
JEST_WORKER_LOGS_PAYLOAD_CODE,
|
|
16
|
+
getTestEndLine,
|
|
17
|
+
isModifiedTest,
|
|
18
|
+
} = require('../../dd-trace/src/plugins/util/test')
|
|
19
|
+
const {
|
|
20
|
+
SEED_SUFFIX_RE,
|
|
21
|
+
getFormattedJestTestParameters,
|
|
22
|
+
getJestTestName,
|
|
23
|
+
getJestSuitesToRun,
|
|
24
|
+
getEfdRetryCount,
|
|
25
|
+
} = require('../../datadog-plugin-jest/src/util')
|
|
26
|
+
const { addHook, channel } = require('./helpers/instrument')
|
|
27
|
+
|
|
28
|
+
const testSessionStartCh = channel('ci:jest:session:start')
|
|
29
|
+
const testSessionFinishCh = channel('ci:jest:session:finish')
|
|
30
|
+
const codeCoverageReportCh = channel('ci:jest:coverage-report')
|
|
31
|
+
|
|
32
|
+
const testSessionConfigurationCh = channel('ci:jest:session:configuration')
|
|
33
|
+
|
|
34
|
+
const testSuiteStartCh = channel('ci:jest:test-suite:start')
|
|
35
|
+
const testSuiteFinishCh = channel('ci:jest:test-suite:finish')
|
|
36
|
+
const testSuiteErrorCh = channel('ci:jest:test-suite:error')
|
|
37
|
+
|
|
38
|
+
const workerReportTraceCh = channel('ci:jest:worker-report:trace')
|
|
39
|
+
const workerReportCoverageCh = channel('ci:jest:worker-report:coverage')
|
|
40
|
+
const workerReportLogsCh = channel('ci:jest:worker-report:logs')
|
|
41
|
+
const workerReportTelemetryCh = channel('ci:jest:worker-report:telemetry')
|
|
42
|
+
|
|
43
|
+
const testSuiteCodeCoverageCh = channel('ci:jest:test-suite:code-coverage')
|
|
44
|
+
|
|
45
|
+
const testStartCh = channel('ci:jest:test:start')
|
|
46
|
+
const testSkippedCh = channel('ci:jest:test:skip')
|
|
47
|
+
const testFinishCh = channel('ci:jest:test:finish')
|
|
48
|
+
const testErrCh = channel('ci:jest:test:err')
|
|
49
|
+
const testFnCh = channel('ci:jest:test:fn')
|
|
50
|
+
const testSuiteHookFnCh = channel('ci:jest:test-suite:hook:fn')
|
|
51
|
+
|
|
52
|
+
const skippableSuitesCh = channel('ci:jest:test-suite:skippable')
|
|
53
|
+
const libraryConfigurationCh = channel('ci:jest:library-configuration')
|
|
54
|
+
const knownTestsCh = channel('ci:jest:known-tests')
|
|
55
|
+
const testManagementTestsCh = channel('ci:jest:test-management-tests')
|
|
56
|
+
const modifiedFilesCh = channel('ci:jest:modified-files')
|
|
57
|
+
|
|
58
|
+
const itrSkippedSuitesCh = channel('ci:jest:itr:skipped-suites')
|
|
59
|
+
|
|
60
|
+
// Message sent by jest's main process to workers to run a test suite (=test file)
|
|
61
|
+
// https://github.com/jestjs/jest/blob/1d682f21c7a35da4d3ab3a1436a357b980ebd0fa/packages/jest-worker/src/types.ts#L37
|
|
62
|
+
const CHILD_MESSAGE_CALL = 1
|
|
63
|
+
|
|
64
|
+
// Maximum time we'll wait for the tracer to flush
|
|
65
|
+
const FLUSH_TIMEOUT = 10_000
|
|
66
|
+
|
|
67
|
+
// https://github.com/jestjs/jest/blob/41f842a46bb2691f828c3a5f27fc1d6290495b82/packages/jest-circus/src/types.ts#L9C8-L9C54
|
|
68
|
+
const RETRY_TIMES = Symbol.for('RETRY_TIMES')
|
|
69
|
+
|
|
70
|
+
let skippableSuites = []
|
|
71
|
+
let knownTests = {}
|
|
72
|
+
let isCodeCoverageEnabled = false
|
|
73
|
+
let isCodeCoverageEnabledBecauseOfUs = false
|
|
74
|
+
let isSuitesSkippingEnabled = false
|
|
75
|
+
let isKeepingCoverageConfiguration = false
|
|
76
|
+
let isUserCodeCoverageEnabled = false
|
|
77
|
+
let isSuitesSkipped = false
|
|
78
|
+
let numSkippedSuites = 0
|
|
79
|
+
let hasUnskippableSuites = false
|
|
80
|
+
let hasForcedToRunSuites = false
|
|
81
|
+
let isEarlyFlakeDetectionEnabled = false
|
|
82
|
+
let earlyFlakeDetectionNumRetries = 0
|
|
83
|
+
let earlyFlakeDetectionSlowTestRetries = {}
|
|
84
|
+
let earlyFlakeDetectionFaultyThreshold = 30
|
|
85
|
+
let isEarlyFlakeDetectionFaulty = false
|
|
86
|
+
let hasFilteredSkippableSuites = false
|
|
87
|
+
let isKnownTestsEnabled = false
|
|
88
|
+
let isTestManagementTestsEnabled = false
|
|
89
|
+
let testManagementTests = {}
|
|
90
|
+
let testManagementAttemptToFixRetries = 0
|
|
91
|
+
let isImpactedTestsEnabled = false
|
|
92
|
+
let modifiedFiles = {}
|
|
93
|
+
|
|
94
|
+
const testContexts = new WeakMap()
|
|
95
|
+
const originalTestFns = new WeakMap()
|
|
96
|
+
const originalHookFns = new WeakMap()
|
|
97
|
+
const retriedTestsToNumAttempts = new Map()
|
|
98
|
+
const newTestsTestStatuses = new Map()
|
|
99
|
+
const attemptToFixRetriedTestsStatuses = new Map()
|
|
100
|
+
const wrappedWorkers = new WeakSet()
|
|
101
|
+
const testSuiteMockedFiles = new Map()
|
|
102
|
+
const testsToBeRetried = new Set()
|
|
103
|
+
// Per-test: how many EFD retries were determined after the first execution.
|
|
104
|
+
const efdDeterminedRetries = new Map()
|
|
105
|
+
// Tests whose first run exceeded the 5-min threshold — tagged "slow".
|
|
106
|
+
const efdSlowAbortedTests = new Set()
|
|
107
|
+
// Tests added as EFD new-test candidates (not ATF, not impacted).
|
|
108
|
+
const efdNewTestCandidates = new Set()
|
|
109
|
+
const testSuiteAbsolutePathsWithFastCheck = new Set()
|
|
110
|
+
const testSuiteJestObjects = new Map()
|
|
111
|
+
|
|
112
|
+
const BREAKPOINT_HIT_GRACE_PERIOD_MS = 200
|
|
113
|
+
const ATR_RETRY_SUPPRESSION_FLAG = '_ddDisableAtrRetry'
|
|
114
|
+
const atrSuppressedErrors = new Map()
|
|
115
|
+
|
|
116
|
+
// based on https://github.com/facebook/jest/blob/main/packages/jest-circus/src/formatNodeAssertErrors.ts#L41
|
|
117
|
+
function formatJestError (errors) {
|
|
118
|
+
let error
|
|
119
|
+
if (Array.isArray(errors)) {
|
|
120
|
+
const [originalError, asyncError] = errors
|
|
121
|
+
if (originalError === null || !originalError.stack) {
|
|
122
|
+
error = asyncError
|
|
123
|
+
error.message = originalError
|
|
124
|
+
} else {
|
|
125
|
+
error = originalError
|
|
126
|
+
}
|
|
127
|
+
} else {
|
|
128
|
+
error = errors
|
|
129
|
+
}
|
|
130
|
+
return error
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function getTestEnvironmentOptions (config) {
|
|
134
|
+
if (config.projectConfig && config.projectConfig.testEnvironmentOptions) { // newer versions
|
|
135
|
+
return config.projectConfig.testEnvironmentOptions
|
|
136
|
+
}
|
|
137
|
+
if (config.testEnvironmentOptions) {
|
|
138
|
+
return config.testEnvironmentOptions
|
|
139
|
+
}
|
|
140
|
+
return {}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const MAX_IGNORED_TEST_NAMES = 10
|
|
144
|
+
|
|
145
|
+
function getTestStats (testStatuses) {
|
|
146
|
+
return testStatuses.reduce((acc, testStatus) => {
|
|
147
|
+
acc[testStatus]++
|
|
148
|
+
return acc
|
|
149
|
+
}, { pass: 0, fail: 0 })
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* @param {string[]} efdNames
|
|
154
|
+
* @param {string[]} quarantineNames
|
|
155
|
+
* @param {number} totalCount
|
|
156
|
+
*/
|
|
157
|
+
function logIgnoredFailuresSummary (efdNames, quarantineNames, totalCount) {
|
|
158
|
+
const names = []
|
|
159
|
+
for (const n of efdNames) {
|
|
160
|
+
names.push({ name: n, reason: 'Early Flake Detection' })
|
|
161
|
+
}
|
|
162
|
+
for (const n of quarantineNames) {
|
|
163
|
+
names.push({ name: n, reason: 'Quarantine' })
|
|
164
|
+
}
|
|
165
|
+
const shown = names.slice(0, MAX_IGNORED_TEST_NAMES)
|
|
166
|
+
const more = names.length - shown.length
|
|
167
|
+
const moreSuffix = more > 0 ? `\n ... and ${more} more` : ''
|
|
168
|
+
const list = shown.map(({ name, reason }) => ` • ${name} (${reason})`).join('\n')
|
|
169
|
+
const line = '-'.repeat(50)
|
|
170
|
+
// eslint-disable-next-line no-console -- Intentional user-facing message when exit code is flipped
|
|
171
|
+
console.warn(
|
|
172
|
+
`\n${line}\nDatadog Test Optimization\n${line}\n` +
|
|
173
|
+
`${totalCount} test failure(s) were ignored. Exit code set to 0.\n\n` +
|
|
174
|
+
`${list}${moreSuffix}\n`
|
|
175
|
+
)
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
179
|
+
return class DatadogEnvironment extends BaseEnvironment {
|
|
180
|
+
constructor (config, context) {
|
|
181
|
+
super(config, context)
|
|
182
|
+
const rootDir = config.globalConfig ? config.globalConfig.rootDir : config.rootDir
|
|
183
|
+
this.rootDir = rootDir
|
|
184
|
+
this.testSuite = getTestSuitePath(context.testPath, rootDir)
|
|
185
|
+
this.nameToParams = {}
|
|
186
|
+
this.global._ddtrace = global._ddtrace
|
|
187
|
+
this.hasSnapshotTests = undefined
|
|
188
|
+
this.testSuiteAbsolutePath = context.testPath
|
|
189
|
+
|
|
190
|
+
this.displayName = config.projectConfig?.displayName?.name || config.displayName
|
|
191
|
+
this.testEnvironmentOptions = getTestEnvironmentOptions(config)
|
|
192
|
+
|
|
193
|
+
const repositoryRoot = this.testEnvironmentOptions._ddRepositoryRoot
|
|
194
|
+
|
|
195
|
+
// TODO: could we grab testPath from `this.getVmContext().expect.getState()` instead?
|
|
196
|
+
// so we don't rely on context being passed (some custom test environment do not pass it)
|
|
197
|
+
if (repositoryRoot) {
|
|
198
|
+
this.testSourceFile = getTestSuitePath(context.testPath, repositoryRoot)
|
|
199
|
+
this.repositoryRoot = repositoryRoot
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
this.isEarlyFlakeDetectionEnabled = this.testEnvironmentOptions._ddIsEarlyFlakeDetectionEnabled
|
|
203
|
+
this.isFlakyTestRetriesEnabled = this.testEnvironmentOptions._ddIsFlakyTestRetriesEnabled
|
|
204
|
+
this.flakyTestRetriesCount = this.testEnvironmentOptions._ddFlakyTestRetriesCount
|
|
205
|
+
this.isDiEnabled = this.testEnvironmentOptions._ddIsDiEnabled
|
|
206
|
+
this.isKnownTestsEnabled = this.testEnvironmentOptions._ddIsKnownTestsEnabled
|
|
207
|
+
this.isTestManagementTestsEnabled = this.testEnvironmentOptions._ddIsTestManagementTestsEnabled
|
|
208
|
+
this.isImpactedTestsEnabled = this.testEnvironmentOptions._ddIsImpactedTestsEnabled
|
|
209
|
+
|
|
210
|
+
if (this.isKnownTestsEnabled) {
|
|
211
|
+
earlyFlakeDetectionSlowTestRetries = this.testEnvironmentOptions._ddEarlyFlakeDetectionSlowTestRetries ?? {}
|
|
212
|
+
try {
|
|
213
|
+
this.knownTestsForThisSuite = this.getKnownTestsForSuite(this.testEnvironmentOptions._ddKnownTests)
|
|
214
|
+
|
|
215
|
+
if (!Array.isArray(this.knownTestsForThisSuite)) {
|
|
216
|
+
log.warn('this.knownTestsForThisSuite is not an array so new test and Early Flake detection is disabled.')
|
|
217
|
+
this.isEarlyFlakeDetectionEnabled = false
|
|
218
|
+
this.isKnownTestsEnabled = false
|
|
219
|
+
}
|
|
220
|
+
} catch {
|
|
221
|
+
// If there has been an error parsing the tests, we'll disable Early Flake Deteciton
|
|
222
|
+
this.isEarlyFlakeDetectionEnabled = false
|
|
223
|
+
this.isKnownTestsEnabled = false
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
if (this.isFlakyTestRetriesEnabled) {
|
|
228
|
+
const currentNumRetries = this.global[RETRY_TIMES]
|
|
229
|
+
if (!currentNumRetries) {
|
|
230
|
+
this.global[RETRY_TIMES] = this.flakyTestRetriesCount
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
if (this.isTestManagementTestsEnabled) {
|
|
235
|
+
try {
|
|
236
|
+
const hasTestManagementTests = !!testManagementTests?.jest
|
|
237
|
+
testManagementAttemptToFixRetries = this.testEnvironmentOptions._ddTestManagementAttemptToFixRetries
|
|
238
|
+
this.testManagementTestsForThisSuite = hasTestManagementTests
|
|
239
|
+
? this.getTestManagementTestsForSuite(testManagementTests?.jest?.suites?.[this.testSuite]?.tests)
|
|
240
|
+
: this.getTestManagementTestsForSuite(this.testEnvironmentOptions._ddTestManagementTests)
|
|
241
|
+
} catch (e) {
|
|
242
|
+
log.error('Error parsing test management tests', e)
|
|
243
|
+
this.isTestManagementTestsEnabled = false
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if (this.isImpactedTestsEnabled) {
|
|
248
|
+
try {
|
|
249
|
+
const hasImpactedTests = Object.keys(modifiedFiles).length > 0
|
|
250
|
+
this.modifiedFiles = hasImpactedTests ? modifiedFiles : this.testEnvironmentOptions._ddModifiedFiles
|
|
251
|
+
} catch (e) {
|
|
252
|
+
log.error('Error parsing impacted tests', e)
|
|
253
|
+
this.isImpactedTestsEnabled = false
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Jest snapshot counter issue during test retries
|
|
260
|
+
*
|
|
261
|
+
* Problem:
|
|
262
|
+
* - Jest tracks snapshot calls using an internal counter per test name
|
|
263
|
+
* - Each `toMatchSnapshot()` call increments this counter
|
|
264
|
+
* - When a test is retried, it keeps the same name but the counter continues from where it left off
|
|
265
|
+
*
|
|
266
|
+
* Example Issue:
|
|
267
|
+
* Original test run creates: `exports["test can do multiple snapshots 1"] = "hello"`
|
|
268
|
+
* Retried test expects: `exports["test can do multiple snapshots 2"] = "hello"`
|
|
269
|
+
*
|
|
270
|
+
* This mismatch causes snapshot tests to fail on retry because Jest is looking
|
|
271
|
+
* for the wrong snapshot number. The solution is to reset the snapshot state.
|
|
272
|
+
*/
|
|
273
|
+
resetSnapshotState () {
|
|
274
|
+
try {
|
|
275
|
+
const expectGlobal = this.getVmContext().expect
|
|
276
|
+
const { snapshotState: { _counters: counters } } = expectGlobal.getState()
|
|
277
|
+
if (counters) {
|
|
278
|
+
counters.clear()
|
|
279
|
+
}
|
|
280
|
+
} catch (e) {
|
|
281
|
+
log.warn('Error resetting snapshot state', e)
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Jest mock state issue during test retries
|
|
287
|
+
*
|
|
288
|
+
* Problem:
|
|
289
|
+
* - Jest tracks mock function calls using internal state (call count, call arguments, etc.)
|
|
290
|
+
* - When a test is retried, the mock state is not automatically reset
|
|
291
|
+
* - This causes assertions like `toHaveBeenCalledTimes(1)` to fail because the call count
|
|
292
|
+
* accumulates across retries
|
|
293
|
+
*
|
|
294
|
+
* The solution is to clear all mocks before each retry attempt.
|
|
295
|
+
*/
|
|
296
|
+
resetMockState () {
|
|
297
|
+
try {
|
|
298
|
+
const jestObject = testSuiteJestObjects.get(this.testSuiteAbsolutePath)
|
|
299
|
+
if (jestObject?.clearAllMocks) {
|
|
300
|
+
jestObject.clearAllMocks()
|
|
301
|
+
}
|
|
302
|
+
} catch (e) {
|
|
303
|
+
log.warn('Error resetting mock state', e)
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// This function returns an array if the known tests are valid and null otherwise.
|
|
308
|
+
getKnownTestsForSuite (suiteKnownTests) {
|
|
309
|
+
// `suiteKnownTests` is `this.testEnvironmentOptions._ddKnownTests`,
|
|
310
|
+
// which is only set if jest is configured to run in parallel.
|
|
311
|
+
if (suiteKnownTests) {
|
|
312
|
+
return suiteKnownTests
|
|
313
|
+
}
|
|
314
|
+
// Global variable `knownTests` is set only in the main process.
|
|
315
|
+
// If jest is configured to run serially, the tests run in the same process, so `knownTests` is set.
|
|
316
|
+
// The assumption is that if the key `jest` is defined in the dictionary, the response is valid.
|
|
317
|
+
if (knownTests?.jest) {
|
|
318
|
+
return knownTests.jest[this.testSuite] || []
|
|
319
|
+
}
|
|
320
|
+
return null
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
getTestManagementTestsForSuite (testManagementTests) {
|
|
324
|
+
if (this.testManagementTestsForThisSuite) {
|
|
325
|
+
return this.testManagementTestsForThisSuite
|
|
326
|
+
}
|
|
327
|
+
if (!testManagementTests) {
|
|
328
|
+
return {
|
|
329
|
+
attemptToFix: [],
|
|
330
|
+
disabled: [],
|
|
331
|
+
quarantined: [],
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
let testManagementTestsForSuite = testManagementTests
|
|
335
|
+
// If jest is using workers, test management tests are serialized to json.
|
|
336
|
+
// If jest runs in band, they are not.
|
|
337
|
+
if (typeof testManagementTestsForSuite === 'string') {
|
|
338
|
+
testManagementTestsForSuite = JSON.parse(testManagementTestsForSuite)
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
const result = {
|
|
342
|
+
attemptToFix: [],
|
|
343
|
+
disabled: [],
|
|
344
|
+
quarantined: [],
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
for (const [testName, { properties }] of Object.entries(testManagementTestsForSuite)) {
|
|
348
|
+
if (properties?.attempt_to_fix) {
|
|
349
|
+
result.attemptToFix.push(testName)
|
|
350
|
+
}
|
|
351
|
+
if (properties?.disabled) {
|
|
352
|
+
result.disabled.push(testName)
|
|
353
|
+
}
|
|
354
|
+
if (properties?.quarantined) {
|
|
355
|
+
result.quarantined.push(testName)
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
return result
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// Generic function to handle test retries
|
|
363
|
+
retryTest ({
|
|
364
|
+
jestEvent,
|
|
365
|
+
retryCount,
|
|
366
|
+
retryType,
|
|
367
|
+
}) {
|
|
368
|
+
const { testName, fn, timeout } = jestEvent
|
|
369
|
+
for (let retryIndex = 0; retryIndex < retryCount; retryIndex++) {
|
|
370
|
+
if (this.global.test) {
|
|
371
|
+
this.global.test(testName, fn, timeout)
|
|
372
|
+
} else {
|
|
373
|
+
log.error('%s could not retry test because global.test is undefined', retryType)
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
getShouldStripSeedFromTestName () {
|
|
379
|
+
return testSuiteAbsolutePathsWithFastCheck.has(this.testSuiteAbsolutePath)
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// At the `add_test` event we don't have the test object yet, so we can't use it
|
|
383
|
+
getTestNameFromAddTestEvent (event, state) {
|
|
384
|
+
const describeSuffix = getJestTestName(state.currentDescribeBlock, this.getShouldStripSeedFromTestName())
|
|
385
|
+
return describeSuffix ? `${describeSuffix} ${event.testName}` : event.testName
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
async handleTestEvent (event, state) {
|
|
389
|
+
if (super.handleTestEvent) {
|
|
390
|
+
await super.handleTestEvent(event, state)
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
const setNameToParams = (name, params) => { this.nameToParams[name] = [...params] }
|
|
394
|
+
|
|
395
|
+
if (event.name === 'setup' && this.global.test) {
|
|
396
|
+
shimmer.wrap(this.global.test, 'each', each => function () {
|
|
397
|
+
const testParameters = getFormattedJestTestParameters(arguments)
|
|
398
|
+
const eachBind = each.apply(this, arguments)
|
|
399
|
+
return function () {
|
|
400
|
+
const [testName] = arguments
|
|
401
|
+
setNameToParams(testName, testParameters)
|
|
402
|
+
return eachBind.apply(this, arguments)
|
|
403
|
+
}
|
|
404
|
+
})
|
|
405
|
+
}
|
|
406
|
+
if (event.name === 'test_start') {
|
|
407
|
+
const testName = getJestTestName(event.test, this.getShouldStripSeedFromTestName())
|
|
408
|
+
if (testsToBeRetried.has(testName)) {
|
|
409
|
+
// This is needed because we're retrying tests with the same name
|
|
410
|
+
this.resetSnapshotState()
|
|
411
|
+
this.resetMockState()
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
let isNewTest = false
|
|
415
|
+
let numEfdRetry = null
|
|
416
|
+
let numOfAttemptsToFixRetries = null
|
|
417
|
+
const testParameters = getTestParametersString(this.nameToParams, event.test.name)
|
|
418
|
+
|
|
419
|
+
let isAttemptToFix = false
|
|
420
|
+
let isDisabled = false
|
|
421
|
+
let isQuarantined = false
|
|
422
|
+
if (this.isTestManagementTestsEnabled) {
|
|
423
|
+
isAttemptToFix = this.testManagementTestsForThisSuite?.attemptToFix?.includes(testName)
|
|
424
|
+
isDisabled = this.testManagementTestsForThisSuite?.disabled?.includes(testName)
|
|
425
|
+
isQuarantined = this.testManagementTestsForThisSuite?.quarantined?.includes(testName)
|
|
426
|
+
if (isAttemptToFix) {
|
|
427
|
+
numOfAttemptsToFixRetries = retriedTestsToNumAttempts.get(testName)
|
|
428
|
+
retriedTestsToNumAttempts.set(testName, numOfAttemptsToFixRetries + 1)
|
|
429
|
+
} else if (isDisabled) {
|
|
430
|
+
event.test.mode = 'skip'
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
let isModified = false
|
|
435
|
+
if (this.isImpactedTestsEnabled) {
|
|
436
|
+
const testStartLine = getTestLineStart(event.test.asyncError, this.testSuite)
|
|
437
|
+
const testEndLine = getTestEndLine(event.test.fn, testStartLine)
|
|
438
|
+
isModified = isModifiedTest(
|
|
439
|
+
this.testSourceFile,
|
|
440
|
+
testStartLine,
|
|
441
|
+
testEndLine,
|
|
442
|
+
this.modifiedFiles,
|
|
443
|
+
'jest'
|
|
444
|
+
)
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
if (this.isKnownTestsEnabled) {
|
|
448
|
+
isNewTest = retriedTestsToNumAttempts.has(testName)
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
const willRunEfd = this.isEarlyFlakeDetectionEnabled && (isNewTest || isModified)
|
|
452
|
+
event.test[ATR_RETRY_SUPPRESSION_FLAG] = Boolean(isAttemptToFix || willRunEfd)
|
|
453
|
+
|
|
454
|
+
if (!isAttemptToFix && willRunEfd) {
|
|
455
|
+
numEfdRetry = retriedTestsToNumAttempts.get(testName)
|
|
456
|
+
retriedTestsToNumAttempts.set(testName, numEfdRetry + 1)
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
const isJestRetry = event.test?.invocations > 1
|
|
460
|
+
const ctx = {
|
|
461
|
+
name: testName,
|
|
462
|
+
suite: this.testSuite,
|
|
463
|
+
testSourceFile: this.testSourceFile,
|
|
464
|
+
displayName: this.displayName,
|
|
465
|
+
testParameters,
|
|
466
|
+
frameworkVersion: jestVersion,
|
|
467
|
+
isNew: isNewTest,
|
|
468
|
+
isEfdRetry: numEfdRetry > 0,
|
|
469
|
+
isAttemptToFix,
|
|
470
|
+
isAttemptToFixRetry: numOfAttemptsToFixRetries > 0,
|
|
471
|
+
isJestRetry,
|
|
472
|
+
isDisabled,
|
|
473
|
+
isQuarantined,
|
|
474
|
+
isModified,
|
|
475
|
+
testSuiteAbsolutePath: this.testSuiteAbsolutePath,
|
|
476
|
+
}
|
|
477
|
+
testContexts.set(event.test, ctx)
|
|
478
|
+
|
|
479
|
+
testStartCh.runStores(ctx, () => {
|
|
480
|
+
let p = event.test.parent
|
|
481
|
+
const hooks = []
|
|
482
|
+
while (p != null) {
|
|
483
|
+
hooks.push(...p.hooks)
|
|
484
|
+
p = p.parent
|
|
485
|
+
}
|
|
486
|
+
for (const hook of hooks) {
|
|
487
|
+
let hookFn = hook.fn
|
|
488
|
+
if (originalHookFns.has(hook)) {
|
|
489
|
+
hookFn = originalHookFns.get(hook)
|
|
490
|
+
} else {
|
|
491
|
+
originalHookFns.set(hook, hookFn)
|
|
492
|
+
}
|
|
493
|
+
const newHookFn = shimmer.wrapFunction(hookFn, hookFn => function () {
|
|
494
|
+
return testFnCh.runStores(ctx, () => hookFn.apply(this, arguments))
|
|
495
|
+
})
|
|
496
|
+
hook.fn = newHookFn
|
|
497
|
+
}
|
|
498
|
+
const originalFn = event.test.fn
|
|
499
|
+
originalTestFns.set(event.test, originalFn)
|
|
500
|
+
|
|
501
|
+
const newFn = shimmer.wrapFunction(event.test.fn, testFn => function () {
|
|
502
|
+
return testFnCh.runStores(ctx, () => testFn.apply(this, arguments))
|
|
503
|
+
})
|
|
504
|
+
|
|
505
|
+
event.test.fn = newFn
|
|
506
|
+
})
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
if (event.name === 'hook_start' && (event.hook.type === 'beforeAll' || event.hook.type === 'afterAll')) {
|
|
510
|
+
const ctx = { testSuiteAbsolutePath: this.testSuiteAbsolutePath }
|
|
511
|
+
let hookFn = event.hook.fn
|
|
512
|
+
if (originalHookFns.has(event.hook)) {
|
|
513
|
+
hookFn = originalHookFns.get(event.hook)
|
|
514
|
+
} else {
|
|
515
|
+
originalHookFns.set(event.hook, hookFn)
|
|
516
|
+
}
|
|
517
|
+
event.hook.fn = shimmer.wrapFunction(hookFn, hookFn => function () {
|
|
518
|
+
return testSuiteHookFnCh.runStores(ctx, () => hookFn.apply(this, arguments))
|
|
519
|
+
})
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
if (event.name === 'add_test') {
|
|
523
|
+
if (event.failing) {
|
|
524
|
+
return
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
const testFullName = this.getTestNameFromAddTestEvent(event, state)
|
|
528
|
+
const isSkipped = event.mode === 'todo' || event.mode === 'skip'
|
|
529
|
+
const isAttemptToFix = this.isTestManagementTestsEnabled &&
|
|
530
|
+
this.testManagementTestsForThisSuite?.attemptToFix?.includes(testFullName)
|
|
531
|
+
if (
|
|
532
|
+
isAttemptToFix &&
|
|
533
|
+
!isSkipped &&
|
|
534
|
+
!retriedTestsToNumAttempts.has(testFullName)
|
|
535
|
+
) {
|
|
536
|
+
retriedTestsToNumAttempts.set(testFullName, 0)
|
|
537
|
+
testsToBeRetried.add(testFullName)
|
|
538
|
+
this.retryTest({
|
|
539
|
+
jestEvent: event,
|
|
540
|
+
retryCount: testManagementAttemptToFixRetries,
|
|
541
|
+
retryType: 'Test Management (Attempt to Fix)',
|
|
542
|
+
})
|
|
543
|
+
}
|
|
544
|
+
if (!isAttemptToFix && this.isImpactedTestsEnabled) {
|
|
545
|
+
const testStartLine = getTestLineStart(event.asyncError, this.testSuite)
|
|
546
|
+
const testEndLine = getTestEndLine(event.fn, testStartLine)
|
|
547
|
+
const isModified = isModifiedTest(
|
|
548
|
+
this.testSourceFile,
|
|
549
|
+
testStartLine,
|
|
550
|
+
testEndLine,
|
|
551
|
+
this.modifiedFiles,
|
|
552
|
+
'jest'
|
|
553
|
+
)
|
|
554
|
+
if (isModified && !retriedTestsToNumAttempts.has(testFullName) && this.isEarlyFlakeDetectionEnabled) {
|
|
555
|
+
retriedTestsToNumAttempts.set(testFullName, 0)
|
|
556
|
+
testsToBeRetried.add(testFullName)
|
|
557
|
+
this.retryTest({
|
|
558
|
+
jestEvent: event,
|
|
559
|
+
retryCount: earlyFlakeDetectionNumRetries,
|
|
560
|
+
retryType: 'Impacted tests',
|
|
561
|
+
})
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
if (!isAttemptToFix && this.isKnownTestsEnabled) {
|
|
565
|
+
const isNew = !this.knownTestsForThisSuite.includes(testFullName)
|
|
566
|
+
if (isNew && !isSkipped && !retriedTestsToNumAttempts.has(testFullName)) {
|
|
567
|
+
retriedTestsToNumAttempts.set(testFullName, 0)
|
|
568
|
+
if (this.isEarlyFlakeDetectionEnabled) {
|
|
569
|
+
testsToBeRetried.add(testFullName)
|
|
570
|
+
efdNewTestCandidates.add(testFullName)
|
|
571
|
+
// Cloning is deferred to test_done after the first execution,
|
|
572
|
+
// when we know the duration and can choose the right retry count.
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
if (event.name === 'test_done') {
|
|
578
|
+
const originalError = event.test?.errors?.[0]
|
|
579
|
+
let status = 'pass'
|
|
580
|
+
if (event.test.errors && event.test.errors.length) {
|
|
581
|
+
status = 'fail'
|
|
582
|
+
}
|
|
583
|
+
// restore in case it is retried
|
|
584
|
+
event.test.fn = originalTestFns.get(event.test)
|
|
585
|
+
// If ATR retry is being suppressed for this test (due to EFD or Attempt to Fix taking precedence)
|
|
586
|
+
// and the test has errors for this attempt, store the errors temporarily and clear them
|
|
587
|
+
// so Jest won't treat this attempt as failed (the real status will be reported after retries).
|
|
588
|
+
if (event.test?.[ATR_RETRY_SUPPRESSION_FLAG] && event.test.errors?.length) {
|
|
589
|
+
atrSuppressedErrors.set(event.test, event.test.errors)
|
|
590
|
+
event.test.errors = []
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
let attemptToFixPassed = false
|
|
594
|
+
let attemptToFixFailed = false
|
|
595
|
+
let failedAllTests = false
|
|
596
|
+
let isAttemptToFix = false
|
|
597
|
+
const testName = getJestTestName(event.test, this.getShouldStripSeedFromTestName())
|
|
598
|
+
if (this.isTestManagementTestsEnabled) {
|
|
599
|
+
isAttemptToFix = this.testManagementTestsForThisSuite?.attemptToFix?.includes(testName)
|
|
600
|
+
if (isAttemptToFix) {
|
|
601
|
+
if (attemptToFixRetriedTestsStatuses.has(testName)) {
|
|
602
|
+
attemptToFixRetriedTestsStatuses.get(testName).push(status)
|
|
603
|
+
} else {
|
|
604
|
+
attemptToFixRetriedTestsStatuses.set(testName, [status])
|
|
605
|
+
}
|
|
606
|
+
const testStatuses = attemptToFixRetriedTestsStatuses.get(testName)
|
|
607
|
+
// Check if this is the last attempt to fix.
|
|
608
|
+
// If it is, we'll set the failedAllTests flag to true if all the tests failed
|
|
609
|
+
// If all tests passed, we'll set the attemptToFixPassed flag to true
|
|
610
|
+
if (testStatuses.length === testManagementAttemptToFixRetries + 1) {
|
|
611
|
+
if (testStatuses.includes('fail')) {
|
|
612
|
+
attemptToFixFailed = true
|
|
613
|
+
}
|
|
614
|
+
if (testStatuses.every(status => status === 'fail')) {
|
|
615
|
+
failedAllTests = true
|
|
616
|
+
} else if (testStatuses.every(status => status === 'pass')) {
|
|
617
|
+
attemptToFixPassed = true
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
// EFD dynamic cloning: on first execution of a new EFD candidate,
|
|
624
|
+
// determine the retry count from the test's duration.
|
|
625
|
+
if (
|
|
626
|
+
this.isEarlyFlakeDetectionEnabled &&
|
|
627
|
+
this.isKnownTestsEnabled &&
|
|
628
|
+
efdNewTestCandidates.has(testName) &&
|
|
629
|
+
event.test.invocations === 1 &&
|
|
630
|
+
!efdDeterminedRetries.has(testName)
|
|
631
|
+
) {
|
|
632
|
+
const durationMs = event.test.duration ?? 0
|
|
633
|
+
const retryCount = getEfdRetryCount(durationMs, earlyFlakeDetectionSlowTestRetries)
|
|
634
|
+
efdDeterminedRetries.set(testName, retryCount)
|
|
635
|
+
if (retryCount > 0) {
|
|
636
|
+
// Temporarily adjust jest-circus state so that retry tests are registered
|
|
637
|
+
// into the correct describe block and bypass the "tests have started" guard.
|
|
638
|
+
//
|
|
639
|
+
// Problem 1 (jest-circus ≤24): currentDescribeBlock points to ROOT during
|
|
640
|
+
// execution, and ROOT's tests loop already finished before children ran.
|
|
641
|
+
//
|
|
642
|
+
// Problem 2 (jest-circus ≥27): `hasStarted = true` causes `test()` to throw
|
|
643
|
+
// "Cannot add a test after tests have started running".
|
|
644
|
+
//
|
|
645
|
+
// Fix: temporarily point currentDescribeBlock to the test's parent (so retries
|
|
646
|
+
// land in the still-iterating children array) and set hasStarted = false (so the
|
|
647
|
+
// guard is bypassed). Both are restored immediately after scheduling the retries.
|
|
648
|
+
const originalDescribeBlock = state.currentDescribeBlock
|
|
649
|
+
const originalHasStarted = state.hasStarted
|
|
650
|
+
state.currentDescribeBlock = event.test.parent ?? originalDescribeBlock
|
|
651
|
+
state.hasStarted = false
|
|
652
|
+
this.retryTest({
|
|
653
|
+
jestEvent: {
|
|
654
|
+
testName: event.test.name,
|
|
655
|
+
fn: event.test.fn,
|
|
656
|
+
timeout: event.test.timeout,
|
|
657
|
+
},
|
|
658
|
+
retryCount,
|
|
659
|
+
retryType: 'Early flake detection',
|
|
660
|
+
})
|
|
661
|
+
state.currentDescribeBlock = originalDescribeBlock
|
|
662
|
+
state.hasStarted = originalHasStarted
|
|
663
|
+
} else {
|
|
664
|
+
efdSlowAbortedTests.add(testName)
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
let isEfdRetry = false
|
|
669
|
+
// We'll store the test statuses of the retries
|
|
670
|
+
if (this.isKnownTestsEnabled) {
|
|
671
|
+
const isNewTest = retriedTestsToNumAttempts.has(testName)
|
|
672
|
+
if (isNewTest) {
|
|
673
|
+
if (newTestsTestStatuses.has(testName)) {
|
|
674
|
+
newTestsTestStatuses.get(testName).push(status)
|
|
675
|
+
isEfdRetry = true
|
|
676
|
+
} else {
|
|
677
|
+
newTestsTestStatuses.set(testName, [status])
|
|
678
|
+
}
|
|
679
|
+
const testStatuses = newTestsTestStatuses.get(testName)
|
|
680
|
+
// Check if this is the last EFD retry.
|
|
681
|
+
// If it is, we'll set the failedAllTests flag to true if all the tests failed
|
|
682
|
+
const efdRetryCount = efdDeterminedRetries.get(testName) ?? 0
|
|
683
|
+
if (efdRetryCount > 0 && testStatuses.length === efdRetryCount + 1 &&
|
|
684
|
+
testStatuses.every(status => status === 'fail')) {
|
|
685
|
+
failedAllTests = true
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
// ATR: set failedAllTests when all auto test retries were exhausted and every attempt failed
|
|
691
|
+
if (this.isFlakyTestRetriesEnabled && !isAttemptToFix && !isEfdRetry) {
|
|
692
|
+
const maxRetries = Number(this.global[RETRY_TIMES]) || 0
|
|
693
|
+
if (event.test?.invocations === maxRetries + 1 && status === 'fail') {
|
|
694
|
+
failedAllTests = true
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
const promises = {}
|
|
699
|
+
const numRetries = this.global[RETRY_TIMES]
|
|
700
|
+
const numTestExecutions = event.test?.invocations
|
|
701
|
+
const willBeRetriedByFailedTestReplay = numRetries > 0 && numTestExecutions - 1 < numRetries
|
|
702
|
+
const mightHitBreakpoint = this.isDiEnabled && numTestExecutions >= 2
|
|
703
|
+
|
|
704
|
+
const ctx = testContexts.get(event.test)
|
|
705
|
+
|
|
706
|
+
const finalStatus = this.getFinalStatus(testName,
|
|
707
|
+
status,
|
|
708
|
+
!!ctx?.isNew,
|
|
709
|
+
!!ctx?.isModified,
|
|
710
|
+
isEfdRetry,
|
|
711
|
+
isAttemptToFix,
|
|
712
|
+
numTestExecutions)
|
|
713
|
+
|
|
714
|
+
if (status === 'fail') {
|
|
715
|
+
const shouldSetProbe = this.isDiEnabled && willBeRetriedByFailedTestReplay && numTestExecutions === 1
|
|
716
|
+
testErrCh.publish({
|
|
717
|
+
...ctx.currentStore,
|
|
718
|
+
error: formatJestError(originalError),
|
|
719
|
+
shouldSetProbe,
|
|
720
|
+
promises,
|
|
721
|
+
finalStatus,
|
|
722
|
+
})
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
// After finishing it might take a bit for the snapshot to be handled.
|
|
726
|
+
// This means that tests retried with DI are BREAKPOINT_HIT_GRACE_PERIOD_MS slower at least.
|
|
727
|
+
if (status === 'fail' && mightHitBreakpoint) {
|
|
728
|
+
await new Promise(resolve => {
|
|
729
|
+
setTimeout(() => {
|
|
730
|
+
resolve()
|
|
731
|
+
}, BREAKPOINT_HIT_GRACE_PERIOD_MS)
|
|
732
|
+
})
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
let isAtrRetry = false
|
|
736
|
+
if (this.isFlakyTestRetriesEnabled && event.test?.invocations > 1 && !isAttemptToFix && !isEfdRetry) {
|
|
737
|
+
isAtrRetry = true
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
testFinishCh.publish({
|
|
741
|
+
...ctx.currentStore,
|
|
742
|
+
status,
|
|
743
|
+
testStartLine: getTestLineStart(event.test.asyncError, this.testSuite),
|
|
744
|
+
attemptToFixPassed,
|
|
745
|
+
failedAllTests,
|
|
746
|
+
attemptToFixFailed,
|
|
747
|
+
isAtrRetry,
|
|
748
|
+
finalStatus,
|
|
749
|
+
earlyFlakeAbortReason: efdSlowAbortedTests.has(testName) ? 'slow' : undefined,
|
|
750
|
+
})
|
|
751
|
+
|
|
752
|
+
if (promises.isProbeReady) {
|
|
753
|
+
await promises.isProbeReady
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
if (event.name === 'run_finish') {
|
|
757
|
+
for (const [test, errors] of atrSuppressedErrors) {
|
|
758
|
+
test.errors = errors
|
|
759
|
+
}
|
|
760
|
+
atrSuppressedErrors.clear()
|
|
761
|
+
efdDeterminedRetries.clear()
|
|
762
|
+
efdSlowAbortedTests.clear()
|
|
763
|
+
efdNewTestCandidates.clear()
|
|
764
|
+
}
|
|
765
|
+
if (event.name === 'test_skip' || event.name === 'test_todo') {
|
|
766
|
+
const testName = getJestTestName(event.test, this.getShouldStripSeedFromTestName())
|
|
767
|
+
testSkippedCh.publish({
|
|
768
|
+
test: {
|
|
769
|
+
name: testName,
|
|
770
|
+
suite: this.testSuite,
|
|
771
|
+
testSourceFile: this.testSourceFile,
|
|
772
|
+
displayName: this.displayName,
|
|
773
|
+
frameworkVersion: jestVersion,
|
|
774
|
+
testStartLine: getTestLineStart(event.test.asyncError, this.testSuite),
|
|
775
|
+
},
|
|
776
|
+
isDisabled: this.testManagementTestsForThisSuite?.disabled?.includes(testName),
|
|
777
|
+
})
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
getEfdResult ({ testName, isNewTest, isModifiedTest, isEfdRetry, numberOfExecutedRetries }) {
|
|
782
|
+
const isEfdEnabled = this.isEarlyFlakeDetectionEnabled
|
|
783
|
+
const isEfdActive = isEfdEnabled && (isNewTest || isModifiedTest)
|
|
784
|
+
const retryCount = efdDeterminedRetries.get(testName) ?? 0
|
|
785
|
+
const isSlowAbort = efdSlowAbortedTests.has(testName)
|
|
786
|
+
const isLastEfdRetry = (isEfdRetry && numberOfExecutedRetries >= (retryCount + 1)) || isSlowAbort
|
|
787
|
+
const isFinalEfdTestExecution = isEfdActive && isLastEfdRetry
|
|
788
|
+
|
|
789
|
+
let finalStatus
|
|
790
|
+
if (isEfdActive && isFinalEfdTestExecution) {
|
|
791
|
+
// For EFD: The framework reports 'pass' if ANY attempt passed (flaky but not failing)
|
|
792
|
+
const testStatuses = newTestsTestStatuses.get(testName)
|
|
793
|
+
finalStatus = testStatuses && testStatuses.includes('pass') ? 'pass' : 'fail'
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
return { isEfdEnabled, isEfdActive, isFinalEfdTestExecution, finalStatus }
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
getAtrResult ({ status, isEfdRetry, isAttemptToFix, numberOfTestInvocations }) {
|
|
800
|
+
const isAtrEnabled =
|
|
801
|
+
this.isFlakyTestRetriesEnabled &&
|
|
802
|
+
!isEfdRetry &&
|
|
803
|
+
!isAttemptToFix &&
|
|
804
|
+
Number.isFinite(this.global[RETRY_TIMES])
|
|
805
|
+
const isLastAtrRetry =
|
|
806
|
+
status === 'pass' || numberOfTestInvocations >= (Number(this.global[RETRY_TIMES]) + 1)
|
|
807
|
+
const isFinalAtrTestExecution = isAtrEnabled && isLastAtrRetry
|
|
808
|
+
|
|
809
|
+
// For ATR: The last execution's status is what the framework reports
|
|
810
|
+
return { isAtrEnabled, isFinalAtrTestExecution, finalStatus: status }
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
getAttemptToFixResult ({ testName, isAttemptToFix, numberOfExecutedRetries }) {
|
|
814
|
+
const isAttemptToFixEnabled =
|
|
815
|
+
this.isTestManagementTestsEnabled &&
|
|
816
|
+
isAttemptToFix &&
|
|
817
|
+
Number.isFinite(testManagementAttemptToFixRetries)
|
|
818
|
+
const isFinalAttemptToFixExecution = isAttemptToFixEnabled &&
|
|
819
|
+
numberOfExecutedRetries >= (testManagementAttemptToFixRetries + 1)
|
|
820
|
+
|
|
821
|
+
let finalStatus
|
|
822
|
+
if (isAttemptToFixEnabled && isFinalAttemptToFixExecution) {
|
|
823
|
+
// For Attempt to Fix: 'pass' only if ALL attempts passed, 'fail' if ANY failed
|
|
824
|
+
const testStatuses = attemptToFixRetriedTestsStatuses.get(testName)
|
|
825
|
+
finalStatus = testStatuses && testStatuses.every(status => status === 'pass') ? 'pass' : 'fail'
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
return { isAttemptToFixEnabled, isFinalAttemptToFixExecution, finalStatus }
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
getFinalStatus (testName, status, isNewTest, isModifiedTest, isEfdRetry, isAttemptToFix, numberOfTestInvocations) {
|
|
832
|
+
const numberOfExecutedRetries = retriedTestsToNumAttempts.get(testName) ?? 0
|
|
833
|
+
|
|
834
|
+
const efdResult = this.getEfdResult({
|
|
835
|
+
testName,
|
|
836
|
+
isNewTest,
|
|
837
|
+
isModifiedTest,
|
|
838
|
+
isEfdRetry,
|
|
839
|
+
numberOfExecutedRetries,
|
|
840
|
+
})
|
|
841
|
+
const atrResult = this.getAtrResult({ status, isEfdRetry, isAttemptToFix, numberOfTestInvocations })
|
|
842
|
+
const attemptToFixResult = this.getAttemptToFixResult({
|
|
843
|
+
testName,
|
|
844
|
+
isAttemptToFix,
|
|
845
|
+
numberOfExecutedRetries,
|
|
846
|
+
})
|
|
847
|
+
|
|
848
|
+
// When no retry features are active, every test execution is final
|
|
849
|
+
const noRetryFeaturesActive =
|
|
850
|
+
!efdResult.isEfdActive &&
|
|
851
|
+
!atrResult.isAtrEnabled &&
|
|
852
|
+
!attemptToFixResult.isAttemptToFixEnabled
|
|
853
|
+
const isFinalTestExecution = noRetryFeaturesActive ||
|
|
854
|
+
efdResult.isFinalEfdTestExecution ||
|
|
855
|
+
atrResult.isFinalAtrTestExecution ||
|
|
856
|
+
attemptToFixResult.isFinalAttemptToFixExecution
|
|
857
|
+
|
|
858
|
+
if (!isFinalTestExecution) {
|
|
859
|
+
return
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
// If the test is quarantined, regardless of its actual execution result,
|
|
863
|
+
// the final status of its last execution should be reported as 'skip'.
|
|
864
|
+
if (this.isTestManagementTestsEnabled &&
|
|
865
|
+
this.testManagementTestsForThisSuite?.quarantined?.includes(testName)) {
|
|
866
|
+
return 'skip'
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
return efdResult.finalStatus || attemptToFixResult.finalStatus || atrResult.finalStatus
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
teardown () {
|
|
873
|
+
if (this._globalProxy?.propertyToValue) {
|
|
874
|
+
for (const [key] of this._globalProxy.propertyToValue) {
|
|
875
|
+
if (typeof key === 'string' && key.startsWith('_dd')) {
|
|
876
|
+
this._globalProxy.propertyToValue.delete(key)
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
return super.teardown()
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
function getTestEnvironment (pkg, jestVersion) {
|
|
886
|
+
if (pkg.default) {
|
|
887
|
+
const wrappedTestEnvironment = getWrappedEnvironment(pkg.default, jestVersion)
|
|
888
|
+
return new Proxy(pkg, {
|
|
889
|
+
get (target, prop) {
|
|
890
|
+
if (prop === 'default') {
|
|
891
|
+
return wrappedTestEnvironment
|
|
892
|
+
}
|
|
893
|
+
if (prop === 'TestEnvironment') {
|
|
894
|
+
return wrappedTestEnvironment
|
|
895
|
+
}
|
|
896
|
+
return target[prop]
|
|
897
|
+
},
|
|
898
|
+
})
|
|
899
|
+
}
|
|
900
|
+
return getWrappedEnvironment(pkg, jestVersion)
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
function applySuiteSkipping (originalTests, rootDir, frameworkVersion) {
|
|
904
|
+
const jestSuitesToRun = getJestSuitesToRun(skippableSuites, originalTests, rootDir || process.cwd())
|
|
905
|
+
hasFilteredSkippableSuites = true
|
|
906
|
+
log.debug('%d out of %d suites are going to run.', jestSuitesToRun.suitesToRun.length, originalTests.length)
|
|
907
|
+
hasUnskippableSuites = jestSuitesToRun.hasUnskippableSuites
|
|
908
|
+
hasForcedToRunSuites = jestSuitesToRun.hasForcedToRunSuites
|
|
909
|
+
|
|
910
|
+
isSuitesSkipped = jestSuitesToRun.suitesToRun.length !== originalTests.length
|
|
911
|
+
numSkippedSuites = jestSuitesToRun.skippedSuites.length
|
|
912
|
+
|
|
913
|
+
itrSkippedSuitesCh.publish({ skippedSuites: jestSuitesToRun.skippedSuites, frameworkVersion })
|
|
914
|
+
|
|
915
|
+
return jestSuitesToRun.suitesToRun
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
addHook({
|
|
919
|
+
name: 'jest-environment-node',
|
|
920
|
+
versions: ['>=24.8.0'],
|
|
921
|
+
}, getTestEnvironment)
|
|
922
|
+
|
|
923
|
+
addHook({
|
|
924
|
+
name: 'jest-environment-jsdom',
|
|
925
|
+
versions: ['>=24.8.0'],
|
|
926
|
+
}, getTestEnvironment)
|
|
927
|
+
|
|
928
|
+
addHook({
|
|
929
|
+
name: '@happy-dom/jest-environment',
|
|
930
|
+
versions: ['>=10.0.0'],
|
|
931
|
+
}, getTestEnvironment)
|
|
932
|
+
|
|
933
|
+
function getWrappedScheduleTests (scheduleTests, frameworkVersion) {
|
|
934
|
+
// `scheduleTests` is an async function
|
|
935
|
+
return function (tests) {
|
|
936
|
+
if (!isSuitesSkippingEnabled || hasFilteredSkippableSuites) {
|
|
937
|
+
return scheduleTests.apply(this, arguments)
|
|
938
|
+
}
|
|
939
|
+
const [test] = tests
|
|
940
|
+
const rootDir = test?.context?.config?.rootDir
|
|
941
|
+
|
|
942
|
+
arguments[0] = applySuiteSkipping(tests, rootDir, frameworkVersion)
|
|
943
|
+
|
|
944
|
+
return scheduleTests.apply(this, arguments)
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
function searchSourceWrapper (searchSourcePackage, frameworkVersion) {
|
|
949
|
+
const SearchSource = searchSourcePackage.default ?? searchSourcePackage
|
|
950
|
+
|
|
951
|
+
shimmer.wrap(SearchSource.prototype, 'getTestPaths', getTestPaths => async function () {
|
|
952
|
+
const testPaths = await getTestPaths.apply(this, arguments)
|
|
953
|
+
const [{ rootDir, shard }] = arguments
|
|
954
|
+
|
|
955
|
+
if (isKnownTestsEnabled) {
|
|
956
|
+
const projectSuites = testPaths.tests.map(test => getTestSuitePath(test.path, test.context.config.rootDir))
|
|
957
|
+
|
|
958
|
+
// If the `jest` key does not exist in the known tests response, we consider the Early Flake detection faulty.
|
|
959
|
+
const isFaulty = !knownTests?.jest ||
|
|
960
|
+
getIsFaultyEarlyFlakeDetection(projectSuites, knownTests.jest, earlyFlakeDetectionFaultyThreshold)
|
|
961
|
+
|
|
962
|
+
if (isFaulty) {
|
|
963
|
+
log.error('Early flake detection is disabled because the number of new suites is too high.')
|
|
964
|
+
isEarlyFlakeDetectionEnabled = false
|
|
965
|
+
isKnownTestsEnabled = false
|
|
966
|
+
const testEnvironmentOptions = testPaths.tests[0]?.context?.config?.testEnvironmentOptions
|
|
967
|
+
// Project config is shared among all tests, so we can modify it here
|
|
968
|
+
if (testEnvironmentOptions) {
|
|
969
|
+
testEnvironmentOptions._ddIsEarlyFlakeDetectionEnabled = false
|
|
970
|
+
testEnvironmentOptions._ddIsKnownTestsEnabled = false
|
|
971
|
+
}
|
|
972
|
+
isEarlyFlakeDetectionFaulty = true
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
if (shard?.shardCount > 1 || !isSuitesSkippingEnabled || !skippableSuites.length) {
|
|
977
|
+
// If the user is using jest sharding, we want to apply the filtering of tests in the shard process.
|
|
978
|
+
// The reason for this is the following:
|
|
979
|
+
// The tests for different shards are likely being run in different CI jobs so
|
|
980
|
+
// the requests to the skippable endpoint might be done at different times and their responses might be different.
|
|
981
|
+
// If the skippable endpoint is returning different suites and we filter the list of tests here,
|
|
982
|
+
// the base list of tests that is used for sharding might be different,
|
|
983
|
+
// causing the shards to potentially run the same suite.
|
|
984
|
+
return testPaths
|
|
985
|
+
}
|
|
986
|
+
const { tests } = testPaths
|
|
987
|
+
|
|
988
|
+
const suitesToRun = applySuiteSkipping(tests, rootDir, frameworkVersion)
|
|
989
|
+
return { ...testPaths, tests: suitesToRun }
|
|
990
|
+
})
|
|
991
|
+
|
|
992
|
+
return searchSourcePackage
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
function getCliWrapper (isNewJestVersion) {
|
|
996
|
+
return function cliWrapper (cli, jestVersion) {
|
|
997
|
+
if (isNewJestVersion) {
|
|
998
|
+
cli = shimmer.wrap(
|
|
999
|
+
cli,
|
|
1000
|
+
'SearchSource',
|
|
1001
|
+
searchSource => searchSourceWrapper(searchSource, jestVersion),
|
|
1002
|
+
{ replaceGetter: true }
|
|
1003
|
+
)
|
|
1004
|
+
}
|
|
1005
|
+
return shimmer.wrap(cli, 'runCLI', runCLI => async function () {
|
|
1006
|
+
let onDone
|
|
1007
|
+
const configurationPromise = new Promise((resolve) => {
|
|
1008
|
+
onDone = resolve
|
|
1009
|
+
})
|
|
1010
|
+
if (!libraryConfigurationCh.hasSubscribers) {
|
|
1011
|
+
return runCLI.apply(this, arguments)
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
libraryConfigurationCh.publish({ onDone, frameworkVersion: jestVersion })
|
|
1015
|
+
|
|
1016
|
+
try {
|
|
1017
|
+
const { err, libraryConfig } = await configurationPromise
|
|
1018
|
+
if (!err) {
|
|
1019
|
+
isCodeCoverageEnabled = libraryConfig.isCodeCoverageEnabled
|
|
1020
|
+
isSuitesSkippingEnabled = libraryConfig.isSuitesSkippingEnabled
|
|
1021
|
+
isKeepingCoverageConfiguration =
|
|
1022
|
+
libraryConfig.isKeepingCoverageConfiguration ?? isKeepingCoverageConfiguration
|
|
1023
|
+
isEarlyFlakeDetectionEnabled = libraryConfig.isEarlyFlakeDetectionEnabled
|
|
1024
|
+
earlyFlakeDetectionNumRetries = libraryConfig.earlyFlakeDetectionNumRetries
|
|
1025
|
+
earlyFlakeDetectionSlowTestRetries = libraryConfig.earlyFlakeDetectionSlowTestRetries ?? {}
|
|
1026
|
+
earlyFlakeDetectionFaultyThreshold = libraryConfig.earlyFlakeDetectionFaultyThreshold
|
|
1027
|
+
isKnownTestsEnabled = libraryConfig.isKnownTestsEnabled
|
|
1028
|
+
isTestManagementTestsEnabled = libraryConfig.isTestManagementEnabled
|
|
1029
|
+
testManagementAttemptToFixRetries = libraryConfig.testManagementAttemptToFixRetries
|
|
1030
|
+
isImpactedTestsEnabled = libraryConfig.isImpactedTestsEnabled
|
|
1031
|
+
}
|
|
1032
|
+
} catch (err) {
|
|
1033
|
+
log.error('Jest library configuration error', err)
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
if (isKnownTestsEnabled) {
|
|
1037
|
+
const knownTestsPromise = new Promise((resolve) => {
|
|
1038
|
+
onDone = resolve
|
|
1039
|
+
})
|
|
1040
|
+
|
|
1041
|
+
knownTestsCh.publish({ onDone })
|
|
1042
|
+
|
|
1043
|
+
try {
|
|
1044
|
+
const { err, knownTests: receivedKnownTests } = await knownTestsPromise
|
|
1045
|
+
if (err) {
|
|
1046
|
+
// We disable EFD if there has been an error in the known tests request
|
|
1047
|
+
isEarlyFlakeDetectionEnabled = false
|
|
1048
|
+
isKnownTestsEnabled = false
|
|
1049
|
+
} else {
|
|
1050
|
+
knownTests = receivedKnownTests
|
|
1051
|
+
}
|
|
1052
|
+
} catch (err) {
|
|
1053
|
+
log.error('Jest known tests error', err)
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
|
|
1057
|
+
if (isSuitesSkippingEnabled) {
|
|
1058
|
+
const skippableSuitesPromise = new Promise((resolve) => {
|
|
1059
|
+
onDone = resolve
|
|
1060
|
+
})
|
|
1061
|
+
|
|
1062
|
+
skippableSuitesCh.publish({ onDone })
|
|
1063
|
+
|
|
1064
|
+
try {
|
|
1065
|
+
const { err, skippableSuites: receivedSkippableSuites } = await skippableSuitesPromise
|
|
1066
|
+
if (!err) {
|
|
1067
|
+
skippableSuites = receivedSkippableSuites
|
|
1068
|
+
}
|
|
1069
|
+
} catch (err) {
|
|
1070
|
+
log.error('Jest test-suite skippable error', err)
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
if (isTestManagementTestsEnabled) {
|
|
1075
|
+
const testManagementTestsPromise = new Promise((resolve) => {
|
|
1076
|
+
onDone = resolve
|
|
1077
|
+
})
|
|
1078
|
+
|
|
1079
|
+
testManagementTestsCh.publish({ onDone })
|
|
1080
|
+
|
|
1081
|
+
try {
|
|
1082
|
+
const { err, testManagementTests: receivedTestManagementTests } = await testManagementTestsPromise
|
|
1083
|
+
if (err) {
|
|
1084
|
+
isTestManagementTestsEnabled = false
|
|
1085
|
+
testManagementTests = {}
|
|
1086
|
+
} else {
|
|
1087
|
+
testManagementTests = receivedTestManagementTests || {}
|
|
1088
|
+
}
|
|
1089
|
+
} catch (err) {
|
|
1090
|
+
log.error('Jest test management tests error', err)
|
|
1091
|
+
isTestManagementTestsEnabled = false
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1095
|
+
if (isImpactedTestsEnabled) {
|
|
1096
|
+
const impactedTestsPromise = new Promise((resolve) => {
|
|
1097
|
+
onDone = resolve
|
|
1098
|
+
})
|
|
1099
|
+
|
|
1100
|
+
modifiedFilesCh.publish({ onDone })
|
|
1101
|
+
|
|
1102
|
+
try {
|
|
1103
|
+
const { err, modifiedFiles: receivedModifiedFiles } = await impactedTestsPromise
|
|
1104
|
+
if (!err) {
|
|
1105
|
+
modifiedFiles = receivedModifiedFiles
|
|
1106
|
+
}
|
|
1107
|
+
} catch (err) {
|
|
1108
|
+
log.error('Jest impacted tests error', err)
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
|
|
1112
|
+
const processArgv = process.argv.slice(2).join(' ')
|
|
1113
|
+
testSessionStartCh.publish({ command: `jest ${processArgv}`, frameworkVersion: jestVersion })
|
|
1114
|
+
|
|
1115
|
+
const result = await runCLI.apply(this, arguments)
|
|
1116
|
+
|
|
1117
|
+
const {
|
|
1118
|
+
results: {
|
|
1119
|
+
coverageMap,
|
|
1120
|
+
numFailedTestSuites,
|
|
1121
|
+
numFailedTests,
|
|
1122
|
+
numRuntimeErrorTestSuites = 0,
|
|
1123
|
+
numTotalTests,
|
|
1124
|
+
numTotalTestSuites,
|
|
1125
|
+
runExecError,
|
|
1126
|
+
wasInterrupted,
|
|
1127
|
+
},
|
|
1128
|
+
} = result
|
|
1129
|
+
|
|
1130
|
+
const hasSuiteLevelFailures = numRuntimeErrorTestSuites > 0
|
|
1131
|
+
const hasRunLevelFailure = runExecError != null || wasInterrupted === true
|
|
1132
|
+
const mustNotFlipSuccess = hasSuiteLevelFailures || hasRunLevelFailure
|
|
1133
|
+
|
|
1134
|
+
let testCodeCoverageLinesTotal
|
|
1135
|
+
|
|
1136
|
+
if (isUserCodeCoverageEnabled) {
|
|
1137
|
+
try {
|
|
1138
|
+
const { pct, total } = coverageMap.getCoverageSummary().lines
|
|
1139
|
+
testCodeCoverageLinesTotal = total === 0 ? 0 : pct
|
|
1140
|
+
} catch {
|
|
1141
|
+
// ignore errors
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1145
|
+
/**
|
|
1146
|
+
* If Early Flake Detection (EFD) is enabled the logic is as follows:
|
|
1147
|
+
* - If all attempts for a test are failing, the test has failed and we will let the test process fail.
|
|
1148
|
+
* - If just a single attempt passes, we will prevent the test process from failing.
|
|
1149
|
+
* The rationale behind is the following: you may still be able to block your CI pipeline by gating
|
|
1150
|
+
* on flakiness (the test will be considered flaky), but you may choose to unblock the pipeline too.
|
|
1151
|
+
*/
|
|
1152
|
+
let numEfdFailedTestsToIgnore = 0
|
|
1153
|
+
const efdIgnoredNames = []
|
|
1154
|
+
const quarantineIgnoredNames = []
|
|
1155
|
+
|
|
1156
|
+
// Build fullName -> suite map from results (for EFD display)
|
|
1157
|
+
const fullNameToSuite = new Map()
|
|
1158
|
+
for (const { testResults, testFilePath } of result.results.testResults) {
|
|
1159
|
+
const suite = getTestSuitePath(testFilePath, result.globalConfig.rootDir)
|
|
1160
|
+
for (const { fullName } of testResults) {
|
|
1161
|
+
const name = testSuiteAbsolutePathsWithFastCheck.has(testFilePath)
|
|
1162
|
+
? fullName.replace(SEED_SUFFIX_RE, '')
|
|
1163
|
+
: fullName
|
|
1164
|
+
fullNameToSuite.set(name, suite)
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
/** @type {{ efdNames: string[], quarantineNames: string[], totalCount: number } | undefined} */
|
|
1169
|
+
let ignoredFailuresSummary
|
|
1170
|
+
if (isEarlyFlakeDetectionEnabled) {
|
|
1171
|
+
for (const [testName, testStatuses] of newTestsTestStatuses) {
|
|
1172
|
+
const { pass, fail } = getTestStats(testStatuses)
|
|
1173
|
+
if (pass > 0) { // as long as one passes, we'll consider the test passed
|
|
1174
|
+
numEfdFailedTestsToIgnore += fail
|
|
1175
|
+
const suite = fullNameToSuite.get(testName)
|
|
1176
|
+
efdIgnoredNames.push(suite ? `${suite} › ${testName}` : testName)
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
// If every test that failed was an EFD retry, we'll consider the suite passed
|
|
1180
|
+
if (
|
|
1181
|
+
!mustNotFlipSuccess &&
|
|
1182
|
+
numEfdFailedTestsToIgnore !== 0 &&
|
|
1183
|
+
result.results.numFailedTests === numEfdFailedTestsToIgnore
|
|
1184
|
+
) {
|
|
1185
|
+
result.results.success = true
|
|
1186
|
+
ignoredFailuresSummary = {
|
|
1187
|
+
efdNames: efdIgnoredNames,
|
|
1188
|
+
quarantineNames: [],
|
|
1189
|
+
totalCount: numEfdFailedTestsToIgnore,
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
let numFailedQuarantinedTests = 0
|
|
1195
|
+
let numFailedQuarantinedOrDisabledAttemptedToFixTests = 0
|
|
1196
|
+
if (isTestManagementTestsEnabled) {
|
|
1197
|
+
const failedTests = result
|
|
1198
|
+
.results
|
|
1199
|
+
.testResults.flatMap(({ testResults, testFilePath: testSuiteAbsolutePath }) => (
|
|
1200
|
+
testResults.map(({ fullName: testName, status }) => (
|
|
1201
|
+
{
|
|
1202
|
+
// Strip @fast-check/jest seed suffix so the name matches what was reported via TEST_NAME
|
|
1203
|
+
testName: testSuiteAbsolutePathsWithFastCheck.has(testSuiteAbsolutePath)
|
|
1204
|
+
? testName.replace(SEED_SUFFIX_RE, '')
|
|
1205
|
+
: testName,
|
|
1206
|
+
testSuiteAbsolutePath,
|
|
1207
|
+
status,
|
|
1208
|
+
}
|
|
1209
|
+
))
|
|
1210
|
+
))
|
|
1211
|
+
.filter(({ status }) => status === 'failed')
|
|
1212
|
+
|
|
1213
|
+
for (const { testName, testSuiteAbsolutePath } of failedTests) {
|
|
1214
|
+
const testSuite = getTestSuitePath(testSuiteAbsolutePath, result.globalConfig.rootDir)
|
|
1215
|
+
const testManagementTest = testManagementTests
|
|
1216
|
+
?.jest
|
|
1217
|
+
?.suites
|
|
1218
|
+
?.[testSuite]
|
|
1219
|
+
?.tests
|
|
1220
|
+
?.[testName]
|
|
1221
|
+
?.properties
|
|
1222
|
+
// This uses `attempt_to_fix` because this is always the main process and it's not formatted in camelCase
|
|
1223
|
+
if (testManagementTest?.attempt_to_fix && (testManagementTest?.quarantined || testManagementTest?.disabled)) {
|
|
1224
|
+
numFailedQuarantinedOrDisabledAttemptedToFixTests++
|
|
1225
|
+
quarantineIgnoredNames.push(`${testSuite} › ${testName}`)
|
|
1226
|
+
} else if (testManagementTest?.quarantined) {
|
|
1227
|
+
numFailedQuarantinedTests++
|
|
1228
|
+
quarantineIgnoredNames.push(`${testSuite} › ${testName}`)
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1232
|
+
// If every test that failed was quarantined, we'll consider the suite passed
|
|
1233
|
+
// Note that if a test is attempted to fix,
|
|
1234
|
+
// it's considered quarantined both if it's disabled and if it's quarantined
|
|
1235
|
+
// (it'll run but its status is ignored)
|
|
1236
|
+
// Skip if EFD block already flipped (to avoid logging twice)
|
|
1237
|
+
if (
|
|
1238
|
+
!result.results.success &&
|
|
1239
|
+
!mustNotFlipSuccess &&
|
|
1240
|
+
(numFailedQuarantinedOrDisabledAttemptedToFixTests !== 0 || numFailedQuarantinedTests !== 0) &&
|
|
1241
|
+
result.results.numFailedTests ===
|
|
1242
|
+
numFailedQuarantinedTests + numFailedQuarantinedOrDisabledAttemptedToFixTests
|
|
1243
|
+
) {
|
|
1244
|
+
result.results.success = true
|
|
1245
|
+
ignoredFailuresSummary = {
|
|
1246
|
+
efdNames: [],
|
|
1247
|
+
quarantineNames: quarantineIgnoredNames,
|
|
1248
|
+
totalCount: numFailedQuarantinedTests + numFailedQuarantinedOrDisabledAttemptedToFixTests,
|
|
1249
|
+
}
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
// Combined check: if all failed tests are accounted for by EFD (flaky retries) and/or quarantine,
|
|
1254
|
+
// we should consider the suite passed even when neither check alone covers all failures.
|
|
1255
|
+
if (
|
|
1256
|
+
!result.results.success &&
|
|
1257
|
+
!mustNotFlipSuccess &&
|
|
1258
|
+
(isEarlyFlakeDetectionEnabled || isTestManagementTestsEnabled)
|
|
1259
|
+
) {
|
|
1260
|
+
const totalIgnoredFailures =
|
|
1261
|
+
numEfdFailedTestsToIgnore + numFailedQuarantinedTests + numFailedQuarantinedOrDisabledAttemptedToFixTests
|
|
1262
|
+
if (
|
|
1263
|
+
totalIgnoredFailures !== 0 &&
|
|
1264
|
+
result.results.numFailedTests === totalIgnoredFailures
|
|
1265
|
+
) {
|
|
1266
|
+
result.results.success = true
|
|
1267
|
+
ignoredFailuresSummary = {
|
|
1268
|
+
efdNames: efdIgnoredNames,
|
|
1269
|
+
quarantineNames: quarantineIgnoredNames,
|
|
1270
|
+
totalCount: totalIgnoredFailures,
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1275
|
+
// Determine session status after EFD and quarantine checks have potentially modified success
|
|
1276
|
+
let status, error
|
|
1277
|
+
if (result.results.success) {
|
|
1278
|
+
status = numTotalTests === 0 && numTotalTestSuites === 0 ? 'skip' : 'pass'
|
|
1279
|
+
} else {
|
|
1280
|
+
status = 'fail'
|
|
1281
|
+
error = new Error(`Failed test suites: ${numFailedTestSuites}. Failed tests: ${numFailedTests}`)
|
|
1282
|
+
}
|
|
1283
|
+
|
|
1284
|
+
let timeoutId
|
|
1285
|
+
|
|
1286
|
+
// Pass the resolve callback to defer it to DC listener
|
|
1287
|
+
const flushPromise = new Promise((resolve) => {
|
|
1288
|
+
onDone = () => {
|
|
1289
|
+
clearTimeout(timeoutId)
|
|
1290
|
+
resolve()
|
|
1291
|
+
}
|
|
1292
|
+
})
|
|
1293
|
+
|
|
1294
|
+
const timeoutPromise = new Promise((resolve) => {
|
|
1295
|
+
timeoutId = setTimeout(() => {
|
|
1296
|
+
resolve('timeout')
|
|
1297
|
+
}, FLUSH_TIMEOUT).unref()
|
|
1298
|
+
})
|
|
1299
|
+
|
|
1300
|
+
testSessionFinishCh.publish({
|
|
1301
|
+
status,
|
|
1302
|
+
isSuitesSkipped,
|
|
1303
|
+
isSuitesSkippingEnabled,
|
|
1304
|
+
isCodeCoverageEnabled,
|
|
1305
|
+
testCodeCoverageLinesTotal,
|
|
1306
|
+
numSkippedSuites,
|
|
1307
|
+
hasUnskippableSuites,
|
|
1308
|
+
hasForcedToRunSuites,
|
|
1309
|
+
error,
|
|
1310
|
+
isEarlyFlakeDetectionEnabled,
|
|
1311
|
+
isEarlyFlakeDetectionFaulty,
|
|
1312
|
+
isTestManagementTestsEnabled,
|
|
1313
|
+
onDone,
|
|
1314
|
+
})
|
|
1315
|
+
|
|
1316
|
+
const waitingResult = await Promise.race([flushPromise, timeoutPromise])
|
|
1317
|
+
|
|
1318
|
+
if (waitingResult === 'timeout') {
|
|
1319
|
+
log.error('Timeout waiting for the tracer to flush')
|
|
1320
|
+
}
|
|
1321
|
+
|
|
1322
|
+
if (codeCoverageReportCh.hasSubscribers) {
|
|
1323
|
+
const rootDir = result.globalConfig?.rootDir || process.cwd()
|
|
1324
|
+
await new Promise((resolve) => {
|
|
1325
|
+
codeCoverageReportCh.publish({ rootDir, onDone: resolve })
|
|
1326
|
+
})
|
|
1327
|
+
}
|
|
1328
|
+
|
|
1329
|
+
if (ignoredFailuresSummary) {
|
|
1330
|
+
logIgnoredFailuresSummary(
|
|
1331
|
+
ignoredFailuresSummary.efdNames,
|
|
1332
|
+
ignoredFailuresSummary.quarantineNames,
|
|
1333
|
+
ignoredFailuresSummary.totalCount
|
|
1334
|
+
)
|
|
1335
|
+
}
|
|
1336
|
+
|
|
1337
|
+
numSkippedSuites = 0
|
|
1338
|
+
|
|
1339
|
+
return result
|
|
1340
|
+
}, {
|
|
1341
|
+
replaceGetter: true,
|
|
1342
|
+
})
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1345
|
+
|
|
1346
|
+
function coverageReporterWrapper (coverageReporter) {
|
|
1347
|
+
const CoverageReporter = coverageReporter.default ?? coverageReporter
|
|
1348
|
+
|
|
1349
|
+
/**
|
|
1350
|
+
* If ITR is active, we're running fewer tests, so of course the total code coverage is reduced.
|
|
1351
|
+
* This calculation adds no value, so we'll skip it, as long as the user has not manually opted in to code coverage,
|
|
1352
|
+
* in which case we'll leave it.
|
|
1353
|
+
*/
|
|
1354
|
+
// `_addUntestedFiles` is an async function
|
|
1355
|
+
shimmer.wrap(CoverageReporter.prototype, '_addUntestedFiles', addUntestedFiles => function () {
|
|
1356
|
+
if (isKeepingCoverageConfiguration) {
|
|
1357
|
+
return addUntestedFiles.apply(this, arguments)
|
|
1358
|
+
}
|
|
1359
|
+
if (isCodeCoverageEnabledBecauseOfUs) {
|
|
1360
|
+
return Promise.resolve()
|
|
1361
|
+
}
|
|
1362
|
+
return addUntestedFiles.apply(this, arguments)
|
|
1363
|
+
})
|
|
1364
|
+
|
|
1365
|
+
return coverageReporter
|
|
1366
|
+
}
|
|
1367
|
+
|
|
1368
|
+
addHook({
|
|
1369
|
+
name: '@jest/core',
|
|
1370
|
+
file: 'build/TestScheduler.js',
|
|
1371
|
+
versions: ['>=27.0.0'],
|
|
1372
|
+
}, (testSchedulerPackage, frameworkVersion) => {
|
|
1373
|
+
const oldCreateTestScheduler = testSchedulerPackage.createTestScheduler
|
|
1374
|
+
const newCreateTestScheduler = async function () {
|
|
1375
|
+
if (!isSuitesSkippingEnabled || hasFilteredSkippableSuites) {
|
|
1376
|
+
return oldCreateTestScheduler.apply(this, arguments)
|
|
1377
|
+
}
|
|
1378
|
+
// If suite skipping is enabled and has not filtered skippable suites yet, we'll attempt to do it
|
|
1379
|
+
const scheduler = await oldCreateTestScheduler.apply(this, arguments)
|
|
1380
|
+
shimmer.wrap(scheduler, 'scheduleTests', scheduleTests => getWrappedScheduleTests(scheduleTests, frameworkVersion))
|
|
1381
|
+
return scheduler
|
|
1382
|
+
}
|
|
1383
|
+
testSchedulerPackage.createTestScheduler = newCreateTestScheduler
|
|
1384
|
+
return testSchedulerPackage
|
|
1385
|
+
})
|
|
1386
|
+
|
|
1387
|
+
addHook({
|
|
1388
|
+
name: '@jest/core',
|
|
1389
|
+
file: 'build/TestScheduler.js',
|
|
1390
|
+
versions: ['>=24.8.0 <27.0.0'],
|
|
1391
|
+
}, (testSchedulerPackage, frameworkVersion) => {
|
|
1392
|
+
shimmer.wrap(
|
|
1393
|
+
testSchedulerPackage.default.prototype,
|
|
1394
|
+
'scheduleTests', scheduleTests => getWrappedScheduleTests(scheduleTests, frameworkVersion)
|
|
1395
|
+
)
|
|
1396
|
+
return testSchedulerPackage
|
|
1397
|
+
})
|
|
1398
|
+
|
|
1399
|
+
addHook({
|
|
1400
|
+
name: '@jest/test-sequencer',
|
|
1401
|
+
versions: ['>=28'],
|
|
1402
|
+
}, (sequencerPackage, frameworkVersion) => {
|
|
1403
|
+
shimmer.wrap(sequencerPackage.default.prototype, 'shard', shard => function () {
|
|
1404
|
+
const shardedTests = shard.apply(this, arguments)
|
|
1405
|
+
|
|
1406
|
+
if (!shardedTests.length || !isSuitesSkippingEnabled || !skippableSuites.length) {
|
|
1407
|
+
return shardedTests
|
|
1408
|
+
}
|
|
1409
|
+
const [test] = shardedTests
|
|
1410
|
+
const rootDir = test?.context?.config?.rootDir
|
|
1411
|
+
|
|
1412
|
+
return applySuiteSkipping(shardedTests, rootDir, frameworkVersion)
|
|
1413
|
+
})
|
|
1414
|
+
return sequencerPackage
|
|
1415
|
+
})
|
|
1416
|
+
|
|
1417
|
+
addHook({
|
|
1418
|
+
name: '@jest/reporters',
|
|
1419
|
+
file: 'build/coverage_reporter.js',
|
|
1420
|
+
versions: ['>=24.8.0 <26.6.2'],
|
|
1421
|
+
}, coverageReporterWrapper)
|
|
1422
|
+
|
|
1423
|
+
addHook({
|
|
1424
|
+
name: '@jest/reporters',
|
|
1425
|
+
file: 'build/CoverageReporter.js',
|
|
1426
|
+
versions: ['>=26.6.2'],
|
|
1427
|
+
}, coverageReporterWrapper)
|
|
1428
|
+
|
|
1429
|
+
addHook({
|
|
1430
|
+
name: '@jest/reporters',
|
|
1431
|
+
versions: ['>=30.0.0'],
|
|
1432
|
+
}, (reporters) => {
|
|
1433
|
+
return shimmer.wrap(reporters, 'CoverageReporter', coverageReporterWrapper, { replaceGetter: true })
|
|
1434
|
+
})
|
|
1435
|
+
|
|
1436
|
+
addHook({
|
|
1437
|
+
name: '@jest/core',
|
|
1438
|
+
file: 'build/cli/index.js',
|
|
1439
|
+
versions: ['>=24.8.0 <30.0.0'],
|
|
1440
|
+
}, getCliWrapper(false))
|
|
1441
|
+
|
|
1442
|
+
addHook({
|
|
1443
|
+
name: '@jest/core',
|
|
1444
|
+
versions: ['>=30.0.0'],
|
|
1445
|
+
}, getCliWrapper(true))
|
|
1446
|
+
|
|
1447
|
+
function jestAdapterWrapper (jestAdapter, jestVersion) {
|
|
1448
|
+
const adapter = jestAdapter.default ?? jestAdapter
|
|
1449
|
+
const newAdapter = shimmer.wrapFunction(adapter, adapter => function () {
|
|
1450
|
+
const environment = arguments[2]
|
|
1451
|
+
if (!environment || !environment.testEnvironmentOptions) {
|
|
1452
|
+
return adapter.apply(this, arguments)
|
|
1453
|
+
}
|
|
1454
|
+
testSuiteStartCh.publish({
|
|
1455
|
+
testSuite: environment.testSuite,
|
|
1456
|
+
testEnvironmentOptions: environment.testEnvironmentOptions,
|
|
1457
|
+
testSourceFile: environment.testSourceFile,
|
|
1458
|
+
displayName: environment.displayName,
|
|
1459
|
+
frameworkVersion: jestVersion,
|
|
1460
|
+
testSuiteAbsolutePath: environment.testSuiteAbsolutePath,
|
|
1461
|
+
})
|
|
1462
|
+
return adapter.apply(this, arguments).then(suiteResults => {
|
|
1463
|
+
const { numFailingTests, skipped, failureMessage: errorMessage } = suiteResults
|
|
1464
|
+
let status = 'pass'
|
|
1465
|
+
if (skipped) {
|
|
1466
|
+
status = 'skipped'
|
|
1467
|
+
} else if (numFailingTests !== 0) {
|
|
1468
|
+
status = 'fail'
|
|
1469
|
+
}
|
|
1470
|
+
|
|
1471
|
+
/**
|
|
1472
|
+
* Child processes do not each request ITR configuration, so the jest's parent process
|
|
1473
|
+
* needs to pass them the configuration. This is done via _ddTestCodeCoverageEnabled, which
|
|
1474
|
+
* controls whether coverage is reported.
|
|
1475
|
+
*/
|
|
1476
|
+
if (environment.testEnvironmentOptions?._ddTestCodeCoverageEnabled) {
|
|
1477
|
+
const root = environment.repositoryRoot || environment.rootDir
|
|
1478
|
+
|
|
1479
|
+
const getFilesWithPath = (files) => files.map(file => getTestSuitePath(file, root))
|
|
1480
|
+
|
|
1481
|
+
const coverageFiles = getFilesWithPath(getCoveredFilenamesFromCoverage(environment.global.__coverage__))
|
|
1482
|
+
const mockedFiles = getFilesWithPath(testSuiteMockedFiles.get(environment.testSuiteAbsolutePath) || [])
|
|
1483
|
+
|
|
1484
|
+
testSuiteCodeCoverageCh.publish({
|
|
1485
|
+
coverageFiles,
|
|
1486
|
+
testSuite: environment.testSourceFile,
|
|
1487
|
+
mockedFiles,
|
|
1488
|
+
testSuiteAbsolutePath: environment.testSuiteAbsolutePath,
|
|
1489
|
+
})
|
|
1490
|
+
}
|
|
1491
|
+
testSuiteFinishCh.publish({ status, errorMessage, testSuiteAbsolutePath: environment.testSuiteAbsolutePath })
|
|
1492
|
+
|
|
1493
|
+
// Cleanup per-suite state to avoid memory leaks
|
|
1494
|
+
testSuiteMockedFiles.delete(environment.testSuiteAbsolutePath)
|
|
1495
|
+
testSuiteJestObjects.delete(environment.testSuiteAbsolutePath)
|
|
1496
|
+
|
|
1497
|
+
return suiteResults
|
|
1498
|
+
}).catch(error => {
|
|
1499
|
+
testSuiteFinishCh.publish({ status: 'fail', error, testSuiteAbsolutePath: environment.testSuiteAbsolutePath })
|
|
1500
|
+
|
|
1501
|
+
// Cleanup per-suite state to avoid memory leaks
|
|
1502
|
+
testSuiteMockedFiles.delete(environment.testSuiteAbsolutePath)
|
|
1503
|
+
testSuiteJestObjects.delete(environment.testSuiteAbsolutePath)
|
|
1504
|
+
|
|
1505
|
+
throw error
|
|
1506
|
+
})
|
|
1507
|
+
})
|
|
1508
|
+
if (jestAdapter.default) {
|
|
1509
|
+
jestAdapter.default = newAdapter
|
|
1510
|
+
} else {
|
|
1511
|
+
jestAdapter = newAdapter
|
|
1512
|
+
}
|
|
1513
|
+
|
|
1514
|
+
return jestAdapter
|
|
1515
|
+
}
|
|
1516
|
+
|
|
1517
|
+
addHook({
|
|
1518
|
+
name: 'jest-circus',
|
|
1519
|
+
file: 'build/runner.js',
|
|
1520
|
+
versions: ['>=30.0.0'],
|
|
1521
|
+
}, jestAdapterWrapper)
|
|
1522
|
+
|
|
1523
|
+
addHook({
|
|
1524
|
+
name: 'jest-circus',
|
|
1525
|
+
file: 'build/legacy-code-todo-rewrite/jestAdapter.js',
|
|
1526
|
+
versions: ['>=24.8.0'],
|
|
1527
|
+
}, jestAdapterWrapper)
|
|
1528
|
+
|
|
1529
|
+
function configureTestEnvironment (readConfigsResult) {
|
|
1530
|
+
const { configs } = readConfigsResult
|
|
1531
|
+
testSessionConfigurationCh.publish(configs.map(config => config.testEnvironmentOptions))
|
|
1532
|
+
// We can't directly use isCodeCoverageEnabled when reporting coverage in `jestAdapterWrapper`
|
|
1533
|
+
// because `jestAdapterWrapper` runs in a different process. We have to go through `testEnvironmentOptions`
|
|
1534
|
+
for (const config of configs) {
|
|
1535
|
+
config.testEnvironmentOptions._ddTestCodeCoverageEnabled = isCodeCoverageEnabled
|
|
1536
|
+
}
|
|
1537
|
+
|
|
1538
|
+
isUserCodeCoverageEnabled = !!readConfigsResult.globalConfig.collectCoverage
|
|
1539
|
+
isCodeCoverageEnabledBecauseOfUs = isCodeCoverageEnabled && !isUserCodeCoverageEnabled
|
|
1540
|
+
|
|
1541
|
+
if (readConfigsResult.globalConfig.forceExit) {
|
|
1542
|
+
log.warn("Jest's '--forceExit' flag has been passed. This may cause loss of data.")
|
|
1543
|
+
}
|
|
1544
|
+
|
|
1545
|
+
if (isCodeCoverageEnabledBecauseOfUs) {
|
|
1546
|
+
const globalConfig = {
|
|
1547
|
+
...readConfigsResult.globalConfig,
|
|
1548
|
+
collectCoverage: true,
|
|
1549
|
+
}
|
|
1550
|
+
readConfigsResult.globalConfig = globalConfig
|
|
1551
|
+
}
|
|
1552
|
+
if (isSuitesSkippingEnabled) {
|
|
1553
|
+
// If suite skipping is enabled, we pass `passWithNoTests` in case every test gets skipped.
|
|
1554
|
+
const globalConfig = {
|
|
1555
|
+
...readConfigsResult.globalConfig,
|
|
1556
|
+
passWithNoTests: true,
|
|
1557
|
+
}
|
|
1558
|
+
if (isCodeCoverageEnabledBecauseOfUs && !isKeepingCoverageConfiguration) {
|
|
1559
|
+
globalConfig.coverageReporters = ['none']
|
|
1560
|
+
readConfigsResult.configs = configs.map(config => ({
|
|
1561
|
+
...config,
|
|
1562
|
+
coverageReporters: ['none'],
|
|
1563
|
+
}))
|
|
1564
|
+
}
|
|
1565
|
+
readConfigsResult.globalConfig = globalConfig
|
|
1566
|
+
}
|
|
1567
|
+
|
|
1568
|
+
return readConfigsResult
|
|
1569
|
+
}
|
|
1570
|
+
|
|
1571
|
+
function jestConfigAsyncWrapper (jestConfig) {
|
|
1572
|
+
return shimmer.wrap(jestConfig, 'readConfigs', readConfigs => async function () {
|
|
1573
|
+
const readConfigsResult = await readConfigs.apply(this, arguments)
|
|
1574
|
+
configureTestEnvironment(readConfigsResult)
|
|
1575
|
+
return readConfigsResult
|
|
1576
|
+
})
|
|
1577
|
+
}
|
|
1578
|
+
|
|
1579
|
+
function jestConfigSyncWrapper (jestConfig) {
|
|
1580
|
+
return shimmer.wrap(jestConfig, 'readConfigs', readConfigs => function () {
|
|
1581
|
+
const readConfigsResult = readConfigs.apply(this, arguments)
|
|
1582
|
+
configureTestEnvironment(readConfigsResult)
|
|
1583
|
+
return readConfigsResult
|
|
1584
|
+
})
|
|
1585
|
+
}
|
|
1586
|
+
|
|
1587
|
+
const DD_TEST_ENVIRONMENT_OPTION_KEYS = [
|
|
1588
|
+
'_ddTestModuleId',
|
|
1589
|
+
'_ddTestSessionId',
|
|
1590
|
+
'_ddTestCommand',
|
|
1591
|
+
'_ddTestSessionName',
|
|
1592
|
+
'_ddForcedToRun',
|
|
1593
|
+
'_ddUnskippable',
|
|
1594
|
+
'_ddItrCorrelationId',
|
|
1595
|
+
'_ddKnownTests',
|
|
1596
|
+
'_ddIsEarlyFlakeDetectionEnabled',
|
|
1597
|
+
'_ddEarlyFlakeDetectionSlowTestRetries',
|
|
1598
|
+
'_ddRepositoryRoot',
|
|
1599
|
+
'_ddIsFlakyTestRetriesEnabled',
|
|
1600
|
+
'_ddFlakyTestRetriesCount',
|
|
1601
|
+
'_ddIsDiEnabled',
|
|
1602
|
+
'_ddIsKnownTestsEnabled',
|
|
1603
|
+
'_ddIsTestManagementTestsEnabled',
|
|
1604
|
+
'_ddTestManagementTests',
|
|
1605
|
+
'_ddTestManagementAttemptToFixRetries',
|
|
1606
|
+
'_ddModifiedFiles',
|
|
1607
|
+
]
|
|
1608
|
+
|
|
1609
|
+
function removeDatadogTestEnvironmentOptions (testEnvironmentOptions) {
|
|
1610
|
+
const removedEntries = []
|
|
1611
|
+
|
|
1612
|
+
for (const key of DD_TEST_ENVIRONMENT_OPTION_KEYS) {
|
|
1613
|
+
if (!Object.hasOwn(testEnvironmentOptions, key)) {
|
|
1614
|
+
continue
|
|
1615
|
+
}
|
|
1616
|
+
|
|
1617
|
+
removedEntries.push([key, testEnvironmentOptions[key]])
|
|
1618
|
+
delete testEnvironmentOptions[key]
|
|
1619
|
+
}
|
|
1620
|
+
|
|
1621
|
+
return function restoreDatadogTestEnvironmentOptions () {
|
|
1622
|
+
for (const [key, value] of removedEntries) {
|
|
1623
|
+
testEnvironmentOptions[key] = value
|
|
1624
|
+
}
|
|
1625
|
+
}
|
|
1626
|
+
}
|
|
1627
|
+
|
|
1628
|
+
/**
|
|
1629
|
+
* Wrap `createScriptTransformer` to temporarily hide Datadog-specific
|
|
1630
|
+
* `testEnvironmentOptions` keys while Jest builds its transform config.
|
|
1631
|
+
*
|
|
1632
|
+
* @param {Function} createScriptTransformer
|
|
1633
|
+
* @returns {Function}
|
|
1634
|
+
*/
|
|
1635
|
+
function wrapCreateScriptTransformer (createScriptTransformer) {
|
|
1636
|
+
return function (config) {
|
|
1637
|
+
const testEnvironmentOptions = config?.testEnvironmentOptions
|
|
1638
|
+
|
|
1639
|
+
if (!testEnvironmentOptions) {
|
|
1640
|
+
return createScriptTransformer.apply(this, arguments)
|
|
1641
|
+
}
|
|
1642
|
+
|
|
1643
|
+
const restoreTestEnvironmentOptions = removeDatadogTestEnvironmentOptions(testEnvironmentOptions)
|
|
1644
|
+
|
|
1645
|
+
try {
|
|
1646
|
+
const result = createScriptTransformer.apply(this, arguments)
|
|
1647
|
+
|
|
1648
|
+
if (result?.then) {
|
|
1649
|
+
return result.finally(restoreTestEnvironmentOptions)
|
|
1650
|
+
}
|
|
1651
|
+
|
|
1652
|
+
restoreTestEnvironmentOptions()
|
|
1653
|
+
return result
|
|
1654
|
+
} catch (e) {
|
|
1655
|
+
restoreTestEnvironmentOptions()
|
|
1656
|
+
throw e
|
|
1657
|
+
}
|
|
1658
|
+
}
|
|
1659
|
+
}
|
|
1660
|
+
|
|
1661
|
+
addHook({
|
|
1662
|
+
name: '@jest/transform',
|
|
1663
|
+
versions: ['>=24.8.0 <30.0.0'],
|
|
1664
|
+
file: 'build/ScriptTransformer.js',
|
|
1665
|
+
}, transformPackage => {
|
|
1666
|
+
transformPackage.createScriptTransformer = wrapCreateScriptTransformer(transformPackage.createScriptTransformer)
|
|
1667
|
+
|
|
1668
|
+
return transformPackage
|
|
1669
|
+
})
|
|
1670
|
+
|
|
1671
|
+
addHook({
|
|
1672
|
+
name: '@jest/transform',
|
|
1673
|
+
versions: ['>=30.0.0'],
|
|
1674
|
+
}, transformPackage => {
|
|
1675
|
+
return shimmer.wrap(transformPackage, 'createScriptTransformer', wrapCreateScriptTransformer, { replaceGetter: true })
|
|
1676
|
+
})
|
|
1677
|
+
|
|
1678
|
+
/**
|
|
1679
|
+
* Hook to remove the test paths (test suite) that are part of `skippableSuites`
|
|
1680
|
+
*/
|
|
1681
|
+
addHook({
|
|
1682
|
+
name: '@jest/core',
|
|
1683
|
+
versions: ['>=24.8.0 <30.0.0'],
|
|
1684
|
+
file: 'build/SearchSource.js',
|
|
1685
|
+
}, searchSourceWrapper)
|
|
1686
|
+
|
|
1687
|
+
// from 25.1.0 on, readConfigs becomes async
|
|
1688
|
+
addHook({
|
|
1689
|
+
name: 'jest-config',
|
|
1690
|
+
versions: ['>=25.1.0'],
|
|
1691
|
+
}, jestConfigAsyncWrapper)
|
|
1692
|
+
|
|
1693
|
+
addHook({
|
|
1694
|
+
name: 'jest-config',
|
|
1695
|
+
versions: ['24.8.0 - 24.9.0'],
|
|
1696
|
+
}, jestConfigSyncWrapper)
|
|
1697
|
+
|
|
1698
|
+
const LIBRARIES_BYPASSING_JEST_REQUIRE_ENGINE = new Set([
|
|
1699
|
+
'selenium-webdriver',
|
|
1700
|
+
'selenium-webdriver/chrome',
|
|
1701
|
+
'selenium-webdriver/edge',
|
|
1702
|
+
'selenium-webdriver/safari',
|
|
1703
|
+
'selenium-webdriver/firefox',
|
|
1704
|
+
'selenium-webdriver/ie',
|
|
1705
|
+
'selenium-webdriver/chromium',
|
|
1706
|
+
'winston',
|
|
1707
|
+
])
|
|
1708
|
+
|
|
1709
|
+
addHook({
|
|
1710
|
+
name: 'jest-runtime',
|
|
1711
|
+
versions: ['>=24.8.0'],
|
|
1712
|
+
}, (runtimePackage) => {
|
|
1713
|
+
const Runtime = runtimePackage.default ?? runtimePackage
|
|
1714
|
+
|
|
1715
|
+
shimmer.wrap(Runtime.prototype, '_createJestObjectFor', _createJestObjectFor => function (from) {
|
|
1716
|
+
const result = _createJestObjectFor.apply(this, arguments)
|
|
1717
|
+
const suiteFilePath = this._testPath || from
|
|
1718
|
+
|
|
1719
|
+
// Store the jest object so we can access it later for resetting mock state
|
|
1720
|
+
if (suiteFilePath) {
|
|
1721
|
+
testSuiteJestObjects.set(suiteFilePath, result)
|
|
1722
|
+
}
|
|
1723
|
+
|
|
1724
|
+
shimmer.wrap(result, 'mock', mock => function (moduleName) {
|
|
1725
|
+
// If the library is mocked with `jest.mock`, we don't want to bypass jest's own require engine
|
|
1726
|
+
if (LIBRARIES_BYPASSING_JEST_REQUIRE_ENGINE.has(moduleName)) {
|
|
1727
|
+
LIBRARIES_BYPASSING_JEST_REQUIRE_ENGINE.delete(moduleName)
|
|
1728
|
+
}
|
|
1729
|
+
if (suiteFilePath) {
|
|
1730
|
+
const existingMockedFiles = testSuiteMockedFiles.get(suiteFilePath) || []
|
|
1731
|
+
const suiteDir = path.dirname(suiteFilePath)
|
|
1732
|
+
const mockPath = path.resolve(suiteDir, moduleName)
|
|
1733
|
+
existingMockedFiles.push(mockPath)
|
|
1734
|
+
testSuiteMockedFiles.set(suiteFilePath, existingMockedFiles)
|
|
1735
|
+
}
|
|
1736
|
+
return mock.apply(this, arguments)
|
|
1737
|
+
})
|
|
1738
|
+
return result
|
|
1739
|
+
})
|
|
1740
|
+
|
|
1741
|
+
shimmer.wrap(Runtime.prototype, 'requireModuleOrMock', requireModuleOrMock => function (from, moduleName) {
|
|
1742
|
+
// `requireModuleOrMock` may log errors to the console. If we don't remove ourselves
|
|
1743
|
+
// from the stack trace, the user might see a useless stack trace rather than the error
|
|
1744
|
+
// that `jest` tries to show.
|
|
1745
|
+
const originalPrepareStackTrace = Error.prepareStackTrace
|
|
1746
|
+
Error.prepareStackTrace = function (error, structuredStackTrace) {
|
|
1747
|
+
const filteredStackTrace = structuredStackTrace
|
|
1748
|
+
.filter(callSite => !callSite.getFileName()?.includes('datadog-instrumentations/src/jest.js'))
|
|
1749
|
+
|
|
1750
|
+
return originalPrepareStackTrace(error, filteredStackTrace)
|
|
1751
|
+
}
|
|
1752
|
+
try {
|
|
1753
|
+
// TODO: do this for every library that we instrument
|
|
1754
|
+
if (LIBRARIES_BYPASSING_JEST_REQUIRE_ENGINE.has(moduleName)) {
|
|
1755
|
+
// To bypass jest's own require engine
|
|
1756
|
+
return this._requireCoreModule(moduleName)
|
|
1757
|
+
}
|
|
1758
|
+
// This means that `@fast-check/jest` is used in the test file.
|
|
1759
|
+
if (moduleName === '@fast-check/jest') {
|
|
1760
|
+
testSuiteAbsolutePathsWithFastCheck.add(this._testPath)
|
|
1761
|
+
}
|
|
1762
|
+
const returnedValue = requireModuleOrMock.apply(this, arguments)
|
|
1763
|
+
if (process.exitCode === 1) {
|
|
1764
|
+
if (this.loggedReferenceErrors?.size > 0) {
|
|
1765
|
+
const errorMessage = [...this.loggedReferenceErrors][0]
|
|
1766
|
+
testSuiteErrorCh.publish({
|
|
1767
|
+
errorMessage,
|
|
1768
|
+
testSuiteAbsolutePath: this._testPath,
|
|
1769
|
+
})
|
|
1770
|
+
} else {
|
|
1771
|
+
testSuiteErrorCh.publish({
|
|
1772
|
+
errorMessage: 'An error occurred while importing a module',
|
|
1773
|
+
testSuiteAbsolutePath: this._testPath,
|
|
1774
|
+
})
|
|
1775
|
+
}
|
|
1776
|
+
}
|
|
1777
|
+
return returnedValue
|
|
1778
|
+
} finally {
|
|
1779
|
+
// Restore original prepareStackTrace
|
|
1780
|
+
Error.prepareStackTrace = originalPrepareStackTrace
|
|
1781
|
+
}
|
|
1782
|
+
})
|
|
1783
|
+
|
|
1784
|
+
return runtimePackage
|
|
1785
|
+
})
|
|
1786
|
+
|
|
1787
|
+
function onMessageWrapper (onMessage) {
|
|
1788
|
+
return function () {
|
|
1789
|
+
const [code, data] = arguments[0]
|
|
1790
|
+
if (code === JEST_WORKER_TRACE_PAYLOAD_CODE) { // datadog trace payload
|
|
1791
|
+
workerReportTraceCh.publish(data)
|
|
1792
|
+
return
|
|
1793
|
+
}
|
|
1794
|
+
if (code === JEST_WORKER_COVERAGE_PAYLOAD_CODE) { // datadog coverage payload
|
|
1795
|
+
workerReportCoverageCh.publish(data)
|
|
1796
|
+
return
|
|
1797
|
+
}
|
|
1798
|
+
if (code === JEST_WORKER_LOGS_PAYLOAD_CODE) { // datadog logs payload
|
|
1799
|
+
workerReportLogsCh.publish(data)
|
|
1800
|
+
return
|
|
1801
|
+
}
|
|
1802
|
+
if (code === JEST_WORKER_TELEMETRY_PAYLOAD_CODE) { // datadog telemetry payload
|
|
1803
|
+
workerReportTelemetryCh.publish(data)
|
|
1804
|
+
return
|
|
1805
|
+
}
|
|
1806
|
+
return onMessage.apply(this, arguments)
|
|
1807
|
+
}
|
|
1808
|
+
}
|
|
1809
|
+
|
|
1810
|
+
function sendWrapper (send) {
|
|
1811
|
+
return function (request) {
|
|
1812
|
+
if (!isKnownTestsEnabled && !isTestManagementTestsEnabled && !isImpactedTestsEnabled) {
|
|
1813
|
+
return send.apply(this, arguments)
|
|
1814
|
+
}
|
|
1815
|
+
const [type] = request
|
|
1816
|
+
|
|
1817
|
+
// https://github.com/jestjs/jest/blob/1d682f21c7a35da4d3ab3a1436a357b980ebd0fa/packages/jest-worker/src/workers/ChildProcessWorker.ts#L424
|
|
1818
|
+
if (type === CHILD_MESSAGE_CALL) {
|
|
1819
|
+
// This is the message that the main process sends to the worker to run a test suite (=test file).
|
|
1820
|
+
// In here we modify the `config.testEnvironmentOptions` to include the known tests for the suite.
|
|
1821
|
+
// This way the suite only knows about the tests that are part of it.
|
|
1822
|
+
const args = request.at(-1)
|
|
1823
|
+
if (args.length > 1) {
|
|
1824
|
+
return send.apply(this, arguments)
|
|
1825
|
+
}
|
|
1826
|
+
if (!args[0]?.config) {
|
|
1827
|
+
return send.apply(this, arguments)
|
|
1828
|
+
}
|
|
1829
|
+
const [{ globalConfig, config, path: testSuiteAbsolutePath }] = args
|
|
1830
|
+
const testSuite = getTestSuitePath(testSuiteAbsolutePath, globalConfig.rootDir || process.cwd())
|
|
1831
|
+
const suiteKnownTests = knownTests?.jest?.[testSuite] || []
|
|
1832
|
+
|
|
1833
|
+
const suiteTestManagementTests = testManagementTests?.jest?.suites?.[testSuite]?.tests || {}
|
|
1834
|
+
|
|
1835
|
+
args[0].config = {
|
|
1836
|
+
...config,
|
|
1837
|
+
testEnvironmentOptions: {
|
|
1838
|
+
...config.testEnvironmentOptions,
|
|
1839
|
+
_ddKnownTests: suiteKnownTests,
|
|
1840
|
+
_ddTestManagementTests: suiteTestManagementTests,
|
|
1841
|
+
// TODO: figure out if we can reduce the size of the modified files object
|
|
1842
|
+
// Can we use `testSuite` (it'd have to be relative to repository root though)
|
|
1843
|
+
_ddModifiedFiles: modifiedFiles,
|
|
1844
|
+
},
|
|
1845
|
+
}
|
|
1846
|
+
}
|
|
1847
|
+
return send.apply(this, arguments)
|
|
1848
|
+
}
|
|
1849
|
+
}
|
|
1850
|
+
|
|
1851
|
+
function enqueueWrapper (enqueue) {
|
|
1852
|
+
return function () {
|
|
1853
|
+
shimmer.wrap(arguments[0], 'onStart', onStart => function (worker) {
|
|
1854
|
+
if (worker && !wrappedWorkers.has(worker)) {
|
|
1855
|
+
shimmer.wrap(worker._child, 'send', sendWrapper)
|
|
1856
|
+
shimmer.wrap(worker, '_onMessage', onMessageWrapper)
|
|
1857
|
+
worker._child.removeAllListeners('message')
|
|
1858
|
+
worker._child.on('message', worker._onMessage.bind(worker))
|
|
1859
|
+
wrappedWorkers.add(worker)
|
|
1860
|
+
}
|
|
1861
|
+
return onStart.apply(this, arguments)
|
|
1862
|
+
})
|
|
1863
|
+
return enqueue.apply(this, arguments)
|
|
1864
|
+
}
|
|
1865
|
+
}
|
|
1866
|
+
|
|
1867
|
+
/*
|
|
1868
|
+
* This hook does three things:
|
|
1869
|
+
* - Pass known tests to the workers.
|
|
1870
|
+
* - Pass test management tests to the workers.
|
|
1871
|
+
* - Receive trace, coverage and logs payloads from the workers.
|
|
1872
|
+
*/
|
|
1873
|
+
addHook({
|
|
1874
|
+
name: 'jest-worker',
|
|
1875
|
+
versions: ['>=24.9.0 <30.0.0'],
|
|
1876
|
+
file: 'build/workers/ChildProcessWorker.js',
|
|
1877
|
+
}, (childProcessWorker) => {
|
|
1878
|
+
const ChildProcessWorker = childProcessWorker.default
|
|
1879
|
+
shimmer.wrap(ChildProcessWorker.prototype, 'send', sendWrapper)
|
|
1880
|
+
if (ChildProcessWorker.prototype._onMessage) {
|
|
1881
|
+
shimmer.wrap(ChildProcessWorker.prototype, '_onMessage', onMessageWrapper)
|
|
1882
|
+
} else if (ChildProcessWorker.prototype.onMessage) {
|
|
1883
|
+
shimmer.wrap(ChildProcessWorker.prototype, 'onMessage', onMessageWrapper)
|
|
1884
|
+
}
|
|
1885
|
+
return childProcessWorker
|
|
1886
|
+
})
|
|
1887
|
+
|
|
1888
|
+
addHook({
|
|
1889
|
+
name: 'jest-worker',
|
|
1890
|
+
versions: ['>=30.0.0'],
|
|
1891
|
+
}, (jestWorkerPackage) => {
|
|
1892
|
+
shimmer.wrap(jestWorkerPackage.FifoQueue.prototype, 'enqueue', enqueueWrapper)
|
|
1893
|
+
shimmer.wrap(jestWorkerPackage.PriorityQueue.prototype, 'enqueue', enqueueWrapper)
|
|
1894
|
+
return jestWorkerPackage
|
|
1895
|
+
})
|