dd-trace 4.45.0 → 4.47.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/index.d.ts +20 -8
- package/package.json +11 -5
- package/packages/datadog-instrumentations/src/aerospike.js +1 -1
- package/packages/datadog-instrumentations/src/apollo-server.js +1 -1
- package/packages/datadog-instrumentations/src/aws-sdk.js +4 -4
- package/packages/datadog-instrumentations/src/body-parser.js +4 -4
- package/packages/datadog-instrumentations/src/cassandra-driver.js +2 -2
- package/packages/datadog-instrumentations/src/child_process.js +2 -2
- package/packages/datadog-instrumentations/src/connect.js +4 -4
- package/packages/datadog-instrumentations/src/cookie-parser.js +4 -4
- package/packages/datadog-instrumentations/src/couchbase.js +12 -12
- package/packages/datadog-instrumentations/src/cucumber.js +294 -56
- package/packages/datadog-instrumentations/src/dns.js +10 -10
- package/packages/datadog-instrumentations/src/elasticsearch.js +4 -4
- package/packages/datadog-instrumentations/src/express-mongo-sanitize.js +3 -3
- package/packages/datadog-instrumentations/src/express.js +4 -4
- package/packages/datadog-instrumentations/src/fastify.js +6 -6
- package/packages/datadog-instrumentations/src/fetch.js +1 -1
- package/packages/datadog-instrumentations/src/find-my-way.js +2 -2
- package/packages/datadog-instrumentations/src/fs.js +2 -2
- package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +2 -2
- package/packages/datadog-instrumentations/src/grpc/client.js +4 -6
- package/packages/datadog-instrumentations/src/grpc/server.js +2 -2
- package/packages/datadog-instrumentations/src/hapi.js +10 -13
- package/packages/datadog-instrumentations/src/helpers/register.js +1 -1
- package/packages/datadog-instrumentations/src/http/client.js +3 -3
- package/packages/datadog-instrumentations/src/jest.js +8 -5
- package/packages/datadog-instrumentations/src/kafkajs.js +67 -31
- package/packages/datadog-instrumentations/src/knex.js +2 -2
- package/packages/datadog-instrumentations/src/koa.js +5 -5
- package/packages/datadog-instrumentations/src/ldapjs.js +1 -1
- package/packages/datadog-instrumentations/src/mariadb.js +8 -8
- package/packages/datadog-instrumentations/src/memcached.js +2 -2
- package/packages/datadog-instrumentations/src/microgateway-core.js +7 -5
- package/packages/datadog-instrumentations/src/mocha/common.js +1 -1
- package/packages/datadog-instrumentations/src/mocha/main.js +139 -53
- package/packages/datadog-instrumentations/src/mocha/utils.js +37 -18
- package/packages/datadog-instrumentations/src/mocha/worker.js +29 -1
- package/packages/datadog-instrumentations/src/mocha.js +4 -0
- package/packages/datadog-instrumentations/src/moleculer/server.js +2 -2
- package/packages/datadog-instrumentations/src/mongodb-core.js +7 -7
- package/packages/datadog-instrumentations/src/mongoose.js +5 -6
- package/packages/datadog-instrumentations/src/mysql.js +3 -3
- package/packages/datadog-instrumentations/src/mysql2.js +6 -6
- package/packages/datadog-instrumentations/src/net.js +2 -2
- package/packages/datadog-instrumentations/src/next.js +5 -5
- package/packages/datadog-instrumentations/src/openai.js +62 -71
- package/packages/datadog-instrumentations/src/oracledb.js +8 -8
- package/packages/datadog-instrumentations/src/passport-http.js +1 -1
- package/packages/datadog-instrumentations/src/passport-local.js +1 -1
- package/packages/datadog-instrumentations/src/passport-utils.js +1 -1
- package/packages/datadog-instrumentations/src/pg.js +60 -5
- package/packages/datadog-instrumentations/src/pino.js +4 -4
- package/packages/datadog-instrumentations/src/playwright.js +6 -4
- package/packages/datadog-instrumentations/src/redis.js +2 -2
- package/packages/datadog-instrumentations/src/restify.js +4 -4
- package/packages/datadog-instrumentations/src/rhea.js +4 -4
- package/packages/datadog-instrumentations/src/router.js +5 -5
- package/packages/datadog-instrumentations/src/sharedb.js +2 -2
- package/packages/datadog-instrumentations/src/vitest.js +188 -12
- package/packages/datadog-instrumentations/src/winston.js +2 -3
- package/packages/datadog-plugin-amqplib/src/consumer.js +1 -3
- package/packages/datadog-plugin-aws-sdk/src/base.js +33 -0
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +2 -0
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +1 -1
- package/packages/datadog-plugin-cucumber/src/index.js +24 -1
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +39 -10
- package/packages/datadog-plugin-cypress/src/support.js +4 -1
- package/packages/datadog-plugin-hapi/src/index.js +2 -2
- package/packages/datadog-plugin-http/src/client.js +1 -42
- package/packages/datadog-plugin-http2/src/client.js +1 -26
- package/packages/datadog-plugin-jest/src/index.js +18 -1
- package/packages/datadog-plugin-kafkajs/src/batch-consumer.js +20 -0
- package/packages/datadog-plugin-kafkajs/src/consumer.js +1 -2
- package/packages/datadog-plugin-kafkajs/src/index.js +3 -1
- package/packages/datadog-plugin-mocha/src/index.js +18 -0
- package/packages/datadog-plugin-openai/src/index.js +85 -65
- package/packages/datadog-plugin-playwright/src/index.js +9 -0
- package/packages/datadog-plugin-rhea/src/consumer.js +1 -3
- package/packages/datadog-plugin-vitest/src/index.js +68 -3
- package/packages/datadog-shimmer/src/shimmer.js +144 -10
- package/packages/dd-trace/src/appsec/addresses.js +3 -1
- package/packages/dd-trace/src/appsec/blocking.js +23 -17
- package/packages/dd-trace/src/appsec/channels.js +4 -2
- package/packages/dd-trace/src/appsec/graphql.js +3 -1
- package/packages/dd-trace/src/appsec/iast/iast-log.js +2 -1
- package/packages/dd-trace/src/appsec/rasp/index.js +103 -0
- package/packages/dd-trace/src/appsec/rasp/sql_injection.js +86 -0
- package/packages/dd-trace/src/appsec/rasp/ssrf.js +37 -0
- package/packages/dd-trace/src/appsec/rasp/utils.js +63 -0
- package/packages/dd-trace/src/appsec/remote_config/capabilities.js +2 -0
- package/packages/dd-trace/src/appsec/remote_config/index.js +16 -7
- package/packages/dd-trace/src/appsec/remote_config/manager.js +93 -52
- package/packages/dd-trace/src/appsec/rule_manager.js +8 -0
- package/packages/dd-trace/src/appsec/telemetry.js +3 -3
- package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +33 -14
- package/packages/dd-trace/src/appsec/waf/waf_manager.js +2 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +4 -0
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +15 -1
- package/packages/dd-trace/src/config.js +100 -40
- package/packages/dd-trace/src/constants.js +11 -1
- package/packages/dd-trace/src/data_streams_context.js +3 -0
- package/packages/dd-trace/src/datastreams/fnv.js +23 -0
- package/packages/dd-trace/src/datastreams/pathway.js +12 -5
- package/packages/dd-trace/src/datastreams/processor.js +35 -0
- package/packages/dd-trace/src/datastreams/schemas/schema.js +8 -0
- package/packages/dd-trace/src/datastreams/schemas/schema_builder.js +125 -0
- package/packages/dd-trace/src/datastreams/schemas/schema_sampler.js +29 -0
- package/packages/dd-trace/src/debugger/devtools_client/config.js +24 -0
- package/packages/dd-trace/src/debugger/devtools_client/index.js +57 -0
- package/packages/dd-trace/src/debugger/devtools_client/inspector_promises_polyfill.js +23 -0
- package/packages/dd-trace/src/debugger/devtools_client/remote_config.js +164 -0
- package/packages/dd-trace/src/debugger/devtools_client/send.js +28 -0
- package/packages/dd-trace/src/debugger/devtools_client/session.js +7 -0
- package/packages/dd-trace/src/debugger/devtools_client/state.js +47 -0
- package/packages/dd-trace/src/debugger/devtools_client/status.js +109 -0
- package/packages/dd-trace/src/debugger/index.js +92 -0
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +29 -2
- package/packages/dd-trace/src/exporters/common/request.js +1 -1
- package/packages/dd-trace/src/lambda/handler.js +1 -0
- package/packages/dd-trace/src/lambda/index.js +12 -1
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +1 -6
- package/packages/dd-trace/src/payload-tagging/config/aws.json +30 -0
- package/packages/dd-trace/src/payload-tagging/config/index.js +30 -0
- package/packages/dd-trace/src/payload-tagging/index.js +93 -0
- package/packages/dd-trace/src/payload-tagging/tagging.js +83 -0
- package/packages/dd-trace/src/plugin_manager.js +11 -10
- package/packages/dd-trace/src/plugins/ci_plugin.js +33 -8
- package/packages/dd-trace/src/plugins/util/env.js +5 -2
- package/packages/dd-trace/src/plugins/util/test.js +24 -4
- package/packages/dd-trace/src/profiler.js +15 -5
- package/packages/dd-trace/src/profiling/config.js +7 -4
- package/packages/dd-trace/src/profiling/exporter_cli.js +13 -1
- package/packages/dd-trace/src/profiling/exporters/agent.js +8 -2
- package/packages/dd-trace/src/profiling/profiler.js +0 -9
- package/packages/dd-trace/src/profiling/profilers/event_plugins/dns.js +13 -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 +48 -0
- package/packages/dd-trace/src/profiling/profilers/event_plugins/net.js +24 -0
- package/packages/dd-trace/src/profiling/profilers/events.js +108 -32
- package/packages/dd-trace/src/profiling/profilers/shared.js +5 -0
- package/packages/dd-trace/src/profiling/profilers/wall.js +9 -3
- package/packages/dd-trace/src/profiling/ssi-heuristics.js +59 -60
- package/packages/dd-trace/src/proxy.js +31 -24
- package/packages/dd-trace/src/span_stats.js +4 -2
- package/packages/dd-trace/src/telemetry/index.js +23 -6
- package/packages/dd-trace/src/telemetry/logs/index.js +20 -0
- package/packages/dd-trace/src/appsec/rasp.js +0 -176
|
@@ -48,14 +48,14 @@ addHook({ name: 'sharedb', versions: ['>=1'], file: 'lib/agent.js' }, Agent => {
|
|
|
48
48
|
|
|
49
49
|
callback = callbackResource.bind(callback)
|
|
50
50
|
|
|
51
|
-
arguments[1] = asyncResource.bind(function (error, res) {
|
|
51
|
+
arguments[1] = shimmer.wrapFunction(callback, callback => asyncResource.bind(function (error, res) {
|
|
52
52
|
if (error) {
|
|
53
53
|
errorCh.publish(error)
|
|
54
54
|
}
|
|
55
55
|
finishCh.publish({ request, res })
|
|
56
56
|
|
|
57
57
|
return callback.apply(this, arguments)
|
|
58
|
-
})
|
|
58
|
+
}))
|
|
59
59
|
|
|
60
60
|
try {
|
|
61
61
|
return origHandleMessageFn.apply(this, arguments)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const { addHook, channel, AsyncResource } = require('./helpers/instrument')
|
|
2
2
|
const shimmer = require('../../datadog-shimmer')
|
|
3
|
-
const
|
|
3
|
+
const log = require('../../dd-trace/src/log')
|
|
4
4
|
|
|
5
5
|
// test hooks
|
|
6
6
|
const testStartCh = channel('ci:vitest:test:start')
|
|
@@ -8,6 +8,7 @@ const testFinishTimeCh = channel('ci:vitest:test:finish-time')
|
|
|
8
8
|
const testPassCh = channel('ci:vitest:test:pass')
|
|
9
9
|
const testErrorCh = channel('ci:vitest:test:error')
|
|
10
10
|
const testSkipCh = channel('ci:vitest:test:skip')
|
|
11
|
+
const isNewTestCh = channel('ci:vitest:test:is-new')
|
|
11
12
|
|
|
12
13
|
// test suite hooks
|
|
13
14
|
const testSuiteStartCh = channel('ci:vitest:test-suite:start')
|
|
@@ -18,9 +19,13 @@ const testSuiteErrorCh = channel('ci:vitest:test-suite:error')
|
|
|
18
19
|
const testSessionStartCh = channel('ci:vitest:session:start')
|
|
19
20
|
const testSessionFinishCh = channel('ci:vitest:session:finish')
|
|
20
21
|
const libraryConfigurationCh = channel('ci:vitest:library-configuration')
|
|
22
|
+
const knownTestsCh = channel('ci:vitest:known-tests')
|
|
23
|
+
const isEarlyFlakeDetectionFaultyCh = channel('ci:vitest:is-early-flake-detection-faulty')
|
|
21
24
|
|
|
22
25
|
const taskToAsync = new WeakMap()
|
|
23
|
-
|
|
26
|
+
const taskToStatuses = new WeakMap()
|
|
27
|
+
const newTasks = new WeakSet()
|
|
28
|
+
const switchedStatuses = new WeakSet()
|
|
24
29
|
const sessionAsyncResource = new AsyncResource('bound-anonymous-fn')
|
|
25
30
|
|
|
26
31
|
function isReporterPackage (vitestPackage) {
|
|
@@ -108,17 +113,60 @@ function getSortWrapper (sort) {
|
|
|
108
113
|
// So we will use the sort from BaseSequencer. This means that a custom sequencer
|
|
109
114
|
// will not work. This will be a known limitation.
|
|
110
115
|
let isFlakyTestRetriesEnabled = false
|
|
116
|
+
let flakyTestRetriesCount = 0
|
|
117
|
+
let isEarlyFlakeDetectionEnabled = false
|
|
118
|
+
let earlyFlakeDetectionNumRetries = 0
|
|
119
|
+
let isEarlyFlakeDetectionFaulty = false
|
|
120
|
+
let knownTests = {}
|
|
111
121
|
|
|
112
122
|
try {
|
|
113
123
|
const { err, libraryConfig } = await getChannelPromise(libraryConfigurationCh)
|
|
114
124
|
if (!err) {
|
|
115
125
|
isFlakyTestRetriesEnabled = libraryConfig.isFlakyTestRetriesEnabled
|
|
126
|
+
flakyTestRetriesCount = libraryConfig.flakyTestRetriesCount
|
|
127
|
+
isEarlyFlakeDetectionEnabled = libraryConfig.isEarlyFlakeDetectionEnabled
|
|
128
|
+
earlyFlakeDetectionNumRetries = libraryConfig.earlyFlakeDetectionNumRetries
|
|
116
129
|
}
|
|
117
130
|
} catch (e) {
|
|
118
131
|
isFlakyTestRetriesEnabled = false
|
|
132
|
+
isEarlyFlakeDetectionEnabled = false
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (isFlakyTestRetriesEnabled && !this.ctx.config.retry && flakyTestRetriesCount > 0) {
|
|
136
|
+
this.ctx.config.retry = flakyTestRetriesCount
|
|
119
137
|
}
|
|
120
|
-
|
|
121
|
-
|
|
138
|
+
|
|
139
|
+
if (isEarlyFlakeDetectionEnabled) {
|
|
140
|
+
const knownTestsResponse = await getChannelPromise(knownTestsCh)
|
|
141
|
+
if (!knownTestsResponse.err) {
|
|
142
|
+
knownTests = knownTestsResponse.knownTests
|
|
143
|
+
const testFilepaths = await this.ctx.getTestFilepaths()
|
|
144
|
+
|
|
145
|
+
isEarlyFlakeDetectionFaultyCh.publish({
|
|
146
|
+
knownTests: knownTests.vitest || {},
|
|
147
|
+
testFilepaths,
|
|
148
|
+
onDone: (isFaulty) => {
|
|
149
|
+
isEarlyFlakeDetectionFaulty = isFaulty
|
|
150
|
+
}
|
|
151
|
+
})
|
|
152
|
+
if (isEarlyFlakeDetectionFaulty) {
|
|
153
|
+
isEarlyFlakeDetectionEnabled = false
|
|
154
|
+
log.warn('Early flake detection is disabled because the number of new tests is too high.')
|
|
155
|
+
} else {
|
|
156
|
+
// TODO: use this to pass session and module IDs to the worker, instead of polluting process.env
|
|
157
|
+
// Note: setting this.ctx.config.provide directly does not work because it's cached
|
|
158
|
+
try {
|
|
159
|
+
const workspaceProject = this.ctx.getCoreWorkspaceProject()
|
|
160
|
+
workspaceProject._provided._ddKnownTests = knownTests.vitest
|
|
161
|
+
workspaceProject._provided._ddIsEarlyFlakeDetectionEnabled = isEarlyFlakeDetectionEnabled
|
|
162
|
+
workspaceProject._provided._ddEarlyFlakeDetectionNumRetries = earlyFlakeDetectionNumRetries
|
|
163
|
+
} catch (e) {
|
|
164
|
+
log.warn('Could not send known tests to workers so Early Flake Detection will not work.')
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
} else {
|
|
168
|
+
isEarlyFlakeDetectionEnabled = false
|
|
169
|
+
}
|
|
122
170
|
}
|
|
123
171
|
|
|
124
172
|
let testCodeCoverageLinesTotal
|
|
@@ -153,6 +201,8 @@ function getSortWrapper (sort) {
|
|
|
153
201
|
status: getSessionStatus(this.state),
|
|
154
202
|
testCodeCoverageLinesTotal,
|
|
155
203
|
error,
|
|
204
|
+
isEarlyFlakeDetectionEnabled,
|
|
205
|
+
isEarlyFlakeDetectionFaulty,
|
|
156
206
|
onFinish
|
|
157
207
|
})
|
|
158
208
|
})
|
|
@@ -187,12 +237,83 @@ addHook({
|
|
|
187
237
|
file: 'dist/runners.js'
|
|
188
238
|
}, (vitestPackage) => {
|
|
189
239
|
const { VitestTestRunner } = vitestPackage
|
|
240
|
+
|
|
241
|
+
// `onBeforeRunTask` is run before any repetition or attempt is run
|
|
242
|
+
shimmer.wrap(VitestTestRunner.prototype, 'onBeforeRunTask', onBeforeRunTask => async function (task) {
|
|
243
|
+
const testName = getTestName(task)
|
|
244
|
+
try {
|
|
245
|
+
const {
|
|
246
|
+
_ddKnownTests: knownTests,
|
|
247
|
+
_ddIsEarlyFlakeDetectionEnabled: isEarlyFlakeDetectionEnabled,
|
|
248
|
+
_ddEarlyFlakeDetectionNumRetries: numRepeats
|
|
249
|
+
} = globalThis.__vitest_worker__.providedContext
|
|
250
|
+
|
|
251
|
+
if (isEarlyFlakeDetectionEnabled) {
|
|
252
|
+
isNewTestCh.publish({
|
|
253
|
+
knownTests,
|
|
254
|
+
testSuiteAbsolutePath: task.file.filepath,
|
|
255
|
+
testName,
|
|
256
|
+
onDone: (isNew) => {
|
|
257
|
+
if (isNew) {
|
|
258
|
+
task.repeats = numRepeats
|
|
259
|
+
newTasks.add(task)
|
|
260
|
+
taskToStatuses.set(task, [])
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
})
|
|
264
|
+
}
|
|
265
|
+
} catch (e) {
|
|
266
|
+
log.error('Vitest workers could not parse known tests, so Early Flake Detection will not work.')
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
return onBeforeRunTask.apply(this, arguments)
|
|
270
|
+
})
|
|
271
|
+
|
|
272
|
+
// `onAfterRunTask` is run after all repetitions or attempts are run
|
|
273
|
+
shimmer.wrap(VitestTestRunner.prototype, 'onAfterRunTask', onAfterRunTask => async function (task) {
|
|
274
|
+
const {
|
|
275
|
+
_ddIsEarlyFlakeDetectionEnabled: isEarlyFlakeDetectionEnabled
|
|
276
|
+
} = globalThis.__vitest_worker__.providedContext
|
|
277
|
+
|
|
278
|
+
if (isEarlyFlakeDetectionEnabled && taskToStatuses.has(task)) {
|
|
279
|
+
const statuses = taskToStatuses.get(task)
|
|
280
|
+
// If the test has passed at least once, we consider it passed
|
|
281
|
+
if (statuses.includes('pass')) {
|
|
282
|
+
if (task.result.state === 'fail') {
|
|
283
|
+
switchedStatuses.add(task)
|
|
284
|
+
}
|
|
285
|
+
task.result.state = 'pass'
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
return onAfterRunTask.apply(this, arguments)
|
|
290
|
+
})
|
|
291
|
+
|
|
190
292
|
// test start (only tests that are not marked as skip or todo)
|
|
293
|
+
// `onBeforeTryTask` is run for every repetition and attempt of the test
|
|
191
294
|
shimmer.wrap(VitestTestRunner.prototype, 'onBeforeTryTask', onBeforeTryTask => async function (task, retryInfo) {
|
|
192
295
|
if (!testStartCh.hasSubscribers) {
|
|
193
296
|
return onBeforeTryTask.apply(this, arguments)
|
|
194
297
|
}
|
|
195
|
-
const
|
|
298
|
+
const testName = getTestName(task)
|
|
299
|
+
let isNew = false
|
|
300
|
+
let isEarlyFlakeDetectionEnabled = false
|
|
301
|
+
|
|
302
|
+
try {
|
|
303
|
+
const {
|
|
304
|
+
_ddIsEarlyFlakeDetectionEnabled
|
|
305
|
+
} = globalThis.__vitest_worker__.providedContext
|
|
306
|
+
|
|
307
|
+
isEarlyFlakeDetectionEnabled = _ddIsEarlyFlakeDetectionEnabled
|
|
308
|
+
|
|
309
|
+
if (isEarlyFlakeDetectionEnabled) {
|
|
310
|
+
isNew = newTasks.has(task)
|
|
311
|
+
}
|
|
312
|
+
} catch (e) {
|
|
313
|
+
log.error('Vitest workers could not parse known tests, so Early Flake Detection will not work.')
|
|
314
|
+
}
|
|
315
|
+
const { retry: numAttempt, repeats: numRepetition } = retryInfo
|
|
316
|
+
|
|
196
317
|
// We finish the previous test here because we know it has failed already
|
|
197
318
|
if (numAttempt > 0) {
|
|
198
319
|
const asyncResource = taskToAsync.get(task)
|
|
@@ -204,14 +325,58 @@ addHook({
|
|
|
204
325
|
}
|
|
205
326
|
}
|
|
206
327
|
|
|
328
|
+
const lastExecutionStatus = task.result.state
|
|
329
|
+
|
|
330
|
+
// These clauses handle task.repeats, whether EFD is enabled or not
|
|
331
|
+
// The only thing that EFD does is to forcefully pass the test if it has passed at least once
|
|
332
|
+
if (numRepetition > 0 && numRepetition < task.repeats) { // it may or may have not failed
|
|
333
|
+
// Here we finish the earlier iteration,
|
|
334
|
+
// as long as it's not the _last_ iteration (which will be finished normally)
|
|
335
|
+
|
|
336
|
+
// TODO: check test duration (not to repeat if it's too slow)
|
|
337
|
+
const asyncResource = taskToAsync.get(task)
|
|
338
|
+
if (asyncResource) {
|
|
339
|
+
if (lastExecutionStatus === 'fail') {
|
|
340
|
+
const testError = task.result?.errors?.[0]
|
|
341
|
+
asyncResource.runInAsyncScope(() => {
|
|
342
|
+
testErrorCh.publish({ error: testError })
|
|
343
|
+
})
|
|
344
|
+
} else {
|
|
345
|
+
asyncResource.runInAsyncScope(() => {
|
|
346
|
+
testPassCh.publish({ task })
|
|
347
|
+
})
|
|
348
|
+
}
|
|
349
|
+
if (isEarlyFlakeDetectionEnabled) {
|
|
350
|
+
const statuses = taskToStatuses.get(task)
|
|
351
|
+
statuses.push(lastExecutionStatus)
|
|
352
|
+
// If we don't "reset" the result.state to "pass", once a repetition fails,
|
|
353
|
+
// vitest will always consider the test as failed, so we can't read the actual status
|
|
354
|
+
task.result.state = 'pass'
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
} else if (numRepetition === task.repeats) {
|
|
358
|
+
const asyncResource = taskToAsync.get(task)
|
|
359
|
+
if (lastExecutionStatus === 'fail') {
|
|
360
|
+
const testError = task.result?.errors?.[0]
|
|
361
|
+
asyncResource.runInAsyncScope(() => {
|
|
362
|
+
testErrorCh.publish({ error: testError })
|
|
363
|
+
})
|
|
364
|
+
} else {
|
|
365
|
+
asyncResource.runInAsyncScope(() => {
|
|
366
|
+
testPassCh.publish({ task })
|
|
367
|
+
})
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
207
371
|
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
208
372
|
taskToAsync.set(task, asyncResource)
|
|
209
373
|
|
|
210
374
|
asyncResource.runInAsyncScope(() => {
|
|
211
375
|
testStartCh.publish({
|
|
212
|
-
testName
|
|
376
|
+
testName,
|
|
213
377
|
testSuiteAbsolutePath: task.file.filepath,
|
|
214
|
-
isRetry: numAttempt > 0
|
|
378
|
+
isRetry: numAttempt > 0 || numRepetition > 0,
|
|
379
|
+
isNew
|
|
215
380
|
})
|
|
216
381
|
})
|
|
217
382
|
return onBeforeTryTask.apply(this, arguments)
|
|
@@ -229,7 +394,7 @@ addHook({
|
|
|
229
394
|
const asyncResource = taskToAsync.get(task)
|
|
230
395
|
|
|
231
396
|
if (asyncResource) {
|
|
232
|
-
// We don't finish here because the test might fail in a later hook
|
|
397
|
+
// We don't finish here because the test might fail in a later hook (afterEach)
|
|
233
398
|
asyncResource.runInAsyncScope(() => {
|
|
234
399
|
testFinishTimeCh.publish({ status, task })
|
|
235
400
|
})
|
|
@@ -269,7 +434,16 @@ addHook({
|
|
|
269
434
|
|
|
270
435
|
addHook({
|
|
271
436
|
name: 'vitest',
|
|
272
|
-
versions: ['>=2.0
|
|
437
|
+
versions: ['>=2.1.0'],
|
|
438
|
+
filePattern: 'dist/chunks/RandomSequencer.*'
|
|
439
|
+
}, (randomSequencerPackage) => {
|
|
440
|
+
shimmer.wrap(randomSequencerPackage.B.prototype, 'sort', getSortWrapper)
|
|
441
|
+
return randomSequencerPackage
|
|
442
|
+
})
|
|
443
|
+
|
|
444
|
+
addHook({
|
|
445
|
+
name: 'vitest',
|
|
446
|
+
versions: ['>=2.0.5 <2.1.0'],
|
|
273
447
|
filePattern: 'dist/chunks/index.*'
|
|
274
448
|
}, (vitestPackage) => {
|
|
275
449
|
if (isReporterPackageNewest(vitestPackage)) {
|
|
@@ -322,19 +496,21 @@ addHook({
|
|
|
322
496
|
testTasks.forEach(task => {
|
|
323
497
|
const testAsyncResource = taskToAsync.get(task)
|
|
324
498
|
const { result } = task
|
|
499
|
+
// We have to trick vitest into thinking that the test has passed
|
|
500
|
+
// but we want to report it as failed if it did fail
|
|
501
|
+
const isSwitchedStatus = switchedStatuses.has(task)
|
|
325
502
|
|
|
326
503
|
if (result) {
|
|
327
504
|
const { state, duration, errors } = result
|
|
328
505
|
if (state === 'skip') { // programmatic skip
|
|
329
506
|
testSkipCh.publish({ testName: getTestName(task), testSuiteAbsolutePath: task.file.filepath })
|
|
330
|
-
} else if (state === 'pass') {
|
|
507
|
+
} else if (state === 'pass' && !isSwitchedStatus) {
|
|
331
508
|
if (testAsyncResource) {
|
|
332
509
|
testAsyncResource.runInAsyncScope(() => {
|
|
333
510
|
testPassCh.publish({ task })
|
|
334
511
|
})
|
|
335
512
|
}
|
|
336
|
-
} else if (state === 'fail') {
|
|
337
|
-
// If it's failing, we have no accurate finish time, so we have to use `duration`
|
|
513
|
+
} else if (state === 'fail' || isSwitchedStatus) {
|
|
338
514
|
let testError
|
|
339
515
|
|
|
340
516
|
if (errors?.length) {
|
|
@@ -42,13 +42,12 @@ function wrapMethod (method, logCh) {
|
|
|
42
42
|
|
|
43
43
|
if (patched.has(transport) || typeof transport.log !== 'function') continue
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
transport.log = function wrappedLog (level, msg, meta, callback) {
|
|
45
|
+
shimmer.wrap(transport, 'log', log => function wrappedLog (level, msg, meta, callback) {
|
|
47
46
|
const payload = { message: meta || {} }
|
|
48
47
|
logCh.publish(payload)
|
|
49
48
|
arguments[2] = payload.message
|
|
50
49
|
log.apply(this, arguments)
|
|
51
|
-
}
|
|
50
|
+
})
|
|
52
51
|
patched.add(transport)
|
|
53
52
|
}
|
|
54
53
|
}
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
const { TEXT_MAP } = require('../../../ext/formats')
|
|
4
4
|
const ConsumerPlugin = require('../../dd-trace/src/plugins/consumer')
|
|
5
5
|
const { getAmqpMessageSize } = require('../../dd-trace/src/datastreams/processor')
|
|
6
|
-
const { DsmPathwayCodec } = require('../../dd-trace/src/datastreams/pathway')
|
|
7
6
|
const { getResourceName } = require('./util')
|
|
8
7
|
|
|
9
8
|
class AmqplibConsumerPlugin extends ConsumerPlugin {
|
|
@@ -30,8 +29,7 @@ class AmqplibConsumerPlugin extends ConsumerPlugin {
|
|
|
30
29
|
})
|
|
31
30
|
|
|
32
31
|
if (
|
|
33
|
-
this.config.dsmEnabled && message?.properties?.headers
|
|
34
|
-
DsmPathwayCodec.contextExists(message.properties.headers)
|
|
32
|
+
this.config.dsmEnabled && message?.properties?.headers
|
|
35
33
|
) {
|
|
36
34
|
const payloadSize = getAmqpMessageSize({ headers: message.properties.headers, content: message.content })
|
|
37
35
|
const queue = fields.queue ? fields.queue : fields.routingKey
|
|
@@ -5,9 +5,11 @@ 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
7
|
const coalesce = require('koalas')
|
|
8
|
+
const { tagsFromRequest, tagsFromResponse } = require('../../dd-trace/src/payload-tagging')
|
|
8
9
|
|
|
9
10
|
class BaseAwsSdkPlugin extends ClientPlugin {
|
|
10
11
|
static get id () { return 'aws' }
|
|
12
|
+
static get isPayloadReporter () { return false }
|
|
11
13
|
|
|
12
14
|
get serviceIdentifier () {
|
|
13
15
|
const id = this.constructor.id.toLowerCase()
|
|
@@ -20,6 +22,14 @@ class BaseAwsSdkPlugin extends ClientPlugin {
|
|
|
20
22
|
return id
|
|
21
23
|
}
|
|
22
24
|
|
|
25
|
+
get cloudTaggingConfig () {
|
|
26
|
+
return this._tracerConfig.cloudPayloadTagging
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
get payloadTaggingRules () {
|
|
30
|
+
return this.cloudTaggingConfig.rules.aws?.[this.constructor.id]
|
|
31
|
+
}
|
|
32
|
+
|
|
23
33
|
constructor (...args) {
|
|
24
34
|
super(...args)
|
|
25
35
|
|
|
@@ -51,6 +61,12 @@ class BaseAwsSdkPlugin extends ClientPlugin {
|
|
|
51
61
|
|
|
52
62
|
this.requestInject(span, request)
|
|
53
63
|
|
|
64
|
+
if (this.constructor.isPayloadReporter && this.cloudTaggingConfig.requestsEnabled) {
|
|
65
|
+
const maxDepth = this.cloudTaggingConfig.maxDepth
|
|
66
|
+
const requestTags = tagsFromRequest(this.payloadTaggingRules, request.params, { maxDepth })
|
|
67
|
+
span.addTags(requestTags)
|
|
68
|
+
}
|
|
69
|
+
|
|
54
70
|
const store = storage.getStore()
|
|
55
71
|
|
|
56
72
|
this.enter(span, store)
|
|
@@ -116,6 +132,7 @@ class BaseAwsSdkPlugin extends ClientPlugin {
|
|
|
116
132
|
const params = response.request.params
|
|
117
133
|
const operation = response.request.operation
|
|
118
134
|
const extraTags = this.generateTags(params, operation, response) || {}
|
|
135
|
+
|
|
119
136
|
const tags = Object.assign({
|
|
120
137
|
'aws.response.request_id': response.requestId,
|
|
121
138
|
'resource.name': operation,
|
|
@@ -123,6 +140,22 @@ class BaseAwsSdkPlugin extends ClientPlugin {
|
|
|
123
140
|
}, extraTags)
|
|
124
141
|
|
|
125
142
|
span.addTags(tags)
|
|
143
|
+
|
|
144
|
+
if (this.constructor.isPayloadReporter && this.cloudTaggingConfig.responsesEnabled) {
|
|
145
|
+
const maxDepth = this.cloudTaggingConfig.maxDepth
|
|
146
|
+
const responseBody = this.extractResponseBody(response)
|
|
147
|
+
const responseTags = tagsFromResponse(this.payloadTaggingRules, responseBody, { maxDepth })
|
|
148
|
+
span.addTags(responseTags)
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
extractResponseBody (response) {
|
|
153
|
+
if (response.hasOwnProperty('data')) {
|
|
154
|
+
return response.data
|
|
155
|
+
}
|
|
156
|
+
return Object.fromEntries(
|
|
157
|
+
Object.entries(response).filter(([key]) => !['request', 'requestId', 'error', '$metadata'].includes(key))
|
|
158
|
+
)
|
|
126
159
|
}
|
|
127
160
|
|
|
128
161
|
generateTags () {
|
|
@@ -113,7 +113,7 @@ class Kinesis extends BaseAwsSdkPlugin {
|
|
|
113
113
|
const parsedAttributes = JSON.parse(Buffer.from(record.Data).toString())
|
|
114
114
|
|
|
115
115
|
if (
|
|
116
|
-
parsedAttributes?._datadog && streamName
|
|
116
|
+
parsedAttributes?._datadog && streamName
|
|
117
117
|
) {
|
|
118
118
|
const payloadSize = getSizeOrZero(record.Data)
|
|
119
119
|
this.tracer.decodeDataStreamsContext(parsedAttributes._datadog)
|
|
@@ -7,6 +7,7 @@ const BaseAwsSdkPlugin = require('../base')
|
|
|
7
7
|
class Sns extends BaseAwsSdkPlugin {
|
|
8
8
|
static get id () { return 'sns' }
|
|
9
9
|
static get peerServicePrecursors () { return ['topicname'] }
|
|
10
|
+
static get isPayloadReporter () { return true }
|
|
10
11
|
|
|
11
12
|
generateTags (params, operation, response) {
|
|
12
13
|
if (!params) return {}
|
|
@@ -20,6 +21,7 @@ class Sns extends BaseAwsSdkPlugin {
|
|
|
20
21
|
|
|
21
22
|
// Get the topic name from the last part of the ARN
|
|
22
23
|
const topicName = arnParts[arnParts.length - 1]
|
|
24
|
+
|
|
23
25
|
return {
|
|
24
26
|
'resource.name': `${operation} ${params.TopicArn || response.data.TopicArn}`,
|
|
25
27
|
'aws.sns.topic_arn': TopicArn,
|
|
@@ -194,7 +194,7 @@ class Sqs extends BaseAwsSdkPlugin {
|
|
|
194
194
|
parsedAttributes = this.parseDatadogAttributes(message.MessageAttributes._datadog)
|
|
195
195
|
}
|
|
196
196
|
}
|
|
197
|
-
if (parsedAttributes
|
|
197
|
+
if (parsedAttributes) {
|
|
198
198
|
const payloadSize = getHeadersSize({
|
|
199
199
|
Body: message.Body,
|
|
200
200
|
MessageAttributes: message.MessageAttributes
|
|
@@ -17,6 +17,7 @@ const {
|
|
|
17
17
|
ITR_CORRELATION_ID,
|
|
18
18
|
TEST_SOURCE_FILE,
|
|
19
19
|
TEST_EARLY_FLAKE_ENABLED,
|
|
20
|
+
TEST_EARLY_FLAKE_ABORT_REASON,
|
|
20
21
|
TEST_IS_NEW,
|
|
21
22
|
TEST_IS_RETRY,
|
|
22
23
|
TEST_SUITE_ID,
|
|
@@ -79,6 +80,7 @@ class CucumberPlugin extends CiPlugin {
|
|
|
79
80
|
hasUnskippableSuites,
|
|
80
81
|
hasForcedToRunSuites,
|
|
81
82
|
isEarlyFlakeDetectionEnabled,
|
|
83
|
+
isEarlyFlakeDetectionFaulty,
|
|
82
84
|
isParallel
|
|
83
85
|
}) => {
|
|
84
86
|
const { isSuitesSkippingEnabled, isCodeCoverageEnabled } = this.libraryConfig || {}
|
|
@@ -99,6 +101,9 @@ class CucumberPlugin extends CiPlugin {
|
|
|
99
101
|
if (isEarlyFlakeDetectionEnabled) {
|
|
100
102
|
this.testSessionSpan.setTag(TEST_EARLY_FLAKE_ENABLED, 'true')
|
|
101
103
|
}
|
|
104
|
+
if (isEarlyFlakeDetectionFaulty) {
|
|
105
|
+
this.testSessionSpan.setTag(TEST_EARLY_FLAKE_ABORT_REASON, 'faulty')
|
|
106
|
+
}
|
|
102
107
|
if (isParallel) {
|
|
103
108
|
this.testSessionSpan.setTag(CUCUMBER_IS_PARALLEL, 'true')
|
|
104
109
|
}
|
|
@@ -116,7 +121,15 @@ class CucumberPlugin extends CiPlugin {
|
|
|
116
121
|
this.tracer._exporter.flush()
|
|
117
122
|
})
|
|
118
123
|
|
|
119
|
-
this.addSub('ci:cucumber:test-suite:start', ({
|
|
124
|
+
this.addSub('ci:cucumber:test-suite:start', ({
|
|
125
|
+
testFileAbsolutePath,
|
|
126
|
+
isUnskippable,
|
|
127
|
+
isForcedToRun,
|
|
128
|
+
itrCorrelationId
|
|
129
|
+
}) => {
|
|
130
|
+
const testSuitePath = getTestSuitePath(testFileAbsolutePath, process.cwd())
|
|
131
|
+
const testSourceFile = getTestSuitePath(testFileAbsolutePath, this.repositoryRoot)
|
|
132
|
+
|
|
120
133
|
const testSuiteMetadata = getTestSuiteCommonTags(
|
|
121
134
|
this.command,
|
|
122
135
|
this.frameworkVersion,
|
|
@@ -134,6 +147,16 @@ class CucumberPlugin extends CiPlugin {
|
|
|
134
147
|
if (itrCorrelationId) {
|
|
135
148
|
testSuiteMetadata[ITR_CORRELATION_ID] = itrCorrelationId
|
|
136
149
|
}
|
|
150
|
+
if (testSourceFile) {
|
|
151
|
+
testSuiteMetadata[TEST_SOURCE_FILE] = testSourceFile
|
|
152
|
+
testSuiteMetadata[TEST_SOURCE_START] = 1
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const codeOwners = this.getCodeOwners(testSuiteMetadata)
|
|
156
|
+
if (codeOwners) {
|
|
157
|
+
testSuiteMetadata[TEST_CODE_OWNERS] = codeOwners
|
|
158
|
+
}
|
|
159
|
+
|
|
137
160
|
const testSuiteSpan = this.tracer.startSpan('cucumber.test_suite', {
|
|
138
161
|
childOf: this.testModuleSpan,
|
|
139
162
|
tags: {
|
|
@@ -29,7 +29,9 @@ const {
|
|
|
29
29
|
TEST_IS_NEW,
|
|
30
30
|
TEST_IS_RETRY,
|
|
31
31
|
TEST_EARLY_FLAKE_ENABLED,
|
|
32
|
-
|
|
32
|
+
getTestSessionName,
|
|
33
|
+
TEST_SESSION_NAME,
|
|
34
|
+
TEST_LEVEL_EVENT_TYPES
|
|
33
35
|
} = require('../../dd-trace/src/plugins/util/test')
|
|
34
36
|
const { isMarkedAsUnskippable } = require('../../datadog-plugin-jest/src/util')
|
|
35
37
|
const { ORIGIN_KEY, COMPONENT } = require('../../dd-trace/src/constants')
|
|
@@ -229,16 +231,16 @@ class CypressPlugin {
|
|
|
229
231
|
isCodeCoverageEnabled,
|
|
230
232
|
isEarlyFlakeDetectionEnabled,
|
|
231
233
|
earlyFlakeDetectionNumRetries,
|
|
232
|
-
isFlakyTestRetriesEnabled
|
|
234
|
+
isFlakyTestRetriesEnabled,
|
|
235
|
+
flakyTestRetriesCount
|
|
233
236
|
}
|
|
234
237
|
} = libraryConfigurationResponse
|
|
235
238
|
this.isSuitesSkippingEnabled = isSuitesSkippingEnabled
|
|
236
239
|
this.isCodeCoverageEnabled = isCodeCoverageEnabled
|
|
237
240
|
this.isEarlyFlakeDetectionEnabled = isEarlyFlakeDetectionEnabled
|
|
238
241
|
this.earlyFlakeDetectionNumRetries = earlyFlakeDetectionNumRetries
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
this.cypressConfig.retries.runMode = NUM_FAILED_TEST_RETRIES
|
|
242
|
+
if (isFlakyTestRetriesEnabled) {
|
|
243
|
+
this.cypressConfig.retries.runMode = flakyTestRetriesCount
|
|
242
244
|
}
|
|
243
245
|
}
|
|
244
246
|
return this.cypressConfig
|
|
@@ -246,10 +248,22 @@ class CypressPlugin {
|
|
|
246
248
|
return this.libraryConfigurationPromise
|
|
247
249
|
}
|
|
248
250
|
|
|
249
|
-
getTestSuiteSpan (
|
|
251
|
+
getTestSuiteSpan ({ testSuite, testSuiteAbsolutePath }) {
|
|
250
252
|
const testSuiteSpanMetadata =
|
|
251
|
-
getTestSuiteCommonTags(this.command, this.frameworkVersion,
|
|
253
|
+
getTestSuiteCommonTags(this.command, this.frameworkVersion, testSuite, TEST_FRAMEWORK_NAME)
|
|
254
|
+
|
|
252
255
|
this.ciVisEvent(TELEMETRY_EVENT_CREATED, 'suite')
|
|
256
|
+
|
|
257
|
+
if (testSuiteAbsolutePath) {
|
|
258
|
+
const testSourceFile = getTestSuitePath(testSuiteAbsolutePath, this.repositoryRoot)
|
|
259
|
+
testSuiteSpanMetadata[TEST_SOURCE_FILE] = testSourceFile
|
|
260
|
+
testSuiteSpanMetadata[TEST_SOURCE_START] = 1
|
|
261
|
+
const codeOwners = this.getTestCodeOwners({ testSuite, testSourceFile })
|
|
262
|
+
if (codeOwners) {
|
|
263
|
+
testSuiteSpanMetadata[TEST_CODE_OWNERS] = codeOwners
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
253
267
|
return this.tracer.startSpan(`${TEST_FRAMEWORK_NAME}.test_suite`, {
|
|
254
268
|
childOf: this.testModuleSpan,
|
|
255
269
|
tags: {
|
|
@@ -388,6 +402,18 @@ class CypressPlugin {
|
|
|
388
402
|
testSessionSpanMetadata[TEST_EARLY_FLAKE_ENABLED] = 'true'
|
|
389
403
|
}
|
|
390
404
|
|
|
405
|
+
const testSessionName = getTestSessionName(this.tracer._tracer._config, this.command, this.testEnvironmentMetadata)
|
|
406
|
+
|
|
407
|
+
if (this.tracer._tracer._exporter?.setMetadataTags) {
|
|
408
|
+
const metadataTags = {}
|
|
409
|
+
for (const testLevel of TEST_LEVEL_EVENT_TYPES) {
|
|
410
|
+
metadataTags[testLevel] = {
|
|
411
|
+
[TEST_SESSION_NAME]: testSessionName
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
this.tracer._tracer._exporter.setMetadataTags(metadataTags)
|
|
415
|
+
}
|
|
416
|
+
|
|
391
417
|
this.testSessionSpan = this.tracer.startSpan(`${TEST_FRAMEWORK_NAME}.test_session`, {
|
|
392
418
|
childOf,
|
|
393
419
|
tags: {
|
|
@@ -474,7 +500,10 @@ class CypressPlugin {
|
|
|
474
500
|
// dd:testSuiteStart hasn't been triggered for whatever reason
|
|
475
501
|
// We will create the test suite span on the spot if that's the case
|
|
476
502
|
log.warn('There was an error creating the test suite event.')
|
|
477
|
-
this.testSuiteSpan = this.getTestSuiteSpan(
|
|
503
|
+
this.testSuiteSpan = this.getTestSuiteSpan({
|
|
504
|
+
testSuite: spec.relative,
|
|
505
|
+
testSuiteAbsolutePath: spec.absolute
|
|
506
|
+
})
|
|
478
507
|
}
|
|
479
508
|
|
|
480
509
|
// Get tests that didn't go through `dd:afterEach`
|
|
@@ -585,7 +614,7 @@ class CypressPlugin {
|
|
|
585
614
|
|
|
586
615
|
getTasks () {
|
|
587
616
|
return {
|
|
588
|
-
'dd:testSuiteStart': (testSuite) => {
|
|
617
|
+
'dd:testSuiteStart': ({ testSuite, testSuiteAbsolutePath }) => {
|
|
589
618
|
const suitePayload = {
|
|
590
619
|
isEarlyFlakeDetectionEnabled: this.isEarlyFlakeDetectionEnabled,
|
|
591
620
|
knownTestsForSuite: this.knownTestsByTestSuite?.[testSuite] || [],
|
|
@@ -595,7 +624,7 @@ class CypressPlugin {
|
|
|
595
624
|
if (this.testSuiteSpan) {
|
|
596
625
|
return suitePayload
|
|
597
626
|
}
|
|
598
|
-
this.testSuiteSpan = this.getTestSuiteSpan(testSuite)
|
|
627
|
+
this.testSuiteSpan = this.getTestSuiteSpan({ testSuite, testSuiteAbsolutePath })
|
|
599
628
|
return suitePayload
|
|
600
629
|
},
|
|
601
630
|
'dd:beforeEach': (test) => {
|
|
@@ -61,7 +61,10 @@ beforeEach(function () {
|
|
|
61
61
|
})
|
|
62
62
|
|
|
63
63
|
before(function () {
|
|
64
|
-
cy.task('dd:testSuiteStart',
|
|
64
|
+
cy.task('dd:testSuiteStart', {
|
|
65
|
+
testSuite: Cypress.mocha.getRootSuite().file,
|
|
66
|
+
testSuiteAbsolutePath: Cypress.spec && Cypress.spec.absolute
|
|
67
|
+
}).then((suiteConfig) => {
|
|
65
68
|
if (suiteConfig) {
|
|
66
69
|
isEarlyFlakeDetectionEnabled = suiteConfig.isEarlyFlakeDetectionEnabled
|
|
67
70
|
knownTestsForSuite = suiteConfig.knownTestsForSuite
|
|
@@ -32,8 +32,8 @@ class HapiPlugin extends RouterPlugin {
|
|
|
32
32
|
}
|
|
33
33
|
})
|
|
34
34
|
|
|
35
|
-
this.
|
|
36
|
-
this.
|
|
35
|
+
this.addBind('apm:hapi:extension:start', ({ req }) => {
|
|
36
|
+
return this._requestSpans.get(req)
|
|
37
37
|
})
|
|
38
38
|
}
|
|
39
39
|
}
|