dd-trace 5.110.0 → 5.111.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/README.md +13 -8
- package/ci/init.js +21 -2
- package/ci/vitest-no-worker-init-setup.mjs +430 -0
- package/ext/tags.js +2 -0
- package/index.d.ts +13 -0
- package/initialize.mjs +5 -6
- package/loader-hook.mjs +76 -55
- package/package.json +9 -9
- package/packages/datadog-instrumentations/src/fs.js +8 -6
- package/packages/datadog-instrumentations/src/graphql.js +26 -495
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/graphql.js +201 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +1 -0
- package/packages/datadog-instrumentations/src/mongoose.js +14 -2
- package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +1293 -0
- package/packages/datadog-instrumentations/src/vitest-main.js +1567 -0
- package/packages/datadog-instrumentations/src/vitest-util.js +249 -0
- package/packages/datadog-instrumentations/src/vitest-worker.js +753 -0
- package/packages/datadog-instrumentations/src/vitest.js +11 -1855
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/client.js +2 -2
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/context.js +18 -10
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/util.js +47 -11
- package/packages/datadog-plugin-cucumber/src/index.js +1 -1
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +10 -4
- package/packages/datadog-plugin-cypress/src/support.js +45 -1
- package/packages/datadog-plugin-express/src/code_origin.js +1 -1
- package/packages/datadog-plugin-fastify/src/code_origin.js +1 -1
- package/packages/datadog-plugin-graphql/src/execute.js +627 -11
- package/packages/datadog-plugin-graphql/src/index.js +20 -8
- package/packages/datadog-plugin-graphql/src/parse.js +24 -4
- package/packages/datadog-plugin-graphql/src/validate.js +16 -5
- package/packages/datadog-plugin-http/src/index.js +6 -8
- package/packages/datadog-plugin-jest/src/index.js +1 -1
- package/packages/datadog-plugin-mocha/src/index.js +1 -1
- package/packages/datadog-plugin-openai/src/services.js +2 -2
- package/packages/datadog-plugin-playwright/src/index.js +1 -1
- package/packages/datadog-plugin-vitest/src/index.js +69 -63
- package/packages/datadog-shimmer/src/shimmer.js +37 -16
- package/packages/dd-trace/src/aiguard/sdk.js +2 -2
- package/packages/dd-trace/src/appsec/api_security/sampler.js +3 -3
- package/packages/dd-trace/src/appsec/channels.js +3 -1
- package/packages/dd-trace/src/appsec/downstream_requests.js +4 -4
- package/packages/dd-trace/src/appsec/graphql.js +5 -5
- package/packages/dd-trace/src/appsec/iast/analyzers/nosql-injection-mongodb-analyzer.js +26 -19
- package/packages/dd-trace/src/appsec/iast/security-controls/index.js +2 -2
- package/packages/dd-trace/src/appsec/iast/telemetry/index.js +2 -1
- package/packages/dd-trace/src/appsec/index.js +10 -1
- package/packages/dd-trace/src/appsec/lambda.js +135 -0
- package/packages/dd-trace/src/appsec/reporter.js +49 -10
- package/packages/dd-trace/src/appsec/telemetry/index.js +1 -1
- package/packages/dd-trace/src/appsec/waf/index.js +16 -4
- package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +4 -4
- package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +21 -6
- package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +1 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +1 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/index.js +3 -2
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +1 -1
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +55 -13
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/writer.js +17 -0
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +47 -26
- package/packages/dd-trace/src/ci-visibility/log-submission/log-submission-plugin.js +2 -2
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +64 -53
- package/packages/dd-trace/src/ci-visibility/requests/upload-coverage-report.js +3 -3
- package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +23 -5
- package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache-schema.js +128 -0
- package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache.js +287 -0
- package/packages/dd-trace/src/config/defaults.js +3 -2
- package/packages/dd-trace/src/config/generated-config-types.d.ts +61 -57
- package/packages/dd-trace/src/config/helper.js +1 -0
- package/packages/dd-trace/src/config/index.js +35 -22
- package/packages/dd-trace/src/config/major-overrides.js +4 -2
- package/packages/dd-trace/src/config/remote_config.js +1 -1
- package/packages/dd-trace/src/config/supported-configurations.json +90 -56
- package/packages/dd-trace/src/constants.js +7 -0
- package/packages/dd-trace/src/datastreams/processor.js +11 -3
- package/packages/dd-trace/src/exporters/agent/index.js +1 -1
- package/packages/dd-trace/src/exporters/agentless/writer.js +4 -4
- package/packages/dd-trace/src/llmobs/index.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/base.js +4 -4
- package/packages/dd-trace/src/llmobs/plugins/langgraph/index.js +1 -1
- package/packages/dd-trace/src/llmobs/sdk.js +3 -3
- package/packages/dd-trace/src/llmobs/span_processor.js +1 -1
- package/packages/dd-trace/src/llmobs/tagger.js +3 -3
- package/packages/dd-trace/src/llmobs/writers/base.js +1 -1
- package/packages/dd-trace/src/opentelemetry/metrics/index.js +54 -5
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_exporter.js +40 -0
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_transformer.js +169 -0
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_http_exporter_base.js +38 -39
- package/packages/dd-trace/src/opentelemetry/trace/index.js +4 -0
- package/packages/dd-trace/src/opentelemetry/tracer_provider.js +1 -1
- package/packages/dd-trace/src/opentracing/tracer.js +6 -1
- package/packages/dd-trace/src/plugin_manager.js +7 -7
- package/packages/dd-trace/src/plugins/ci_plugin.js +12 -3
- package/packages/dd-trace/src/plugins/util/llm.js +6 -1
- package/packages/dd-trace/src/plugins/util/test.js +11 -9
- package/packages/dd-trace/src/profiling/exporter_cli.js +2 -2
- package/packages/dd-trace/src/profiling/exporters/event_serializer.js +3 -3
- package/packages/dd-trace/src/profiling/profilers/wall.js +1 -1
- package/packages/dd-trace/src/proxy.js +8 -8
- package/packages/dd-trace/src/span_processor.js +5 -6
- package/packages/dd-trace/src/span_stats.js +96 -78
- package/packages/dd-trace/src/startup-log.js +2 -1
- package/packages/dd-trace/src/telemetry/dependencies.js +1 -1
- package/packages/dd-trace/src/telemetry/endpoints.js +6 -4
- package/packages/dd-trace/src/telemetry/index.js +2 -2
- package/packages/dd-trace/src/telemetry/logs/index.js +1 -1
- package/packages/dd-trace/src/telemetry/send-data.js +8 -8
- package/packages/dd-trace/src/telemetry/session-propagation.js +1 -1
- package/packages/dd-trace/src/telemetry/telemetry.js +9 -9
- package/vendor/dist/@datadog/sketches-js/index.js +1 -1
- package/vendor/dist/protobufjs/index.js +1 -1
- package/vendor/dist/protobufjs/minimal/index.js +1 -1
- package/vendor/dist/shell-quote/index.js +1 -1
- package/packages/datadog-plugin-graphql/src/resolve.js +0 -170
|
@@ -7,6 +7,8 @@ const { getSkippableSuites: getSkippableSuitesRequest } = require('../intelligen
|
|
|
7
7
|
const { getKnownTests: getKnownTestsRequest } = require('../early-flake-detection/get-known-tests')
|
|
8
8
|
const { getTestManagementTests: getTestManagementTestsRequest } =
|
|
9
9
|
require('../test-management/get-test-management-tests')
|
|
10
|
+
const { writeSettingsToCache } = require('../test-optimization-cache')
|
|
11
|
+
const { CACHE_MISS, TestOptimizationHttpCache } = require('../test-optimization-http-cache')
|
|
10
12
|
const { uploadCoverageReport: uploadCoverageReportRequest } = require('../requests/upload-coverage-report')
|
|
11
13
|
const log = require('../../log')
|
|
12
14
|
const BufferingExporter = require('../../exporters/common/buffering-exporter')
|
|
@@ -42,6 +44,7 @@ class CiVisibilityExporter extends BufferingExporter {
|
|
|
42
44
|
this._coverageTimer = undefined
|
|
43
45
|
this._logsTimer = undefined
|
|
44
46
|
this._coverageBuffer = []
|
|
47
|
+
this._testOptimizationHttpCache = new TestOptimizationHttpCache()
|
|
45
48
|
// The library can use new features like ITR and test suite level visibility
|
|
46
49
|
// AKA CI Vis Protocol
|
|
47
50
|
this._canUseCiVisProtocol = false
|
|
@@ -86,7 +89,7 @@ class CiVisibilityExporter extends BufferingExporter {
|
|
|
86
89
|
}
|
|
87
90
|
|
|
88
91
|
shouldRequestSkippableSuites () {
|
|
89
|
-
return !!(this._config.
|
|
92
|
+
return !!(this._config.testOptimization.DD_CIVISIBILITY_ITR_ENABLED &&
|
|
90
93
|
this._canUseCiVisProtocol &&
|
|
91
94
|
this._libraryConfig?.isSuitesSkippingEnabled)
|
|
92
95
|
}
|
|
@@ -101,7 +104,7 @@ class CiVisibilityExporter extends BufferingExporter {
|
|
|
101
104
|
shouldRequestTestManagementTests () {
|
|
102
105
|
return !!(
|
|
103
106
|
this._canUseCiVisProtocol &&
|
|
104
|
-
this._config.
|
|
107
|
+
this._config.testOptimization.DD_TEST_MANAGEMENT_ENABLED &&
|
|
105
108
|
this._libraryConfig?.isTestManagementEnabled
|
|
106
109
|
)
|
|
107
110
|
}
|
|
@@ -133,11 +136,21 @@ class CiVisibilityExporter extends BufferingExporter {
|
|
|
133
136
|
if (!this.shouldRequestSkippableSuites()) {
|
|
134
137
|
return callback(null, [])
|
|
135
138
|
}
|
|
139
|
+
const requestConfiguration = this.getRequestConfiguration(testConfiguration)
|
|
140
|
+
const cachedSkippableSuites = this._testOptimizationHttpCache.readSkippableSuites({
|
|
141
|
+
testLevel: requestConfiguration.testLevel,
|
|
142
|
+
isCoverageReportUploadEnabled: requestConfiguration.isCoverageReportUploadEnabled,
|
|
143
|
+
})
|
|
144
|
+
if (cachedSkippableSuites !== CACHE_MISS) {
|
|
145
|
+
const { skippableSuites, correlationId, coverage } = cachedSkippableSuites
|
|
146
|
+
return callback(null, skippableSuites, correlationId, coverage)
|
|
147
|
+
}
|
|
148
|
+
|
|
136
149
|
this._gitUploadPromise.then(gitUploadError => {
|
|
137
150
|
if (gitUploadError) {
|
|
138
151
|
return callback(gitUploadError, [])
|
|
139
152
|
}
|
|
140
|
-
getSkippableSuitesRequest(
|
|
153
|
+
getSkippableSuitesRequest(requestConfiguration, callback)
|
|
141
154
|
})
|
|
142
155
|
}
|
|
143
156
|
|
|
@@ -145,6 +158,10 @@ class CiVisibilityExporter extends BufferingExporter {
|
|
|
145
158
|
if (!this.shouldRequestKnownTests()) {
|
|
146
159
|
return callback(null)
|
|
147
160
|
}
|
|
161
|
+
const cachedKnownTests = this._testOptimizationHttpCache.readKnownTests()
|
|
162
|
+
if (cachedKnownTests !== CACHE_MISS) {
|
|
163
|
+
return callback(null, cachedKnownTests)
|
|
164
|
+
}
|
|
148
165
|
getKnownTestsRequest(this.getRequestConfiguration(testConfiguration), callback)
|
|
149
166
|
}
|
|
150
167
|
|
|
@@ -152,6 +169,10 @@ class CiVisibilityExporter extends BufferingExporter {
|
|
|
152
169
|
if (!this.shouldRequestTestManagementTests()) {
|
|
153
170
|
return callback(null)
|
|
154
171
|
}
|
|
172
|
+
const cachedTestManagementTests = this._testOptimizationHttpCache.readTestManagementTests()
|
|
173
|
+
if (cachedTestManagementTests !== CACHE_MISS) {
|
|
174
|
+
return callback(null, cachedTestManagementTests)
|
|
175
|
+
}
|
|
155
176
|
getTestManagementTestsRequest(this.getRequestConfiguration(testConfiguration), callback)
|
|
156
177
|
}
|
|
157
178
|
|
|
@@ -161,13 +182,30 @@ class CiVisibilityExporter extends BufferingExporter {
|
|
|
161
182
|
*/
|
|
162
183
|
getLibraryConfiguration (testConfiguration, callback) {
|
|
163
184
|
const { repositoryUrl } = testConfiguration
|
|
164
|
-
this.sendGitMetadata(repositoryUrl)
|
|
165
185
|
this._canUseCiVisProtocolPromise.then((canUseCiVisProtocol) => {
|
|
166
186
|
if (!canUseCiVisProtocol) {
|
|
167
187
|
return callback(null, {})
|
|
168
188
|
}
|
|
169
189
|
const configuration = this.getRequestConfiguration(testConfiguration)
|
|
190
|
+
const cachedLibraryConfig = this._testOptimizationHttpCache.readSettings()
|
|
191
|
+
if (cachedLibraryConfig !== CACHE_MISS) {
|
|
192
|
+
log.debug('Test Optimization HTTP cache settings found, skipping settings request')
|
|
193
|
+
writeSettingsToCache(cachedLibraryConfig)
|
|
194
|
+
this._libraryConfig = this.filterConfiguration(cachedLibraryConfig)
|
|
195
|
+
const canUseCachedSkippableSuites = !this.shouldRequestSkippableSuites() ||
|
|
196
|
+
this._testOptimizationHttpCache.hasValidSkippableSuites({
|
|
197
|
+
testLevel: configuration.testLevel,
|
|
198
|
+
isCoverageReportUploadEnabled: configuration.isCoverageReportUploadEnabled,
|
|
199
|
+
})
|
|
200
|
+
if (this._libraryConfig.requireGit && !canUseCachedSkippableSuites) {
|
|
201
|
+
this.sendGitMetadata(repositoryUrl)
|
|
202
|
+
} else {
|
|
203
|
+
this._resolveGit()
|
|
204
|
+
}
|
|
205
|
+
return callback(null, this._libraryConfig)
|
|
206
|
+
}
|
|
170
207
|
|
|
208
|
+
this.sendGitMetadata(repositoryUrl)
|
|
171
209
|
getLibraryConfigurationRequest(configuration, (err, libraryConfig) => {
|
|
172
210
|
/**
|
|
173
211
|
* **Important**: this._libraryConfig remains empty in testing frameworks
|
|
@@ -218,29 +256,32 @@ class CiVisibilityExporter extends BufferingExporter {
|
|
|
218
256
|
isImpactedTestsEnabled,
|
|
219
257
|
isCoverageReportUploadEnabled,
|
|
220
258
|
} = remoteConfiguration
|
|
259
|
+
const { testOptimization } = this._config
|
|
221
260
|
return {
|
|
222
261
|
isCodeCoverageEnabled,
|
|
223
262
|
isSuitesSkippingEnabled,
|
|
224
263
|
isItrEnabled,
|
|
225
264
|
requireGit,
|
|
226
|
-
isEarlyFlakeDetectionEnabled:
|
|
265
|
+
isEarlyFlakeDetectionEnabled:
|
|
266
|
+
isEarlyFlakeDetectionEnabled && testOptimization.DD_CIVISIBILITY_EARLY_FLAKE_DETECTION_ENABLED,
|
|
227
267
|
earlyFlakeDetectionNumRetries,
|
|
228
268
|
earlyFlakeDetectionSlowTestRetries,
|
|
229
269
|
earlyFlakeDetectionFaultyThreshold,
|
|
230
|
-
isFlakyTestRetriesEnabled: isFlakyTestRetriesEnabled &&
|
|
231
|
-
flakyTestRetriesCount:
|
|
232
|
-
isDiEnabled: isDiEnabled &&
|
|
270
|
+
isFlakyTestRetriesEnabled: isFlakyTestRetriesEnabled && testOptimization.DD_CIVISIBILITY_FLAKY_RETRY_ENABLED,
|
|
271
|
+
flakyTestRetriesCount: testOptimization.DD_CIVISIBILITY_FLAKY_RETRY_COUNT,
|
|
272
|
+
isDiEnabled: isDiEnabled && testOptimization.DD_TEST_FAILED_TEST_REPLAY_ENABLED,
|
|
233
273
|
isKnownTestsEnabled,
|
|
234
|
-
isTestManagementEnabled: isTestManagementEnabled &&
|
|
274
|
+
isTestManagementEnabled: isTestManagementEnabled && testOptimization.DD_TEST_MANAGEMENT_ENABLED,
|
|
235
275
|
testManagementAttemptToFixRetries:
|
|
236
|
-
testManagementAttemptToFixRetries ??
|
|
237
|
-
isImpactedTestsEnabled:
|
|
276
|
+
testManagementAttemptToFixRetries ?? testOptimization.DD_TEST_MANAGEMENT_ATTEMPT_TO_FIX_RETRIES,
|
|
277
|
+
isImpactedTestsEnabled:
|
|
278
|
+
isImpactedTestsEnabled && testOptimization.DD_CIVISIBILITY_IMPACTED_TESTS_DETECTION_ENABLED,
|
|
238
279
|
isCoverageReportUploadEnabled,
|
|
239
280
|
}
|
|
240
281
|
}
|
|
241
282
|
|
|
242
283
|
sendGitMetadata (repositoryUrl) {
|
|
243
|
-
if (!this._config.
|
|
284
|
+
if (!this._config.testOptimization.DD_CIVISIBILITY_GIT_UPLOAD_ENABLED) {
|
|
244
285
|
return
|
|
245
286
|
}
|
|
246
287
|
this._canUseCiVisProtocolPromise.then((canUseCiVisProtocol) => {
|
|
@@ -318,7 +359,8 @@ class CiVisibilityExporter extends BufferingExporter {
|
|
|
318
359
|
// DI logs
|
|
319
360
|
exportDiLogs (testEnvironmentMetadata, logMessage) {
|
|
320
361
|
// TODO: could we lose logs if it's not initialized?
|
|
321
|
-
if (!this._config.
|
|
362
|
+
if (!this._config.testOptimization.DD_TEST_FAILED_TEST_REPLAY_ENABLED ||
|
|
363
|
+
!this._isInitialized || !this._canForwardLogs) {
|
|
322
364
|
return
|
|
323
365
|
}
|
|
324
366
|
|
|
@@ -50,7 +50,7 @@ function getCommonRequestOptions (url) {
|
|
|
50
50
|
return {
|
|
51
51
|
method: 'POST',
|
|
52
52
|
headers: {
|
|
53
|
-
'dd-api-key': getConfig().
|
|
53
|
+
'dd-api-key': getConfig().DD_API_KEY,
|
|
54
54
|
},
|
|
55
55
|
timeout: 15_000,
|
|
56
56
|
url,
|
|
@@ -287,7 +287,7 @@ function sendGitMetadata (url, { isEvpProxy, evpProxyPrefix }, configRepositoryU
|
|
|
287
287
|
}
|
|
288
288
|
// Otherwise we unshallow and get commits to upload again
|
|
289
289
|
log.debug('It is shallow clone, unshallowing...')
|
|
290
|
-
if (getConfig().DD_CIVISIBILITY_GIT_UNSHALLOW_ENABLED) {
|
|
290
|
+
if (getConfig().testOptimization.DD_CIVISIBILITY_GIT_UNSHALLOW_ENABLED) {
|
|
291
291
|
unshallowRepository(false)
|
|
292
292
|
}
|
|
293
293
|
|
|
@@ -3,6 +3,11 @@ const { JSONEncoder } = require('../../encode/json-encoder')
|
|
|
3
3
|
const { getEnvironmentVariable } = require('../../../config/helper')
|
|
4
4
|
const log = require('../../../log')
|
|
5
5
|
|
|
6
|
+
function getVitestWorkerPort () {
|
|
7
|
+
const port = globalThis.__vitest_worker__?.ctx?.port
|
|
8
|
+
return typeof port?.postMessage === 'function' ? port : undefined
|
|
9
|
+
}
|
|
10
|
+
|
|
6
11
|
class Writer {
|
|
7
12
|
constructor (interprocessCode) {
|
|
8
13
|
this._encoder = new JSONEncoder()
|
|
@@ -37,6 +42,18 @@ class Writer {
|
|
|
37
42
|
? { __tinypool_worker_message__: true, interprocessCode: this._interprocessCode, data }
|
|
38
43
|
: [this._interprocessCode, data]
|
|
39
44
|
|
|
45
|
+
const vitestWorkerPort = getVitestWorkerPort()
|
|
46
|
+
if (vitestWorkerPort) {
|
|
47
|
+
try {
|
|
48
|
+
vitestWorkerPort.postMessage(payload)
|
|
49
|
+
} catch (error) {
|
|
50
|
+
log.error('Error posting message to vitest worker port', error)
|
|
51
|
+
} finally {
|
|
52
|
+
onDone()
|
|
53
|
+
}
|
|
54
|
+
return
|
|
55
|
+
}
|
|
56
|
+
|
|
40
57
|
// child_process workers (jest default, cucumber)
|
|
41
58
|
if (process.send) {
|
|
42
59
|
process.send(payload, () => {
|
|
@@ -14,6 +14,42 @@ const {
|
|
|
14
14
|
TELEMETRY_ITR_SKIPPABLE_TESTS_RESPONSE_BYTES,
|
|
15
15
|
} = require('../../ci-visibility/telemetry')
|
|
16
16
|
const { buildCacheKey, writeToCache, withCache } = require('../requests/fs-cache')
|
|
17
|
+
const { validateSkippableTestsResponse } = require('../test-optimization-http-cache-schema')
|
|
18
|
+
|
|
19
|
+
function parseJsonResponse (rawJson) {
|
|
20
|
+
return typeof rawJson === 'string' ? JSON.parse(rawJson) : rawJson
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function parseSkippableSuitesResponse (
|
|
24
|
+
rawJson,
|
|
25
|
+
{ testLevel = 'suite', isCoverageReportUploadEnabled = false, validateRequiredFields = false } = {}
|
|
26
|
+
) {
|
|
27
|
+
const parsedResponse = parseJsonResponse(rawJson)
|
|
28
|
+
if (validateRequiredFields) {
|
|
29
|
+
validateSkippableTestsResponse(parsedResponse)
|
|
30
|
+
}
|
|
31
|
+
const coverage = parsedResponse.meta?.coverage || {}
|
|
32
|
+
|
|
33
|
+
const skippableItems = parsedResponse
|
|
34
|
+
.data
|
|
35
|
+
.filter(({ type }) => type === testLevel)
|
|
36
|
+
const skippableSuites = []
|
|
37
|
+
for (const {
|
|
38
|
+
attributes: {
|
|
39
|
+
suite,
|
|
40
|
+
name,
|
|
41
|
+
_is_missing_line_code_coverage: isMissingLineCodeCoverage,
|
|
42
|
+
},
|
|
43
|
+
} of skippableItems) {
|
|
44
|
+
// Only reject candidates without backend line coverage when we need that coverage to backfill reports.
|
|
45
|
+
if (isCoverageReportUploadEnabled && isMissingLineCodeCoverage) continue
|
|
46
|
+
|
|
47
|
+
skippableSuites.push(testLevel === 'suite' ? suite : { suite, name })
|
|
48
|
+
}
|
|
49
|
+
const correlationId = parsedResponse.meta?.correlation_id
|
|
50
|
+
|
|
51
|
+
return { skippableSuites, correlationId, coverage }
|
|
52
|
+
}
|
|
17
53
|
|
|
18
54
|
function getSkippableSuites ({
|
|
19
55
|
url,
|
|
@@ -124,12 +160,12 @@ function fetchFromApi ({
|
|
|
124
160
|
options.path = `${evpProxyPrefix}/api/v2/ci/tests/skippable`
|
|
125
161
|
options.headers['X-Datadog-EVP-Subdomain'] = 'api'
|
|
126
162
|
} else {
|
|
127
|
-
const {
|
|
128
|
-
if (!
|
|
163
|
+
const { DD_API_KEY } = getConfig()
|
|
164
|
+
if (!DD_API_KEY) {
|
|
129
165
|
return done(new Error('Skippable suites were not fetched because Datadog API key is not defined.'))
|
|
130
166
|
}
|
|
131
167
|
|
|
132
|
-
options.headers['dd-api-key'] =
|
|
168
|
+
options.headers['dd-api-key'] = DD_API_KEY
|
|
133
169
|
}
|
|
134
170
|
|
|
135
171
|
const data = JSON.stringify({
|
|
@@ -163,26 +199,12 @@ function fetchFromApi ({
|
|
|
163
199
|
done(err)
|
|
164
200
|
} else {
|
|
165
201
|
try {
|
|
166
|
-
const parsedResponse =
|
|
167
|
-
const
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
const skippableSuites = []
|
|
173
|
-
for (const {
|
|
174
|
-
attributes: {
|
|
175
|
-
suite,
|
|
176
|
-
name,
|
|
177
|
-
_is_missing_line_code_coverage: isMissingLineCodeCoverage,
|
|
178
|
-
},
|
|
179
|
-
} of skippableItems) {
|
|
180
|
-
// Only reject candidates without backend line coverage when we need that coverage to backfill reports.
|
|
181
|
-
if (isCoverageReportUploadEnabled && isMissingLineCodeCoverage) continue
|
|
182
|
-
|
|
183
|
-
skippableSuites.push(testLevel === 'suite' ? suite : { suite, name })
|
|
184
|
-
}
|
|
185
|
-
const correlationId = parsedResponse.meta?.correlation_id
|
|
202
|
+
const parsedResponse = parseJsonResponse(res)
|
|
203
|
+
const result = parseSkippableSuitesResponse(parsedResponse, {
|
|
204
|
+
testLevel,
|
|
205
|
+
isCoverageReportUploadEnabled,
|
|
206
|
+
})
|
|
207
|
+
const skippableItems = parsedResponse.data.filter(({ type }) => type === testLevel)
|
|
186
208
|
incrementCountMetric(
|
|
187
209
|
testLevel === 'test'
|
|
188
210
|
? TELEMETRY_ITR_SKIPPABLE_TESTS_RESPONSE_TESTS
|
|
@@ -191,9 +213,8 @@ function fetchFromApi ({
|
|
|
191
213
|
skippableItems.length
|
|
192
214
|
)
|
|
193
215
|
distributionMetric(TELEMETRY_ITR_SKIPPABLE_TESTS_RESPONSE_BYTES, {}, res.length)
|
|
194
|
-
log.debug('Number of received skippable %ss:', testLevel, skippableSuites.length)
|
|
216
|
+
log.debug('Number of received skippable %ss:', testLevel, result.skippableSuites.length)
|
|
195
217
|
|
|
196
|
-
const result = { skippableSuites, correlationId, coverage }
|
|
197
218
|
writeToCache(cacheKey, result)
|
|
198
219
|
|
|
199
220
|
done(null, result)
|
|
@@ -204,4 +225,4 @@ function fetchFromApi ({
|
|
|
204
225
|
})
|
|
205
226
|
}
|
|
206
227
|
|
|
207
|
-
module.exports = { getSkippableSuites }
|
|
228
|
+
module.exports = { getSkippableSuites, parseSkippableSuitesResponse }
|
|
@@ -4,14 +4,14 @@ const Plugin = require('../../plugins/plugin')
|
|
|
4
4
|
const log = require('../../log')
|
|
5
5
|
|
|
6
6
|
function getWinstonLogSubmissionParameters (config) {
|
|
7
|
-
const { site, service,
|
|
7
|
+
const { site, service, DD_API_KEY, DD_AGENTLESS_LOG_SUBMISSION_URL } = config
|
|
8
8
|
|
|
9
9
|
const defaultParameters = {
|
|
10
10
|
host: `http-intake.logs.${site}`,
|
|
11
11
|
path: `/api/v2/logs?ddsource=winston&service=${service}`,
|
|
12
12
|
ssl: true,
|
|
13
13
|
headers: {
|
|
14
|
-
'DD-API-KEY':
|
|
14
|
+
'DD-API-KEY': DD_API_KEY,
|
|
15
15
|
},
|
|
16
16
|
}
|
|
17
17
|
|
|
@@ -12,12 +12,72 @@ const {
|
|
|
12
12
|
TELEMETRY_GIT_REQUESTS_SETTINGS_RESPONSE,
|
|
13
13
|
} = require('../telemetry')
|
|
14
14
|
const { writeSettingsToCache } = require('../test-optimization-cache')
|
|
15
|
+
const { validateSettingsResponse } = require('../test-optimization-http-cache-schema')
|
|
15
16
|
const request = require('./request')
|
|
16
17
|
|
|
17
18
|
const DEFAULT_EARLY_FLAKE_DETECTION_NUM_RETRIES = 2
|
|
18
19
|
const DEFAULT_EARLY_FLAKE_DETECTION_SLOW_TEST_RETRIES = { '5s': 10, '10s': 5, '30s': 3, '5m': 2 }
|
|
19
20
|
const DEFAULT_EARLY_FLAKE_DETECTION_ERROR_THRESHOLD = 30
|
|
20
21
|
|
|
22
|
+
function parseJsonResponse (rawJson) {
|
|
23
|
+
return typeof rawJson === 'string' ? JSON.parse(rawJson) : rawJson
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function parseLibraryConfigurationResponse (rawJson, config = getConfig(), options = {}) {
|
|
27
|
+
const parsedResponse = parseJsonResponse(rawJson)
|
|
28
|
+
if (options.validateRequiredFields) {
|
|
29
|
+
validateSettingsResponse(parsedResponse)
|
|
30
|
+
}
|
|
31
|
+
const {
|
|
32
|
+
code_coverage: isCodeCoverageEnabled,
|
|
33
|
+
tests_skipping: isSuitesSkippingEnabled,
|
|
34
|
+
itr_enabled: isItrEnabled,
|
|
35
|
+
require_git: requireGit,
|
|
36
|
+
early_flake_detection: earlyFlakeDetectionConfig,
|
|
37
|
+
flaky_test_retries_enabled: isFlakyTestRetriesEnabled,
|
|
38
|
+
di_enabled: isDiEnabled,
|
|
39
|
+
known_tests_enabled: isKnownTestsEnabled,
|
|
40
|
+
test_management: testManagementConfig,
|
|
41
|
+
impacted_tests_enabled: isImpactedTestsEnabled,
|
|
42
|
+
coverage_report_upload_enabled: isCoverageReportUploadEnabled,
|
|
43
|
+
} = parsedResponse?.data?.attributes ?? parsedResponse
|
|
44
|
+
|
|
45
|
+
const settings = {
|
|
46
|
+
isCodeCoverageEnabled,
|
|
47
|
+
isSuitesSkippingEnabled,
|
|
48
|
+
isItrEnabled,
|
|
49
|
+
requireGit,
|
|
50
|
+
isEarlyFlakeDetectionEnabled: isKnownTestsEnabled && (earlyFlakeDetectionConfig?.enabled ?? false),
|
|
51
|
+
earlyFlakeDetectionNumRetries:
|
|
52
|
+
earlyFlakeDetectionConfig?.slow_test_retries?.['5s'] || DEFAULT_EARLY_FLAKE_DETECTION_NUM_RETRIES,
|
|
53
|
+
earlyFlakeDetectionSlowTestRetries:
|
|
54
|
+
earlyFlakeDetectionConfig?.slow_test_retries ?? DEFAULT_EARLY_FLAKE_DETECTION_SLOW_TEST_RETRIES,
|
|
55
|
+
earlyFlakeDetectionFaultyThreshold:
|
|
56
|
+
earlyFlakeDetectionConfig?.faulty_session_threshold ?? DEFAULT_EARLY_FLAKE_DETECTION_ERROR_THRESHOLD,
|
|
57
|
+
isFlakyTestRetriesEnabled,
|
|
58
|
+
isDiEnabled: isDiEnabled && isFlakyTestRetriesEnabled,
|
|
59
|
+
isKnownTestsEnabled,
|
|
60
|
+
isTestManagementEnabled: (testManagementConfig?.enabled ?? false),
|
|
61
|
+
testManagementAttemptToFixRetries:
|
|
62
|
+
testManagementConfig?.attempt_to_fix_retries,
|
|
63
|
+
isImpactedTestsEnabled,
|
|
64
|
+
isCoverageReportUploadEnabled: isCoverageReportUploadEnabled ?? false,
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
log.debug('Remote settings: %j', settings)
|
|
68
|
+
|
|
69
|
+
if (config.testOptimization.DD_CIVISIBILITY_DANGEROUSLY_FORCE_COVERAGE) {
|
|
70
|
+
settings.isCodeCoverageEnabled = true
|
|
71
|
+
log.debug('Dangerously set code coverage to true')
|
|
72
|
+
}
|
|
73
|
+
if (config.testOptimization.DD_CIVISIBILITY_DANGEROUSLY_FORCE_TEST_SKIPPING) {
|
|
74
|
+
settings.isSuitesSkippingEnabled = true
|
|
75
|
+
log.debug('Dangerously set test skipping to true')
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return settings
|
|
79
|
+
}
|
|
80
|
+
|
|
21
81
|
function getLibraryConfiguration ({
|
|
22
82
|
url,
|
|
23
83
|
isEvpProxy,
|
|
@@ -51,10 +111,10 @@ function getLibraryConfiguration ({
|
|
|
51
111
|
options.path = `${evpProxyPrefix}/api/v2/libraries/tests/services/setting`
|
|
52
112
|
options.headers['X-Datadog-EVP-Subdomain'] = 'api'
|
|
53
113
|
} else {
|
|
54
|
-
if (!config.
|
|
114
|
+
if (!config.DD_API_KEY) {
|
|
55
115
|
return done(new Error('Request to settings endpoint was not done because Datadog API key is not defined.'))
|
|
56
116
|
}
|
|
57
|
-
options.headers['dd-api-key'] = config.
|
|
117
|
+
options.headers['dd-api-key'] = config.DD_API_KEY
|
|
58
118
|
}
|
|
59
119
|
|
|
60
120
|
const data = JSON.stringify({
|
|
@@ -90,56 +150,7 @@ function getLibraryConfiguration ({
|
|
|
90
150
|
done(err)
|
|
91
151
|
} else {
|
|
92
152
|
try {
|
|
93
|
-
const
|
|
94
|
-
data: {
|
|
95
|
-
attributes: {
|
|
96
|
-
code_coverage: isCodeCoverageEnabled,
|
|
97
|
-
tests_skipping: isSuitesSkippingEnabled,
|
|
98
|
-
itr_enabled: isItrEnabled,
|
|
99
|
-
require_git: requireGit,
|
|
100
|
-
early_flake_detection: earlyFlakeDetectionConfig,
|
|
101
|
-
flaky_test_retries_enabled: isFlakyTestRetriesEnabled,
|
|
102
|
-
di_enabled: isDiEnabled,
|
|
103
|
-
known_tests_enabled: isKnownTestsEnabled,
|
|
104
|
-
test_management: testManagementConfig,
|
|
105
|
-
impacted_tests_enabled: isImpactedTestsEnabled,
|
|
106
|
-
coverage_report_upload_enabled: isCoverageReportUploadEnabled,
|
|
107
|
-
},
|
|
108
|
-
},
|
|
109
|
-
} = JSON.parse(res)
|
|
110
|
-
|
|
111
|
-
const settings = {
|
|
112
|
-
isCodeCoverageEnabled,
|
|
113
|
-
isSuitesSkippingEnabled,
|
|
114
|
-
isItrEnabled,
|
|
115
|
-
requireGit,
|
|
116
|
-
isEarlyFlakeDetectionEnabled: isKnownTestsEnabled && (earlyFlakeDetectionConfig?.enabled ?? false),
|
|
117
|
-
earlyFlakeDetectionNumRetries:
|
|
118
|
-
earlyFlakeDetectionConfig?.slow_test_retries?.['5s'] || DEFAULT_EARLY_FLAKE_DETECTION_NUM_RETRIES,
|
|
119
|
-
earlyFlakeDetectionSlowTestRetries:
|
|
120
|
-
earlyFlakeDetectionConfig?.slow_test_retries ?? DEFAULT_EARLY_FLAKE_DETECTION_SLOW_TEST_RETRIES,
|
|
121
|
-
earlyFlakeDetectionFaultyThreshold:
|
|
122
|
-
earlyFlakeDetectionConfig?.faulty_session_threshold ?? DEFAULT_EARLY_FLAKE_DETECTION_ERROR_THRESHOLD,
|
|
123
|
-
isFlakyTestRetriesEnabled,
|
|
124
|
-
isDiEnabled: isDiEnabled && isFlakyTestRetriesEnabled,
|
|
125
|
-
isKnownTestsEnabled,
|
|
126
|
-
isTestManagementEnabled: (testManagementConfig?.enabled ?? false),
|
|
127
|
-
testManagementAttemptToFixRetries:
|
|
128
|
-
testManagementConfig?.attempt_to_fix_retries,
|
|
129
|
-
isImpactedTestsEnabled,
|
|
130
|
-
isCoverageReportUploadEnabled: isCoverageReportUploadEnabled ?? false,
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
log.debug('Remote settings: %j', settings)
|
|
134
|
-
|
|
135
|
-
if (config.DD_CIVISIBILITY_DANGEROUSLY_FORCE_COVERAGE) {
|
|
136
|
-
settings.isCodeCoverageEnabled = true
|
|
137
|
-
log.debug('Dangerously set code coverage to true')
|
|
138
|
-
}
|
|
139
|
-
if (config.DD_CIVISIBILITY_DANGEROUSLY_FORCE_TEST_SKIPPING) {
|
|
140
|
-
settings.isSuitesSkippingEnabled = true
|
|
141
|
-
log.debug('Dangerously set test skipping to true')
|
|
142
|
-
}
|
|
153
|
+
const settings = parseLibraryConfigurationResponse(res, config)
|
|
143
154
|
|
|
144
155
|
incrementCountMetric(TELEMETRY_GIT_REQUESTS_SETTINGS_RESPONSE, settings)
|
|
145
156
|
|
|
@@ -153,4 +164,4 @@ function getLibraryConfiguration ({
|
|
|
153
164
|
})
|
|
154
165
|
}
|
|
155
166
|
|
|
156
|
-
module.exports = { getLibraryConfiguration }
|
|
167
|
+
module.exports = { getLibraryConfiguration, parseLibraryConfigurationResponse }
|
|
@@ -34,9 +34,9 @@ function uploadCoverageReport (
|
|
|
34
34
|
{ filePath, format, testEnvironmentMetadata, url, isEvpProxy, evpProxyPrefix },
|
|
35
35
|
callback
|
|
36
36
|
) {
|
|
37
|
-
const
|
|
37
|
+
const { DD_API_KEY } = getConfig()
|
|
38
38
|
|
|
39
|
-
if (!
|
|
39
|
+
if (!DD_API_KEY && !isEvpProxy) {
|
|
40
40
|
return callback(new Error('DD_API_KEY is required for coverage report upload'))
|
|
41
41
|
}
|
|
42
42
|
|
|
@@ -82,7 +82,7 @@ function uploadCoverageReport (
|
|
|
82
82
|
options.headers['X-Datadog-EVP-Subdomain'] = 'ci-intake'
|
|
83
83
|
} else {
|
|
84
84
|
options.path = '/api/v2/cicovreprt'
|
|
85
|
-
options.headers['dd-api-key'] =
|
|
85
|
+
options.headers['dd-api-key'] = DD_API_KEY
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
log.debug('Uploading coverage report %s to %s%s', filePath, url, options.path)
|
|
@@ -16,6 +16,7 @@ const {
|
|
|
16
16
|
} = require('../telemetry')
|
|
17
17
|
|
|
18
18
|
const { buildCacheKey, writeToCache, withCache } = require('../requests/fs-cache')
|
|
19
|
+
const { validateTestManagementTestsResponse } = require('../test-optimization-http-cache-schema')
|
|
19
20
|
|
|
20
21
|
// Calculate the number of tests from the test management tests response, which has a shape like:
|
|
21
22
|
// { module: { suites: { suite: { tests: { testName: { properties: {...} } } } } } }
|
|
@@ -39,6 +40,19 @@ function getNumFromTestManagementTests (testManagementTests) {
|
|
|
39
40
|
return totalNumTests
|
|
40
41
|
}
|
|
41
42
|
|
|
43
|
+
function parseJsonResponse (rawJson) {
|
|
44
|
+
return typeof rawJson === 'string' ? JSON.parse(rawJson) : rawJson
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function parseTestManagementTestsResponse (rawJson, options = {}) {
|
|
48
|
+
const parsedResponse = parseJsonResponse(rawJson)
|
|
49
|
+
if (options.validateRequiredFields) {
|
|
50
|
+
validateTestManagementTestsResponse(parsedResponse)
|
|
51
|
+
}
|
|
52
|
+
const { data: { attributes: { modules: testManagementTests } } } = parsedResponse
|
|
53
|
+
return testManagementTests
|
|
54
|
+
}
|
|
55
|
+
|
|
42
56
|
function getTestManagementTests ({
|
|
43
57
|
url,
|
|
44
58
|
isEvpProxy,
|
|
@@ -121,12 +135,12 @@ function fetchFromApi ({
|
|
|
121
135
|
options.path = `${evpProxyPrefix}/api/v2/test/libraries/test-management/tests`
|
|
122
136
|
options.headers['X-Datadog-EVP-Subdomain'] = 'api'
|
|
123
137
|
} else {
|
|
124
|
-
const {
|
|
125
|
-
if (!
|
|
138
|
+
const { DD_API_KEY } = getConfig()
|
|
139
|
+
if (!DD_API_KEY) {
|
|
126
140
|
return done(new Error('Test management tests were not fetched because Datadog API key is not defined.'))
|
|
127
141
|
}
|
|
128
142
|
|
|
129
|
-
options.headers['dd-api-key'] =
|
|
143
|
+
options.headers['dd-api-key'] = DD_API_KEY
|
|
130
144
|
}
|
|
131
145
|
|
|
132
146
|
const data = JSON.stringify({
|
|
@@ -155,7 +169,7 @@ function fetchFromApi ({
|
|
|
155
169
|
done(err)
|
|
156
170
|
} else {
|
|
157
171
|
try {
|
|
158
|
-
const
|
|
172
|
+
const testManagementTests = parseTestManagementTestsResponse(res)
|
|
159
173
|
|
|
160
174
|
const numTests = getNumFromTestManagementTests(testManagementTests)
|
|
161
175
|
|
|
@@ -174,4 +188,8 @@ function fetchFromApi ({
|
|
|
174
188
|
})
|
|
175
189
|
}
|
|
176
190
|
|
|
177
|
-
module.exports = {
|
|
191
|
+
module.exports = {
|
|
192
|
+
getNumFromTestManagementTests, // Exported for later use in the cache
|
|
193
|
+
getTestManagementTests,
|
|
194
|
+
parseTestManagementTestsResponse,
|
|
195
|
+
}
|