dd-trace 3.3.1 → 3.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE-3rdparty.csv +8 -0
- package/README.md +108 -43
- package/ci/init.js +6 -1
- package/ext/exporters.d.ts +2 -1
- package/ext/exporters.js +2 -1
- package/index.d.ts +129 -36
- package/package.json +18 -9
- package/packages/datadog-instrumentations/src/body-parser.js +26 -0
- package/packages/datadog-instrumentations/src/cassandra-driver.js +7 -7
- package/packages/datadog-instrumentations/src/child-process.js +30 -0
- package/packages/datadog-instrumentations/src/connect.js +15 -15
- package/packages/datadog-instrumentations/src/cucumber.js +1 -3
- package/packages/datadog-instrumentations/src/elasticsearch.js +51 -47
- package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +1 -1
- package/packages/datadog-instrumentations/src/helpers/hooks.js +9 -0
- package/packages/datadog-instrumentations/src/helpers/register.js +5 -0
- package/packages/datadog-instrumentations/src/http/server.js +20 -12
- package/packages/datadog-instrumentations/src/http2/server.js +67 -1
- package/packages/datadog-instrumentations/src/jest.js +182 -25
- package/packages/datadog-instrumentations/src/koa.js +32 -32
- package/packages/datadog-instrumentations/src/ldapjs.js +91 -0
- package/packages/datadog-instrumentations/src/mariadb.js +63 -0
- package/packages/datadog-instrumentations/src/memcached.js +1 -4
- package/packages/datadog-instrumentations/src/mocha.js +135 -24
- package/packages/datadog-instrumentations/src/next.js +10 -2
- package/packages/datadog-instrumentations/src/opensearch.js +10 -0
- package/packages/datadog-instrumentations/src/oracledb.js +8 -8
- package/packages/datadog-instrumentations/src/pg.js +7 -3
- package/packages/datadog-instrumentations/src/qs.js +24 -0
- package/packages/datadog-instrumentations/src/redis.js +12 -3
- package/packages/datadog-instrumentations/src/restify.js +5 -1
- package/packages/datadog-instrumentations/src/rhea.js +29 -15
- package/packages/datadog-instrumentations/src/router.js +23 -23
- package/packages/datadog-plugin-amqp10/src/consumer.js +32 -0
- package/packages/datadog-plugin-amqp10/src/index.js +11 -101
- package/packages/datadog-plugin-amqp10/src/producer.js +34 -0
- package/packages/datadog-plugin-amqp10/src/util.js +15 -0
- package/packages/datadog-plugin-amqplib/src/client.js +38 -0
- package/packages/datadog-plugin-amqplib/src/consumer.js +40 -0
- package/packages/datadog-plugin-amqplib/src/index.js +14 -102
- package/packages/datadog-plugin-amqplib/src/producer.js +37 -0
- package/packages/datadog-plugin-amqplib/src/util.js +14 -0
- package/packages/datadog-plugin-cassandra-driver/src/index.js +22 -60
- package/packages/datadog-plugin-cucumber/src/index.js +14 -33
- package/packages/datadog-plugin-cypress/src/plugin.js +2 -1
- package/packages/datadog-plugin-dns/src/index.js +16 -91
- package/packages/datadog-plugin-dns/src/lookup.js +40 -0
- package/packages/datadog-plugin-dns/src/lookup_service.js +24 -0
- package/packages/datadog-plugin-dns/src/resolve.js +24 -0
- package/packages/datadog-plugin-dns/src/reverse.js +21 -0
- package/packages/datadog-plugin-elasticsearch/src/index.js +24 -60
- package/packages/datadog-plugin-google-cloud-pubsub/src/client.js +24 -0
- package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +41 -0
- package/packages/datadog-plugin-google-cloud-pubsub/src/index.js +14 -99
- package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +33 -0
- package/packages/datadog-plugin-graphql/src/execute.js +73 -0
- package/packages/datadog-plugin-graphql/src/index.js +14 -176
- package/packages/datadog-plugin-graphql/src/parse.js +32 -0
- package/packages/datadog-plugin-graphql/src/resolve.js +70 -76
- package/packages/datadog-plugin-graphql/src/validate.js +28 -0
- package/packages/datadog-plugin-grpc/src/client.js +46 -55
- package/packages/datadog-plugin-grpc/src/index.js +7 -24
- package/packages/datadog-plugin-grpc/src/server.js +50 -52
- package/packages/datadog-plugin-grpc/src/util.js +15 -14
- package/packages/datadog-plugin-http/src/client.js +15 -5
- package/packages/datadog-plugin-http/src/index.js +7 -22
- package/packages/datadog-plugin-http/src/server.js +19 -3
- package/packages/datadog-plugin-http2/src/client.js +20 -1
- package/packages/datadog-plugin-http2/src/index.js +8 -26
- package/packages/datadog-plugin-http2/src/server.js +44 -0
- package/packages/datadog-plugin-jest/src/index.js +41 -65
- package/packages/datadog-plugin-kafkajs/src/consumer.js +42 -0
- package/packages/datadog-plugin-kafkajs/src/index.js +11 -87
- package/packages/datadog-plugin-kafkajs/src/producer.js +31 -0
- package/packages/datadog-plugin-mariadb/src/index.js +10 -0
- package/packages/datadog-plugin-memcached/src/index.js +17 -52
- package/packages/datadog-plugin-mocha/src/index.js +40 -60
- package/packages/datadog-plugin-moleculer/src/client.js +22 -36
- package/packages/datadog-plugin-moleculer/src/index.js +8 -26
- package/packages/datadog-plugin-moleculer/src/server.js +18 -30
- package/packages/datadog-plugin-mongodb-core/src/index.js +23 -51
- package/packages/datadog-plugin-mysql/src/index.js +23 -52
- package/packages/datadog-plugin-mysql2/src/index.js +1 -3
- package/packages/datadog-plugin-net/src/index.js +4 -0
- package/packages/datadog-plugin-net/src/ipc.js +21 -0
- package/packages/datadog-plugin-net/src/tcp.js +46 -0
- package/packages/datadog-plugin-next/src/index.js +3 -0
- package/packages/datadog-plugin-opensearch/src/index.js +11 -0
- package/packages/datadog-plugin-oracledb/src/index.js +29 -55
- package/packages/datadog-plugin-pg/src/index.js +27 -51
- package/packages/datadog-plugin-redis/src/index.js +29 -60
- package/packages/datadog-plugin-rhea/src/consumer.js +55 -0
- package/packages/datadog-plugin-rhea/src/index.js +11 -96
- package/packages/datadog-plugin-rhea/src/producer.js +45 -0
- package/packages/datadog-plugin-router/src/index.js +13 -2
- package/packages/datadog-plugin-sharedb/src/index.js +22 -39
- package/packages/datadog-plugin-tedious/src/index.js +20 -41
- package/packages/dd-trace/src/appsec/addresses.js +3 -1
- package/packages/dd-trace/src/appsec/blocking.js +44 -0
- package/packages/dd-trace/src/appsec/callbacks/ddwaf.js +8 -6
- package/packages/dd-trace/src/appsec/gateway/engine/engine.js +1 -1
- package/packages/dd-trace/src/appsec/gateway/engine/index.js +7 -2
- package/packages/dd-trace/src/appsec/gateway/engine/runner.js +0 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +4 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/command-injection-analyzer.js +11 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/injection-analyzer.js +19 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/ldap-injection-analyzer.js +11 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/sql-injection-analyzer.js +13 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/vulnerability-analyzer.js +43 -5
- package/packages/dd-trace/src/appsec/iast/iast-context.js +3 -1
- package/packages/dd-trace/src/appsec/iast/index.js +24 -8
- package/packages/dd-trace/src/appsec/iast/overhead-controller.js +20 -1
- package/packages/dd-trace/src/appsec/iast/path-line.js +17 -6
- package/packages/dd-trace/src/appsec/iast/taint-tracking/csi-methods.js +17 -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 +18 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/operations.js +98 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/origin-types.js +4 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +38 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +67 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +103 -0
- package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +98 -30
- package/packages/dd-trace/src/appsec/index.js +79 -25
- package/packages/dd-trace/src/{plugins/util → appsec}/ip_blocklist.js +0 -0
- package/packages/dd-trace/src/appsec/ip_extractor.js +98 -0
- package/packages/dd-trace/src/appsec/recommended.json +134 -53
- package/packages/dd-trace/src/appsec/remote_config/capabilities.js +7 -0
- package/packages/dd-trace/src/appsec/remote_config/index.js +56 -0
- package/packages/dd-trace/src/appsec/remote_config/manager.js +264 -0
- package/packages/dd-trace/src/{exporters → appsec/remote_config}/scheduler.js +9 -9
- package/packages/dd-trace/src/appsec/rule_manager.js +61 -1
- package/packages/dd-trace/src/appsec/templates/blocked.html +99 -0
- package/packages/dd-trace/src/appsec/templates/blocked.json +8 -0
- package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +66 -0
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +9 -5
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/index.js +19 -51
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +10 -5
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +202 -0
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +51 -62
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-itr-configuration.js +89 -0
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +82 -0
- package/packages/dd-trace/src/config.js +119 -35
- package/packages/dd-trace/src/constants.js +9 -1
- package/packages/dd-trace/src/dogstatsd.js +42 -10
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +10 -2
- package/packages/dd-trace/src/encode/coverage-ci-visibility.js +0 -1
- package/packages/dd-trace/src/exporter.js +3 -0
- package/packages/dd-trace/src/exporters/agent/index.js +10 -2
- package/packages/dd-trace/src/exporters/agent/writer.js +2 -9
- package/packages/dd-trace/src/exporters/common/agent-info-exporter.js +82 -0
- package/packages/dd-trace/src/exporters/common/request.js +51 -1
- package/packages/dd-trace/src/exporters/span-stats/index.js +6 -2
- package/packages/dd-trace/src/format.js +29 -10
- package/packages/dd-trace/src/lambda/handler.js +72 -0
- package/packages/dd-trace/src/lambda/index.js +5 -0
- package/packages/dd-trace/src/lambda/runtime/errors.js +20 -0
- package/packages/dd-trace/src/lambda/runtime/patch.js +74 -0
- package/packages/dd-trace/src/lambda/runtime/ritm.js +138 -0
- package/packages/dd-trace/src/metrics.js +15 -2
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +1 -5
- package/packages/dd-trace/src/opentracing/span.js +2 -1
- package/packages/dd-trace/src/opentracing/span_context.js +9 -0
- package/packages/dd-trace/src/plugin_manager.js +11 -17
- package/packages/dd-trace/src/plugins/cache.js +9 -0
- package/packages/dd-trace/src/plugins/ci_plugin.js +97 -0
- package/packages/dd-trace/src/plugins/client.js +9 -0
- package/packages/dd-trace/src/plugins/composite.js +26 -0
- package/packages/dd-trace/src/plugins/consumer.js +9 -0
- package/packages/dd-trace/src/plugins/database.js +55 -0
- package/packages/dd-trace/src/plugins/incoming.js +7 -0
- package/packages/dd-trace/src/plugins/index.js +3 -0
- package/packages/dd-trace/src/plugins/log_plugin.js +2 -2
- package/packages/dd-trace/src/plugins/outgoing.js +31 -0
- package/packages/dd-trace/src/plugins/plugin.js +3 -0
- package/packages/dd-trace/src/plugins/producer.js +9 -0
- package/packages/dd-trace/src/plugins/server.js +9 -0
- package/packages/dd-trace/src/plugins/storage.js +21 -0
- package/packages/dd-trace/src/plugins/tracing.js +94 -0
- package/packages/dd-trace/src/plugins/util/ci.js +40 -4
- package/packages/dd-trace/src/plugins/util/git.js +58 -18
- package/packages/dd-trace/src/plugins/util/test.js +71 -8
- package/packages/dd-trace/src/plugins/util/user-provided-git.js +14 -1
- package/packages/dd-trace/src/plugins/util/web.js +11 -114
- package/packages/dd-trace/src/priority_sampler.js +6 -2
- package/packages/dd-trace/src/profiling/config.js +11 -6
- package/packages/dd-trace/src/profiling/exporters/agent.js +4 -0
- package/packages/dd-trace/src/profiling/index.js +2 -2
- package/packages/dd-trace/src/profiling/profiler.js +43 -7
- package/packages/dd-trace/src/proxy.js +8 -16
- package/packages/dd-trace/src/ritm.js +25 -14
- package/packages/dd-trace/src/span_processor.js +17 -0
- package/packages/dd-trace/src/span_sampler.js +77 -0
- package/packages/dd-trace/src/span_stats.js +2 -2
- package/packages/dd-trace/src/telemetry/dependencies.js +21 -7
- package/packages/dd-trace/src/telemetry/index.js +7 -1
- package/packages/dd-trace/src/telemetry/send-data.js +3 -1
- package/packages/dd-trace/src/tracer.js +10 -5
- package/packages/dd-trace/src/util.js +43 -1
|
@@ -7,76 +7,80 @@ const {
|
|
|
7
7
|
} = require('./helpers/instrument')
|
|
8
8
|
const shimmer = require('../../datadog-shimmer')
|
|
9
9
|
|
|
10
|
-
const startCh = channel('apm:elasticsearch:query:start')
|
|
11
|
-
const finishCh = channel('apm:elasticsearch:query:finish')
|
|
12
|
-
const errorCh = channel('apm:elasticsearch:query:error')
|
|
13
|
-
|
|
14
10
|
addHook({ name: '@elastic/transport', file: 'lib/Transport.js', versions: ['>=8'] }, (exports) => {
|
|
15
|
-
shimmer.wrap(exports.default.prototype, 'request',
|
|
11
|
+
shimmer.wrap(exports.default.prototype, 'request', createWrapRequest('elasticsearch'))
|
|
16
12
|
return exports
|
|
17
13
|
})
|
|
18
14
|
|
|
19
15
|
addHook({ name: '@elastic/elasticsearch', file: 'lib/Transport.js', versions: ['>=5.6.16 <8', '>=8'] }, Transport => {
|
|
20
|
-
shimmer.wrap(Transport.prototype, 'request',
|
|
16
|
+
shimmer.wrap(Transport.prototype, 'request', createWrapRequest('elasticsearch'))
|
|
21
17
|
return Transport
|
|
22
18
|
})
|
|
23
19
|
|
|
24
20
|
addHook({ name: 'elasticsearch', file: 'src/lib/transport.js', versions: ['>=10'] }, Transport => {
|
|
25
|
-
shimmer.wrap(Transport.prototype, 'request',
|
|
21
|
+
shimmer.wrap(Transport.prototype, 'request', createWrapRequest('elasticsearch'))
|
|
26
22
|
return Transport
|
|
27
23
|
})
|
|
28
24
|
|
|
29
|
-
function
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
25
|
+
function createWrapRequest (name) {
|
|
26
|
+
const startCh = channel(`apm:${name}:query:start`)
|
|
27
|
+
const finishCh = channel(`apm:${name}:query:finish`)
|
|
28
|
+
const errorCh = channel(`apm:${name}:query:error`)
|
|
34
29
|
|
|
35
|
-
|
|
30
|
+
return function wrapRequest (request) {
|
|
31
|
+
return function (params, options, cb) {
|
|
32
|
+
if (!startCh.hasSubscribers) {
|
|
33
|
+
return request.apply(this, arguments)
|
|
34
|
+
}
|
|
36
35
|
|
|
37
|
-
|
|
38
|
-
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
36
|
+
if (!params) return request.apply(this, arguments)
|
|
39
37
|
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
const parentResource = new AsyncResource('bound-anonymous-fn')
|
|
39
|
+
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
42
40
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
cb = arguments[lastIndex]
|
|
41
|
+
return asyncResource.runInAsyncScope(() => {
|
|
42
|
+
startCh.publish({ params })
|
|
46
43
|
|
|
47
|
-
|
|
48
|
-
|
|
44
|
+
try {
|
|
45
|
+
const lastIndex = arguments.length - 1
|
|
46
|
+
cb = arguments[lastIndex]
|
|
49
47
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
return cb.apply(null, arguments)
|
|
53
|
-
})
|
|
54
|
-
return request.apply(this, arguments)
|
|
55
|
-
} else {
|
|
56
|
-
const promise = request.apply(this, arguments)
|
|
57
|
-
if (promise && typeof promise.then === 'function') {
|
|
58
|
-
const onResolve = asyncResource.bind(() => finish(params))
|
|
59
|
-
const onReject = asyncResource.bind(e => finish(params, e))
|
|
48
|
+
if (typeof cb === 'function') {
|
|
49
|
+
cb = parentResource.bind(cb)
|
|
60
50
|
|
|
61
|
-
|
|
51
|
+
arguments[lastIndex] = asyncResource.bind(function (error) {
|
|
52
|
+
finish(params, error)
|
|
53
|
+
return cb.apply(null, arguments)
|
|
54
|
+
})
|
|
55
|
+
return request.apply(this, arguments)
|
|
62
56
|
} else {
|
|
63
|
-
|
|
57
|
+
const promise = request.apply(this, arguments)
|
|
58
|
+
if (promise && typeof promise.then === 'function') {
|
|
59
|
+
const onResolve = asyncResource.bind(() => finish(params))
|
|
60
|
+
const onReject = asyncResource.bind(e => finish(params, e))
|
|
61
|
+
|
|
62
|
+
promise.then(onResolve, onReject)
|
|
63
|
+
} else {
|
|
64
|
+
finish(params)
|
|
65
|
+
}
|
|
66
|
+
return promise
|
|
64
67
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
err.stack // trigger getting the stack at the original throwing point
|
|
69
|
-
errorCh.publish(err)
|
|
68
|
+
} catch (err) {
|
|
69
|
+
err.stack // trigger getting the stack at the original throwing point
|
|
70
|
+
errorCh.publish(err)
|
|
70
71
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
72
|
+
throw err
|
|
73
|
+
}
|
|
74
|
+
})
|
|
75
|
+
}
|
|
74
76
|
}
|
|
75
|
-
}
|
|
76
77
|
|
|
77
|
-
function finish (params, error) {
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
function finish (params, error) {
|
|
79
|
+
if (error) {
|
|
80
|
+
errorCh.publish(error)
|
|
81
|
+
}
|
|
82
|
+
finishCh.publish({ params })
|
|
80
83
|
}
|
|
81
|
-
finishCh.publish({ params })
|
|
82
84
|
}
|
|
85
|
+
|
|
86
|
+
module.exports = { createWrapRequest }
|
|
@@ -8,14 +8,20 @@ module.exports = {
|
|
|
8
8
|
'@grpc/grpc-js': () => require('../grpc'),
|
|
9
9
|
'@hapi/hapi': () => require('../hapi'),
|
|
10
10
|
'@jest/core': () => require('../jest'),
|
|
11
|
+
'@jest/reporters': () => require('../jest'),
|
|
11
12
|
'@koa/router': () => require('../koa'),
|
|
12
13
|
'@node-redis/client': () => require('../redis'),
|
|
14
|
+
'@opensearch-project/opensearch': () => require('../opensearch'),
|
|
15
|
+
'@redis/client': () => require('../redis'),
|
|
13
16
|
'amqp10': () => require('../amqp10'),
|
|
14
17
|
'amqplib': () => require('../amqplib'),
|
|
15
18
|
'aws-sdk': () => require('../aws-sdk'),
|
|
16
19
|
'bluebird': () => require('../bluebird'),
|
|
20
|
+
'body-parser': () => require('../body-parser'),
|
|
17
21
|
'bunyan': () => require('../bunyan'),
|
|
18
22
|
'cassandra-driver': () => require('../cassandra-driver'),
|
|
23
|
+
'child_process': () => require('../child-process'),
|
|
24
|
+
'node:child_process': () => require('../child-process'),
|
|
19
25
|
'connect': () => require('../connect'),
|
|
20
26
|
'couchbase': () => require('../couchbase'),
|
|
21
27
|
'crypto': () => require('../crypto'),
|
|
@@ -40,7 +46,9 @@ module.exports = {
|
|
|
40
46
|
'koa': () => require('../koa'),
|
|
41
47
|
'koa-router': () => require('../koa'),
|
|
42
48
|
'kafkajs': () => require('../kafkajs'),
|
|
49
|
+
'ldapjs': () => require('../ldapjs'),
|
|
43
50
|
'limitd-client': () => require('../limitd-client'),
|
|
51
|
+
'mariadb': () => require('../mariadb'),
|
|
44
52
|
'memcached': () => require('../memcached'),
|
|
45
53
|
'microgateway-core': () => require('../microgateway-core'),
|
|
46
54
|
'mocha': () => require('../mocha'),
|
|
@@ -61,6 +69,7 @@ module.exports = {
|
|
|
61
69
|
'promise-js': () => require('../promise-js'),
|
|
62
70
|
'promise': () => require('../promise'),
|
|
63
71
|
'q': () => require('../q'),
|
|
72
|
+
'qs': () => require('../qs'),
|
|
64
73
|
'redis': () => require('../redis'),
|
|
65
74
|
'restify': () => require('../restify'),
|
|
66
75
|
'rhea': () => require('../rhea'),
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const { AbortController } = require('node-abort-controller') // AbortController is not available in node <15
|
|
3
4
|
const {
|
|
4
5
|
channel,
|
|
5
|
-
addHook
|
|
6
|
-
AsyncResource
|
|
6
|
+
addHook
|
|
7
7
|
} = require('../helpers/instrument')
|
|
8
8
|
const shimmer = require('../../../datadog-shimmer')
|
|
9
9
|
|
|
10
10
|
const startServerCh = channel('apm:http:server:request:start')
|
|
11
|
+
const exitServerCh = channel('apm:http:server:request:exit')
|
|
11
12
|
const errorServerCh = channel('apm:http:server:request:error')
|
|
12
13
|
const finishServerCh = channel('apm:http:server:request:finish')
|
|
13
14
|
|
|
15
|
+
const requestFinishedSet = new WeakSet()
|
|
16
|
+
|
|
14
17
|
addHook({ name: 'https' }, http => {
|
|
15
18
|
// http.ServerResponse not present on https
|
|
16
19
|
shimmer.wrap(http.Server.prototype, 'emit', wrapEmit)
|
|
@@ -29,8 +32,9 @@ function wrapResponseEmit (emit) {
|
|
|
29
32
|
return emit.apply(this, arguments)
|
|
30
33
|
}
|
|
31
34
|
|
|
32
|
-
if (
|
|
35
|
+
if (['finish', 'close'].includes(eventName) && !requestFinishedSet.has(this)) {
|
|
33
36
|
finishServerCh.publish({ req: this.req })
|
|
37
|
+
requestFinishedSet.add(this)
|
|
34
38
|
}
|
|
35
39
|
|
|
36
40
|
return emit.apply(this, arguments)
|
|
@@ -45,18 +49,22 @@ function wrapEmit (emit) {
|
|
|
45
49
|
if (eventName === 'request') {
|
|
46
50
|
res.req = req
|
|
47
51
|
|
|
48
|
-
const
|
|
49
|
-
return asyncResource.runInAsyncScope(() => {
|
|
50
|
-
startServerCh.publish({ req, res })
|
|
52
|
+
const abortController = new AbortController()
|
|
51
53
|
|
|
52
|
-
|
|
53
|
-
return emit.apply(this, arguments)
|
|
54
|
-
} catch (err) {
|
|
55
|
-
errorServerCh.publish(err)
|
|
54
|
+
startServerCh.publish({ req, res, abortController })
|
|
56
55
|
|
|
57
|
-
|
|
56
|
+
try {
|
|
57
|
+
if (abortController.signal.aborted) {
|
|
58
|
+
return res.end()
|
|
58
59
|
}
|
|
59
|
-
|
|
60
|
+
return emit.apply(this, arguments)
|
|
61
|
+
} catch (err) {
|
|
62
|
+
errorServerCh.publish(err)
|
|
63
|
+
|
|
64
|
+
throw err
|
|
65
|
+
} finally {
|
|
66
|
+
exitServerCh.publish({ req })
|
|
67
|
+
}
|
|
60
68
|
}
|
|
61
69
|
return emit.apply(this, arguments)
|
|
62
70
|
}
|
|
@@ -1,3 +1,69 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
//
|
|
3
|
+
// Old instrumentation temporarily replaced with compatibility mode only instrumentation.
|
|
4
|
+
// See https://github.com/DataDog/dd-trace-js/issues/312
|
|
5
|
+
|
|
6
|
+
const {
|
|
7
|
+
channel,
|
|
8
|
+
addHook,
|
|
9
|
+
AsyncResource
|
|
10
|
+
} = require('../helpers/instrument')
|
|
11
|
+
const shimmer = require('../../../datadog-shimmer')
|
|
12
|
+
|
|
13
|
+
const startServerCh = channel('apm:http2:server:request:start')
|
|
14
|
+
const errorServerCh = channel('apm:http2:server:request:error')
|
|
15
|
+
const finishServerCh = channel('apm:http2:server:request:finish')
|
|
16
|
+
|
|
17
|
+
addHook({ name: 'http2' }, http2 => {
|
|
18
|
+
shimmer.wrap(http2, 'createSecureServer', wrapCreateServer)
|
|
19
|
+
shimmer.wrap(http2, 'createServer', wrapCreateServer)
|
|
20
|
+
return http2
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
function wrapCreateServer (createServer) {
|
|
24
|
+
return function (...args) {
|
|
25
|
+
const server = createServer.apply(this, args)
|
|
26
|
+
shimmer.wrap(server, 'emit', wrapEmit)
|
|
27
|
+
return server
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function wrapResponseEmit (emit) {
|
|
32
|
+
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
33
|
+
return function (eventName, event) {
|
|
34
|
+
return asyncResource.runInAsyncScope(() => {
|
|
35
|
+
if (eventName === 'close' && finishServerCh.hasSubscribers) {
|
|
36
|
+
finishServerCh.publish({ req: this.req })
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return emit.apply(this, arguments)
|
|
40
|
+
})
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function wrapEmit (emit) {
|
|
44
|
+
return function (eventName, req, res) {
|
|
45
|
+
if (!startServerCh.hasSubscribers) {
|
|
46
|
+
return emit.apply(this, arguments)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (eventName === 'request') {
|
|
50
|
+
res.req = req
|
|
51
|
+
|
|
52
|
+
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
53
|
+
return asyncResource.runInAsyncScope(() => {
|
|
54
|
+
startServerCh.publish({ req, res })
|
|
55
|
+
|
|
56
|
+
shimmer.wrap(res, 'emit', wrapResponseEmit)
|
|
57
|
+
|
|
58
|
+
try {
|
|
59
|
+
return emit.apply(this, arguments)
|
|
60
|
+
} catch (err) {
|
|
61
|
+
errorServerCh.publish(err)
|
|
62
|
+
|
|
63
|
+
throw err
|
|
64
|
+
}
|
|
65
|
+
})
|
|
66
|
+
}
|
|
67
|
+
return emit.apply(this, arguments)
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
'use strict'
|
|
2
|
-
const istanbul = require('istanbul-lib-coverage')
|
|
3
2
|
const { addHook, channel, AsyncResource } = require('./helpers/instrument')
|
|
4
3
|
const shimmer = require('../../datadog-shimmer')
|
|
4
|
+
const log = require('../../dd-trace/src/log')
|
|
5
|
+
const { getCoveredFilenamesFromCoverage } = require('../../dd-trace/src/plugins/util/test')
|
|
5
6
|
|
|
6
7
|
const testSessionStartCh = channel('ci:jest:session:start')
|
|
7
8
|
const testSessionFinishCh = channel('ci:jest:session:finish')
|
|
@@ -17,6 +18,13 @@ const testSkippedCh = channel('ci:jest:test:skip')
|
|
|
17
18
|
const testRunFinishCh = channel('ci:jest:test:finish')
|
|
18
19
|
const testErrCh = channel('ci:jest:test:err')
|
|
19
20
|
|
|
21
|
+
const skippableSuitesCh = channel('ci:jest:test-suite:skippable')
|
|
22
|
+
const jestItrConfigurationCh = channel('ci:jest:itr-configuration')
|
|
23
|
+
|
|
24
|
+
let skippableSuites = []
|
|
25
|
+
let isCodeCoverageEnabled = false
|
|
26
|
+
let isSuitesSkippingEnabled = false
|
|
27
|
+
|
|
20
28
|
const {
|
|
21
29
|
getTestSuitePath,
|
|
22
30
|
getTestParametersString
|
|
@@ -26,21 +34,6 @@ const { getFormattedJestTestParameters, getJestTestName } = require('../../datad
|
|
|
26
34
|
|
|
27
35
|
const sessionAsyncResource = new AsyncResource('bound-anonymous-fn')
|
|
28
36
|
|
|
29
|
-
function extractCoverageInformation (coverage, rootDir) {
|
|
30
|
-
const coverageMap = istanbul.createCoverageMap(coverage)
|
|
31
|
-
|
|
32
|
-
return coverageMap
|
|
33
|
-
.files()
|
|
34
|
-
.filter(filename => {
|
|
35
|
-
const fileCoverage = coverageMap.fileCoverageFor(filename)
|
|
36
|
-
const lineCoverage = fileCoverage.getLineCoverage()
|
|
37
|
-
const isAnyLineExecuted = Object.entries(lineCoverage).some(([, numExecutions]) => !!numExecutions)
|
|
38
|
-
|
|
39
|
-
return isAnyLineExecuted
|
|
40
|
-
})
|
|
41
|
-
.map(filename => filename.replace(`${rootDir}/`, ''))
|
|
42
|
-
}
|
|
43
|
-
|
|
44
37
|
const specStatusToTestStatus = {
|
|
45
38
|
'pending': 'skip',
|
|
46
39
|
'disabled': 'skip',
|
|
@@ -179,17 +172,80 @@ addHook({
|
|
|
179
172
|
|
|
180
173
|
function cliWrapper (cli) {
|
|
181
174
|
const wrapped = shimmer.wrap(cli, 'runCLI', runCLI => async function () {
|
|
175
|
+
let onDone
|
|
176
|
+
const configurationPromise = new Promise((resolve) => {
|
|
177
|
+
onDone = resolve
|
|
178
|
+
})
|
|
179
|
+
if (!jestItrConfigurationCh.hasSubscribers) {
|
|
180
|
+
return runCLI.apply(this, arguments)
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
sessionAsyncResource.runInAsyncScope(() => {
|
|
184
|
+
jestItrConfigurationCh.publish({ onDone })
|
|
185
|
+
})
|
|
186
|
+
|
|
187
|
+
try {
|
|
188
|
+
const { err, itrConfig } = await configurationPromise
|
|
189
|
+
if (err) {
|
|
190
|
+
log.error(err)
|
|
191
|
+
}
|
|
192
|
+
isCodeCoverageEnabled = itrConfig.isCodeCoverageEnabled
|
|
193
|
+
isSuitesSkippingEnabled = itrConfig.isSuitesSkippingEnabled
|
|
194
|
+
} catch (e) {
|
|
195
|
+
log.error(e)
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (isSuitesSkippingEnabled) {
|
|
199
|
+
const skippableSuitesPromise = new Promise((resolve) => {
|
|
200
|
+
onDone = resolve
|
|
201
|
+
})
|
|
202
|
+
|
|
203
|
+
sessionAsyncResource.runInAsyncScope(() => {
|
|
204
|
+
skippableSuitesCh.publish({ onDone })
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
try {
|
|
208
|
+
const { err, skippableSuites: receivedSkippableSuites } = await skippableSuitesPromise
|
|
209
|
+
if (err) {
|
|
210
|
+
log.error(err)
|
|
211
|
+
} else {
|
|
212
|
+
skippableSuites = receivedSkippableSuites
|
|
213
|
+
}
|
|
214
|
+
} catch (e) {
|
|
215
|
+
log.error(e)
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const isSuitesSkipped = !!skippableSuites.length
|
|
220
|
+
|
|
182
221
|
const processArgv = process.argv.slice(2).join(' ')
|
|
183
222
|
sessionAsyncResource.runInAsyncScope(() => {
|
|
184
223
|
testSessionStartCh.publish(`jest ${processArgv}`)
|
|
185
224
|
})
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
225
|
+
|
|
226
|
+
const result = await runCLI.apply(this, arguments)
|
|
227
|
+
|
|
228
|
+
const { results: { success, coverageMap } } = result
|
|
229
|
+
|
|
230
|
+
let testCodeCoverageLinesTotal
|
|
231
|
+
try {
|
|
232
|
+
const { pct, total } = coverageMap.getCoverageSummary().lines
|
|
233
|
+
testCodeCoverageLinesTotal = total !== 0 ? pct : 0
|
|
234
|
+
} catch (e) {
|
|
235
|
+
// ignore errors
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
sessionAsyncResource.runInAsyncScope(() => {
|
|
239
|
+
testSessionFinishCh.publish({
|
|
240
|
+
status: success ? 'pass' : 'fail',
|
|
241
|
+
isSuitesSkipped,
|
|
242
|
+
isSuitesSkippingEnabled,
|
|
243
|
+
isCodeCoverageEnabled,
|
|
244
|
+
testCodeCoverageLinesTotal
|
|
190
245
|
})
|
|
191
|
-
return result
|
|
192
246
|
})
|
|
247
|
+
|
|
248
|
+
return result
|
|
193
249
|
})
|
|
194
250
|
|
|
195
251
|
cli.runCLI = wrapped.runCLI
|
|
@@ -197,6 +253,35 @@ function cliWrapper (cli) {
|
|
|
197
253
|
return cli
|
|
198
254
|
}
|
|
199
255
|
|
|
256
|
+
function coverageReporterWrapper (coverageReporter) {
|
|
257
|
+
const CoverageReporter = coverageReporter.default ? coverageReporter.default : coverageReporter
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* If ITR is active, we're running fewer tests, so of course the total code coverage is reduced.
|
|
261
|
+
* This calculation adds no value, so we'll skip it.
|
|
262
|
+
*/
|
|
263
|
+
shimmer.wrap(CoverageReporter.prototype, '_addUntestedFiles', addUntestedFiles => async function () {
|
|
264
|
+
if (isSuitesSkippingEnabled) {
|
|
265
|
+
return Promise.resolve()
|
|
266
|
+
}
|
|
267
|
+
return addUntestedFiles.apply(this, arguments)
|
|
268
|
+
})
|
|
269
|
+
|
|
270
|
+
return coverageReporter
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
addHook({
|
|
274
|
+
name: '@jest/reporters',
|
|
275
|
+
file: 'build/coverage_reporter.js',
|
|
276
|
+
versions: ['>=24.8.0 <26.6.2']
|
|
277
|
+
}, coverageReporterWrapper)
|
|
278
|
+
|
|
279
|
+
addHook({
|
|
280
|
+
name: '@jest/reporters',
|
|
281
|
+
file: 'build/CoverageReporter.js',
|
|
282
|
+
versions: ['>=26.6.2']
|
|
283
|
+
}, coverageReporterWrapper)
|
|
284
|
+
|
|
200
285
|
addHook({
|
|
201
286
|
name: '@jest/core',
|
|
202
287
|
file: 'build/cli/index.js',
|
|
@@ -207,6 +292,9 @@ function jestAdapterWrapper (jestAdapter) {
|
|
|
207
292
|
const adapter = jestAdapter.default ? jestAdapter.default : jestAdapter
|
|
208
293
|
const newAdapter = shimmer.wrap(adapter, function () {
|
|
209
294
|
const environment = arguments[2]
|
|
295
|
+
if (!environment) {
|
|
296
|
+
return adapter.apply(this, arguments)
|
|
297
|
+
}
|
|
210
298
|
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
211
299
|
return asyncResource.runInAsyncScope(() => {
|
|
212
300
|
testSuiteStartCh.publish({
|
|
@@ -222,11 +310,21 @@ function jestAdapterWrapper (jestAdapter) {
|
|
|
222
310
|
status = 'fail'
|
|
223
311
|
}
|
|
224
312
|
testSuiteFinishCh.publish({ status, errorMessage })
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
313
|
+
|
|
314
|
+
const coverageFiles = getCoveredFilenamesFromCoverage(environment.global.__coverage__)
|
|
315
|
+
.map(filename => getTestSuitePath(filename, environment.rootDir))
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* Child processes do not each request ITR configuration, so the jest's parent process
|
|
319
|
+
* needs to pass them the configuration. This is done via _ddTestCodeCoverageEnabled, which
|
|
320
|
+
* controls whether coverage is reported.
|
|
321
|
+
*/
|
|
322
|
+
if (coverageFiles &&
|
|
323
|
+
environment.testEnvironmentOptions &&
|
|
324
|
+
environment.testEnvironmentOptions._ddTestCodeCoverageEnabled) {
|
|
325
|
+
asyncResource.runInAsyncScope(() => {
|
|
228
326
|
testSuiteCodeCoverageCh.publish([...coverageFiles, environment.testSuite])
|
|
229
|
-
}
|
|
327
|
+
})
|
|
230
328
|
}
|
|
231
329
|
return suiteResults
|
|
232
330
|
})
|
|
@@ -252,6 +350,32 @@ function configureTestEnvironment (readConfigsResult) {
|
|
|
252
350
|
sessionAsyncResource.runInAsyncScope(() => {
|
|
253
351
|
testSessionConfigurationCh.publish(configs.map(config => config.testEnvironmentOptions))
|
|
254
352
|
})
|
|
353
|
+
// We can't directly use isCodeCoverageEnabled when reporting coverage in `jestAdapterWrapper`
|
|
354
|
+
// because `jestAdapterWrapper` runs in a different process. We have to go through `testEnvironmentOptions`
|
|
355
|
+
configs.forEach(config => {
|
|
356
|
+
config.testEnvironmentOptions._ddTestCodeCoverageEnabled = isCodeCoverageEnabled
|
|
357
|
+
})
|
|
358
|
+
|
|
359
|
+
if (isCodeCoverageEnabled) {
|
|
360
|
+
const globalConfig = {
|
|
361
|
+
...readConfigsResult.globalConfig,
|
|
362
|
+
collectCoverage: true
|
|
363
|
+
}
|
|
364
|
+
readConfigsResult.globalConfig = globalConfig
|
|
365
|
+
}
|
|
366
|
+
if (isSuitesSkippingEnabled) {
|
|
367
|
+
// If suite skipping is enabled, the code coverage results are not going to be relevant,
|
|
368
|
+
// so we do not show them.
|
|
369
|
+
// Also, we might skip every test, so we need to pass `passWithNoTests`
|
|
370
|
+
const globalConfig = {
|
|
371
|
+
...readConfigsResult.globalConfig,
|
|
372
|
+
coverageReporters: ['none'],
|
|
373
|
+
passWithNoTests: true
|
|
374
|
+
}
|
|
375
|
+
readConfigsResult.globalConfig = globalConfig
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
return readConfigsResult
|
|
255
379
|
}
|
|
256
380
|
|
|
257
381
|
function jestConfigAsyncWrapper (jestConfig) {
|
|
@@ -272,6 +396,39 @@ function jestConfigSyncWrapper (jestConfig) {
|
|
|
272
396
|
return jestConfig
|
|
273
397
|
}
|
|
274
398
|
|
|
399
|
+
/**
|
|
400
|
+
* Hook to remove the test paths (test suite) that are part of `skippableSuites`
|
|
401
|
+
*/
|
|
402
|
+
addHook({
|
|
403
|
+
name: '@jest/core',
|
|
404
|
+
versions: ['>=24.8.0'],
|
|
405
|
+
file: 'build/SearchSource.js'
|
|
406
|
+
}, searchSourcePackage => {
|
|
407
|
+
const SearchSource = searchSourcePackage.default ? searchSourcePackage.default : searchSourcePackage
|
|
408
|
+
|
|
409
|
+
shimmer.wrap(SearchSource.prototype, 'getTestPaths', getTestPaths => async function () {
|
|
410
|
+
if (!skippableSuites.length) {
|
|
411
|
+
return getTestPaths.apply(this, arguments)
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
const [{ rootDir }] = arguments
|
|
415
|
+
|
|
416
|
+
const testPaths = await getTestPaths.apply(this, arguments)
|
|
417
|
+
const { tests } = testPaths
|
|
418
|
+
|
|
419
|
+
const filteredTests = tests.filter(({ path: testPath }) => {
|
|
420
|
+
const relativePath = testPath.replace(`${rootDir}/`, '')
|
|
421
|
+
return !skippableSuites.includes(relativePath)
|
|
422
|
+
})
|
|
423
|
+
|
|
424
|
+
skippableSuites = []
|
|
425
|
+
|
|
426
|
+
return { ...testPaths, tests: filteredTests }
|
|
427
|
+
})
|
|
428
|
+
|
|
429
|
+
return searchSourcePackage
|
|
430
|
+
})
|
|
431
|
+
|
|
275
432
|
// from 25.1.0 on, readConfigs becomes async
|
|
276
433
|
addHook({
|
|
277
434
|
name: 'jest-config',
|