dd-trace 2.14.0 → 2.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE-3rdparty.csv +2 -0
- package/README.md +4 -0
- package/ext/tags.d.ts +2 -1
- package/ext/tags.js +2 -1
- package/index.d.ts +43 -20
- package/package.json +6 -4
- package/packages/datadog-instrumentations/src/crypto.js +32 -0
- package/packages/datadog-instrumentations/src/grpc/server.js +15 -7
- package/packages/datadog-instrumentations/src/helpers/hooks.js +4 -0
- package/packages/datadog-instrumentations/src/http/server.js +1 -1
- package/packages/datadog-instrumentations/src/jest.js +136 -14
- package/packages/datadog-instrumentations/src/mocha.js +77 -31
- package/packages/datadog-instrumentations/src/net.js +13 -0
- package/packages/datadog-instrumentations/src/next.js +7 -3
- package/packages/datadog-plugin-jest/src/index.js +106 -6
- package/packages/datadog-plugin-mocha/src/index.js +15 -7
- package/packages/datadog-plugin-mongodb-core/src/index.js +19 -10
- package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +4 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/index.js +20 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/vulnerability-analyzer.js +48 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/weak-cipher-analyzer.js +27 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/weak-hash-analyzer.js +24 -0
- package/packages/dd-trace/src/appsec/iast/iast-context.js +50 -0
- package/packages/dd-trace/src/appsec/iast/index.js +59 -0
- package/packages/dd-trace/src/appsec/iast/overhead-controller.js +94 -0
- package/packages/dd-trace/src/appsec/iast/path-line.js +70 -0
- package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +121 -0
- package/packages/dd-trace/src/appsec/recommended.json +1144 -275
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +1 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/index.js +3 -3
- package/packages/dd-trace/src/config.js +90 -10
- package/packages/dd-trace/src/constants.js +9 -1
- package/packages/dd-trace/src/encode/0.4.js +7 -1
- package/packages/dd-trace/src/encode/0.5.js +7 -1
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +2 -2
- package/packages/dd-trace/src/encode/coverage-ci-visibility.js +32 -20
- package/packages/dd-trace/src/encode/span-stats.js +155 -0
- package/packages/dd-trace/src/exporters/agent/index.js +14 -2
- package/packages/dd-trace/src/exporters/agent/writer.js +6 -3
- package/packages/dd-trace/src/exporters/common/request.js +9 -5
- 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/format.js +2 -0
- package/packages/dd-trace/src/iitm.js +11 -0
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +71 -0
- package/packages/dd-trace/src/opentracing/tracer.js +1 -1
- package/packages/dd-trace/src/plugin_manager.js +12 -2
- package/packages/dd-trace/src/plugins/index.js +3 -0
- package/packages/dd-trace/src/plugins/log_plugin.js +16 -9
- package/packages/dd-trace/src/plugins/util/ip_blocklist.js +51 -0
- package/packages/dd-trace/src/plugins/util/web.js +99 -2
- package/packages/dd-trace/src/priority_sampler.js +36 -1
- package/packages/dd-trace/src/proxy.js +3 -0
- package/packages/dd-trace/src/ritm.js +10 -1
- package/packages/dd-trace/src/span_processor.js +7 -1
- package/packages/dd-trace/src/span_stats.js +210 -0
- package/packages/dd-trace/src/telemetry/dependencies.js +83 -0
- package/packages/dd-trace/src/{telemetry.js → telemetry/index.js} +10 -65
- package/packages/dd-trace/src/telemetry/send-data.js +35 -0
- package/packages/dd-trace/src/plugins/util/redis.js +0 -74
- package/packages/dd-trace/src/plugins/util/tx.js +0 -75
package/LICENSE-3rdparty.csv
CHANGED
|
@@ -8,6 +8,7 @@ require,crypto-randomuuid,MIT,Copyright 2021 Node.js Foundation and contributors
|
|
|
8
8
|
require,diagnostics_channel,MIT,Copyright 2021 Simon D.
|
|
9
9
|
require,ignore,MIT,Copyright 2013 Kael Zhang and contributors
|
|
10
10
|
require,import-in-the-middle,Apache license 2.0,Copyright 2021 Datadog Inc.
|
|
11
|
+
require,ipaddr.js,MIT,Copyright 2011-2017 whitequark
|
|
11
12
|
require,istanbul-lib-coverage,BSD-3-Clause,Copyright 2012-2015 Yahoo! Inc.
|
|
12
13
|
require,koalas,MIT,Copyright 2013-2017 Brian Woodward
|
|
13
14
|
require,limiter,MIT,Copyright 2011 John Hurliman
|
|
@@ -15,6 +16,7 @@ require,lodash.kebabcase,MIT,Copyright JS Foundation and other contributors
|
|
|
15
16
|
require,lodash.pick,MIT,Copyright JS Foundation and other contributors
|
|
16
17
|
require,lodash.sortby,MIT,Copyright JS Foundation and other contributors
|
|
17
18
|
require,lodash.uniq,MIT,Copyright JS Foundation and other contributors
|
|
19
|
+
require,lru-cache,ISC,Copyright (c) 2010-2022 Isaac Z. Schlueter and Contributors
|
|
18
20
|
require,methods,MIT,Copyright 2013-2014 TJ Holowaychuk
|
|
19
21
|
require,module-details-from-path,MIT,Copyright 2016 Thomas Watson Steen
|
|
20
22
|
require,opentracing,MIT,Copyright 2016 Resonance Labs Inc
|
package/README.md
CHANGED
|
@@ -21,6 +21,10 @@ For descriptions of terminology used in APM, take a look at the [official docume
|
|
|
21
21
|
|
|
22
22
|
Before contributing to this open source project, read our [CONTRIBUTING.md](https://github.com/DataDog/dd-trace-js/blob/master/CONTRIBUTING.md).
|
|
23
23
|
|
|
24
|
+
## Security Vulnerabilities
|
|
25
|
+
|
|
26
|
+
If you have found a security issue, please contact the security team directly at [security@datadoghq.com](mailto:security@datadoghq.com).
|
|
27
|
+
|
|
24
28
|
### Requirements
|
|
25
29
|
|
|
26
30
|
Since this project supports multiple Node versions, using a version
|
package/ext/tags.d.ts
CHANGED
|
@@ -15,7 +15,8 @@ declare const tags: {
|
|
|
15
15
|
HTTP_ROUTE: 'http.route'
|
|
16
16
|
HTTP_REQUEST_HEADERS: 'http.request.headers'
|
|
17
17
|
HTTP_RESPONSE_HEADERS: 'http.response.headers'
|
|
18
|
-
HTTP_USERAGENT: 'http.useragent'
|
|
18
|
+
HTTP_USERAGENT: 'http.useragent',
|
|
19
|
+
HTTP_CLIENT_IP: 'http.client_ip'
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
export = tags
|
package/ext/tags.js
CHANGED
|
@@ -20,7 +20,8 @@ const tags = {
|
|
|
20
20
|
HTTP_ROUTE: 'http.route',
|
|
21
21
|
HTTP_REQUEST_HEADERS: 'http.request.headers',
|
|
22
22
|
HTTP_RESPONSE_HEADERS: 'http.response.headers',
|
|
23
|
-
HTTP_USERAGENT: 'http.useragent'
|
|
23
|
+
HTTP_USERAGENT: 'http.useragent',
|
|
24
|
+
HTTP_CLIENT_IP: 'http.client_ip'
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
// Deprecated
|
package/index.d.ts
CHANGED
|
@@ -267,6 +267,22 @@ export declare interface TracerOptions {
|
|
|
267
267
|
*/
|
|
268
268
|
sampleRate?: number;
|
|
269
269
|
|
|
270
|
+
/**
|
|
271
|
+
* Global rate limit that is applied on the global sample rate and all rules,
|
|
272
|
+
* and controls the ingestion rate limit between the agent and the backend.
|
|
273
|
+
* Defaults to deferring the decision to the agent.
|
|
274
|
+
*/
|
|
275
|
+
rateLimit?: Number,
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Sampling rules to apply to priority samplin. Each rule is a JSON,
|
|
279
|
+
* consisting of `service` and `name`, which are regexes to match against
|
|
280
|
+
* a trace's `service` and `name`, and a corresponding `sampleRate`. If not
|
|
281
|
+
* specified, will defer to global sampling rate for all spans.
|
|
282
|
+
* @default []
|
|
283
|
+
*/
|
|
284
|
+
samplingRules?: SamplingRule[]
|
|
285
|
+
|
|
270
286
|
/**
|
|
271
287
|
* Interval in milliseconds at which the tracer will submit traces to the agent.
|
|
272
288
|
* @default 2000
|
|
@@ -298,7 +314,10 @@ export declare interface TracerOptions {
|
|
|
298
314
|
protocolVersion?: string
|
|
299
315
|
|
|
300
316
|
/**
|
|
301
|
-
*
|
|
317
|
+
* Deprecated in favor of the global versions of the variables provided under this option
|
|
318
|
+
*
|
|
319
|
+
* @deprecated
|
|
320
|
+
* @hidden
|
|
302
321
|
*/
|
|
303
322
|
ingestion?: {
|
|
304
323
|
/**
|
|
@@ -307,7 +326,7 @@ export declare interface TracerOptions {
|
|
|
307
326
|
sampleRate?: number
|
|
308
327
|
|
|
309
328
|
/**
|
|
310
|
-
* Controls the ingestion rate limit between the agent and the backend.
|
|
329
|
+
* Controls the ingestion rate limit between the agent and the backend. Defaults to deferring the decision to the agent.
|
|
311
330
|
*/
|
|
312
331
|
rateLimit?: number
|
|
313
332
|
};
|
|
@@ -333,32 +352,36 @@ export declare interface TracerOptions {
|
|
|
333
352
|
exporter?: 'log' | 'agent'
|
|
334
353
|
|
|
335
354
|
/**
|
|
336
|
-
*
|
|
355
|
+
* Whether to enable the experimental `getRumData` method.
|
|
356
|
+
* @default false
|
|
337
357
|
*/
|
|
338
|
-
|
|
358
|
+
enableGetRumData?: boolean
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* Configuration of the IAST. Can be a boolean as an alias to `iast.enabled`.
|
|
362
|
+
*/
|
|
363
|
+
iast?: boolean | {
|
|
339
364
|
/**
|
|
340
|
-
*
|
|
365
|
+
* Whether to enable IAST.
|
|
366
|
+
* @default false
|
|
341
367
|
*/
|
|
342
|
-
|
|
343
|
-
|
|
368
|
+
enabled?: boolean,
|
|
344
369
|
/**
|
|
345
|
-
*
|
|
346
|
-
* @default
|
|
370
|
+
* Controls the percentage of requests that iast will analyze
|
|
371
|
+
* @default 30
|
|
347
372
|
*/
|
|
348
|
-
|
|
349
|
-
|
|
373
|
+
requestSampling?: number,
|
|
350
374
|
/**
|
|
351
|
-
*
|
|
352
|
-
* @default
|
|
375
|
+
* Controls how many request can be analyzing code vulnerabilities at the same time
|
|
376
|
+
* @default 2
|
|
353
377
|
*/
|
|
354
|
-
|
|
378
|
+
maxConcurrentRequests?: number,
|
|
379
|
+
/**
|
|
380
|
+
* Controls how many code vulnerabilities can be detected in the same request
|
|
381
|
+
* @default 2
|
|
382
|
+
*/
|
|
383
|
+
maxContextOperations?: number
|
|
355
384
|
}
|
|
356
|
-
|
|
357
|
-
/**
|
|
358
|
-
* Whether to enable the experimental `getRumData` method.
|
|
359
|
-
* @default false
|
|
360
|
-
*/
|
|
361
|
-
enableGetRumData?: boolean
|
|
362
385
|
};
|
|
363
386
|
|
|
364
387
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dd-trace",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.16.0",
|
|
4
4
|
"description": "Datadog APM tracing client for JavaScript",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"typings": "index.d.ts",
|
|
@@ -59,14 +59,15 @@
|
|
|
59
59
|
},
|
|
60
60
|
"dependencies": {
|
|
61
61
|
"@datadog/native-appsec": "^1.2.1",
|
|
62
|
-
"@datadog/native-metrics": "^1.4.
|
|
62
|
+
"@datadog/native-metrics": "^1.4.3",
|
|
63
63
|
"@datadog/pprof": "^1.0.2",
|
|
64
|
-
"@datadog/sketches-js": "^2.
|
|
64
|
+
"@datadog/sketches-js": "^2.1.0",
|
|
65
65
|
"@types/node": ">=12",
|
|
66
66
|
"crypto-randomuuid": "^1.0.0",
|
|
67
67
|
"diagnostics_channel": "^1.1.0",
|
|
68
68
|
"ignore": "^5.2.0",
|
|
69
|
-
"import-in-the-middle": "^1.3.
|
|
69
|
+
"import-in-the-middle": "^1.3.3",
|
|
70
|
+
"ipaddr.js": "^2.0.1",
|
|
70
71
|
"istanbul-lib-coverage": "3.2.0",
|
|
71
72
|
"koalas": "^1.0.2",
|
|
72
73
|
"limiter": "^1.1.4",
|
|
@@ -74,6 +75,7 @@
|
|
|
74
75
|
"lodash.pick": "^4.4.0",
|
|
75
76
|
"lodash.sortby": "^4.7.0",
|
|
76
77
|
"lodash.uniq": "^4.5.0",
|
|
78
|
+
"lru-cache": "^7.14.0",
|
|
77
79
|
"methods": "^1.1.2",
|
|
78
80
|
"module-details-from-path": "^1.0.3",
|
|
79
81
|
"opentracing": ">=0.12.1",
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
channel,
|
|
5
|
+
addHook
|
|
6
|
+
} = require('./helpers/instrument')
|
|
7
|
+
const shimmer = require('../../datadog-shimmer')
|
|
8
|
+
|
|
9
|
+
const cryptoHashCh = channel('datadog:crypto:hashing:start')
|
|
10
|
+
const cryptoCipherCh = channel('datadog:crypto:cipher:start')
|
|
11
|
+
|
|
12
|
+
const hashMethods = ['createHash', 'createHmac', 'createSign', 'createVerify', 'sign', 'verify']
|
|
13
|
+
const cipherMethods = ['createCipheriv', 'createDecipheriv']
|
|
14
|
+
|
|
15
|
+
addHook({ name: 'crypto' }, crypto => {
|
|
16
|
+
shimmer.massWrap(crypto, hashMethods, wrapCryptoMethod(cryptoHashCh))
|
|
17
|
+
shimmer.massWrap(crypto, cipherMethods, wrapCryptoMethod(cryptoCipherCh))
|
|
18
|
+
return crypto
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
function wrapCryptoMethod (channel) {
|
|
22
|
+
function wrapMethod (cryptoMethod) {
|
|
23
|
+
return function () {
|
|
24
|
+
if (channel.hasSubscribers && arguments.length > 0) {
|
|
25
|
+
const algorithm = arguments[0]
|
|
26
|
+
channel.publish({ algorithm })
|
|
27
|
+
}
|
|
28
|
+
return cryptoMethod.apply(this, arguments)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return wrapMethod
|
|
32
|
+
}
|
|
@@ -37,15 +37,17 @@ function wrapHandler (func, name) {
|
|
|
37
37
|
return requestResource.runInAsyncScope(() => {
|
|
38
38
|
startChannel.publish({ name, metadata, type })
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
call.once('cancelled', requestResource.bind(() => {
|
|
40
|
+
const onCancel = requestResource.bind(() => {
|
|
42
41
|
finishChannel.publish({ code: CANCELLED })
|
|
43
|
-
})
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
// Finish the span if the call was cancelled.
|
|
45
|
+
call.once('cancelled', onCancel)
|
|
44
46
|
|
|
45
47
|
if (isStream) {
|
|
46
|
-
wrapStream(call, requestResource,
|
|
48
|
+
wrapStream(call, requestResource, onCancel)
|
|
47
49
|
} else {
|
|
48
|
-
arguments[1] = wrapCallback(callback, requestResource, parentResource)
|
|
50
|
+
arguments[1] = wrapCallback(callback, call, requestResource, parentResource, onCancel)
|
|
49
51
|
}
|
|
50
52
|
|
|
51
53
|
shimmer.wrap(call, 'emit', emit => requestResource.bind(emit))
|
|
@@ -65,7 +67,7 @@ function wrapRegister (register) {
|
|
|
65
67
|
}
|
|
66
68
|
}
|
|
67
69
|
|
|
68
|
-
function wrapStream (call, requestResource) {
|
|
70
|
+
function wrapStream (call, requestResource, onCancel) {
|
|
69
71
|
if (call.call && call.call.sendStatus) {
|
|
70
72
|
call.call.sendStatus = wrapSendStatus(call.call.sendStatus, requestResource)
|
|
71
73
|
}
|
|
@@ -77,6 +79,8 @@ function wrapStream (call, requestResource) {
|
|
|
77
79
|
errorChannel.publish(args[0])
|
|
78
80
|
finishChannel.publish({ code: args[0].code })
|
|
79
81
|
|
|
82
|
+
call.removeListener('cancelled', onCancel)
|
|
83
|
+
|
|
80
84
|
break
|
|
81
85
|
|
|
82
86
|
// Finish the span of the response only if it was successful.
|
|
@@ -90,6 +94,8 @@ function wrapStream (call, requestResource) {
|
|
|
90
94
|
finishChannel.publish()
|
|
91
95
|
}
|
|
92
96
|
|
|
97
|
+
call.removeListener('cancelled', onCancel)
|
|
98
|
+
|
|
93
99
|
break
|
|
94
100
|
}
|
|
95
101
|
|
|
@@ -98,7 +104,7 @@ function wrapStream (call, requestResource) {
|
|
|
98
104
|
})
|
|
99
105
|
}
|
|
100
106
|
|
|
101
|
-
function wrapCallback (callback, requestResource, parentResource) {
|
|
107
|
+
function wrapCallback (callback, call, requestResource, parentResource, onCancel) {
|
|
102
108
|
return function (err, value, trailer, flags) {
|
|
103
109
|
requestResource.runInAsyncScope(() => {
|
|
104
110
|
if (err instanceof Error) {
|
|
@@ -107,6 +113,8 @@ function wrapCallback (callback, requestResource, parentResource) {
|
|
|
107
113
|
} else {
|
|
108
114
|
finishChannel.publish({ code: OK, trailer })
|
|
109
115
|
}
|
|
116
|
+
|
|
117
|
+
call.removeListener('cancelled', onCancel)
|
|
110
118
|
})
|
|
111
119
|
|
|
112
120
|
if (callback) {
|
|
@@ -7,6 +7,7 @@ module.exports = {
|
|
|
7
7
|
'@google-cloud/pubsub': () => require('../google-cloud-pubsub'),
|
|
8
8
|
'@grpc/grpc-js': () => require('../grpc'),
|
|
9
9
|
'@hapi/hapi': () => require('../hapi'),
|
|
10
|
+
'@jest/core': () => require('../jest'),
|
|
10
11
|
'@koa/router': () => require('../koa'),
|
|
11
12
|
'@node-redis/client': () => require('../redis'),
|
|
12
13
|
'amqp10': () => require('../amqp10'),
|
|
@@ -17,6 +18,7 @@ module.exports = {
|
|
|
17
18
|
'cassandra-driver': () => require('../cassandra-driver'),
|
|
18
19
|
'connect': () => require('../connect'),
|
|
19
20
|
'couchbase': () => require('../couchbase'),
|
|
21
|
+
'crypto': () => require('../crypto'),
|
|
20
22
|
'cypress': () => require('../cypress'),
|
|
21
23
|
'dns': () => require('../dns'),
|
|
22
24
|
'elasticsearch': () => require('../elasticsearch'),
|
|
@@ -31,6 +33,8 @@ module.exports = {
|
|
|
31
33
|
'http2': () => require('../http2'),
|
|
32
34
|
'https': () => require('../http'),
|
|
33
35
|
'ioredis': () => require('../ioredis'),
|
|
36
|
+
'jest-circus': () => require('../jest'),
|
|
37
|
+
'jest-config': () => require('../jest'),
|
|
34
38
|
'jest-environment-node': () => require('../jest'),
|
|
35
39
|
'jest-environment-jsdom': () => require('../jest'),
|
|
36
40
|
'jest-jasmine2': () => require('../jest'),
|
|
@@ -3,13 +3,20 @@ const istanbul = require('istanbul-lib-coverage')
|
|
|
3
3
|
const { addHook, channel, AsyncResource } = require('./helpers/instrument')
|
|
4
4
|
const shimmer = require('../../datadog-shimmer')
|
|
5
5
|
|
|
6
|
+
const testSessionStartCh = channel('ci:jest:session:start')
|
|
7
|
+
const testSessionFinishCh = channel('ci:jest:session:finish')
|
|
8
|
+
|
|
9
|
+
const testSessionConfigurationCh = channel('ci:jest:session:configuration')
|
|
10
|
+
|
|
11
|
+
const testSuiteStartCh = channel('ci:jest:test-suite:start')
|
|
12
|
+
const testSuiteFinishCh = channel('ci:jest:test-suite:finish')
|
|
13
|
+
const testSuiteCodeCoverageCh = channel('ci:jest:test-suite:code-coverage')
|
|
14
|
+
|
|
6
15
|
const testStartCh = channel('ci:jest:test:start')
|
|
7
16
|
const testSkippedCh = channel('ci:jest:test:skip')
|
|
8
17
|
const testRunFinishCh = channel('ci:jest:test:finish')
|
|
9
18
|
const testErrCh = channel('ci:jest:test:err')
|
|
10
19
|
|
|
11
|
-
const testCodeCoverageCh = channel('ci:jest:test:code-coverage')
|
|
12
|
-
|
|
13
20
|
const {
|
|
14
21
|
getTestSuitePath,
|
|
15
22
|
getTestParametersString
|
|
@@ -17,7 +24,8 @@ const {
|
|
|
17
24
|
|
|
18
25
|
const { getFormattedJestTestParameters, getJestTestName } = require('../../datadog-plugin-jest/src/util')
|
|
19
26
|
|
|
20
|
-
|
|
27
|
+
const sessionAsyncResource = new AsyncResource('bound-anonymous-fn')
|
|
28
|
+
|
|
21
29
|
function extractCoverageInformation (coverage, rootDir) {
|
|
22
30
|
const coverageMap = istanbul.createCoverageMap(coverage)
|
|
23
31
|
|
|
@@ -28,8 +36,6 @@ function extractCoverageInformation (coverage, rootDir) {
|
|
|
28
36
|
const lineCoverage = fileCoverage.getLineCoverage()
|
|
29
37
|
const isAnyLineExecuted = Object.entries(lineCoverage).some(([, numExecutions]) => !!numExecutions)
|
|
30
38
|
|
|
31
|
-
fileCoverage.resetHits()
|
|
32
|
-
|
|
33
39
|
return isAnyLineExecuted
|
|
34
40
|
})
|
|
35
41
|
.map(filename => filename.replace(`${rootDir}/`, ''))
|
|
@@ -63,6 +69,16 @@ function formatJestError (errors) {
|
|
|
63
69
|
return error
|
|
64
70
|
}
|
|
65
71
|
|
|
72
|
+
function getTestEnvironmentOptions (config) {
|
|
73
|
+
if (config.projectConfig && config.projectConfig.testEnvironmentOptions) { // newer versions
|
|
74
|
+
return config.projectConfig.testEnvironmentOptions
|
|
75
|
+
}
|
|
76
|
+
if (config.testEnvironmentOptions) {
|
|
77
|
+
return config.testEnvironmentOptions
|
|
78
|
+
}
|
|
79
|
+
return {}
|
|
80
|
+
}
|
|
81
|
+
|
|
66
82
|
function getWrappedEnvironment (BaseEnvironment) {
|
|
67
83
|
return class DatadogEnvironment extends BaseEnvironment {
|
|
68
84
|
constructor (config, context) {
|
|
@@ -72,6 +88,8 @@ function getWrappedEnvironment (BaseEnvironment) {
|
|
|
72
88
|
this.testSuite = getTestSuitePath(context.testPath, rootDir)
|
|
73
89
|
this.nameToParams = {}
|
|
74
90
|
this.global._ddtrace = global._ddtrace
|
|
91
|
+
|
|
92
|
+
this.testEnvironmentOptions = getTestEnvironmentOptions(config)
|
|
75
93
|
}
|
|
76
94
|
|
|
77
95
|
async handleTestEvent (event, state) {
|
|
@@ -114,10 +132,6 @@ function getWrappedEnvironment (BaseEnvironment) {
|
|
|
114
132
|
if (event.name === 'test_done') {
|
|
115
133
|
const asyncResource = asyncResources.get(event.test)
|
|
116
134
|
asyncResource.runInAsyncScope(() => {
|
|
117
|
-
if (this.global.__coverage__) {
|
|
118
|
-
const coverageFiles = extractCoverageInformation(this.global.__coverage__, this.rootDir)
|
|
119
|
-
testCodeCoverageCh.publish(coverageFiles)
|
|
120
|
-
}
|
|
121
135
|
let status = 'pass'
|
|
122
136
|
if (event.test.errors && event.test.errors.length) {
|
|
123
137
|
status = 'fail'
|
|
@@ -163,11 +177,113 @@ addHook({
|
|
|
163
177
|
versions: ['>=24.8.0']
|
|
164
178
|
}, getTestEnvironment)
|
|
165
179
|
|
|
180
|
+
function cliWrapper (cli) {
|
|
181
|
+
const wrapped = shimmer.wrap(cli, 'runCLI', runCLI => async function () {
|
|
182
|
+
const processArgv = process.argv.slice(2).join(' ')
|
|
183
|
+
sessionAsyncResource.runInAsyncScope(() => {
|
|
184
|
+
testSessionStartCh.publish(`jest ${processArgv}`)
|
|
185
|
+
})
|
|
186
|
+
return runCLI.apply(this, arguments).then(result => {
|
|
187
|
+
const { results: { success } } = result
|
|
188
|
+
sessionAsyncResource.runInAsyncScope(() => {
|
|
189
|
+
testSessionFinishCh.publish(success ? 'pass' : 'fail')
|
|
190
|
+
})
|
|
191
|
+
return result
|
|
192
|
+
})
|
|
193
|
+
})
|
|
194
|
+
|
|
195
|
+
cli.runCLI = wrapped.runCLI
|
|
196
|
+
|
|
197
|
+
return cli
|
|
198
|
+
}
|
|
199
|
+
|
|
166
200
|
addHook({
|
|
167
|
-
name: 'jest
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
},
|
|
201
|
+
name: '@jest/core',
|
|
202
|
+
file: 'build/cli/index.js',
|
|
203
|
+
versions: ['>=24.8.0']
|
|
204
|
+
}, cliWrapper)
|
|
205
|
+
|
|
206
|
+
function jestAdapterWrapper (jestAdapter) {
|
|
207
|
+
const adapter = jestAdapter.default ? jestAdapter.default : jestAdapter
|
|
208
|
+
const newAdapter = shimmer.wrap(adapter, function () {
|
|
209
|
+
const environment = arguments[2]
|
|
210
|
+
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
211
|
+
return asyncResource.runInAsyncScope(() => {
|
|
212
|
+
testSuiteStartCh.publish({
|
|
213
|
+
testSuite: environment.testSuite,
|
|
214
|
+
testEnvironmentOptions: environment.testEnvironmentOptions
|
|
215
|
+
})
|
|
216
|
+
return adapter.apply(this, arguments).then(suiteResults => {
|
|
217
|
+
const { numFailingTests, skipped, failureMessage: errorMessage } = suiteResults
|
|
218
|
+
let status = 'pass'
|
|
219
|
+
if (skipped) {
|
|
220
|
+
status = 'skipped'
|
|
221
|
+
} else if (numFailingTests !== 0) {
|
|
222
|
+
status = 'fail'
|
|
223
|
+
}
|
|
224
|
+
testSuiteFinishCh.publish({ status, errorMessage })
|
|
225
|
+
if (environment.global.__coverage__) {
|
|
226
|
+
const coverageFiles = extractCoverageInformation(environment.global.__coverage__, environment.rootDir)
|
|
227
|
+
if (coverageFiles.length) {
|
|
228
|
+
testSuiteCodeCoverageCh.publish([...coverageFiles, environment.testSuite])
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return suiteResults
|
|
232
|
+
})
|
|
233
|
+
})
|
|
234
|
+
})
|
|
235
|
+
if (jestAdapter.default) {
|
|
236
|
+
jestAdapter.default = newAdapter
|
|
237
|
+
} else {
|
|
238
|
+
jestAdapter = newAdapter
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return jestAdapter
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
addHook({
|
|
245
|
+
name: 'jest-circus',
|
|
246
|
+
file: 'build/legacy-code-todo-rewrite/jestAdapter.js',
|
|
247
|
+
versions: ['>=24.8.0']
|
|
248
|
+
}, jestAdapterWrapper)
|
|
249
|
+
|
|
250
|
+
function configureTestEnvironment (readConfigsResult) {
|
|
251
|
+
const { configs } = readConfigsResult
|
|
252
|
+
sessionAsyncResource.runInAsyncScope(() => {
|
|
253
|
+
testSessionConfigurationCh.publish(configs.map(config => config.testEnvironmentOptions))
|
|
254
|
+
})
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
function jestConfigAsyncWrapper (jestConfig) {
|
|
258
|
+
shimmer.wrap(jestConfig, 'readConfigs', readConfigs => async function () {
|
|
259
|
+
const readConfigsResult = await readConfigs.apply(this, arguments)
|
|
260
|
+
configureTestEnvironment(readConfigsResult)
|
|
261
|
+
return readConfigsResult
|
|
262
|
+
})
|
|
263
|
+
return jestConfig
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
function jestConfigSyncWrapper (jestConfig) {
|
|
267
|
+
shimmer.wrap(jestConfig, 'readConfigs', readConfigs => function () {
|
|
268
|
+
const readConfigsResult = readConfigs.apply(this, arguments)
|
|
269
|
+
configureTestEnvironment(readConfigsResult)
|
|
270
|
+
return readConfigsResult
|
|
271
|
+
})
|
|
272
|
+
return jestConfig
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// from 25.1.0 on, readConfigs becomes async
|
|
276
|
+
addHook({
|
|
277
|
+
name: 'jest-config',
|
|
278
|
+
versions: ['>=25.1.0']
|
|
279
|
+
}, jestConfigAsyncWrapper)
|
|
280
|
+
|
|
281
|
+
addHook({
|
|
282
|
+
name: 'jest-config',
|
|
283
|
+
versions: ['24.8.0 - 24.9.0']
|
|
284
|
+
}, jestConfigSyncWrapper)
|
|
285
|
+
|
|
286
|
+
function jasmineAsyncInstallWraper (jasmineAsyncInstallExport) {
|
|
171
287
|
return function (globalConfig, globalInput) {
|
|
172
288
|
globalInput._ddtrace = global._ddtrace
|
|
173
289
|
shimmer.wrap(globalInput.jasmine.Spec.prototype, 'execute', execute => function (onComplete) {
|
|
@@ -194,4 +310,10 @@ addHook({
|
|
|
194
310
|
})
|
|
195
311
|
return jasmineAsyncInstallExport.default(globalConfig, globalInput)
|
|
196
312
|
}
|
|
197
|
-
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
addHook({
|
|
316
|
+
name: 'jest-jasmine2',
|
|
317
|
+
versions: ['>=24.8.0'],
|
|
318
|
+
file: 'build/jasmineAsyncInstall.js'
|
|
319
|
+
}, jasmineAsyncInstallWraper)
|