dd-trace 5.3.0 → 5.5.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.
Files changed (44) hide show
  1. package/CONTRIBUTING.md +98 -0
  2. package/README.md +4 -102
  3. package/ci/cypress/after-run.js +1 -0
  4. package/package.json +2 -2
  5. package/packages/datadog-instrumentations/src/cucumber.js +156 -42
  6. package/packages/datadog-instrumentations/src/jest.js +84 -49
  7. package/packages/datadog-instrumentations/src/mocha.js +139 -13
  8. package/packages/datadog-plugin-amqplib/src/consumer.js +5 -2
  9. package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +60 -50
  10. package/packages/datadog-plugin-aws-sdk/src/services/sns.js +40 -17
  11. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +62 -26
  12. package/packages/datadog-plugin-cucumber/src/index.js +25 -9
  13. package/packages/datadog-plugin-cypress/src/after-run.js +3 -0
  14. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +560 -0
  15. package/packages/datadog-plugin-cypress/src/plugin.js +6 -533
  16. package/packages/datadog-plugin-jest/src/index.js +4 -8
  17. package/packages/datadog-plugin-kafkajs/src/consumer.js +16 -0
  18. package/packages/datadog-plugin-mocha/src/index.js +38 -17
  19. package/packages/datadog-plugin-rhea/src/consumer.js +4 -1
  20. package/packages/dd-trace/src/appsec/iast/context/context-plugin.js +90 -0
  21. package/packages/dd-trace/src/appsec/iast/context/kafka-ctx-plugin.js +14 -0
  22. package/packages/dd-trace/src/appsec/iast/iast-plugin.js +8 -0
  23. package/packages/dd-trace/src/appsec/iast/index.js +4 -4
  24. package/packages/dd-trace/src/appsec/iast/overhead-controller.js +1 -1
  25. package/packages/dd-trace/src/appsec/iast/taint-tracking/csi-methods.js +1 -0
  26. package/packages/dd-trace/src/appsec/iast/taint-tracking/index.js +10 -0
  27. package/packages/dd-trace/src/appsec/iast/taint-tracking/operations-taint-object.js +53 -0
  28. package/packages/dd-trace/src/appsec/iast/taint-tracking/operations.js +10 -46
  29. package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +13 -9
  30. package/packages/dd-trace/src/appsec/iast/taint-tracking/plugins/kafka.js +47 -0
  31. package/packages/dd-trace/src/appsec/iast/taint-tracking/source-types.js +3 -1
  32. package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +29 -2
  33. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +1 -1
  34. package/packages/dd-trace/src/appsec/remote_config/capabilities.js +2 -1
  35. package/packages/dd-trace/src/appsec/remote_config/index.js +1 -0
  36. package/packages/dd-trace/src/config.js +3 -2
  37. package/packages/dd-trace/src/opentracing/propagation/text_map.js +1 -1
  38. package/packages/dd-trace/src/opentracing/span.js +4 -4
  39. package/packages/dd-trace/src/plugins/ci_plugin.js +1 -1
  40. package/packages/dd-trace/src/plugins/util/test.js +17 -1
  41. package/packages/dd-trace/src/profiling/exporters/agent.js +40 -31
  42. package/packages/dd-trace/src/telemetry/index.js +3 -0
  43. package/packages/dd-trace/src/telemetry/logs/index.js +2 -2
  44. package/packages/dd-trace/src/telemetry/send-data.js +0 -3
@@ -1,155 +1,5 @@
1
- const {
2
- TEST_STATUS,
3
- TEST_IS_RUM_ACTIVE,
4
- TEST_CODE_OWNERS,
5
- getTestEnvironmentMetadata,
6
- CI_APP_ORIGIN,
7
- getTestParentSpan,
8
- getCodeOwnersFileEntries,
9
- getCodeOwnersForFilename,
10
- getTestCommonTags,
11
- getTestSessionCommonTags,
12
- getTestModuleCommonTags,
13
- getTestSuiteCommonTags,
14
- TEST_SUITE_ID,
15
- TEST_MODULE_ID,
16
- TEST_SESSION_ID,
17
- TEST_COMMAND,
18
- TEST_MODULE,
19
- TEST_SOURCE_START,
20
- finishAllTraceSpans,
21
- getCoveredFilenamesFromCoverage,
22
- getTestSuitePath,
23
- addIntelligentTestRunnerSpanTags,
24
- TEST_SKIPPED_BY_ITR,
25
- TEST_ITR_UNSKIPPABLE,
26
- TEST_ITR_FORCED_RUN,
27
- ITR_CORRELATION_ID,
28
- TEST_SOURCE_FILE
29
- } = require('../../dd-trace/src/plugins/util/test')
30
- const { ORIGIN_KEY, COMPONENT } = require('../../dd-trace/src/constants')
31
- const log = require('../../dd-trace/src/log')
32
1
  const NoopTracer = require('../../dd-trace/src/noop/tracer')
33
- const { isMarkedAsUnskippable } = require('../../datadog-plugin-jest/src/util')
34
- const {
35
- TELEMETRY_EVENT_CREATED,
36
- TELEMETRY_EVENT_FINISHED,
37
- TELEMETRY_ITR_FORCED_TO_RUN,
38
- TELEMETRY_CODE_COVERAGE_EMPTY,
39
- TELEMETRY_ITR_UNSKIPPABLE,
40
- TELEMETRY_CODE_COVERAGE_NUM_FILES,
41
- incrementCountMetric,
42
- distributionMetric
43
- } = require('../../dd-trace/src/ci-visibility/telemetry')
44
- const { appClosing: appClosingTelemetry } = require('../../dd-trace/src/telemetry')
45
- const {
46
- GIT_REPOSITORY_URL,
47
- GIT_COMMIT_SHA,
48
- GIT_BRANCH,
49
- CI_PROVIDER_NAME,
50
- CI_WORKSPACE_PATH
51
- } = require('../../dd-trace/src/plugins/util/tags')
52
- const {
53
- OS_VERSION,
54
- OS_PLATFORM,
55
- OS_ARCHITECTURE,
56
- RUNTIME_NAME,
57
- RUNTIME_VERSION
58
- } = require('../../dd-trace/src/plugins/util/env')
59
-
60
- const TEST_FRAMEWORK_NAME = 'cypress'
61
-
62
- const CYPRESS_STATUS_TO_TEST_STATUS = {
63
- passed: 'pass',
64
- failed: 'fail',
65
- pending: 'skip',
66
- skipped: 'skip'
67
- }
68
-
69
- function getTestSpanMetadata (tracer, testName, testSuite, cypressConfig) {
70
- const childOf = getTestParentSpan(tracer)
71
-
72
- const commonTags = getTestCommonTags(testName, testSuite, cypressConfig.version, TEST_FRAMEWORK_NAME)
73
-
74
- return {
75
- childOf,
76
- ...commonTags
77
- }
78
- }
79
-
80
- function getCypressVersion (details) {
81
- if (details && details.cypressVersion) {
82
- return details.cypressVersion
83
- }
84
- if (details && details.config && details.config.version) {
85
- return details.config.version
86
- }
87
- return ''
88
- }
89
-
90
- function getRootDir (details) {
91
- if (details && details.config) {
92
- return details.config.projectRoot || details.config.repoRoot || process.cwd()
93
- }
94
- return process.cwd()
95
- }
96
-
97
- function getCypressCommand (details) {
98
- if (!details) {
99
- return TEST_FRAMEWORK_NAME
100
- }
101
- return `${TEST_FRAMEWORK_NAME} ${details.specPattern || ''}`
102
- }
103
-
104
- function getSessionStatus (summary) {
105
- if (summary.totalFailed !== undefined && summary.totalFailed > 0) {
106
- return 'fail'
107
- }
108
- if (summary.totalSkipped !== undefined && summary.totalSkipped === summary.totalTests) {
109
- return 'skip'
110
- }
111
- return 'pass'
112
- }
113
-
114
- function getSuiteStatus (suiteStats) {
115
- if (suiteStats.failures !== undefined && suiteStats.failures > 0) {
116
- return 'fail'
117
- }
118
- if (suiteStats.tests !== undefined && suiteStats.tests === suiteStats.pending) {
119
- return 'skip'
120
- }
121
- return 'pass'
122
- }
123
-
124
- function getLibraryConfiguration (tracer, testConfiguration) {
125
- return new Promise(resolve => {
126
- if (!tracer._tracer._exporter?.getLibraryConfiguration) {
127
- return resolve({ err: new Error('CI Visibility was not initialized correctly') })
128
- }
129
-
130
- tracer._tracer._exporter.getLibraryConfiguration(testConfiguration, (err, libraryConfig) => {
131
- resolve({ err, libraryConfig })
132
- })
133
- })
134
- }
135
-
136
- function getSkippableTests (isSuitesSkippingEnabled, tracer, testConfiguration) {
137
- if (!isSuitesSkippingEnabled) {
138
- return Promise.resolve({ skippableTests: [] })
139
- }
140
- return new Promise(resolve => {
141
- if (!tracer._tracer._exporter?.getLibraryConfiguration) {
142
- return resolve({ err: new Error('CI Visibility was not initialized correctly') })
143
- }
144
- tracer._tracer._exporter.getSkippableSuites(testConfiguration, (err, skippableTests, correlationId) => {
145
- resolve({
146
- err,
147
- skippableTests,
148
- correlationId
149
- })
150
- })
151
- })
152
- }
2
+ const cypressPlugin = require('./cypress-plugin')
153
3
 
154
4
  const noopTask = {
155
5
  'dd:testSuiteStart': () => {
@@ -167,8 +17,6 @@ const noopTask = {
167
17
  }
168
18
 
169
19
  module.exports = (on, config) => {
170
- let isTestsSkipped = false
171
- const skippedTests = []
172
20
  const tracer = require('../../dd-trace')
173
21
 
174
22
  // The tracer was not init correctly for whatever reason (such as invalid DD_SITE)
@@ -177,385 +25,10 @@ module.exports = (on, config) => {
177
25
  return on('task', noopTask)
178
26
  }
179
27
 
180
- const testEnvironmentMetadata = getTestEnvironmentMetadata(TEST_FRAMEWORK_NAME)
181
-
182
- const {
183
- [GIT_REPOSITORY_URL]: repositoryUrl,
184
- [GIT_COMMIT_SHA]: sha,
185
- [OS_VERSION]: osVersion,
186
- [OS_PLATFORM]: osPlatform,
187
- [OS_ARCHITECTURE]: osArchitecture,
188
- [RUNTIME_NAME]: runtimeName,
189
- [RUNTIME_VERSION]: runtimeVersion,
190
- [GIT_BRANCH]: branch,
191
- [CI_PROVIDER_NAME]: ciProviderName,
192
- [CI_WORKSPACE_PATH]: repositoryRoot
193
- } = testEnvironmentMetadata
194
-
195
- const isUnsupportedCIProvider = !ciProviderName
196
-
197
- const finishedTestsByFile = {}
198
-
199
- const testConfiguration = {
200
- repositoryUrl,
201
- sha,
202
- osVersion,
203
- osPlatform,
204
- osArchitecture,
205
- runtimeName,
206
- runtimeVersion,
207
- branch,
208
- testLevel: 'test'
209
- }
210
-
211
- const codeOwnersEntries = getCodeOwnersFileEntries(repositoryRoot)
212
-
213
- let activeSpan = null
214
- let testSessionSpan = null
215
- let testModuleSpan = null
216
- let testSuiteSpan = null
217
- let command = null
218
- let frameworkVersion
219
- let rootDir
220
- let isSuitesSkippingEnabled = false
221
- let isCodeCoverageEnabled = false
222
- let testsToSkip = []
223
- let itrCorrelationId = ''
224
- const unskippableSuites = []
225
- let hasForcedToRunSuites = false
226
- let hasUnskippableSuites = false
227
-
228
- function ciVisEvent (name, testLevel, tags = {}) {
229
- incrementCountMetric(name, {
230
- testLevel,
231
- testFramework: 'cypress',
232
- isUnsupportedCIProvider,
233
- ...tags
234
- })
235
- }
236
-
237
- function getTestSpan (testName, testSuite, isUnskippable, isForcedToRun) {
238
- const testSuiteTags = {
239
- [TEST_COMMAND]: command,
240
- [TEST_COMMAND]: command,
241
- [TEST_MODULE]: TEST_FRAMEWORK_NAME
242
- }
243
- if (testSuiteSpan) {
244
- testSuiteTags[TEST_SUITE_ID] = testSuiteSpan.context().toSpanId()
245
- }
246
- if (testSessionSpan && testModuleSpan) {
247
- testSuiteTags[TEST_SESSION_ID] = testSessionSpan.context().toTraceId()
248
- testSuiteTags[TEST_MODULE_ID] = testModuleSpan.context().toSpanId()
249
- }
250
-
251
- const {
252
- childOf,
253
- resource,
254
- ...testSpanMetadata
255
- } = getTestSpanMetadata(tracer, testName, testSuite, config)
256
-
257
- const codeOwners = getCodeOwnersForFilename(testSuite, codeOwnersEntries)
258
-
259
- if (codeOwners) {
260
- testSpanMetadata[TEST_CODE_OWNERS] = codeOwners
261
- }
262
-
263
- if (isUnskippable) {
264
- hasUnskippableSuites = true
265
- incrementCountMetric(TELEMETRY_ITR_UNSKIPPABLE, { testLevel: 'suite' })
266
- testSpanMetadata[TEST_ITR_UNSKIPPABLE] = 'true'
267
- }
268
-
269
- if (isForcedToRun) {
270
- hasForcedToRunSuites = true
271
- incrementCountMetric(TELEMETRY_ITR_FORCED_TO_RUN, { testLevel: 'suite' })
272
- testSpanMetadata[TEST_ITR_FORCED_RUN] = 'true'
273
- }
274
-
275
- ciVisEvent(TELEMETRY_EVENT_CREATED, 'test', { hasCodeOwners: !!codeOwners })
276
-
277
- return tracer.startSpan(`${TEST_FRAMEWORK_NAME}.test`, {
278
- childOf,
279
- tags: {
280
- [COMPONENT]: TEST_FRAMEWORK_NAME,
281
- [ORIGIN_KEY]: CI_APP_ORIGIN,
282
- ...testSpanMetadata,
283
- ...testEnvironmentMetadata,
284
- ...testSuiteTags
285
- }
286
- })
287
- }
288
-
289
- on('before:run', (details) => {
290
- return getLibraryConfiguration(tracer, testConfiguration).then(({ err, libraryConfig }) => {
291
- if (err) {
292
- log.error(err)
293
- } else {
294
- isSuitesSkippingEnabled = libraryConfig.isSuitesSkippingEnabled
295
- isCodeCoverageEnabled = libraryConfig.isCodeCoverageEnabled
296
- }
297
-
298
- return getSkippableTests(isSuitesSkippingEnabled, tracer, testConfiguration)
299
- .then(({ err, skippableTests, correlationId }) => {
300
- if (err) {
301
- log.error(err)
302
- } else {
303
- testsToSkip = skippableTests || []
304
- itrCorrelationId = correlationId
305
- }
306
-
307
- // `details.specs` are test files
308
- details.specs.forEach(({ absolute, relative }) => {
309
- const isUnskippableSuite = isMarkedAsUnskippable({ path: absolute })
310
- if (isUnskippableSuite) {
311
- unskippableSuites.push(relative)
312
- }
313
- })
314
-
315
- const childOf = getTestParentSpan(tracer)
316
- rootDir = getRootDir(details)
317
-
318
- command = getCypressCommand(details)
319
- frameworkVersion = getCypressVersion(details)
320
-
321
- const testSessionSpanMetadata = getTestSessionCommonTags(command, frameworkVersion, TEST_FRAMEWORK_NAME)
322
- const testModuleSpanMetadata = getTestModuleCommonTags(command, frameworkVersion, TEST_FRAMEWORK_NAME)
323
-
324
- testSessionSpan = tracer.startSpan(`${TEST_FRAMEWORK_NAME}.test_session`, {
325
- childOf,
326
- tags: {
327
- [COMPONENT]: TEST_FRAMEWORK_NAME,
328
- ...testEnvironmentMetadata,
329
- ...testSessionSpanMetadata
330
- }
331
- })
332
- ciVisEvent(TELEMETRY_EVENT_CREATED, 'session')
333
-
334
- testModuleSpan = tracer.startSpan(`${TEST_FRAMEWORK_NAME}.test_module`, {
335
- childOf: testSessionSpan,
336
- tags: {
337
- [COMPONENT]: TEST_FRAMEWORK_NAME,
338
- ...testEnvironmentMetadata,
339
- ...testModuleSpanMetadata
340
- }
341
- })
342
- ciVisEvent(TELEMETRY_EVENT_CREATED, 'module')
343
-
344
- return details
345
- })
346
- })
347
- })
348
- on('after:spec', (spec, { tests, stats }) => {
349
- const cypressTests = tests || []
350
- const finishedTests = finishedTestsByFile[spec.relative] || []
351
-
352
- // Get tests that didn't go through `dd:afterEach`
353
- // and create a skipped test span for each of them
354
- cypressTests.filter(({ title }) => {
355
- const cypressTestName = title.join(' ')
356
- const isTestFinished = finishedTests.find(({ testName }) => cypressTestName === testName)
357
-
358
- return !isTestFinished
359
- }).forEach(({ title }) => {
360
- const cypressTestName = title.join(' ')
361
- const isSkippedByItr = testsToSkip.find(test =>
362
- cypressTestName === test.name && spec.relative === test.suite
363
- )
364
- const skippedTestSpan = getTestSpan(cypressTestName, spec.relative)
365
- if (spec.absolute && repositoryRoot) {
366
- skippedTestSpan.setTag(TEST_SOURCE_FILE, getTestSuitePath(spec.absolute, repositoryRoot))
367
- } else {
368
- skippedTestSpan.setTag(TEST_SOURCE_FILE, spec.relative)
369
- }
370
- skippedTestSpan.setTag(TEST_STATUS, 'skip')
371
- if (isSkippedByItr) {
372
- skippedTestSpan.setTag(TEST_SKIPPED_BY_ITR, 'true')
373
- }
374
- if (itrCorrelationId) {
375
- skippedTestSpan.setTag(ITR_CORRELATION_ID, itrCorrelationId)
376
- }
377
- skippedTestSpan.finish()
378
- })
379
-
380
- // Make sure that reported test statuses are the same as Cypress reports.
381
- // This is not always the case, such as when an `after` hook fails:
382
- // Cypress will report the last run test as failed, but we don't know that yet at `dd:afterEach`
383
- let latestError
384
- finishedTests.forEach((finishedTest) => {
385
- const cypressTest = cypressTests.find(test => test.title.join(' ') === finishedTest.testName)
386
- if (!cypressTest) {
387
- return
388
- }
389
- if (cypressTest.displayError) {
390
- latestError = new Error(cypressTest.displayError)
391
- }
392
- const cypressTestStatus = CYPRESS_STATUS_TO_TEST_STATUS[cypressTest.state]
393
- // update test status
394
- if (cypressTestStatus !== finishedTest.testStatus) {
395
- finishedTest.testSpan.setTag(TEST_STATUS, cypressTestStatus)
396
- finishedTest.testSpan.setTag('error', latestError)
397
- }
398
- if (itrCorrelationId) {
399
- finishedTest.testSpan.setTag(ITR_CORRELATION_ID, itrCorrelationId)
400
- }
401
- if (spec.absolute && repositoryRoot) {
402
- finishedTest.testSpan.setTag(TEST_SOURCE_FILE, getTestSuitePath(spec.absolute, repositoryRoot))
403
- } else {
404
- finishedTest.testSpan.setTag(TEST_SOURCE_FILE, spec.relative)
405
- }
406
- finishedTest.testSpan.finish(finishedTest.finishTime)
407
- })
408
-
409
- if (testSuiteSpan) {
410
- const status = getSuiteStatus(stats)
411
- testSuiteSpan.setTag(TEST_STATUS, status)
412
-
413
- if (latestError) {
414
- testSuiteSpan.setTag('error', latestError)
415
- }
416
- testSuiteSpan.finish()
417
- testSuiteSpan = null
418
- ciVisEvent(TELEMETRY_EVENT_FINISHED, 'suite')
419
- }
420
- })
421
-
422
- on('after:run', (suiteStats) => {
423
- if (testSessionSpan && testModuleSpan) {
424
- const testStatus = getSessionStatus(suiteStats)
425
- testModuleSpan.setTag(TEST_STATUS, testStatus)
426
- testSessionSpan.setTag(TEST_STATUS, testStatus)
427
-
428
- addIntelligentTestRunnerSpanTags(
429
- testSessionSpan,
430
- testModuleSpan,
431
- {
432
- isSuitesSkipped: isTestsSkipped,
433
- isSuitesSkippingEnabled,
434
- isCodeCoverageEnabled,
435
- skippingType: 'test',
436
- skippingCount: skippedTests.length,
437
- hasForcedToRunSuites,
438
- hasUnskippableSuites
439
- }
440
- )
441
-
442
- testModuleSpan.finish()
443
- ciVisEvent(TELEMETRY_EVENT_FINISHED, 'module')
444
- testSessionSpan.finish()
445
- ciVisEvent(TELEMETRY_EVENT_FINISHED, 'session')
446
-
447
- finishAllTraceSpans(testSessionSpan)
448
- }
449
-
450
- return new Promise(resolve => {
451
- const exporter = tracer._tracer._exporter
452
- if (!exporter) {
453
- return resolve(null)
454
- }
455
- if (exporter.flush) {
456
- exporter.flush(() => {
457
- appClosingTelemetry()
458
- resolve(null)
459
- })
460
- } else if (exporter._writer) {
461
- exporter._writer.flush(() => {
462
- appClosingTelemetry()
463
- resolve(null)
464
- })
465
- }
466
- })
467
- })
468
- on('task', {
469
- 'dd:testSuiteStart': (suite) => {
470
- if (testSuiteSpan) {
471
- return null
472
- }
473
- const testSuiteSpanMetadata = getTestSuiteCommonTags(command, frameworkVersion, suite, TEST_FRAMEWORK_NAME)
474
- testSuiteSpan = tracer.startSpan(`${TEST_FRAMEWORK_NAME}.test_suite`, {
475
- childOf: testModuleSpan,
476
- tags: {
477
- [COMPONENT]: TEST_FRAMEWORK_NAME,
478
- ...testEnvironmentMetadata,
479
- ...testSuiteSpanMetadata
480
- }
481
- })
482
- ciVisEvent(TELEMETRY_EVENT_CREATED, 'suite')
483
- return null
484
- },
485
- 'dd:beforeEach': (test) => {
486
- const { testName, testSuite } = test
487
- const shouldSkip = !!testsToSkip.find(test => {
488
- return testName === test.name && testSuite === test.suite
489
- })
490
- const isUnskippable = unskippableSuites.includes(testSuite)
491
- const isForcedToRun = shouldSkip && isUnskippable
492
-
493
- // skip test
494
- if (shouldSkip && !isUnskippable) {
495
- skippedTests.push(test)
496
- isTestsSkipped = true
497
- return { shouldSkip: true }
498
- }
499
-
500
- if (!activeSpan) {
501
- activeSpan = getTestSpan(testName, testSuite, isUnskippable, isForcedToRun)
502
- }
503
-
504
- return activeSpan ? { traceId: activeSpan.context().toTraceId() } : {}
505
- },
506
- 'dd:afterEach': ({ test, coverage }) => {
507
- const { state, error, isRUMActive, testSourceLine, testSuite, testName } = test
508
- if (activeSpan) {
509
- if (coverage && isCodeCoverageEnabled && tracer._tracer._exporter && tracer._tracer._exporter.exportCoverage) {
510
- const coverageFiles = getCoveredFilenamesFromCoverage(coverage)
511
- const relativeCoverageFiles = coverageFiles.map(file => getTestSuitePath(file, rootDir))
512
- if (!relativeCoverageFiles.length) {
513
- incrementCountMetric(TELEMETRY_CODE_COVERAGE_EMPTY)
514
- }
515
- distributionMetric(TELEMETRY_CODE_COVERAGE_NUM_FILES, {}, relativeCoverageFiles.length)
516
- const { _traceId, _spanId } = testSuiteSpan.context()
517
- const formattedCoverage = {
518
- sessionId: _traceId,
519
- suiteId: _spanId,
520
- testId: activeSpan.context()._spanId,
521
- files: relativeCoverageFiles
522
- }
523
- tracer._tracer._exporter.exportCoverage(formattedCoverage)
524
- }
525
- const testStatus = CYPRESS_STATUS_TO_TEST_STATUS[state]
526
- activeSpan.setTag(TEST_STATUS, testStatus)
28
+ cypressPlugin.init(tracer, config)
527
29
 
528
- if (error) {
529
- activeSpan.setTag('error', error)
530
- }
531
- if (isRUMActive) {
532
- activeSpan.setTag(TEST_IS_RUM_ACTIVE, 'true')
533
- }
534
- if (testSourceLine) {
535
- activeSpan.setTag(TEST_SOURCE_START, testSourceLine)
536
- }
537
- const finishedTest = {
538
- testName,
539
- testStatus,
540
- finishTime: activeSpan._getTime(), // we store the finish time here
541
- testSpan: activeSpan
542
- }
543
- if (finishedTestsByFile[testSuite]) {
544
- finishedTestsByFile[testSuite].push(finishedTest)
545
- } else {
546
- finishedTestsByFile[testSuite] = [finishedTest]
547
- }
548
- // test spans are finished at after:spec
549
- }
550
- activeSpan = null
551
- ciVisEvent(TELEMETRY_EVENT_FINISHED, 'test')
552
- return null
553
- },
554
- 'dd:addTags': (tags) => {
555
- if (activeSpan) {
556
- activeSpan.addTags(tags)
557
- }
558
- return null
559
- }
560
- })
30
+ on('before:run', cypressPlugin.beforeRun.bind(cypressPlugin))
31
+ on('after:spec', cypressPlugin.afterSpec.bind(cypressPlugin))
32
+ on('after:run', cypressPlugin.afterRun.bind(cypressPlugin))
33
+ on('task', cypressPlugin.getTasks())
561
34
  }
@@ -16,7 +16,6 @@ const {
16
16
  TEST_CODE_OWNERS,
17
17
  ITR_CORRELATION_ID,
18
18
  TEST_SOURCE_FILE,
19
- getTestSuitePath,
20
19
  TEST_IS_NEW,
21
20
  TEST_EARLY_FLAKE_IS_RETRY,
22
21
  TEST_EARLY_FLAKE_IS_ENABLED
@@ -141,6 +140,7 @@ class JestPlugin extends CiPlugin {
141
140
  config._ddItrCorrelationId = this.itrCorrelationId
142
141
  config._ddIsEarlyFlakeDetectionEnabled = !!this.libraryConfig?.isEarlyFlakeDetectionEnabled
143
142
  config._ddEarlyFlakeDetectionNumRetries = this.libraryConfig?.earlyFlakeDetectionNumRetries ?? 0
143
+ config._ddRepositoryRoot = this.repositoryRoot
144
144
  })
145
145
  })
146
146
 
@@ -311,7 +311,7 @@ class JestPlugin extends CiPlugin {
311
311
  testParameters,
312
312
  frameworkVersion,
313
313
  testStartLine,
314
- testFileAbsolutePath,
314
+ testSourceFile,
315
315
  isNew,
316
316
  isEfdRetry
317
317
  } = test
@@ -324,12 +324,8 @@ class JestPlugin extends CiPlugin {
324
324
  if (testStartLine) {
325
325
  extraTags[TEST_SOURCE_START] = testStartLine
326
326
  }
327
- if (testFileAbsolutePath) {
328
- extraTags[TEST_SOURCE_FILE] = getTestSuitePath(testFileAbsolutePath, this.repositoryRoot)
329
- } else {
330
- // If for whatever we don't have the full path, we'll set the source file to the suite name
331
- extraTags[TEST_SOURCE_FILE] = suite
332
- }
327
+ // If for whatever we don't have the source file, we'll fall back to the suite name
328
+ extraTags[TEST_SOURCE_FILE] = testSourceFile || suite
333
329
 
334
330
  if (isNew) {
335
331
  extraTags[TEST_IS_NEW] = 'true'
@@ -1,8 +1,12 @@
1
1
  'use strict'
2
2
 
3
+ const dc = require('dc-polyfill')
3
4
  const { getMessageSize, CONTEXT_PROPAGATION_KEY } = require('../../dd-trace/src/datastreams/processor')
4
5
  const ConsumerPlugin = require('../../dd-trace/src/plugins/consumer')
5
6
 
7
+ const afterStartCh = dc.channel('dd-trace:kafkajs:consumer:afterStart')
8
+ const beforeFinishCh = dc.channel('dd-trace:kafkajs:consumer:beforeFinish')
9
+
6
10
  class KafkajsConsumerPlugin extends ConsumerPlugin {
7
11
  static get id () { return 'kafkajs' }
8
12
  static get operation () { return 'consume' }
@@ -79,6 +83,18 @@ class KafkajsConsumerPlugin extends ConsumerPlugin {
79
83
  this.tracer
80
84
  .setCheckpoint(['direction:in', `group:${groupId}`, `topic:${topic}`, 'type:kafka'], span, payloadSize)
81
85
  }
86
+
87
+ if (afterStartCh.hasSubscribers) {
88
+ afterStartCh.publish({ topic, partition, message, groupId })
89
+ }
90
+ }
91
+
92
+ finish () {
93
+ if (beforeFinishCh.hasSubscribers) {
94
+ beforeFinishCh.publish()
95
+ }
96
+
97
+ super.finish()
82
98
  }
83
99
  }
84
100