dd-trace 5.103.0 → 5.104.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/index.d.ts +25 -3
- package/package.json +4 -3
- package/packages/datadog-instrumentations/src/aws-sdk.js +2 -2
- package/packages/datadog-instrumentations/src/cassandra-driver.js +5 -2
- package/packages/datadog-instrumentations/src/cucumber.js +103 -30
- package/packages/datadog-instrumentations/src/elasticsearch.js +4 -4
- package/packages/datadog-instrumentations/src/graphql.js +0 -5
- package/packages/datadog-instrumentations/src/grpc/client.js +48 -32
- package/packages/datadog-instrumentations/src/helpers/callback-instrumentor.js +1 -1
- package/packages/datadog-instrumentations/src/helpers/kafka.js +17 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/compiler.js +3 -2
- package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +19 -5
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +14 -13
- package/packages/datadog-instrumentations/src/http/client.js +2 -2
- package/packages/datadog-instrumentations/src/ioredis.js +3 -3
- package/packages/datadog-instrumentations/src/jest.js +33 -36
- package/packages/datadog-instrumentations/src/kafkajs.js +25 -6
- package/packages/datadog-instrumentations/src/mariadb.js +1 -1
- package/packages/datadog-instrumentations/src/memcached.js +2 -1
- package/packages/datadog-instrumentations/src/mocha/main.js +272 -91
- package/packages/datadog-instrumentations/src/mocha/utils.js +48 -8
- package/packages/datadog-instrumentations/src/mongodb-core.js +1 -1
- package/packages/datadog-instrumentations/src/mongoose.js +10 -12
- package/packages/datadog-instrumentations/src/mysql.js +2 -2
- package/packages/datadog-instrumentations/src/mysql2.js +1 -1
- package/packages/datadog-instrumentations/src/pg.js +1 -1
- package/packages/datadog-instrumentations/src/playwright.js +22 -5
- package/packages/datadog-instrumentations/src/router.js +4 -2
- package/packages/datadog-instrumentations/src/vitest.js +246 -149
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +26 -19
- package/packages/datadog-plugin-elasticsearch/src/index.js +28 -8
- package/packages/datadog-plugin-graphql/src/utils.js +4 -1
- package/packages/datadog-plugin-kafkajs/src/producer.js +32 -0
- package/packages/datadog-plugin-mongodb-core/src/index.js +54 -19
- package/packages/datadog-plugin-redis/src/index.js +37 -2
- package/packages/datadog-plugin-undici/src/index.js +19 -0
- package/packages/datadog-plugin-vitest/src/index.js +19 -7
- package/packages/datadog-shimmer/src/shimmer.js +35 -0
- package/packages/dd-trace/src/appsec/blocking.js +2 -2
- package/packages/dd-trace/src/appsec/index.js +10 -3
- package/packages/dd-trace/src/appsec/reporter.js +19 -5
- package/packages/dd-trace/src/ci-visibility/requests/request.js +3 -1
- package/packages/dd-trace/src/ci-visibility/test-api-manual/test-api-manual-plugin.js +5 -3
- package/packages/dd-trace/src/config/generated-config-types.d.ts +1 -0
- package/packages/dd-trace/src/config/supported-configurations.json +9 -0
- package/packages/dd-trace/src/crashtracking/crashtracker.js +15 -3
- package/packages/dd-trace/src/datastreams/context.js +4 -2
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +26 -19
- package/packages/dd-trace/src/exporters/common/agents.js +3 -1
- package/packages/dd-trace/src/exporters/common/request.js +3 -1
- package/packages/dd-trace/src/id.js +17 -4
- package/packages/dd-trace/src/lambda/handler.js +2 -4
- package/packages/dd-trace/src/llmobs/sdk.js +10 -0
- package/packages/dd-trace/src/log/writer.js +3 -1
- package/packages/dd-trace/src/noop/span.js +3 -1
- package/packages/dd-trace/src/openfeature/writers/exposures.js +51 -20
- package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +1 -1
- package/packages/dd-trace/src/plugins/apollo.js +3 -1
- package/packages/dd-trace/src/plugins/ci_plugin.js +3 -13
- package/packages/dd-trace/src/plugins/log_plugin.js +3 -1
- package/packages/dd-trace/src/plugins/tracing.js +5 -3
- package/packages/dd-trace/src/plugins/util/git.js +3 -1
- package/packages/dd-trace/src/plugins/util/test.js +82 -0
- package/packages/dd-trace/src/plugins/util/web.js +11 -0
- package/packages/dd-trace/src/scope.js +7 -5
- package/packages/dd-trace/src/service-naming/extra-services.js +14 -0
- package/vendor/dist/opentracing/LICENSE +0 -201
- package/vendor/dist/opentracing/binary_carrier.d.ts +0 -11
- package/vendor/dist/opentracing/constants.d.ts +0 -61
- package/vendor/dist/opentracing/examples/demo/demo.d.ts +0 -2
- package/vendor/dist/opentracing/ext/tags.d.ts +0 -90
- package/vendor/dist/opentracing/functions.d.ts +0 -20
- package/vendor/dist/opentracing/global_tracer.d.ts +0 -14
- package/vendor/dist/opentracing/index.d.ts +0 -12
- package/vendor/dist/opentracing/index.js +0 -1
- package/vendor/dist/opentracing/mock_tracer/index.d.ts +0 -5
- package/vendor/dist/opentracing/mock_tracer/mock_context.d.ts +0 -13
- package/vendor/dist/opentracing/mock_tracer/mock_report.d.ts +0 -16
- package/vendor/dist/opentracing/mock_tracer/mock_span.d.ts +0 -50
- package/vendor/dist/opentracing/mock_tracer/mock_tracer.d.ts +0 -26
- package/vendor/dist/opentracing/noop.d.ts +0 -8
- package/vendor/dist/opentracing/reference.d.ts +0 -33
- package/vendor/dist/opentracing/span.d.ts +0 -147
- package/vendor/dist/opentracing/span_context.d.ts +0 -26
- package/vendor/dist/opentracing/test/api_compatibility.d.ts +0 -16
- package/vendor/dist/opentracing/test/mocktracer_implemenation.d.ts +0 -3
- package/vendor/dist/opentracing/test/noop_implementation.d.ts +0 -4
- package/vendor/dist/opentracing/test/opentracing_api.d.ts +0 -3
- package/vendor/dist/opentracing/test/unittest.d.ts +0 -2
- package/vendor/dist/opentracing/tracer.d.ts +0 -127
|
@@ -18,6 +18,7 @@ const {
|
|
|
18
18
|
recordAttemptToFixExecution,
|
|
19
19
|
logAttemptToFixTestExecution,
|
|
20
20
|
logTestOptimizationSummary,
|
|
21
|
+
getTestOptimizationRequestResults,
|
|
21
22
|
} = require('../../dd-trace/src/plugins/util/test')
|
|
22
23
|
const log = require('../../dd-trace/src/log')
|
|
23
24
|
const {
|
|
@@ -1075,9 +1076,24 @@ function runAllTestsWrapper (runAllTests, playwrightVersion) {
|
|
|
1075
1076
|
log.error('Playwright session start error', e)
|
|
1076
1077
|
}
|
|
1077
1078
|
|
|
1078
|
-
|
|
1079
|
+
const isTestOptimizationSupported = satisfies(playwrightVersion, MINIMUM_SUPPORTED_VERSION_RANGE_EFD)
|
|
1080
|
+
const shouldGetKnownTests = isKnownTestsEnabled && isTestOptimizationSupported
|
|
1081
|
+
const shouldGetTestManagementTests = isTestManagementTestsEnabled && isTestOptimizationSupported
|
|
1082
|
+
|
|
1083
|
+
const {
|
|
1084
|
+
knownTestsResponse,
|
|
1085
|
+
testManagementTestsResponse,
|
|
1086
|
+
} = await getTestOptimizationRequestResults({
|
|
1087
|
+
isKnownTestsEnabled: shouldGetKnownTests,
|
|
1088
|
+
isTestManagementTestsEnabled: shouldGetTestManagementTests,
|
|
1089
|
+
getKnownTests: () => getChannelPromise(knownTestsCh),
|
|
1090
|
+
getTestManagementTests: () => getChannelPromise(testManagementTestsCh),
|
|
1091
|
+
})
|
|
1092
|
+
|
|
1093
|
+
if (shouldGetKnownTests) {
|
|
1079
1094
|
try {
|
|
1080
|
-
const { err, knownTests: receivedKnownTests } =
|
|
1095
|
+
const { err, knownTests: receivedKnownTests } =
|
|
1096
|
+
knownTestsResponse || await getChannelPromise(knownTestsCh)
|
|
1081
1097
|
if (err) {
|
|
1082
1098
|
isEarlyFlakeDetectionEnabled = false
|
|
1083
1099
|
isKnownTestsEnabled = false
|
|
@@ -1096,9 +1112,10 @@ function runAllTestsWrapper (runAllTests, playwrightVersion) {
|
|
|
1096
1112
|
}
|
|
1097
1113
|
}
|
|
1098
1114
|
|
|
1099
|
-
if (
|
|
1115
|
+
if (shouldGetTestManagementTests) {
|
|
1100
1116
|
try {
|
|
1101
|
-
const { err, testManagementTests: receivedTestManagementTests } =
|
|
1117
|
+
const { err, testManagementTests: receivedTestManagementTests } =
|
|
1118
|
+
testManagementTestsResponse || await getChannelPromise(testManagementTestsCh)
|
|
1102
1119
|
if (err) {
|
|
1103
1120
|
isTestManagementTestsEnabled = false
|
|
1104
1121
|
} else {
|
|
@@ -1110,7 +1127,7 @@ function runAllTestsWrapper (runAllTests, playwrightVersion) {
|
|
|
1110
1127
|
}
|
|
1111
1128
|
}
|
|
1112
1129
|
|
|
1113
|
-
if (isImpactedTestsEnabled &&
|
|
1130
|
+
if (isImpactedTestsEnabled && isTestOptimizationSupported) {
|
|
1114
1131
|
try {
|
|
1115
1132
|
const { err, modifiedFiles: receivedModifiedFiles } = await getChannelPromise(modifiedFilesCh)
|
|
1116
1133
|
if (err) {
|
|
@@ -112,8 +112,10 @@ function createWrapRouterMethod (name, compile) {
|
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
function wrapNext (req,
|
|
116
|
-
|
|
115
|
+
function wrapNext (req, originalNext) {
|
|
116
|
+
// Per layer dispatch, N per request. `shimmer.wrapCallback` preserves
|
|
117
|
+
// only `name` + `length`; see its JSDoc for the full contract.
|
|
118
|
+
return shimmer.wrapCallback(originalNext, next => function (error) {
|
|
117
119
|
if (error && error !== 'route' && error !== 'router') {
|
|
118
120
|
errorChannel.publish({ req, error })
|
|
119
121
|
}
|
|
@@ -19,6 +19,7 @@ const {
|
|
|
19
19
|
collectTestOptimizationSummariesFromTraces,
|
|
20
20
|
logAttemptToFixTestExecution,
|
|
21
21
|
logTestOptimizationSummary,
|
|
22
|
+
getTestOptimizationRequestResults,
|
|
22
23
|
} = require('../../dd-trace/src/plugins/util/test')
|
|
23
24
|
const { addHook, channel } = require('./helpers/instrument')
|
|
24
25
|
|
|
@@ -43,6 +44,7 @@ const testSuiteErrorCh = channel('ci:vitest:test-suite:error')
|
|
|
43
44
|
// test session hooks
|
|
44
45
|
const testSessionStartCh = channel('ci:vitest:session:start')
|
|
45
46
|
const testSessionFinishCh = channel('ci:vitest:session:finish')
|
|
47
|
+
const testSessionConfigurationCh = channel('ci:vitest:session:configuration')
|
|
46
48
|
const libraryConfigurationCh = channel('ci:vitest:library-configuration')
|
|
47
49
|
const knownTestsCh = channel('ci:vitest:known-tests')
|
|
48
50
|
const isEarlyFlakeDetectionFaultyCh = channel('ci:vitest:is-early-flake-detection-faulty')
|
|
@@ -74,6 +76,9 @@ let isRetryReasonEfd = false
|
|
|
74
76
|
let isRetryReasonAttemptToFix = false
|
|
75
77
|
const switchedStatuses = new WeakSet()
|
|
76
78
|
const workerProcesses = new WeakSet()
|
|
79
|
+
const mainProcessSetupPromises = new WeakMap()
|
|
80
|
+
const coverageWrappedProviders = new WeakSet()
|
|
81
|
+
const finishWrappedContexts = new WeakSet()
|
|
77
82
|
let isFlakyTestRetriesEnabled = false
|
|
78
83
|
let flakyTestRetriesCount = 0
|
|
79
84
|
let isEarlyFlakeDetectionEnabled = false
|
|
@@ -134,6 +139,9 @@ function getProvidedContext () {
|
|
|
134
139
|
_ddFlakyTestRetriesCount: flakyTestRetriesCount,
|
|
135
140
|
_ddIsImpactedTestsEnabled: isImpactedTestsEnabled,
|
|
136
141
|
_ddModifiedFiles: modifiedFiles,
|
|
142
|
+
_ddTestSessionId: testSessionId,
|
|
143
|
+
_ddTestModuleId: testModuleId,
|
|
144
|
+
_ddTestCommand: testCommand,
|
|
137
145
|
} = globalThis.__vitest_worker__.providedContext
|
|
138
146
|
|
|
139
147
|
return {
|
|
@@ -150,6 +158,9 @@ function getProvidedContext () {
|
|
|
150
158
|
flakyTestRetriesCount: flakyTestRetriesCount ?? 0,
|
|
151
159
|
isImpactedTestsEnabled,
|
|
152
160
|
modifiedFiles,
|
|
161
|
+
testSessionId,
|
|
162
|
+
testModuleId,
|
|
163
|
+
testCommand,
|
|
153
164
|
}
|
|
154
165
|
} catch {
|
|
155
166
|
log.error('Vitest workers could not parse provided context, so some features will not work.')
|
|
@@ -167,6 +178,9 @@ function getProvidedContext () {
|
|
|
167
178
|
flakyTestRetriesCount: 0,
|
|
168
179
|
isImpactedTestsEnabled: false,
|
|
169
180
|
modifiedFiles: {},
|
|
181
|
+
testSessionId: undefined,
|
|
182
|
+
testModuleId: undefined,
|
|
183
|
+
testCommand: undefined,
|
|
170
184
|
}
|
|
171
185
|
}
|
|
172
186
|
}
|
|
@@ -217,6 +231,10 @@ function getTestRunnerExport (testPackage) {
|
|
|
217
231
|
return findExportByName(testPackage, 'VitestTestRunner') || findExportByName(testPackage, 'TestRunner')
|
|
218
232
|
}
|
|
219
233
|
|
|
234
|
+
function getVitestExport (vitestPackage) {
|
|
235
|
+
return findExportByName(vitestPackage, 'Vitest')
|
|
236
|
+
}
|
|
237
|
+
|
|
220
238
|
function getForksPoolWorkerExport (vitestPackage) {
|
|
221
239
|
return findExportByName(vitestPackage, 'ForksPoolWorker')
|
|
222
240
|
}
|
|
@@ -329,170 +347,223 @@ function wrapBeforeEachCleanupResult (task, result) {
|
|
|
329
347
|
return result
|
|
330
348
|
}
|
|
331
349
|
|
|
332
|
-
function
|
|
333
|
-
return
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
350
|
+
function getWorkspaceProject (ctx) {
|
|
351
|
+
return ctx.getCoreWorkspaceProject
|
|
352
|
+
? ctx.getCoreWorkspaceProject()
|
|
353
|
+
: ctx.getRootProject()
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
function setProvidedContext (ctx, values, warningMessage) {
|
|
357
|
+
try {
|
|
358
|
+
Object.assign(getWorkspaceProject(ctx)._provided, values)
|
|
359
|
+
} catch {
|
|
360
|
+
log.warn(warningMessage)
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
function getTestFilepathsFromSpecifications (testSpecifications) {
|
|
365
|
+
if (!Array.isArray(testSpecifications) || !testSpecifications.length) {
|
|
366
|
+
return
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
return testSpecifications.map(testSpecification => {
|
|
370
|
+
const testFile = Array.isArray(testSpecification) ? testSpecification[1] : testSpecification
|
|
371
|
+
return testFile?.moduleId || testFile?.filepath || testFile
|
|
372
|
+
})
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
function getTestFilepaths (ctx, testSpecifications) {
|
|
376
|
+
const testFilepaths = getTestFilepathsFromSpecifications(testSpecifications)
|
|
377
|
+
if (testFilepaths) {
|
|
378
|
+
return testFilepaths
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
const getFilePaths = ctx.getTestFilepaths || ctx._globTestFilepaths
|
|
382
|
+
return getFilePaths.call(ctx)
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
function wrapCoverageProvider (ctx) {
|
|
386
|
+
const { coverageProvider } = ctx
|
|
387
|
+
if (!coverageProvider?.generateCoverage || coverageWrappedProviders.has(coverageProvider)) {
|
|
388
|
+
return
|
|
389
|
+
}
|
|
390
|
+
coverageWrappedProviders.add(coverageProvider)
|
|
391
|
+
|
|
392
|
+
// Capture coverage root directory from config (default is 'coverage' in cwd)
|
|
393
|
+
try {
|
|
394
|
+
const coverageConfig = ctx.config?.coverage
|
|
395
|
+
const reportsDirectory = coverageConfig?.reportsDirectory || 'coverage'
|
|
396
|
+
const rootDir = ctx.config?.root || process.cwd()
|
|
397
|
+
coverageRootDir = path.isAbsolute(reportsDirectory) ? reportsDirectory : path.join(rootDir, reportsDirectory)
|
|
398
|
+
} catch {
|
|
399
|
+
// Fallback to cwd if we can't get config
|
|
400
|
+
coverageRootDir = process.cwd()
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
shimmer.wrap(coverageProvider, 'generateCoverage', generateCoverage => async function () {
|
|
404
|
+
const totalCodeCoverage = await generateCoverage.apply(this, arguments)
|
|
340
405
|
|
|
341
406
|
try {
|
|
342
|
-
|
|
343
|
-
if (!err) {
|
|
344
|
-
isFlakyTestRetriesEnabled = libraryConfig.isFlakyTestRetriesEnabled
|
|
345
|
-
flakyTestRetriesCount = libraryConfig.flakyTestRetriesCount
|
|
346
|
-
isEarlyFlakeDetectionEnabled = libraryConfig.isEarlyFlakeDetectionEnabled
|
|
347
|
-
earlyFlakeDetectionNumRetries = libraryConfig.earlyFlakeDetectionNumRetries
|
|
348
|
-
earlyFlakeDetectionSlowTestRetries = libraryConfig.earlyFlakeDetectionSlowTestRetries ?? {}
|
|
349
|
-
isDiEnabled = libraryConfig.isDiEnabled
|
|
350
|
-
isKnownTestsEnabled = libraryConfig.isKnownTestsEnabled
|
|
351
|
-
isTestManagementTestsEnabled = libraryConfig.isTestManagementEnabled
|
|
352
|
-
testManagementAttemptToFixRetries = libraryConfig.testManagementAttemptToFixRetries
|
|
353
|
-
isImpactedTestsEnabled = libraryConfig.isImpactedTestsEnabled
|
|
354
|
-
}
|
|
407
|
+
testCodeCoverageLinesTotal = totalCodeCoverage.getCoverageSummary().lines.pct
|
|
355
408
|
} catch {
|
|
356
|
-
|
|
357
|
-
isEarlyFlakeDetectionEnabled = false
|
|
358
|
-
isDiEnabled = false
|
|
359
|
-
isKnownTestsEnabled = false
|
|
360
|
-
isImpactedTestsEnabled = false
|
|
409
|
+
// ignore errors
|
|
361
410
|
}
|
|
411
|
+
return totalCodeCoverage
|
|
412
|
+
})
|
|
413
|
+
}
|
|
362
414
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
: this.ctx.getRootProject()
|
|
369
|
-
workspaceProject._provided._ddIsFlakyTestRetriesEnabled = isFlakyTestRetriesEnabled
|
|
370
|
-
workspaceProject._provided._ddFlakyTestRetriesCount = flakyTestRetriesCount
|
|
371
|
-
} catch {
|
|
372
|
-
log.warn('Could not send library configuration to workers.')
|
|
373
|
-
}
|
|
374
|
-
}
|
|
415
|
+
function wrapSessionFinish (ctx) {
|
|
416
|
+
if (finishWrappedContexts.has(ctx)) {
|
|
417
|
+
return
|
|
418
|
+
}
|
|
419
|
+
finishWrappedContexts.add(ctx)
|
|
375
420
|
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
isEarlyFlakeDetectionEnabled = false
|
|
380
|
-
} else {
|
|
381
|
-
const knownTests = knownTestsResponse.knownTests
|
|
382
|
-
const getFilePaths = this.ctx.getTestFilepaths || this.ctx._globTestFilepaths
|
|
383
|
-
|
|
384
|
-
const testFilepaths = await getFilePaths.call(this.ctx)
|
|
385
|
-
|
|
386
|
-
if (isValidKnownTests(knownTests)) {
|
|
387
|
-
isEarlyFlakeDetectionFaultyCh.publish({
|
|
388
|
-
knownTests: knownTests.vitest,
|
|
389
|
-
testFilepaths,
|
|
390
|
-
onDone: (isFaulty) => {
|
|
391
|
-
isEarlyFlakeDetectionFaulty = isFaulty
|
|
392
|
-
},
|
|
393
|
-
})
|
|
394
|
-
if (isEarlyFlakeDetectionFaulty) {
|
|
395
|
-
isEarlyFlakeDetectionEnabled = false
|
|
396
|
-
log.warn('New test detection is disabled because the number of new tests is too high.')
|
|
397
|
-
} else {
|
|
398
|
-
// TODO: use this to pass session and module IDs to the worker, instead of polluting process.env
|
|
399
|
-
// Note: setting this.ctx.config.provide directly does not work because it's cached
|
|
400
|
-
try {
|
|
401
|
-
const workspaceProject = this.ctx.getCoreWorkspaceProject
|
|
402
|
-
? this.ctx.getCoreWorkspaceProject()
|
|
403
|
-
: this.ctx.getRootProject()
|
|
404
|
-
workspaceProject._provided._ddIsKnownTestsEnabled = isKnownTestsEnabled
|
|
405
|
-
workspaceProject._provided._ddKnownTests = knownTests
|
|
406
|
-
workspaceProject._provided._ddIsEarlyFlakeDetectionEnabled = isEarlyFlakeDetectionEnabled
|
|
407
|
-
workspaceProject._provided._ddEarlyFlakeDetectionNumRetries =
|
|
408
|
-
getConfiguredEfdRetryCount(earlyFlakeDetectionSlowTestRetries, earlyFlakeDetectionNumRetries)
|
|
409
|
-
workspaceProject._provided._ddEarlyFlakeDetectionSlowTestRetries = earlyFlakeDetectionSlowTestRetries
|
|
410
|
-
} catch {
|
|
411
|
-
log.warn('Could not send known tests to workers so Early Flake Detection will not work.')
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
} else {
|
|
415
|
-
isEarlyFlakeDetectionFaulty = true
|
|
416
|
-
isEarlyFlakeDetectionEnabled = false
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
}
|
|
421
|
+
shimmer.wrap(ctx, 'exit', getFinishWrapper)
|
|
422
|
+
shimmer.wrap(ctx, 'close', getFinishWrapper)
|
|
423
|
+
}
|
|
420
424
|
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
: this.ctx.getRootProject()
|
|
426
|
-
workspaceProject._provided._ddIsDiEnabled = isDiEnabled
|
|
427
|
-
} catch {
|
|
428
|
-
log.warn('Could not send Dynamic Instrumentation configuration to workers.')
|
|
429
|
-
}
|
|
430
|
-
}
|
|
425
|
+
async function runMainProcessSetup (ctx, frameworkVersion, testSpecifications) {
|
|
426
|
+
if (!testSessionFinishCh.hasSubscribers) {
|
|
427
|
+
return
|
|
428
|
+
}
|
|
431
429
|
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
workspaceProject._provided._ddTestManagementTests = testManagementTests
|
|
446
|
-
} catch {
|
|
447
|
-
log.warn('Could not send test management tests to workers so Test Management will not work.')
|
|
448
|
-
}
|
|
449
|
-
}
|
|
430
|
+
try {
|
|
431
|
+
const { err, libraryConfig } = await getChannelPromise(libraryConfigurationCh, frameworkVersion)
|
|
432
|
+
if (!err) {
|
|
433
|
+
isFlakyTestRetriesEnabled = libraryConfig.isFlakyTestRetriesEnabled
|
|
434
|
+
flakyTestRetriesCount = libraryConfig.flakyTestRetriesCount
|
|
435
|
+
isEarlyFlakeDetectionEnabled = libraryConfig.isEarlyFlakeDetectionEnabled
|
|
436
|
+
earlyFlakeDetectionNumRetries = libraryConfig.earlyFlakeDetectionNumRetries
|
|
437
|
+
earlyFlakeDetectionSlowTestRetries = libraryConfig.earlyFlakeDetectionSlowTestRetries ?? {}
|
|
438
|
+
isDiEnabled = libraryConfig.isDiEnabled
|
|
439
|
+
isKnownTestsEnabled = libraryConfig.isKnownTestsEnabled
|
|
440
|
+
isTestManagementTestsEnabled = libraryConfig.isTestManagementEnabled
|
|
441
|
+
testManagementAttemptToFixRetries = libraryConfig.testManagementAttemptToFixRetries
|
|
442
|
+
isImpactedTestsEnabled = libraryConfig.isImpactedTestsEnabled
|
|
450
443
|
}
|
|
444
|
+
} catch {
|
|
445
|
+
isFlakyTestRetriesEnabled = false
|
|
446
|
+
isEarlyFlakeDetectionEnabled = false
|
|
447
|
+
isDiEnabled = false
|
|
448
|
+
isKnownTestsEnabled = false
|
|
449
|
+
isImpactedTestsEnabled = false
|
|
450
|
+
}
|
|
451
451
|
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
452
|
+
if (testSessionConfigurationCh.hasSubscribers) {
|
|
453
|
+
const { testSessionId, testModuleId, testCommand } = await getChannelPromise(
|
|
454
|
+
testSessionConfigurationCh,
|
|
455
|
+
frameworkVersion
|
|
456
|
+
)
|
|
457
|
+
setProvidedContext(ctx, {
|
|
458
|
+
_ddTestSessionId: testSessionId,
|
|
459
|
+
_ddTestModuleId: testModuleId,
|
|
460
|
+
_ddTestCommand: testCommand,
|
|
461
|
+
}, 'Could not send test session configuration to workers.')
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
const {
|
|
465
|
+
knownTestsResponse,
|
|
466
|
+
testManagementTestsResponse,
|
|
467
|
+
} = await getTestOptimizationRequestResults({
|
|
468
|
+
isKnownTestsEnabled,
|
|
469
|
+
isTestManagementTestsEnabled,
|
|
470
|
+
getKnownTests: () => getChannelPromise(knownTestsCh),
|
|
471
|
+
getTestManagementTests: () => getChannelPromise(testManagementTestsCh),
|
|
472
|
+
})
|
|
473
|
+
|
|
474
|
+
if (isFlakyTestRetriesEnabled && !ctx.config.retry && flakyTestRetriesCount > 0) {
|
|
475
|
+
ctx.config.retry = flakyTestRetriesCount
|
|
476
|
+
setProvidedContext(ctx, {
|
|
477
|
+
_ddIsFlakyTestRetriesEnabled: isFlakyTestRetriesEnabled,
|
|
478
|
+
_ddFlakyTestRetriesCount: flakyTestRetriesCount,
|
|
479
|
+
}, 'Could not send library configuration to workers.')
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
if (isKnownTestsEnabled) {
|
|
483
|
+
const currentKnownTestsResponse = knownTestsResponse || await getChannelPromise(knownTestsCh)
|
|
484
|
+
if (currentKnownTestsResponse.err) {
|
|
485
|
+
isEarlyFlakeDetectionEnabled = false
|
|
486
|
+
} else {
|
|
487
|
+
const knownTests = currentKnownTestsResponse.knownTests
|
|
488
|
+
const testFilepaths = await getTestFilepaths(ctx, testSpecifications)
|
|
489
|
+
|
|
490
|
+
if (isValidKnownTests(knownTests)) {
|
|
491
|
+
isEarlyFlakeDetectionFaultyCh.publish({
|
|
492
|
+
knownTests: knownTests.vitest,
|
|
493
|
+
testFilepaths,
|
|
494
|
+
onDone: (isFaulty) => {
|
|
495
|
+
isEarlyFlakeDetectionFaulty = isFaulty
|
|
496
|
+
},
|
|
497
|
+
})
|
|
498
|
+
if (isEarlyFlakeDetectionFaulty) {
|
|
499
|
+
isEarlyFlakeDetectionEnabled = false
|
|
500
|
+
log.warn('New test detection is disabled because the number of new tests is too high.')
|
|
501
|
+
} else {
|
|
502
|
+
setProvidedContext(ctx, {
|
|
503
|
+
_ddIsKnownTestsEnabled: isKnownTestsEnabled,
|
|
504
|
+
_ddKnownTests: knownTests,
|
|
505
|
+
_ddIsEarlyFlakeDetectionEnabled: isEarlyFlakeDetectionEnabled,
|
|
506
|
+
_ddEarlyFlakeDetectionNumRetries:
|
|
507
|
+
getConfiguredEfdRetryCount(earlyFlakeDetectionSlowTestRetries, earlyFlakeDetectionNumRetries),
|
|
508
|
+
_ddEarlyFlakeDetectionSlowTestRetries: earlyFlakeDetectionSlowTestRetries,
|
|
509
|
+
}, 'Could not send known tests to workers so Early Flake Detection will not work.')
|
|
465
510
|
}
|
|
511
|
+
} else {
|
|
512
|
+
isEarlyFlakeDetectionFaulty = true
|
|
513
|
+
isEarlyFlakeDetectionEnabled = false
|
|
466
514
|
}
|
|
467
515
|
}
|
|
516
|
+
}
|
|
468
517
|
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
const rootDir = this.ctx.config?.root || process.cwd()
|
|
475
|
-
coverageRootDir = path.isAbsolute(reportsDirectory) ? reportsDirectory : path.join(rootDir, reportsDirectory)
|
|
476
|
-
} catch {
|
|
477
|
-
// Fallback to cwd if we can't get config
|
|
478
|
-
coverageRootDir = process.cwd()
|
|
479
|
-
}
|
|
518
|
+
if (isDiEnabled) {
|
|
519
|
+
setProvidedContext(ctx, {
|
|
520
|
+
_ddIsDiEnabled: isDiEnabled,
|
|
521
|
+
}, 'Could not send Dynamic Instrumentation configuration to workers.')
|
|
522
|
+
}
|
|
480
523
|
|
|
481
|
-
|
|
482
|
-
|
|
524
|
+
if (isTestManagementTestsEnabled) {
|
|
525
|
+
const { err, testManagementTests: receivedTestManagementTests } =
|
|
526
|
+
testManagementTestsResponse || await getChannelPromise(testManagementTestsCh)
|
|
527
|
+
if (err) {
|
|
528
|
+
isTestManagementTestsEnabled = false
|
|
529
|
+
log.error('Could not get test management tests.')
|
|
530
|
+
} else {
|
|
531
|
+
setProvidedContext(ctx, {
|
|
532
|
+
_ddIsTestManagementTestsEnabled: isTestManagementTestsEnabled,
|
|
533
|
+
_ddTestManagementAttemptToFixRetries: testManagementAttemptToFixRetries,
|
|
534
|
+
_ddTestManagementTests: receivedTestManagementTests,
|
|
535
|
+
}, 'Could not send test management tests to workers so Test Management will not work.')
|
|
536
|
+
}
|
|
537
|
+
}
|
|
483
538
|
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
539
|
+
if (isImpactedTestsEnabled) {
|
|
540
|
+
const { err, modifiedFiles } = await getChannelPromise(modifiedFilesCh)
|
|
541
|
+
if (err) {
|
|
542
|
+
log.error('Could not get modified tests.')
|
|
543
|
+
} else {
|
|
544
|
+
setProvidedContext(ctx, {
|
|
545
|
+
_ddIsImpactedTestsEnabled: isImpactedTestsEnabled,
|
|
546
|
+
_ddModifiedFiles: modifiedFiles,
|
|
547
|
+
}, 'Could not send modified tests to workers so Impacted Tests will not work.')
|
|
491
548
|
}
|
|
549
|
+
}
|
|
492
550
|
|
|
493
|
-
|
|
494
|
-
|
|
551
|
+
wrapCoverageProvider(ctx)
|
|
552
|
+
wrapSessionFinish(ctx)
|
|
553
|
+
}
|
|
495
554
|
|
|
555
|
+
function ensureMainProcessSetup (ctx, frameworkVersion, testSpecifications) {
|
|
556
|
+
let setupPromise = mainProcessSetupPromises.get(ctx)
|
|
557
|
+
if (!setupPromise) {
|
|
558
|
+
setupPromise = runMainProcessSetup(ctx, frameworkVersion, testSpecifications)
|
|
559
|
+
mainProcessSetupPromises.set(ctx, setupPromise)
|
|
560
|
+
}
|
|
561
|
+
return setupPromise
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
function getSortWrapper (sort, frameworkVersion) {
|
|
565
|
+
return async function () {
|
|
566
|
+
await ensureMainProcessSetup(this.ctx, frameworkVersion, arguments[0])
|
|
496
567
|
return sort.apply(this, arguments)
|
|
497
568
|
}
|
|
498
569
|
}
|
|
@@ -504,6 +575,11 @@ function getFinishWrapper (exitOrClose) {
|
|
|
504
575
|
return exitOrClose.apply(this, arguments)
|
|
505
576
|
}
|
|
506
577
|
isClosed = true
|
|
578
|
+
|
|
579
|
+
if (!testSessionFinishCh.hasSubscribers) {
|
|
580
|
+
return exitOrClose.apply(this, arguments)
|
|
581
|
+
}
|
|
582
|
+
|
|
507
583
|
let onFinish
|
|
508
584
|
|
|
509
585
|
const flushPromise = new Promise(resolve => {
|
|
@@ -555,6 +631,17 @@ function getCliOrStartVitestWrapper (frameworkVersion) {
|
|
|
555
631
|
}
|
|
556
632
|
}
|
|
557
633
|
|
|
634
|
+
function wrapVitestRunFiles (Vitest, frameworkVersion) {
|
|
635
|
+
if (!Vitest?.prototype?.runFiles) {
|
|
636
|
+
return
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
shimmer.wrap(Vitest.prototype, 'runFiles', runFiles => async function (testSpecifications) {
|
|
640
|
+
await ensureMainProcessSetup(this, frameworkVersion, testSpecifications)
|
|
641
|
+
return runFiles.apply(this, arguments)
|
|
642
|
+
})
|
|
643
|
+
}
|
|
644
|
+
|
|
558
645
|
function getCreateCliWrapper (vitestPackage, frameworkVersion) {
|
|
559
646
|
const createCliExport = findExportByName(vitestPackage, 'createCLI')
|
|
560
647
|
if (!createCliExport) {
|
|
@@ -658,6 +745,11 @@ function getStartVitestWrapper (cliApiPackage, frameworkVersion) {
|
|
|
658
745
|
const startVitestExport = findExportByName(cliApiPackage, 'startVitest')
|
|
659
746
|
shimmer.wrap(cliApiPackage, startVitestExport.key, getCliOrStartVitestWrapper(frameworkVersion))
|
|
660
747
|
|
|
748
|
+
const vitest = getVitestExport(cliApiPackage)
|
|
749
|
+
if (vitest) {
|
|
750
|
+
wrapVitestRunFiles(vitest.value, frameworkVersion)
|
|
751
|
+
}
|
|
752
|
+
|
|
661
753
|
const forksPoolWorker = getForksPoolWorkerExport(cliApiPackage)
|
|
662
754
|
if (forksPoolWorker) {
|
|
663
755
|
// function is async
|
|
@@ -921,7 +1013,6 @@ function wrapVitestTestRunner (VitestTestRunner) {
|
|
|
921
1013
|
// Here we finish the earlier iteration,
|
|
922
1014
|
// as long as it's not the _last_ iteration (which will be finished normally)
|
|
923
1015
|
|
|
924
|
-
// TODO: check test duration (not to repeat if it's too slow)
|
|
925
1016
|
const ctx = taskToCtx.get(task)
|
|
926
1017
|
if (ctx) {
|
|
927
1018
|
if (lastExecutionStatus === 'fail') {
|
|
@@ -1269,8 +1360,15 @@ addHook({
|
|
|
1269
1360
|
}
|
|
1270
1361
|
// From >=3.0.1, the first arguments changes from a string to an object containing the filepath
|
|
1271
1362
|
const testSuiteAbsolutePath = testPaths[0]?.filepath || testPaths[0]
|
|
1272
|
-
|
|
1273
|
-
|
|
1363
|
+
const providedContext = getProvidedContext()
|
|
1364
|
+
|
|
1365
|
+
const testSuiteCtx = {
|
|
1366
|
+
testSuiteAbsolutePath,
|
|
1367
|
+
frameworkVersion,
|
|
1368
|
+
testSessionId: providedContext.testSessionId,
|
|
1369
|
+
testModuleId: providedContext.testModuleId,
|
|
1370
|
+
testCommand: providedContext.testCommand,
|
|
1371
|
+
}
|
|
1274
1372
|
testSuiteStartCh.runStores(testSuiteCtx, () => {})
|
|
1275
1373
|
const startTestsResponse = await startTests.apply(this, arguments)
|
|
1276
1374
|
|
|
@@ -1288,7 +1386,6 @@ addHook({
|
|
|
1288
1386
|
// We have to trick vitest into thinking that the test has passed
|
|
1289
1387
|
// but we want to report it as failed if it did fail
|
|
1290
1388
|
const isSwitchedStatus = switchedStatuses.has(task)
|
|
1291
|
-
const providedContext = getProvidedContext()
|
|
1292
1389
|
|
|
1293
1390
|
if (result) {
|
|
1294
1391
|
const { state, duration, errors } = result
|
|
@@ -70,6 +70,7 @@ const {
|
|
|
70
70
|
getMaxEfdRetryCount,
|
|
71
71
|
getPullRequestBaseBranch,
|
|
72
72
|
TEST_FINAL_STATUS,
|
|
73
|
+
getTestOptimizationRequestResults,
|
|
73
74
|
} = require('../../dd-trace/src/plugins/util/test')
|
|
74
75
|
const { isMarkedAsUnskippable } = require('../../datadog-plugin-jest/src/util')
|
|
75
76
|
const { ORIGIN_KEY, COMPONENT } = require('../../dd-trace/src/constants')
|
|
@@ -787,19 +788,29 @@ class CypressPlugin {
|
|
|
787
788
|
this.frameworkVersion = getCypressVersion(details)
|
|
788
789
|
this.rootDir = getRootDir(details)
|
|
789
790
|
|
|
791
|
+
const {
|
|
792
|
+
knownTestsResponse,
|
|
793
|
+
testManagementTestsResponse,
|
|
794
|
+
skippableSuitesResponse: skippableTestsRequestResponse,
|
|
795
|
+
} = await getTestOptimizationRequestResults({
|
|
796
|
+
isKnownTestsEnabled: this.isKnownTestsEnabled,
|
|
797
|
+
isTestManagementTestsEnabled: this.isTestManagementTestsEnabled,
|
|
798
|
+
isSuitesSkippingEnabled: this.isSuitesSkippingEnabled,
|
|
799
|
+
getKnownTests: () => getKnownTests(this.tracer, this.testConfiguration),
|
|
800
|
+
getTestManagementTests: () => getTestManagementTests(this.tracer, this.testConfiguration),
|
|
801
|
+
getSkippableSuites: () => getSkippableTests(this.tracer, this.testConfiguration),
|
|
802
|
+
})
|
|
803
|
+
|
|
790
804
|
if (this.isKnownTestsEnabled) {
|
|
791
|
-
const
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
)
|
|
795
|
-
if (knownTestsResponse.err) {
|
|
796
|
-
log.error('Cypress known tests response error', knownTestsResponse.err)
|
|
805
|
+
const currentKnownTestsResponse = knownTestsResponse || await getKnownTests(this.tracer, this.testConfiguration)
|
|
806
|
+
if (currentKnownTestsResponse.err) {
|
|
807
|
+
log.error('Cypress known tests response error', currentKnownTestsResponse.err)
|
|
797
808
|
this._pendingRequestErrorTags.push({ tag: DD_CI_LIBRARY_CONFIGURATION_ERROR_KNOWN_TESTS, value: 'true' })
|
|
798
809
|
this.isEarlyFlakeDetectionEnabled = false
|
|
799
810
|
this.isKnownTestsEnabled = false
|
|
800
811
|
} else {
|
|
801
|
-
if (
|
|
802
|
-
this.knownTestsByTestSuite =
|
|
812
|
+
if (currentKnownTestsResponse.knownTests?.[TEST_FRAMEWORK_NAME]) {
|
|
813
|
+
this.knownTestsByTestSuite = currentKnownTestsResponse.knownTests[TEST_FRAMEWORK_NAME]
|
|
803
814
|
} else {
|
|
804
815
|
this.isEarlyFlakeDetectionEnabled = false
|
|
805
816
|
this.isKnownTestsEnabled = false
|
|
@@ -823,10 +834,8 @@ class CypressPlugin {
|
|
|
823
834
|
}
|
|
824
835
|
|
|
825
836
|
if (this.isSuitesSkippingEnabled) {
|
|
826
|
-
const skippableTestsResponse =
|
|
827
|
-
this.tracer,
|
|
828
|
-
this.testConfiguration
|
|
829
|
-
)
|
|
837
|
+
const skippableTestsResponse =
|
|
838
|
+
skippableTestsRequestResponse || await getSkippableTests(this.tracer, this.testConfiguration)
|
|
830
839
|
if (skippableTestsResponse.err) {
|
|
831
840
|
log.error('Cypress skippable tests response error', skippableTestsResponse.err)
|
|
832
841
|
this._pendingRequestErrorTags.push({ tag: DD_CI_LIBRARY_CONFIGURATION_ERROR_SKIPPABLE_TESTS, value: 'true' })
|
|
@@ -839,19 +848,17 @@ class CypressPlugin {
|
|
|
839
848
|
}
|
|
840
849
|
|
|
841
850
|
if (this.isTestManagementTestsEnabled) {
|
|
842
|
-
const
|
|
843
|
-
this.tracer,
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
if (testManagementTestsResponse.err) {
|
|
847
|
-
log.error('Cypress test management tests response error', testManagementTestsResponse.err)
|
|
851
|
+
const currentTestManagementTestsResponse =
|
|
852
|
+
testManagementTestsResponse || await getTestManagementTests(this.tracer, this.testConfiguration)
|
|
853
|
+
if (currentTestManagementTestsResponse.err) {
|
|
854
|
+
log.error('Cypress test management tests response error', currentTestManagementTestsResponse.err)
|
|
848
855
|
this._pendingRequestErrorTags.push({
|
|
849
856
|
tag: DD_CI_LIBRARY_CONFIGURATION_ERROR_TEST_MANAGEMENT_TESTS,
|
|
850
857
|
value: 'true',
|
|
851
858
|
})
|
|
852
859
|
this.isTestManagementTestsEnabled = false
|
|
853
860
|
} else {
|
|
854
|
-
this.testManagementTests =
|
|
861
|
+
this.testManagementTests = currentTestManagementTestsResponse.testManagementTests
|
|
855
862
|
}
|
|
856
863
|
}
|
|
857
864
|
|