dd-trace 5.19.0 → 5.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ext/formats.d.ts +1 -0
- package/ext/formats.js +2 -1
- package/index.d.ts +2 -1
- package/init.js +3 -15
- package/package.json +5 -4
- package/packages/datadog-instrumentations/src/body-parser.js +14 -2
- package/packages/datadog-instrumentations/src/cucumber.js +10 -0
- package/packages/datadog-instrumentations/src/helpers/hooks.js +3 -2
- package/packages/datadog-instrumentations/src/helpers/register.js +21 -12
- package/packages/datadog-instrumentations/src/http/client.js +7 -1
- package/packages/datadog-instrumentations/src/http/server.js +50 -13
- package/packages/datadog-instrumentations/src/mocha/main.js +111 -78
- package/packages/datadog-instrumentations/src/nyc.js +23 -0
- package/packages/datadog-instrumentations/src/process.js +29 -0
- package/packages/datadog-instrumentations/src/vitest.js +65 -25
- package/packages/datadog-plugin-aws-sdk/src/base.js +15 -1
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +3 -3
- package/packages/datadog-plugin-cucumber/src/index.js +12 -2
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +53 -12
- package/packages/datadog-plugin-jest/src/index.js +17 -4
- package/packages/datadog-plugin-mocha/src/index.js +25 -6
- package/packages/datadog-plugin-nyc/src/index.js +35 -0
- package/packages/datadog-plugin-playwright/src/index.js +9 -4
- package/packages/datadog-plugin-vitest/src/index.js +32 -5
- package/packages/dd-trace/src/appsec/blocking.js +10 -1
- package/packages/dd-trace/src/appsec/channels.js +4 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +1 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/code-injection-analyzer.js +16 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/weak-hash-analyzer.js +2 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/csi-methods.js +2 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +11 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/code-injection-sensitive-analyzer.js +25 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +2 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-regex.js +2 -2
- package/packages/dd-trace/src/appsec/iast/vulnerabilities.js +1 -0
- package/packages/dd-trace/src/appsec/index.js +12 -7
- package/packages/dd-trace/src/appsec/rasp.js +121 -7
- package/packages/dd-trace/src/appsec/recommended.json +220 -2
- package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +40 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +2 -4
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +2 -4
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +8 -7
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +2 -4
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +2 -4
- package/packages/dd-trace/src/ci-visibility/telemetry.js +29 -2
- package/packages/dd-trace/src/config.js +158 -153
- package/packages/dd-trace/src/data_streams.js +44 -0
- package/packages/dd-trace/src/datastreams/pathway.js +4 -2
- package/packages/dd-trace/src/log/index.js +32 -0
- package/packages/dd-trace/src/opentelemetry/context_manager.js +22 -39
- package/packages/dd-trace/src/opentelemetry/span_context.js +2 -2
- package/packages/dd-trace/src/opentelemetry/tracer.js +23 -14
- package/packages/dd-trace/src/opentelemetry/tracer_provider.js +9 -1
- package/packages/dd-trace/src/opentracing/propagation/log.js +1 -1
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +60 -0
- package/packages/dd-trace/src/opentracing/propagation/text_map_dsm.js +43 -0
- package/packages/dd-trace/src/opentracing/span_context.js +1 -0
- package/packages/dd-trace/src/opentracing/tracer.js +10 -6
- package/packages/dd-trace/src/plugins/ci_plugin.js +11 -4
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/dd-trace/src/plugins/plugin.js +12 -1
- package/packages/dd-trace/src/plugins/util/git.js +14 -1
- package/packages/dd-trace/src/proxy.js +1 -0
- package/packages/dd-trace/src/telemetry/index.js +1 -1
- package/packages/dd-trace/src/tracer.js +2 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const shimmer = require('../../datadog-shimmer')
|
|
4
|
+
const { channel } = require('dc-polyfill')
|
|
5
|
+
|
|
6
|
+
const startSetUncaughtExceptionCaptureCallback = channel('datadog:process:setUncaughtExceptionCaptureCallback:start')
|
|
7
|
+
|
|
8
|
+
if (process.setUncaughtExceptionCaptureCallback) {
|
|
9
|
+
let currentCallback
|
|
10
|
+
|
|
11
|
+
shimmer.wrap(process, 'setUncaughtExceptionCaptureCallback',
|
|
12
|
+
function wrapSetUncaughtExceptionCaptureCallback (originalSetUncaughtExceptionCaptureCallback) {
|
|
13
|
+
return function setUncaughtExceptionCaptureCallback (newCallback) {
|
|
14
|
+
if (startSetUncaughtExceptionCaptureCallback.hasSubscribers) {
|
|
15
|
+
const abortController = new AbortController()
|
|
16
|
+
startSetUncaughtExceptionCaptureCallback.publish({ newCallback, currentCallback, abortController })
|
|
17
|
+
if (abortController.signal.aborted) {
|
|
18
|
+
return
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const result = originalSetUncaughtExceptionCaptureCallback.apply(this, arguments)
|
|
23
|
+
|
|
24
|
+
currentCallback = newCallback
|
|
25
|
+
|
|
26
|
+
return result
|
|
27
|
+
}
|
|
28
|
+
})
|
|
29
|
+
}
|
|
@@ -32,6 +32,10 @@ function isReporterPackageNew (vitestPackage) {
|
|
|
32
32
|
return vitestPackage.e?.name === 'BaseSequencer'
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
function isReporterPackageNewest (vitestPackage) {
|
|
36
|
+
return vitestPackage.h?.name === 'BaseSequencer'
|
|
37
|
+
}
|
|
38
|
+
|
|
35
39
|
function getChannelPromise (channelToPublishTo) {
|
|
36
40
|
return new Promise(resolve => {
|
|
37
41
|
sessionAsyncResource.runInAsyncScope(() => {
|
|
@@ -117,6 +121,21 @@ function getSortWrapper (sort) {
|
|
|
117
121
|
this.ctx.config.retry = NUM_FAILED_TEST_RETRIES
|
|
118
122
|
}
|
|
119
123
|
|
|
124
|
+
let testCodeCoverageLinesTotal
|
|
125
|
+
|
|
126
|
+
if (this.ctx.coverageProvider?.generateCoverage) {
|
|
127
|
+
shimmer.wrap(this.ctx.coverageProvider, 'generateCoverage', generateCoverage => async function () {
|
|
128
|
+
const totalCodeCoverage = await generateCoverage.apply(this, arguments)
|
|
129
|
+
|
|
130
|
+
try {
|
|
131
|
+
testCodeCoverageLinesTotal = totalCodeCoverage.getCoverageSummary().lines.pct
|
|
132
|
+
} catch (e) {
|
|
133
|
+
// ignore errors
|
|
134
|
+
}
|
|
135
|
+
return totalCodeCoverage
|
|
136
|
+
})
|
|
137
|
+
}
|
|
138
|
+
|
|
120
139
|
shimmer.wrap(this.ctx, 'exit', exit => async function () {
|
|
121
140
|
let onFinish
|
|
122
141
|
|
|
@@ -132,8 +151,9 @@ function getSortWrapper (sort) {
|
|
|
132
151
|
sessionAsyncResource.runInAsyncScope(() => {
|
|
133
152
|
testSessionFinishCh.publish({
|
|
134
153
|
status: getSessionStatus(this.state),
|
|
135
|
-
|
|
136
|
-
error
|
|
154
|
+
testCodeCoverageLinesTotal,
|
|
155
|
+
error,
|
|
156
|
+
onFinish
|
|
137
157
|
})
|
|
138
158
|
})
|
|
139
159
|
|
|
@@ -146,6 +166,21 @@ function getSortWrapper (sort) {
|
|
|
146
166
|
}
|
|
147
167
|
}
|
|
148
168
|
|
|
169
|
+
function getCreateCliWrapper (vitestPackage, frameworkVersion) {
|
|
170
|
+
shimmer.wrap(vitestPackage, 'c', oldCreateCli => function () {
|
|
171
|
+
if (!testSessionStartCh.hasSubscribers) {
|
|
172
|
+
return oldCreateCli.apply(this, arguments)
|
|
173
|
+
}
|
|
174
|
+
sessionAsyncResource.runInAsyncScope(() => {
|
|
175
|
+
const processArgv = process.argv.slice(2).join(' ')
|
|
176
|
+
testSessionStartCh.publish({ command: `vitest ${processArgv}`, frameworkVersion })
|
|
177
|
+
})
|
|
178
|
+
return oldCreateCli.apply(this, arguments)
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
return vitestPackage
|
|
182
|
+
}
|
|
183
|
+
|
|
149
184
|
addHook({
|
|
150
185
|
name: 'vitest',
|
|
151
186
|
versions: ['>=1.6.0'],
|
|
@@ -206,12 +241,25 @@ addHook({
|
|
|
206
241
|
return vitestPackage
|
|
207
242
|
})
|
|
208
243
|
|
|
244
|
+
// There are multiple index* files across different versions of vitest,
|
|
245
|
+
// so we check for the existence of BaseSequencer to determine if we are in the right file
|
|
246
|
+
addHook({
|
|
247
|
+
name: 'vitest',
|
|
248
|
+
versions: ['>=1.6.0 <2.0.0'],
|
|
249
|
+
filePattern: 'dist/vendor/index.*'
|
|
250
|
+
}, (vitestPackage) => {
|
|
251
|
+
if (isReporterPackage(vitestPackage)) {
|
|
252
|
+
shimmer.wrap(vitestPackage.B.prototype, 'sort', getSortWrapper)
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
return vitestPackage
|
|
256
|
+
})
|
|
257
|
+
|
|
209
258
|
addHook({
|
|
210
259
|
name: 'vitest',
|
|
211
|
-
versions: ['>=2.0.0'],
|
|
260
|
+
versions: ['>=2.0.0 <2.0.5'],
|
|
212
261
|
filePattern: 'dist/vendor/index.*'
|
|
213
262
|
}, (vitestPackage) => {
|
|
214
|
-
// there are multiple index* files so we have to check the exported values
|
|
215
263
|
if (isReporterPackageNew(vitestPackage)) {
|
|
216
264
|
shimmer.wrap(vitestPackage.e.prototype, 'sort', getSortWrapper)
|
|
217
265
|
}
|
|
@@ -221,12 +269,11 @@ addHook({
|
|
|
221
269
|
|
|
222
270
|
addHook({
|
|
223
271
|
name: 'vitest',
|
|
224
|
-
versions: ['>=
|
|
225
|
-
filePattern: 'dist/
|
|
272
|
+
versions: ['>=2.0.5'],
|
|
273
|
+
filePattern: 'dist/chunks/index.*'
|
|
226
274
|
}, (vitestPackage) => {
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
shimmer.wrap(vitestPackage.B.prototype, 'sort', getSortWrapper)
|
|
275
|
+
if (isReporterPackageNewest(vitestPackage)) {
|
|
276
|
+
shimmer.wrap(vitestPackage.h.prototype, 'sort', getSortWrapper)
|
|
230
277
|
}
|
|
231
278
|
|
|
232
279
|
return vitestPackage
|
|
@@ -235,22 +282,15 @@ addHook({
|
|
|
235
282
|
// Can't specify file because compiled vitest includes hashes in their files
|
|
236
283
|
addHook({
|
|
237
284
|
name: 'vitest',
|
|
238
|
-
versions: ['>=1.6.0'],
|
|
285
|
+
versions: ['>=1.6.0 <2.0.5'],
|
|
239
286
|
filePattern: 'dist/vendor/cac.*'
|
|
240
|
-
},
|
|
241
|
-
shimmer.wrap(vitestPackage, 'c', oldCreateCli => function () {
|
|
242
|
-
if (!testSessionStartCh.hasSubscribers) {
|
|
243
|
-
return oldCreateCli.apply(this, arguments)
|
|
244
|
-
}
|
|
245
|
-
sessionAsyncResource.runInAsyncScope(() => {
|
|
246
|
-
const processArgv = process.argv.slice(2).join(' ')
|
|
247
|
-
testSessionStartCh.publish({ command: `vitest ${processArgv}`, frameworkVersion })
|
|
248
|
-
})
|
|
249
|
-
return oldCreateCli.apply(this, arguments)
|
|
250
|
-
})
|
|
287
|
+
}, getCreateCliWrapper)
|
|
251
288
|
|
|
252
|
-
|
|
253
|
-
|
|
289
|
+
addHook({
|
|
290
|
+
name: 'vitest',
|
|
291
|
+
versions: ['>=2.0.5'],
|
|
292
|
+
filePattern: 'dist/chunks/cac.*'
|
|
293
|
+
}, getCreateCliWrapper)
|
|
254
294
|
|
|
255
295
|
// test suite start and finish
|
|
256
296
|
// only relevant for workers
|
|
@@ -258,7 +298,7 @@ addHook({
|
|
|
258
298
|
name: '@vitest/runner',
|
|
259
299
|
versions: ['>=1.6.0'],
|
|
260
300
|
file: 'dist/index.js'
|
|
261
|
-
}, vitestPackage => {
|
|
301
|
+
}, (vitestPackage, frameworkVersion) => {
|
|
262
302
|
shimmer.wrap(vitestPackage, 'startTests', startTests => async function (testPath) {
|
|
263
303
|
let testSuiteError = null
|
|
264
304
|
if (!testSuiteStartCh.hasSubscribers) {
|
|
@@ -267,7 +307,7 @@ addHook({
|
|
|
267
307
|
|
|
268
308
|
const testSuiteAsyncResource = new AsyncResource('bound-anonymous-fn')
|
|
269
309
|
testSuiteAsyncResource.runInAsyncScope(() => {
|
|
270
|
-
testSuiteStartCh.publish(testPath[0])
|
|
310
|
+
testSuiteStartCh.publish({ testSuiteAbsolutePath: testPath[0], frameworkVersion })
|
|
271
311
|
})
|
|
272
312
|
const startTestsResponse = await startTests.apply(this, arguments)
|
|
273
313
|
|
|
@@ -4,6 +4,7 @@ const analyticsSampler = require('../../dd-trace/src/analytics_sampler')
|
|
|
4
4
|
const ClientPlugin = require('../../dd-trace/src/plugins/client')
|
|
5
5
|
const { storage } = require('../../datadog-core')
|
|
6
6
|
const { isTrue } = require('../../dd-trace/src/util')
|
|
7
|
+
const coalesce = require('koalas')
|
|
7
8
|
|
|
8
9
|
class BaseAwsSdkPlugin extends ClientPlugin {
|
|
9
10
|
static get id () { return 'aws' }
|
|
@@ -163,9 +164,22 @@ function normalizeConfig (config, serviceIdentifier) {
|
|
|
163
164
|
break
|
|
164
165
|
}
|
|
165
166
|
|
|
167
|
+
// check if AWS batch propagation or AWS_[SERVICE] batch propagation is enabled via env variable
|
|
168
|
+
const serviceId = serviceIdentifier.toUpperCase()
|
|
169
|
+
const batchPropagationEnabled = isTrue(
|
|
170
|
+
coalesce(
|
|
171
|
+
specificConfig.batchPropagationEnabled,
|
|
172
|
+
process.env[`DD_TRACE_AWS_SDK_${serviceId}_BATCH_PROPAGATION_ENABLED`],
|
|
173
|
+
config.batchPropagationEnabled,
|
|
174
|
+
process.env.DD_TRACE_AWS_SDK_BATCH_PROPAGATION_ENABLED,
|
|
175
|
+
false
|
|
176
|
+
)
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
// Merge the specific config back into the main config
|
|
166
180
|
return Object.assign({}, config, specificConfig, {
|
|
167
181
|
splitByAwsService: config.splitByAwsService !== false,
|
|
168
|
-
batchPropagationEnabled
|
|
182
|
+
batchPropagationEnabled,
|
|
169
183
|
hooks
|
|
170
184
|
})
|
|
171
185
|
}
|
|
@@ -157,8 +157,8 @@ class Sqs extends BaseAwsSdkPlugin {
|
|
|
157
157
|
if (attributes.StringValue) {
|
|
158
158
|
const textMap = attributes.StringValue
|
|
159
159
|
return JSON.parse(textMap)
|
|
160
|
-
} else if (attributes.Type === 'Binary') {
|
|
161
|
-
const buffer = Buffer.from(attributes.Value, 'base64')
|
|
160
|
+
} else if (attributes.Type === 'Binary' || attributes.DataType === 'Binary') {
|
|
161
|
+
const buffer = Buffer.from(attributes.Value ?? attributes.BinaryValue, 'base64')
|
|
162
162
|
return JSON.parse(buffer)
|
|
163
163
|
}
|
|
164
164
|
} catch (e) {
|
|
@@ -222,7 +222,7 @@ class Sqs extends BaseAwsSdkPlugin {
|
|
|
222
222
|
span,
|
|
223
223
|
params.Entries[i],
|
|
224
224
|
params.QueueUrl,
|
|
225
|
-
i === 0 || (this.config.
|
|
225
|
+
i === 0 || (this.config.batchPropagationEnabled)
|
|
226
226
|
)
|
|
227
227
|
}
|
|
228
228
|
break
|
|
@@ -37,7 +37,10 @@ const {
|
|
|
37
37
|
TELEMETRY_ITR_FORCED_TO_RUN,
|
|
38
38
|
TELEMETRY_CODE_COVERAGE_EMPTY,
|
|
39
39
|
TELEMETRY_ITR_UNSKIPPABLE,
|
|
40
|
-
TELEMETRY_CODE_COVERAGE_NUM_FILES
|
|
40
|
+
TELEMETRY_CODE_COVERAGE_NUM_FILES,
|
|
41
|
+
TEST_IS_RUM_ACTIVE,
|
|
42
|
+
TEST_BROWSER_DRIVER,
|
|
43
|
+
TELEMETRY_TEST_SESSION
|
|
41
44
|
} = require('../../dd-trace/src/ci-visibility/telemetry')
|
|
42
45
|
const id = require('../../dd-trace/src/id')
|
|
43
46
|
|
|
@@ -107,6 +110,7 @@ class CucumberPlugin extends CiPlugin {
|
|
|
107
110
|
this.testSessionSpan.finish()
|
|
108
111
|
this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'session')
|
|
109
112
|
finishAllTraceSpans(this.testSessionSpan)
|
|
113
|
+
this.telemetry.count(TELEMETRY_TEST_SESSION, { provider: this.ciProviderName })
|
|
110
114
|
|
|
111
115
|
this.libraryConfig = null
|
|
112
116
|
this.tracer._exporter.flush()
|
|
@@ -285,10 +289,16 @@ class CucumberPlugin extends CiPlugin {
|
|
|
285
289
|
|
|
286
290
|
span.finish()
|
|
287
291
|
if (!isStep) {
|
|
292
|
+
const spanTags = span.context()._tags
|
|
288
293
|
this.telemetry.ciVisEvent(
|
|
289
294
|
TELEMETRY_EVENT_FINISHED,
|
|
290
295
|
'test',
|
|
291
|
-
{
|
|
296
|
+
{
|
|
297
|
+
hasCodeOwners: !!spanTags[TEST_CODE_OWNERS],
|
|
298
|
+
isNew,
|
|
299
|
+
isRum: spanTags[TEST_IS_RUM_ACTIVE] === 'true',
|
|
300
|
+
browserDriver: spanTags[TEST_BROWSER_DRIVER]
|
|
301
|
+
}
|
|
292
302
|
)
|
|
293
303
|
finishAllTraceSpans(span)
|
|
294
304
|
// If it's a worker, flushing is cheap, as it's just sending data to the main process
|
|
@@ -44,7 +44,9 @@ const {
|
|
|
44
44
|
TELEMETRY_ITR_UNSKIPPABLE,
|
|
45
45
|
TELEMETRY_CODE_COVERAGE_NUM_FILES,
|
|
46
46
|
incrementCountMetric,
|
|
47
|
-
distributionMetric
|
|
47
|
+
distributionMetric,
|
|
48
|
+
TELEMETRY_ITR_SKIPPED,
|
|
49
|
+
TELEMETRY_TEST_SESSION
|
|
48
50
|
} = require('../../dd-trace/src/ci-visibility/telemetry')
|
|
49
51
|
|
|
50
52
|
const {
|
|
@@ -179,7 +181,7 @@ class CypressPlugin {
|
|
|
179
181
|
} = this.testEnvironmentMetadata
|
|
180
182
|
|
|
181
183
|
this.repositoryRoot = repositoryRoot
|
|
182
|
-
this.
|
|
184
|
+
this.ciProviderName = ciProviderName
|
|
183
185
|
this.codeOwnersEntries = getCodeOwnersFileEntries(repositoryRoot)
|
|
184
186
|
|
|
185
187
|
this.testConfiguration = {
|
|
@@ -258,7 +260,7 @@ class CypressPlugin {
|
|
|
258
260
|
})
|
|
259
261
|
}
|
|
260
262
|
|
|
261
|
-
getTestSpan (testName, testSuite, isUnskippable, isForcedToRun) {
|
|
263
|
+
getTestSpan ({ testName, testSuite, isUnskippable, isForcedToRun, testSourceFile }) {
|
|
262
264
|
const testSuiteTags = {
|
|
263
265
|
[TEST_COMMAND]: this.command,
|
|
264
266
|
[TEST_COMMAND]: this.command,
|
|
@@ -282,8 +284,11 @@ class CypressPlugin {
|
|
|
282
284
|
...testSpanMetadata
|
|
283
285
|
} = getTestCommonTags(testName, testSuite, this.cypressConfig.version, TEST_FRAMEWORK_NAME)
|
|
284
286
|
|
|
285
|
-
|
|
287
|
+
if (testSourceFile) {
|
|
288
|
+
testSpanMetadata[TEST_SOURCE_FILE] = testSourceFile
|
|
289
|
+
}
|
|
286
290
|
|
|
291
|
+
const codeOwners = this.getTestCodeOwners({ testSuite, testSourceFile })
|
|
287
292
|
if (codeOwners) {
|
|
288
293
|
testSpanMetadata[TEST_CODE_OWNERS] = codeOwners
|
|
289
294
|
}
|
|
@@ -318,7 +323,7 @@ class CypressPlugin {
|
|
|
318
323
|
incrementCountMetric(name, {
|
|
319
324
|
testLevel,
|
|
320
325
|
testFramework: 'cypress',
|
|
321
|
-
isUnsupportedCIProvider: this.
|
|
326
|
+
isUnsupportedCIProvider: !this.ciProviderName,
|
|
322
327
|
...tags
|
|
323
328
|
})
|
|
324
329
|
}
|
|
@@ -360,6 +365,7 @@ class CypressPlugin {
|
|
|
360
365
|
const { skippableTests, correlationId } = skippableTestsResponse
|
|
361
366
|
this.testsToSkip = skippableTests || []
|
|
362
367
|
this.itrCorrelationId = correlationId
|
|
368
|
+
incrementCountMetric(TELEMETRY_ITR_SKIPPED, { testLevel: 'test' }, this.testsToSkip.length)
|
|
363
369
|
}
|
|
364
370
|
}
|
|
365
371
|
|
|
@@ -433,6 +439,9 @@ class CypressPlugin {
|
|
|
433
439
|
this.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'module')
|
|
434
440
|
this.testSessionSpan.finish()
|
|
435
441
|
this.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'session')
|
|
442
|
+
incrementCountMetric(TELEMETRY_TEST_SESSION, {
|
|
443
|
+
provider: this.ciProviderName
|
|
444
|
+
})
|
|
436
445
|
|
|
437
446
|
finishAllTraceSpans(this.testSessionSpan)
|
|
438
447
|
}
|
|
@@ -480,12 +489,16 @@ class CypressPlugin {
|
|
|
480
489
|
const isSkippedByItr = this.testsToSkip.find(test =>
|
|
481
490
|
cypressTestName === test.name && spec.relative === test.suite
|
|
482
491
|
)
|
|
483
|
-
|
|
492
|
+
let testSourceFile
|
|
493
|
+
|
|
484
494
|
if (spec.absolute && this.repositoryRoot) {
|
|
485
|
-
|
|
495
|
+
testSourceFile = getTestSuitePath(spec.absolute, this.repositoryRoot)
|
|
486
496
|
} else {
|
|
487
|
-
|
|
497
|
+
testSourceFile = spec.relative
|
|
488
498
|
}
|
|
499
|
+
|
|
500
|
+
const skippedTestSpan = this.getTestSpan({ testName: cypressTestName, testSuite: spec.relative, testSourceFile })
|
|
501
|
+
|
|
489
502
|
skippedTestSpan.setTag(TEST_STATUS, 'skip')
|
|
490
503
|
if (isSkippedByItr) {
|
|
491
504
|
skippedTestSpan.setTag(TEST_SKIPPED_BY_ITR, 'true')
|
|
@@ -538,11 +551,21 @@ class CypressPlugin {
|
|
|
538
551
|
if (this.itrCorrelationId) {
|
|
539
552
|
finishedTest.testSpan.setTag(ITR_CORRELATION_ID, this.itrCorrelationId)
|
|
540
553
|
}
|
|
554
|
+
let testSourceFile
|
|
541
555
|
if (spec.absolute && this.repositoryRoot) {
|
|
542
|
-
|
|
556
|
+
testSourceFile = getTestSuitePath(spec.absolute, this.repositoryRoot)
|
|
543
557
|
} else {
|
|
544
|
-
|
|
558
|
+
testSourceFile = spec.relative
|
|
559
|
+
}
|
|
560
|
+
if (testSourceFile) {
|
|
561
|
+
finishedTest.testSpan.setTag(TEST_SOURCE_FILE, testSourceFile)
|
|
562
|
+
}
|
|
563
|
+
const codeOwners = this.getTestCodeOwners({ testSuite: spec.relative, testSourceFile })
|
|
564
|
+
|
|
565
|
+
if (codeOwners) {
|
|
566
|
+
finishedTest.testSpan.setTag(TEST_CODE_OWNERS, codeOwners)
|
|
545
567
|
}
|
|
568
|
+
|
|
546
569
|
finishedTest.testSpan.finish(finishedTest.finishTime)
|
|
547
570
|
})
|
|
548
571
|
})
|
|
@@ -591,7 +614,12 @@ class CypressPlugin {
|
|
|
591
614
|
}
|
|
592
615
|
|
|
593
616
|
if (!this.activeTestSpan) {
|
|
594
|
-
this.activeTestSpan = this.getTestSpan(
|
|
617
|
+
this.activeTestSpan = this.getTestSpan({
|
|
618
|
+
testName,
|
|
619
|
+
testSuite,
|
|
620
|
+
isUnskippable,
|
|
621
|
+
isForcedToRun
|
|
622
|
+
})
|
|
595
623
|
}
|
|
596
624
|
|
|
597
625
|
return this.activeTestSpan ? { traceId: this.activeTestSpan.context().toTraceId() } : {}
|
|
@@ -646,8 +674,14 @@ class CypressPlugin {
|
|
|
646
674
|
}
|
|
647
675
|
// test spans are finished at after:spec
|
|
648
676
|
}
|
|
677
|
+
this.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'test', {
|
|
678
|
+
hasCodeOwners: !!this.activeTestSpan.context()._tags[TEST_CODE_OWNERS],
|
|
679
|
+
isNew,
|
|
680
|
+
isRum: isRUMActive,
|
|
681
|
+
browserDriver: 'cypress'
|
|
682
|
+
})
|
|
649
683
|
this.activeTestSpan = null
|
|
650
|
-
|
|
684
|
+
|
|
651
685
|
return null
|
|
652
686
|
},
|
|
653
687
|
'dd:addTags': (tags) => {
|
|
@@ -658,6 +692,13 @@ class CypressPlugin {
|
|
|
658
692
|
}
|
|
659
693
|
}
|
|
660
694
|
}
|
|
695
|
+
|
|
696
|
+
getTestCodeOwners ({ testSuite, testSourceFile }) {
|
|
697
|
+
if (testSourceFile) {
|
|
698
|
+
return getCodeOwnersForFilename(testSourceFile, this.codeOwnersEntries)
|
|
699
|
+
}
|
|
700
|
+
return getCodeOwnersForFilename(testSuite, this.codeOwnersEntries)
|
|
701
|
+
}
|
|
661
702
|
}
|
|
662
703
|
|
|
663
704
|
module.exports = new CypressPlugin()
|
|
@@ -20,7 +20,9 @@ const {
|
|
|
20
20
|
TEST_IS_RETRY,
|
|
21
21
|
TEST_EARLY_FLAKE_ENABLED,
|
|
22
22
|
TEST_EARLY_FLAKE_ABORT_REASON,
|
|
23
|
-
JEST_DISPLAY_NAME
|
|
23
|
+
JEST_DISPLAY_NAME,
|
|
24
|
+
TEST_IS_RUM_ACTIVE,
|
|
25
|
+
TEST_BROWSER_DRIVER
|
|
24
26
|
} = require('../../dd-trace/src/plugins/util/test')
|
|
25
27
|
const { COMPONENT } = require('../../dd-trace/src/constants')
|
|
26
28
|
const id = require('../../dd-trace/src/id')
|
|
@@ -32,7 +34,8 @@ const {
|
|
|
32
34
|
TELEMETRY_ITR_FORCED_TO_RUN,
|
|
33
35
|
TELEMETRY_CODE_COVERAGE_EMPTY,
|
|
34
36
|
TELEMETRY_ITR_UNSKIPPABLE,
|
|
35
|
-
TELEMETRY_CODE_COVERAGE_NUM_FILES
|
|
37
|
+
TELEMETRY_CODE_COVERAGE_NUM_FILES,
|
|
38
|
+
TELEMETRY_TEST_SESSION
|
|
36
39
|
} = require('../../dd-trace/src/ci-visibility/telemetry')
|
|
37
40
|
|
|
38
41
|
const isJestWorker = !!process.env.JEST_WORKER_ID
|
|
@@ -129,6 +132,8 @@ class JestPlugin extends CiPlugin {
|
|
|
129
132
|
this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'session')
|
|
130
133
|
finishAllTraceSpans(this.testSessionSpan)
|
|
131
134
|
|
|
135
|
+
this.telemetry.count(TELEMETRY_TEST_SESSION, { provider: this.ciProviderName })
|
|
136
|
+
|
|
132
137
|
this.tracer._exporter.flush(() => {
|
|
133
138
|
if (onDone) {
|
|
134
139
|
onDone()
|
|
@@ -287,12 +292,20 @@ class JestPlugin extends CiPlugin {
|
|
|
287
292
|
if (testStartLine) {
|
|
288
293
|
span.setTag(TEST_SOURCE_START, testStartLine)
|
|
289
294
|
}
|
|
290
|
-
|
|
295
|
+
|
|
296
|
+
const spanTags = span.context()._tags
|
|
291
297
|
this.telemetry.ciVisEvent(
|
|
292
298
|
TELEMETRY_EVENT_FINISHED,
|
|
293
299
|
'test',
|
|
294
|
-
{
|
|
300
|
+
{
|
|
301
|
+
hasCodeOwners: !!spanTags[TEST_CODE_OWNERS],
|
|
302
|
+
isNew: spanTags[TEST_IS_NEW] === 'true',
|
|
303
|
+
isRum: spanTags[TEST_IS_RUM_ACTIVE] === 'true',
|
|
304
|
+
browserDriver: spanTags[TEST_BROWSER_DRIVER]
|
|
305
|
+
}
|
|
295
306
|
)
|
|
307
|
+
|
|
308
|
+
span.finish()
|
|
296
309
|
finishAllTraceSpans(span)
|
|
297
310
|
})
|
|
298
311
|
|
|
@@ -27,7 +27,9 @@ const {
|
|
|
27
27
|
TEST_SUITE_ID,
|
|
28
28
|
TEST_COMMAND,
|
|
29
29
|
TEST_SUITE,
|
|
30
|
-
MOCHA_IS_PARALLEL
|
|
30
|
+
MOCHA_IS_PARALLEL,
|
|
31
|
+
TEST_IS_RUM_ACTIVE,
|
|
32
|
+
TEST_BROWSER_DRIVER
|
|
31
33
|
} = require('../../dd-trace/src/plugins/util/test')
|
|
32
34
|
const { COMPONENT } = require('../../dd-trace/src/constants')
|
|
33
35
|
const {
|
|
@@ -38,7 +40,8 @@ const {
|
|
|
38
40
|
TELEMETRY_ITR_FORCED_TO_RUN,
|
|
39
41
|
TELEMETRY_CODE_COVERAGE_EMPTY,
|
|
40
42
|
TELEMETRY_ITR_UNSKIPPABLE,
|
|
41
|
-
TELEMETRY_CODE_COVERAGE_NUM_FILES
|
|
43
|
+
TELEMETRY_CODE_COVERAGE_NUM_FILES,
|
|
44
|
+
TELEMETRY_TEST_SESSION
|
|
42
45
|
} = require('../../dd-trace/src/ci-visibility/telemetry')
|
|
43
46
|
const id = require('../../dd-trace/src/id')
|
|
44
47
|
const log = require('../../dd-trace/src/log')
|
|
@@ -184,12 +187,20 @@ class MochaPlugin extends CiPlugin {
|
|
|
184
187
|
if (hasBeenRetried) {
|
|
185
188
|
span.setTag(TEST_IS_RETRY, 'true')
|
|
186
189
|
}
|
|
187
|
-
|
|
190
|
+
|
|
191
|
+
const spanTags = span.context()._tags
|
|
188
192
|
this.telemetry.ciVisEvent(
|
|
189
193
|
TELEMETRY_EVENT_FINISHED,
|
|
190
194
|
'test',
|
|
191
|
-
{
|
|
195
|
+
{
|
|
196
|
+
hasCodeOwners: !!spanTags[TEST_CODE_OWNERS],
|
|
197
|
+
isNew: spanTags[TEST_IS_NEW] === 'true',
|
|
198
|
+
isRum: spanTags[TEST_IS_RUM_ACTIVE] === 'true',
|
|
199
|
+
browserDriver: spanTags[TEST_BROWSER_DRIVER]
|
|
200
|
+
}
|
|
192
201
|
)
|
|
202
|
+
|
|
203
|
+
span.finish()
|
|
193
204
|
finishAllTraceSpans(span)
|
|
194
205
|
}
|
|
195
206
|
})
|
|
@@ -226,12 +237,19 @@ class MochaPlugin extends CiPlugin {
|
|
|
226
237
|
span.setTag(TEST_IS_RETRY, 'true')
|
|
227
238
|
}
|
|
228
239
|
|
|
229
|
-
span.
|
|
240
|
+
const spanTags = span.context()._tags
|
|
230
241
|
this.telemetry.ciVisEvent(
|
|
231
242
|
TELEMETRY_EVENT_FINISHED,
|
|
232
243
|
'test',
|
|
233
|
-
{
|
|
244
|
+
{
|
|
245
|
+
hasCodeOwners: !!spanTags[TEST_CODE_OWNERS],
|
|
246
|
+
isNew: spanTags[TEST_IS_NEW] === 'true',
|
|
247
|
+
isRum: spanTags[TEST_IS_RUM_ACTIVE] === 'true',
|
|
248
|
+
browserDriver: spanTags[TEST_BROWSER_DRIVER]
|
|
249
|
+
}
|
|
234
250
|
)
|
|
251
|
+
|
|
252
|
+
span.finish()
|
|
235
253
|
finishAllTraceSpans(span)
|
|
236
254
|
}
|
|
237
255
|
})
|
|
@@ -289,6 +307,7 @@ class MochaPlugin extends CiPlugin {
|
|
|
289
307
|
this.testSessionSpan.finish()
|
|
290
308
|
this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'session')
|
|
291
309
|
finishAllTraceSpans(this.testSessionSpan)
|
|
310
|
+
this.telemetry.count(TELEMETRY_TEST_SESSION, { provider: this.ciProviderName })
|
|
292
311
|
}
|
|
293
312
|
this.libraryConfig = null
|
|
294
313
|
this.tracer._exporter.flush()
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
const CiPlugin = require('../../dd-trace/src/plugins/ci_plugin')
|
|
2
|
+
|
|
3
|
+
class NycPlugin extends CiPlugin {
|
|
4
|
+
static get id () {
|
|
5
|
+
return 'nyc'
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
constructor (...args) {
|
|
9
|
+
super(...args)
|
|
10
|
+
|
|
11
|
+
this.addSub('ci:nyc:wrap', (nyc) => {
|
|
12
|
+
if (nyc?.config?.all) {
|
|
13
|
+
this.nyc = nyc
|
|
14
|
+
}
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
this.addSub('ci:nyc:get-coverage', ({ onDone }) => {
|
|
18
|
+
if (this.nyc?.getCoverageMapFromAllCoverageFiles) {
|
|
19
|
+
this.nyc.getCoverageMapFromAllCoverageFiles()
|
|
20
|
+
.then((untestedCoverageMap) => {
|
|
21
|
+
this.nyc = null
|
|
22
|
+
onDone(untestedCoverageMap)
|
|
23
|
+
}).catch((e) => {
|
|
24
|
+
this.nyc = null
|
|
25
|
+
onDone()
|
|
26
|
+
})
|
|
27
|
+
} else {
|
|
28
|
+
this.nyc = null
|
|
29
|
+
onDone()
|
|
30
|
+
}
|
|
31
|
+
})
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
module.exports = NycPlugin
|
|
@@ -14,7 +14,8 @@ const {
|
|
|
14
14
|
TEST_CONFIGURATION_BROWSER_NAME,
|
|
15
15
|
TEST_IS_NEW,
|
|
16
16
|
TEST_IS_RETRY,
|
|
17
|
-
TEST_EARLY_FLAKE_ENABLED
|
|
17
|
+
TEST_EARLY_FLAKE_ENABLED,
|
|
18
|
+
TELEMETRY_TEST_SESSION
|
|
18
19
|
} = require('../../dd-trace/src/plugins/util/test')
|
|
19
20
|
const { RESOURCE_NAME } = require('../../../ext/tags')
|
|
20
21
|
const { COMPONENT } = require('../../dd-trace/src/constants')
|
|
@@ -59,6 +60,7 @@ class PlaywrightPlugin extends CiPlugin {
|
|
|
59
60
|
this.testSessionSpan.finish()
|
|
60
61
|
this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'session')
|
|
61
62
|
finishAllTraceSpans(this.testSessionSpan)
|
|
63
|
+
this.telemetry.count(TELEMETRY_TEST_SESSION, { provider: this.ciProviderName })
|
|
62
64
|
appClosingTelemetry()
|
|
63
65
|
this.tracer._exporter.flush(onDone)
|
|
64
66
|
this.numFailedTests = 0
|
|
@@ -160,8 +162,6 @@ class PlaywrightPlugin extends CiPlugin {
|
|
|
160
162
|
stepSpan.finish(stepStartTime + stepDuration)
|
|
161
163
|
})
|
|
162
164
|
|
|
163
|
-
span.finish()
|
|
164
|
-
|
|
165
165
|
if (testStatus === 'fail') {
|
|
166
166
|
this.numFailedTests++
|
|
167
167
|
}
|
|
@@ -169,8 +169,13 @@ class PlaywrightPlugin extends CiPlugin {
|
|
|
169
169
|
this.telemetry.ciVisEvent(
|
|
170
170
|
TELEMETRY_EVENT_FINISHED,
|
|
171
171
|
'test',
|
|
172
|
-
{
|
|
172
|
+
{
|
|
173
|
+
hasCodeOwners: !!span.context()._tags[TEST_CODE_OWNERS],
|
|
174
|
+
isNew,
|
|
175
|
+
browserDriver: 'playwright'
|
|
176
|
+
}
|
|
173
177
|
)
|
|
178
|
+
span.finish()
|
|
174
179
|
|
|
175
180
|
finishAllTraceSpans(span)
|
|
176
181
|
})
|