dd-trace 5.110.0 → 5.112.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 (164) hide show
  1. package/LICENSE-3rdparty.csv +1 -2
  2. package/README.md +13 -8
  3. package/ci/init.js +21 -2
  4. package/ci/vitest-no-worker-init-setup.mjs +430 -0
  5. package/ext/tags.js +2 -0
  6. package/index.d.ts +34 -1
  7. package/initialize.mjs +5 -6
  8. package/loader-hook.mjs +76 -55
  9. package/package.json +37 -34
  10. package/packages/datadog-instrumentations/src/ai.js +45 -0
  11. package/packages/datadog-instrumentations/src/apollo-server.js +5 -13
  12. package/packages/datadog-instrumentations/src/child_process.js +3 -3
  13. package/packages/datadog-instrumentations/src/claude-agent-sdk.js +587 -0
  14. package/packages/datadog-instrumentations/src/cucumber.js +102 -43
  15. package/packages/datadog-instrumentations/src/cypress-config.js +11 -3
  16. package/packages/datadog-instrumentations/src/fastify.js +27 -8
  17. package/packages/datadog-instrumentations/src/fs.js +8 -6
  18. package/packages/datadog-instrumentations/src/graphql.js +26 -495
  19. package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
  20. package/packages/datadog-instrumentations/src/helpers/instrument.js +7 -0
  21. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/ai.js +6 -6
  22. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/claude-agent-sdk.js +17 -0
  23. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/graphql.js +201 -0
  24. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +2 -0
  25. package/packages/datadog-instrumentations/src/jest.js +713 -63
  26. package/packages/datadog-instrumentations/src/mocha/main.js +24 -3
  27. package/packages/datadog-instrumentations/src/mocha/utils.js +128 -22
  28. package/packages/datadog-instrumentations/src/mocha/worker.js +13 -0
  29. package/packages/datadog-instrumentations/src/mongodb.js +74 -0
  30. package/packages/datadog-instrumentations/src/mongoose.js +13 -2
  31. package/packages/datadog-instrumentations/src/playwright.js +13 -9
  32. package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +1297 -0
  33. package/packages/datadog-instrumentations/src/vitest-main.js +1594 -0
  34. package/packages/datadog-instrumentations/src/vitest-util.js +254 -0
  35. package/packages/datadog-instrumentations/src/vitest-worker.js +823 -0
  36. package/packages/datadog-instrumentations/src/vitest.js +11 -1855
  37. package/packages/datadog-plugin-ai/src/index.js +1 -1
  38. package/packages/datadog-plugin-ai/src/tracing.js +66 -3
  39. package/packages/datadog-plugin-ai/src/utils.js +17 -4
  40. package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/client.js +2 -2
  41. package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/context.js +19 -10
  42. package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/handler.js +1 -0
  43. package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/util.js +47 -11
  44. package/packages/datadog-plugin-child_process/src/index.js +13 -2
  45. package/packages/datadog-plugin-claude-agent-sdk/src/index.js +31 -0
  46. package/packages/datadog-plugin-claude-agent-sdk/src/tracing.js +107 -0
  47. package/packages/datadog-plugin-claude-agent-sdk/src/util.js +15 -0
  48. package/packages/datadog-plugin-cucumber/src/index.js +15 -24
  49. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +360 -14
  50. package/packages/datadog-plugin-cypress/src/index.js +47 -2
  51. package/packages/datadog-plugin-cypress/src/plugin.js +1 -0
  52. package/packages/datadog-plugin-cypress/src/support.js +45 -1
  53. package/packages/datadog-plugin-express/src/code_origin.js +1 -1
  54. package/packages/datadog-plugin-fastify/src/code_origin.js +1 -1
  55. package/packages/datadog-plugin-graphql/src/execute.js +639 -12
  56. package/packages/datadog-plugin-graphql/src/index.js +37 -9
  57. package/packages/datadog-plugin-graphql/src/parse.js +24 -4
  58. package/packages/datadog-plugin-graphql/src/utils.js +9 -2
  59. package/packages/datadog-plugin-graphql/src/validate.js +17 -6
  60. package/packages/datadog-plugin-http/src/index.js +6 -8
  61. package/packages/datadog-plugin-jest/src/index.js +31 -15
  62. package/packages/datadog-plugin-mocha/src/index.js +40 -15
  63. package/packages/datadog-plugin-mongodb-core/src/bulk-write.js +43 -0
  64. package/packages/datadog-plugin-mongodb-core/src/index.js +8 -443
  65. package/packages/datadog-plugin-mongodb-core/src/query.js +452 -0
  66. package/packages/datadog-plugin-openai/src/services.js +2 -2
  67. package/packages/datadog-plugin-playwright/src/index.js +4 -3
  68. package/packages/datadog-plugin-vitest/src/index.js +120 -72
  69. package/packages/datadog-shimmer/src/shimmer.js +37 -16
  70. package/packages/dd-trace/src/aiguard/index.js +9 -14
  71. package/packages/dd-trace/src/aiguard/integrations/index.js +34 -0
  72. package/packages/dd-trace/src/aiguard/integrations/openai.js +47 -33
  73. package/packages/dd-trace/src/aiguard/integrations/vercel-ai.js +42 -28
  74. package/packages/dd-trace/src/aiguard/sdk.js +2 -2
  75. package/packages/dd-trace/src/appsec/api_security/sampler.js +3 -3
  76. package/packages/dd-trace/src/appsec/channels.js +3 -1
  77. package/packages/dd-trace/src/appsec/downstream_requests.js +4 -4
  78. package/packages/dd-trace/src/appsec/graphql.js +14 -11
  79. package/packages/dd-trace/src/appsec/iast/analyzers/nosql-injection-mongodb-analyzer.js +23 -23
  80. package/packages/dd-trace/src/appsec/iast/security-controls/index.js +2 -2
  81. package/packages/dd-trace/src/appsec/iast/telemetry/index.js +2 -1
  82. package/packages/dd-trace/src/appsec/index.js +10 -1
  83. package/packages/dd-trace/src/appsec/lambda.js +135 -0
  84. package/packages/dd-trace/src/appsec/reporter.js +49 -10
  85. package/packages/dd-trace/src/appsec/telemetry/index.js +1 -1
  86. package/packages/dd-trace/src/appsec/waf/index.js +16 -4
  87. package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +4 -4
  88. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +26 -1
  89. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +115 -24
  90. package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +21 -6
  91. package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +5 -2
  92. package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +1 -1
  93. package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +1 -1
  94. package/packages/dd-trace/src/ci-visibility/exporters/agentless/index.js +6 -2
  95. package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +1 -1
  96. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +130 -20
  97. package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +2 -2
  98. package/packages/dd-trace/src/ci-visibility/exporters/test-worker/writer.js +17 -0
  99. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +47 -26
  100. package/packages/dd-trace/src/ci-visibility/log-submission/log-submission-plugin.js +2 -2
  101. package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +64 -53
  102. package/packages/dd-trace/src/ci-visibility/requests/upload-coverage-report.js +3 -3
  103. package/packages/dd-trace/src/ci-visibility/requests/upload-test-screenshot.js +156 -0
  104. package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +23 -5
  105. package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache-schema.js +128 -0
  106. package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache.js +287 -0
  107. package/packages/dd-trace/src/config/defaults.js +3 -2
  108. package/packages/dd-trace/src/config/generated-config-types.d.ts +71 -57
  109. package/packages/dd-trace/src/config/helper.js +1 -0
  110. package/packages/dd-trace/src/config/index.js +35 -22
  111. package/packages/dd-trace/src/config/major-overrides.js +4 -2
  112. package/packages/dd-trace/src/config/remote_config.js +1 -1
  113. package/packages/dd-trace/src/config/supported-configurations.json +127 -56
  114. package/packages/dd-trace/src/constants.js +7 -0
  115. package/packages/dd-trace/src/crashtracking/crashtracker.js +2 -2
  116. package/packages/dd-trace/src/datastreams/processor.js +11 -3
  117. package/packages/dd-trace/src/exporters/agent/index.js +1 -1
  118. package/packages/dd-trace/src/exporters/agentless/writer.js +4 -4
  119. package/packages/dd-trace/src/llmobs/index.js +1 -1
  120. package/packages/dd-trace/src/llmobs/plugins/ai/ddTelemetry.js +403 -0
  121. package/packages/dd-trace/src/llmobs/plugins/ai/index.js +8 -395
  122. package/packages/dd-trace/src/llmobs/plugins/ai/util.js +27 -0
  123. package/packages/dd-trace/src/llmobs/plugins/ai/vercelTelemetry.js +363 -0
  124. package/packages/dd-trace/src/llmobs/plugins/base.js +4 -4
  125. package/packages/dd-trace/src/llmobs/plugins/claude-agent-sdk/index.js +270 -0
  126. package/packages/dd-trace/src/llmobs/plugins/claude-agent-sdk/utils.js +10 -0
  127. package/packages/dd-trace/src/llmobs/plugins/langgraph/index.js +1 -1
  128. package/packages/dd-trace/src/llmobs/sdk.js +3 -3
  129. package/packages/dd-trace/src/llmobs/span_processor.js +1 -1
  130. package/packages/dd-trace/src/llmobs/tagger.js +3 -3
  131. package/packages/dd-trace/src/llmobs/writers/base.js +1 -1
  132. package/packages/dd-trace/src/opentelemetry/metrics/index.js +54 -5
  133. package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_exporter.js +40 -0
  134. package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_transformer.js +169 -0
  135. package/packages/dd-trace/src/opentelemetry/otlp/otlp_http_exporter_base.js +38 -39
  136. package/packages/dd-trace/src/opentelemetry/span.js +5 -0
  137. package/packages/dd-trace/src/opentelemetry/trace/index.js +4 -0
  138. package/packages/dd-trace/src/opentelemetry/tracer_provider.js +1 -1
  139. package/packages/dd-trace/src/opentracing/tracer.js +6 -1
  140. package/packages/dd-trace/src/plugin_manager.js +23 -7
  141. package/packages/dd-trace/src/plugins/ci_plugin.js +159 -10
  142. package/packages/dd-trace/src/plugins/index.js +2 -0
  143. package/packages/dd-trace/src/plugins/util/llm.js +6 -1
  144. package/packages/dd-trace/src/plugins/util/test.js +15 -9
  145. package/packages/dd-trace/src/profiling/exporter_cli.js +2 -2
  146. package/packages/dd-trace/src/profiling/exporters/agent.js +28 -3
  147. package/packages/dd-trace/src/profiling/exporters/event_serializer.js +3 -3
  148. package/packages/dd-trace/src/profiling/profilers/wall.js +1 -1
  149. package/packages/dd-trace/src/proxy.js +8 -8
  150. package/packages/dd-trace/src/span_processor.js +5 -6
  151. package/packages/dd-trace/src/span_stats.js +96 -78
  152. package/packages/dd-trace/src/startup-log.js +2 -1
  153. package/packages/dd-trace/src/telemetry/dependencies.js +1 -1
  154. package/packages/dd-trace/src/telemetry/endpoints.js +6 -4
  155. package/packages/dd-trace/src/telemetry/index.js +2 -2
  156. package/packages/dd-trace/src/telemetry/logs/index.js +1 -1
  157. package/packages/dd-trace/src/telemetry/send-data.js +8 -8
  158. package/packages/dd-trace/src/telemetry/session-propagation.js +1 -1
  159. package/packages/dd-trace/src/telemetry/telemetry.js +9 -9
  160. package/vendor/dist/@datadog/sketches-js/index.js +1 -1
  161. package/vendor/dist/protobufjs/index.js +1 -1
  162. package/vendor/dist/protobufjs/minimal/index.js +1 -1
  163. package/vendor/dist/shell-quote/index.js +1 -1
  164. package/packages/datadog-plugin-graphql/src/resolve.js +0 -170
@@ -0,0 +1,128 @@
1
+ 'use strict'
2
+
3
+ const REQUIRED_SETTINGS_KEYS = [
4
+ 'code_coverage',
5
+ 'tests_skipping',
6
+ 'itr_enabled',
7
+ 'require_git',
8
+ 'early_flake_detection',
9
+ 'flaky_test_retries_enabled',
10
+ 'di_enabled',
11
+ 'known_tests_enabled',
12
+ 'test_management',
13
+ 'impacted_tests_enabled',
14
+ 'coverage_report_upload_enabled',
15
+ ]
16
+
17
+ function isObject (value) {
18
+ return value !== null && typeof value === 'object' && !Array.isArray(value)
19
+ }
20
+
21
+ function assertObject (value, message) {
22
+ if (!isObject(value)) {
23
+ throw new Error(message)
24
+ }
25
+ }
26
+
27
+ function assertHasKeys (value, keys, endpoint) {
28
+ for (const key of keys) {
29
+ if (!Object.hasOwn(value, key)) {
30
+ throw new Error(`Invalid ${endpoint} response: missing ${key}`)
31
+ }
32
+ }
33
+ }
34
+
35
+ function getAttributes (response, endpoint) {
36
+ const attributes = response?.data?.attributes
37
+ assertObject(attributes, `Invalid ${endpoint} response: attributes must be an object`)
38
+ return attributes
39
+ }
40
+
41
+ function validateSettingsResponse (response) {
42
+ const attributes = response?.data?.attributes ?? response
43
+ assertObject(attributes, 'Invalid settings response: attributes must be an object')
44
+ assertHasKeys(attributes, REQUIRED_SETTINGS_KEYS, 'settings')
45
+ assertObject(attributes.early_flake_detection, 'Invalid settings response: early_flake_detection must be an object')
46
+ assertObject(attributes.test_management, 'Invalid settings response: test_management must be an object')
47
+ assertHasKeys(attributes.early_flake_detection, ['enabled'], 'settings early_flake_detection')
48
+ assertHasKeys(attributes.test_management, ['enabled'], 'settings test_management')
49
+ }
50
+
51
+ function validateKnownTestsResponse (response) {
52
+ const attributes = getAttributes(response, 'known tests')
53
+ assertHasKeys(attributes, ['tests'], 'known tests')
54
+
55
+ const { tests } = attributes
56
+ if (tests === null) return
57
+ assertObject(tests, 'Invalid known tests response: tests must be an object or null')
58
+
59
+ for (const suites of Object.values(tests)) {
60
+ assertObject(suites, 'Invalid known tests response: module suites must be objects')
61
+ for (const testNames of Object.values(suites)) {
62
+ if (!Array.isArray(testNames)) {
63
+ throw new TypeError('Invalid known tests response: suite tests must be arrays')
64
+ }
65
+ for (const testName of testNames) {
66
+ if (typeof testName !== 'string') {
67
+ throw new TypeError('Invalid known tests response: test names must be strings')
68
+ }
69
+ }
70
+ }
71
+ }
72
+ }
73
+
74
+ function validateSkippableTestsResponse (response) {
75
+ assertObject(response, 'Invalid skippable tests response: response must be an object')
76
+ if (!Array.isArray(response.data)) {
77
+ throw new TypeError('Invalid skippable tests response: data must be an array')
78
+ }
79
+ if (response.meta !== undefined) {
80
+ assertObject(response.meta, 'Invalid skippable tests response: meta must be an object')
81
+ }
82
+ if (response.meta?.coverage !== undefined) {
83
+ assertObject(response.meta.coverage, 'Invalid skippable tests response: meta.coverage must be an object')
84
+ }
85
+ if (response.meta?.correlation_id !== undefined && typeof response.meta.correlation_id !== 'string') {
86
+ throw new Error('Invalid skippable tests response: meta.correlation_id must be a string')
87
+ }
88
+
89
+ for (const item of response.data) {
90
+ assertObject(item, 'Invalid skippable tests response: data entries must be objects')
91
+ if (typeof item.type !== 'string') {
92
+ throw new TypeError('Invalid skippable tests response: data entry type must be a string')
93
+ }
94
+ assertObject(item.attributes, 'Invalid skippable tests response: data entry attributes must be an object')
95
+ if ((item.type === 'suite' || item.type === 'test') && typeof item.attributes.suite !== 'string') {
96
+ throw new Error('Invalid skippable tests response: data entry suite must be a string')
97
+ }
98
+ if (item.type === 'test' && typeof item.attributes.name !== 'string') {
99
+ throw new Error('Invalid skippable tests response: data entry name must be a string')
100
+ }
101
+ }
102
+ }
103
+
104
+ function validateTestManagementTestsResponse (response) {
105
+ const attributes = getAttributes(response, 'test management tests')
106
+ assertHasKeys(attributes, ['modules'], 'test management tests')
107
+ assertObject(attributes.modules, 'Invalid test management tests response: modules must be an object')
108
+
109
+ for (const testModule of Object.values(attributes.modules)) {
110
+ assertObject(testModule, 'Invalid test management tests response: modules entries must be objects')
111
+ assertObject(testModule.suites, 'Invalid test management tests response: module suites must be objects')
112
+ for (const suite of Object.values(testModule.suites)) {
113
+ assertObject(suite, 'Invalid test management tests response: suites entries must be objects')
114
+ assertObject(suite.tests, 'Invalid test management tests response: suite tests must be objects')
115
+ for (const test of Object.values(suite.tests)) {
116
+ assertObject(test, 'Invalid test management tests response: tests entries must be objects')
117
+ assertObject(test.properties, 'Invalid test management tests response: test properties must be objects')
118
+ }
119
+ }
120
+ }
121
+ }
122
+
123
+ module.exports = {
124
+ validateKnownTestsResponse,
125
+ validateSettingsResponse,
126
+ validateSkippableTestsResponse,
127
+ validateTestManagementTestsResponse,
128
+ }
@@ -0,0 +1,287 @@
1
+ 'use strict'
2
+
3
+ const fs = require('node:fs')
4
+ const path = require('node:path')
5
+
6
+ const log = require('../log')
7
+ const { getNumFromKnownTests } = require('../plugins/util/test')
8
+ const { parseKnownTestsResponse } = require('./early-flake-detection/get-known-tests')
9
+ const { parseSkippableSuitesResponse } = require('./intelligent-test-runner/get-skippable-suites')
10
+ const { parseLibraryConfigurationResponse } = require('./requests/get-library-configuration')
11
+ const {
12
+ getNumFromTestManagementTests,
13
+ parseTestManagementTestsResponse,
14
+ } = require('./test-management/get-test-management-tests')
15
+ const {
16
+ incrementCountMetric,
17
+ distributionMetric,
18
+ TELEMETRY_GIT_REQUESTS_SETTINGS_RESPONSE,
19
+ TELEMETRY_KNOWN_TESTS_RESPONSE_TESTS,
20
+ TELEMETRY_KNOWN_TESTS_RESPONSE_BYTES,
21
+ TELEMETRY_ITR_SKIPPABLE_TESTS_RESPONSE_SUITES,
22
+ TELEMETRY_ITR_SKIPPABLE_TESTS_RESPONSE_TESTS,
23
+ TELEMETRY_ITR_SKIPPABLE_TESTS_RESPONSE_BYTES,
24
+ TELEMETRY_TEST_MANAGEMENT_TESTS_RESPONSE_TESTS,
25
+ TELEMETRY_TEST_MANAGEMENT_TESTS_RESPONSE_BYTES,
26
+ } = require('./telemetry')
27
+
28
+ const CACHE_MISS = Symbol('test optimization http cache miss')
29
+
30
+ const PLAN_FOLDER = '.testoptimization'
31
+ const MANIFEST_FILE_NAME = 'manifest.txt'
32
+ const SUPPORTED_MANIFEST_VERSION = '1'
33
+ const CACHE_FOLDER_NAME = 'cache'
34
+ const HTTP_CACHE_FOLDER_NAME = 'http'
35
+
36
+ const ENV_MANIFEST_FILE = 'TEST_OPTIMIZATION_MANIFEST_FILE'
37
+ const ENV_MANIFEST_FILE_ALIAS = 'DD_TEST_OPTIMIZATION_MANIFEST_FILE'
38
+ const ENV_RUNFILES_DIR = 'RUNFILES_DIR'
39
+ const ENV_RUNFILES_MANIFEST_FILE = 'RUNFILES_MANIFEST_FILE'
40
+ const ENV_TEST_SRCDIR = 'TEST_SRCDIR'
41
+
42
+ const SETTINGS_FILE_NAME = 'settings.json'
43
+ const KNOWN_TESTS_FILE_NAME = 'known_tests.json'
44
+ const SKIPPABLE_TESTS_FILE_NAME = 'skippable_tests.json'
45
+ const TEST_MANAGEMENT_FILE_NAME = 'test_management.json'
46
+
47
+ const RUNFILES_MANIFEST_SEPARATOR = ' '
48
+
49
+ function parseManifestVersion (content) {
50
+ // Supported just the number version or 'version=x'
51
+ const version = content.replace(/^\uFEFF/, '').trim()
52
+ const match = version.match(/^version=(.+)$/)
53
+ return match ? match[1].trim() : version
54
+ }
55
+
56
+ class TestOptimizationHttpCache {
57
+ constructor ({ cwd = process.cwd(), env } = {}) {
58
+ this._cwd = cwd
59
+ // This cache intentionally consumes env vars that are not tracer config keys. (??)
60
+ // eslint-disable-next-line eslint-rules/eslint-process-env
61
+ this._env = env ?? process.env
62
+ this._manifestPath = this._resolveManifestPath()
63
+ this._testOptimizationPath = undefined
64
+ this._httpCachePath = undefined
65
+ this._available = false
66
+
67
+ this._buildReader()
68
+ }
69
+
70
+ isAvailable () {
71
+ return this._available
72
+ }
73
+
74
+ readSettings () {
75
+ const payload = this._readFile(SETTINGS_FILE_NAME)
76
+ if (payload === CACHE_MISS) {
77
+ this._disable()
78
+ return CACHE_MISS
79
+ }
80
+
81
+ try {
82
+ const settings = parseLibraryConfigurationResponse(payload, undefined, { validateRequiredFields: true })
83
+ incrementCountMetric(TELEMETRY_GIT_REQUESTS_SETTINGS_RESPONSE, settings)
84
+ return settings
85
+ } catch (err) {
86
+ this._logInvalidCacheFile(SETTINGS_FILE_NAME, err)
87
+ this._disable()
88
+ return CACHE_MISS
89
+ }
90
+ }
91
+
92
+ readKnownTests () {
93
+ const payload = this._readFile(KNOWN_TESTS_FILE_NAME)
94
+ if (payload === CACHE_MISS) return CACHE_MISS
95
+
96
+ try {
97
+ const knownTests = parseKnownTestsResponse(payload, { validateRequiredFields: true })
98
+ distributionMetric(TELEMETRY_KNOWN_TESTS_RESPONSE_TESTS, {}, getNumFromKnownTests(knownTests))
99
+ distributionMetric(TELEMETRY_KNOWN_TESTS_RESPONSE_BYTES, {}, payload.length)
100
+ return knownTests
101
+ } catch (err) {
102
+ this._logInvalidCacheFile(KNOWN_TESTS_FILE_NAME, err)
103
+ return CACHE_MISS
104
+ }
105
+ }
106
+
107
+ readSkippableSuites (options = {}) {
108
+ const payload = this._readFile(SKIPPABLE_TESTS_FILE_NAME)
109
+ if (payload === CACHE_MISS) return CACHE_MISS
110
+
111
+ try {
112
+ const parsedResponse = JSON.parse(payload)
113
+ const result = parseSkippableSuitesResponse(parsedResponse, { ...options, validateRequiredFields: true })
114
+ const testLevel = options.testLevel || 'suite'
115
+ const skippableItems = parsedResponse.data.filter(({ type }) => type === testLevel)
116
+ incrementCountMetric(
117
+ testLevel === 'test'
118
+ ? TELEMETRY_ITR_SKIPPABLE_TESTS_RESPONSE_TESTS
119
+ : TELEMETRY_ITR_SKIPPABLE_TESTS_RESPONSE_SUITES,
120
+ {},
121
+ skippableItems.length
122
+ )
123
+ distributionMetric(TELEMETRY_ITR_SKIPPABLE_TESTS_RESPONSE_BYTES, {}, payload.length)
124
+ return result
125
+ } catch (err) {
126
+ this._logInvalidCacheFile(SKIPPABLE_TESTS_FILE_NAME, err)
127
+ return CACHE_MISS
128
+ }
129
+ }
130
+
131
+ hasValidSkippableSuites (options = {}) {
132
+ const payload = this._readFile(SKIPPABLE_TESTS_FILE_NAME)
133
+ if (payload === CACHE_MISS) return false
134
+
135
+ try {
136
+ parseSkippableSuitesResponse(JSON.parse(payload), { ...options, validateRequiredFields: true })
137
+ return true
138
+ } catch {
139
+ return false
140
+ }
141
+ }
142
+
143
+ readTestManagementTests () {
144
+ const payload = this._readFile(TEST_MANAGEMENT_FILE_NAME)
145
+ if (payload === CACHE_MISS) return CACHE_MISS
146
+
147
+ try {
148
+ const testManagementTests = parseTestManagementTestsResponse(payload, { validateRequiredFields: true })
149
+ distributionMetric(
150
+ TELEMETRY_TEST_MANAGEMENT_TESTS_RESPONSE_TESTS,
151
+ {},
152
+ getNumFromTestManagementTests(testManagementTests)
153
+ )
154
+ distributionMetric(TELEMETRY_TEST_MANAGEMENT_TESTS_RESPONSE_BYTES, {}, payload.length)
155
+ return testManagementTests
156
+ } catch (err) {
157
+ this._logInvalidCacheFile(TEST_MANAGEMENT_FILE_NAME, err)
158
+ return CACHE_MISS
159
+ }
160
+ }
161
+
162
+ _buildReader () {
163
+ if (!this._manifestPath) {
164
+ log.debug('Test Optimization HTTP cache manifest not found')
165
+ return
166
+ }
167
+
168
+ const version = this._readManifestVersion(this._manifestPath)
169
+ if (version !== SUPPORTED_MANIFEST_VERSION) {
170
+ log.debug('Unsupported Test Optimization HTTP cache manifest version %j at %s', version, this._manifestPath)
171
+ return
172
+ }
173
+
174
+ this._testOptimizationPath = path.dirname(this._manifestPath)
175
+ this._httpCachePath = path.join(
176
+ this._testOptimizationPath,
177
+ CACHE_FOLDER_NAME,
178
+ HTTP_CACHE_FOLDER_NAME
179
+ )
180
+
181
+ const settingsPath = path.join(this._httpCachePath, SETTINGS_FILE_NAME)
182
+ if (!fs.existsSync(settingsPath)) {
183
+ log.debug('Test Optimization HTTP cache settings file not found at %s', settingsPath)
184
+ return
185
+ }
186
+
187
+ log.debug('Test Optimization HTTP cache found at %s', this._httpCachePath)
188
+ this._available = true
189
+ }
190
+
191
+ _resolveManifestPath () {
192
+ const localManifest = path.join(this._cwd, PLAN_FOLDER, MANIFEST_FILE_NAME)
193
+ if (fs.existsSync(localManifest)) {
194
+ return localManifest
195
+ }
196
+
197
+ const manifestFile = this._env[ENV_MANIFEST_FILE] || this._env[ENV_MANIFEST_FILE_ALIAS]
198
+ if (!manifestFile) return
199
+
200
+ const resolvedManifestPath = this._resolveRunfilePath(manifestFile)
201
+ if (fs.existsSync(resolvedManifestPath)) {
202
+ return resolvedManifestPath
203
+ }
204
+ }
205
+
206
+ _resolveRunfilePath (manifestFile) {
207
+ if (fs.existsSync(manifestFile)) {
208
+ return manifestFile
209
+ }
210
+
211
+ const runfilesDir = this._env[ENV_RUNFILES_DIR]
212
+ if (runfilesDir) {
213
+ const candidate = path.join(runfilesDir, manifestFile)
214
+ if (fs.existsSync(candidate)) {
215
+ return candidate
216
+ }
217
+ }
218
+
219
+ const runfilesManifestCandidate = this._resolveRunfilePathFromManifest(manifestFile)
220
+ if (runfilesManifestCandidate) {
221
+ return runfilesManifestCandidate
222
+ }
223
+
224
+ const testSrcdir = this._env[ENV_TEST_SRCDIR]
225
+ if (testSrcdir) {
226
+ const candidate = path.join(testSrcdir, manifestFile)
227
+ if (fs.existsSync(candidate)) {
228
+ return candidate
229
+ }
230
+ }
231
+
232
+ return manifestFile
233
+ }
234
+
235
+ _resolveRunfilePathFromManifest (manifestFile) {
236
+ const runfilesManifest = this._env[ENV_RUNFILES_MANIFEST_FILE]
237
+ if (!runfilesManifest || !fs.existsSync(runfilesManifest)) return
238
+
239
+ try {
240
+ const lines = fs.readFileSync(runfilesManifest, 'utf8').split('\n')
241
+ for (const line of lines) {
242
+ const separatorIndex = line.indexOf(RUNFILES_MANIFEST_SEPARATOR)
243
+ if (separatorIndex <= 0) continue
244
+ if (line.slice(0, separatorIndex) !== manifestFile) continue
245
+
246
+ const resolvedPath = line.slice(separatorIndex + 1).trim()
247
+ if (resolvedPath) return resolvedPath
248
+ }
249
+ } catch (err) {
250
+ log.debug('Failed to resolve Test Optimization HTTP cache manifest from %s: %s', runfilesManifest, err.message)
251
+ }
252
+ }
253
+
254
+ _readManifestVersion (manifestPath) {
255
+ try {
256
+ return parseManifestVersion(fs.readFileSync(manifestPath, 'utf8'))
257
+ } catch (err) {
258
+ log.debug('Failed to read Test Optimization HTTP cache manifest %s: %s', manifestPath, err.message)
259
+ }
260
+ }
261
+
262
+ _readFile (fileName) {
263
+ if (!this.isAvailable()) return CACHE_MISS
264
+
265
+ const filePath = path.join(this._httpCachePath, fileName)
266
+ try {
267
+ log.debug('Reading Test Optimization HTTP cache file %s', filePath)
268
+ return fs.readFileSync(filePath, 'utf8')
269
+ } catch (err) {
270
+ log.debug('Test Optimization HTTP cache file %s could not be read: %s', filePath, err.message)
271
+ return CACHE_MISS
272
+ }
273
+ }
274
+
275
+ _logInvalidCacheFile (fileName, err) {
276
+ log.debug('Test Optimization HTTP cache file %s could not be parsed: %s', fileName, err.message)
277
+ }
278
+
279
+ _disable () {
280
+ this._available = false
281
+ }
282
+ }
283
+
284
+ module.exports = {
285
+ CACHE_MISS,
286
+ TestOptimizationHttpCache,
287
+ }
@@ -227,8 +227,9 @@ for (const [canonicalName, entries] of Object.entries(supportedConfigurations))
227
227
  if (entry.sensitive) {
228
228
  sensitiveConfigurations.add(canonicalName)
229
229
  }
230
- const configurationNames = entry.internalPropertyName ? [entry.internalPropertyName] : entry.configurationNames
231
- const fullPropertyName = configurationNames?.[0] ?? canonicalName
230
+ const fullPropertyName = entry.namespace
231
+ ? `${entry.namespace}.${canonicalName}`
232
+ : (entry.internalPropertyName ?? entry.configurationNames?.[0] ?? canonicalName)
232
233
  const type = entry.type.toUpperCase()
233
234
 
234
235
  let transformer = transformers[entry.transform]