dd-trace 3.50.0 → 3.52.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 +7 -0
- package/ci/cypress/after-spec.js +1 -0
- package/index.d.ts +1502 -1485
- package/package.json +4 -4
- package/packages/datadog-core/src/utils/src/get.js +11 -0
- package/packages/datadog-core/src/utils/src/has.js +14 -0
- package/packages/datadog-core/src/utils/src/set.js +16 -0
- package/packages/datadog-instrumentations/src/amqplib.js +1 -1
- package/packages/datadog-instrumentations/src/cucumber.js +2 -1
- package/packages/datadog-instrumentations/src/grpc/server.js +3 -1
- package/packages/datadog-instrumentations/src/jest.js +11 -5
- package/packages/datadog-instrumentations/src/mocha.js +4 -1
- package/packages/datadog-instrumentations/src/mongodb-core.js +34 -3
- package/packages/datadog-instrumentations/src/playwright.js +78 -16
- package/packages/datadog-plugin-amqplib/src/consumer.js +5 -4
- package/packages/datadog-plugin-amqplib/src/producer.js +3 -4
- package/packages/datadog-plugin-aws-sdk/src/base.js +3 -2
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +4 -11
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +3 -6
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +5 -7
- package/packages/datadog-plugin-cucumber/src/index.js +2 -2
- package/packages/datadog-plugin-cypress/src/after-spec.js +3 -0
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +123 -58
- package/packages/datadog-plugin-cypress/src/support.js +50 -3
- package/packages/datadog-plugin-graphql/src/index.js +1 -1
- package/packages/datadog-plugin-graphql/src/resolve.js +10 -8
- package/packages/datadog-plugin-grpc/src/util.js +1 -1
- package/packages/datadog-plugin-jest/src/index.js +13 -4
- package/packages/datadog-plugin-kafkajs/src/consumer.js +4 -3
- package/packages/datadog-plugin-kafkajs/src/producer.js +3 -5
- package/packages/datadog-plugin-mocha/src/index.js +2 -2
- package/packages/datadog-plugin-playwright/src/index.js +34 -3
- package/packages/datadog-plugin-rhea/src/consumer.js +5 -3
- package/packages/datadog-plugin-rhea/src/producer.js +3 -4
- package/packages/dd-trace/src/appsec/iast/iast-plugin.js +23 -12
- package/packages/dd-trace/src/appsec/iast/index.js +10 -0
- package/packages/dd-trace/src/appsec/iast/path-line.js +9 -6
- package/packages/dd-trace/src/appsec/iast/taint-tracking/operations.js +1 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +6 -2
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter-telemetry.js +1 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +14 -2
- package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +1 -1
- package/packages/dd-trace/src/appsec/iast/telemetry/iast-metric.js +34 -27
- package/packages/dd-trace/src/appsec/iast/telemetry/namespaces.js +39 -11
- package/packages/dd-trace/src/appsec/iast/telemetry/span-tags.js +7 -6
- package/packages/dd-trace/src/appsec/recommended.json +67 -27
- package/packages/dd-trace/src/appsec/remote_config/index.js +1 -1
- package/packages/dd-trace/src/appsec/reporter.js +24 -11
- package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +1 -3
- package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +6 -1
- package/packages/dd-trace/src/config.js +451 -460
- package/packages/dd-trace/src/data_streams_context.js +1 -1
- package/packages/dd-trace/src/datastreams/pathway.js +58 -1
- package/packages/dd-trace/src/datastreams/processor.js +3 -5
- package/packages/dd-trace/src/format.js +0 -1
- package/packages/dd-trace/src/lambda/runtime/ritm.js +1 -1
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +22 -3
- package/packages/dd-trace/src/opentracing/span.js +2 -0
- package/packages/dd-trace/src/opentracing/span_context.js +1 -0
- package/packages/dd-trace/src/plugins/util/test.js +4 -2
- package/packages/dd-trace/src/plugins/util/web.js +1 -1
- package/packages/dd-trace/src/priority_sampler.js +11 -6
- package/packages/dd-trace/src/profiling/exporters/agent.js +38 -2
- package/packages/dd-trace/src/telemetry/index.js +32 -33
- package/packages/dd-trace/src/tracer.js +3 -3
- package/register.js +4 -0
- package/CONTRIBUTING.md +0 -171
- package/MIGRATING.md +0 -224
- package/packages/dd-trace/src/external-logger/test/index.spec.js +0 -147
- package/scripts/check-proposal-labels.js +0 -71
- package/scripts/check_licenses.js +0 -69
- package/scripts/helpers/color.js +0 -8
- package/scripts/helpers/exec.js +0 -22
- package/scripts/helpers/title.js +0 -15
- package/scripts/install_plugin_modules.js +0 -248
- package/scripts/publish_docs.js +0 -21
- package/scripts/st.js +0 -105
- /package/packages/{utils → datadog-core/src/utils}/src/kebabcase.js +0 -0
- /package/packages/{utils → datadog-core/src/utils}/src/pick.js +0 -0
- /package/packages/{utils → datadog-core/src/utils}/src/uniq.js +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dd-trace",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.52.0",
|
|
4
4
|
"description": "Datadog APM tracing client for JavaScript",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"typings": "index.d.ts",
|
|
@@ -69,11 +69,11 @@
|
|
|
69
69
|
"node": ">=14"
|
|
70
70
|
},
|
|
71
71
|
"dependencies": {
|
|
72
|
-
"@datadog/native-appsec": "7.
|
|
73
|
-
"@datadog/native-iast-rewriter": "2.
|
|
72
|
+
"@datadog/native-appsec": "7.1.0",
|
|
73
|
+
"@datadog/native-iast-rewriter": "2.3.0",
|
|
74
74
|
"@datadog/native-iast-taint-tracking": "1.7.0",
|
|
75
75
|
"@datadog/native-metrics": "^2.0.0",
|
|
76
|
-
"@datadog/pprof": "5.
|
|
76
|
+
"@datadog/pprof": "5.1.0",
|
|
77
77
|
"@datadog/sketches-js": "^2.1.0",
|
|
78
78
|
"@opentelemetry/api": "^1.0.0",
|
|
79
79
|
"@opentelemetry/core": "^1.14.0",
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
module.exports = (object, path) => {
|
|
4
|
+
const pathArr = path.split('.')
|
|
5
|
+
let property = object
|
|
6
|
+
for (const n of pathArr) {
|
|
7
|
+
if (property.hasOwnProperty(n)) {
|
|
8
|
+
property = property[n]
|
|
9
|
+
} else {
|
|
10
|
+
return false
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
return true
|
|
14
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
module.exports = (object, path, value) => {
|
|
4
|
+
const pathArr = path.split('.')
|
|
5
|
+
let property = object
|
|
6
|
+
let i
|
|
7
|
+
for (i = 0; i < pathArr.length - 1; i++) {
|
|
8
|
+
const n = pathArr[i]
|
|
9
|
+
if (property.hasOwnProperty(n)) {
|
|
10
|
+
property = property[n]
|
|
11
|
+
} else {
|
|
12
|
+
property[n] = property = {}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
property[pathArr[i]] = value
|
|
16
|
+
}
|
|
@@ -5,7 +5,7 @@ const {
|
|
|
5
5
|
addHook,
|
|
6
6
|
AsyncResource
|
|
7
7
|
} = require('./helpers/instrument')
|
|
8
|
-
const kebabCase = require('../../utils/src/kebabcase')
|
|
8
|
+
const kebabCase = require('../../datadog-core/src/utils/src/kebabcase')
|
|
9
9
|
const shimmer = require('../../datadog-shimmer')
|
|
10
10
|
|
|
11
11
|
const startCh = channel('apm:amqplib:command:start')
|
|
@@ -92,7 +92,8 @@ function getStatusFromResultLatest (result) {
|
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
function isNewTest (testSuite, testName) {
|
|
95
|
-
|
|
95
|
+
const testsForSuite = knownTests.cucumber?.[testSuite] || []
|
|
96
|
+
return !testsForSuite.includes(testName)
|
|
96
97
|
}
|
|
97
98
|
|
|
98
99
|
function getTestStatusFromRetries (testStatuses) {
|
|
@@ -92,7 +92,9 @@ function createWrapEmit (call, ctx, onCancel) {
|
|
|
92
92
|
finishChannel.publish(ctx)
|
|
93
93
|
call.removeListener('cancelled', onCancel)
|
|
94
94
|
break
|
|
95
|
-
|
|
95
|
+
// Streams are always cancelled before `finish` since 1.10.0 so we have
|
|
96
|
+
// to use `prefinish` instead to avoid cancellation false positives.
|
|
97
|
+
case 'prefinish':
|
|
96
98
|
if (call.status) {
|
|
97
99
|
updateChannel.publish(call.status)
|
|
98
100
|
}
|
|
@@ -115,6 +115,7 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
115
115
|
this.nameToParams = {}
|
|
116
116
|
this.global._ddtrace = global._ddtrace
|
|
117
117
|
|
|
118
|
+
this.displayName = config.projectConfig?.displayName?.name
|
|
118
119
|
this.testEnvironmentOptions = getTestEnvironmentOptions(config)
|
|
119
120
|
|
|
120
121
|
const repositoryRoot = this.testEnvironmentOptions._ddRepositoryRoot
|
|
@@ -139,14 +140,16 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
139
140
|
// Function that receives a list of known tests for a test service and
|
|
140
141
|
// returns the ones that belong to the current suite
|
|
141
142
|
getKnownTestsForSuite (knownTests) {
|
|
143
|
+
if (this.knownTestsForThisSuite) {
|
|
144
|
+
return this.knownTestsForThisSuite
|
|
145
|
+
}
|
|
142
146
|
let knownTestsForSuite = knownTests
|
|
143
|
-
// If jest
|
|
144
|
-
|
|
147
|
+
// If jest is using workers, known tests are serialized to json.
|
|
148
|
+
// If jest runs in band, they are not.
|
|
149
|
+
if (typeof knownTestsForSuite === 'string') {
|
|
145
150
|
knownTestsForSuite = JSON.parse(knownTestsForSuite)
|
|
146
151
|
}
|
|
147
|
-
return knownTestsForSuite
|
|
148
|
-
.filter(test => test.includes(this.testSuite))
|
|
149
|
-
.map(test => test.replace(`jest.${this.testSuite}.`, '').trim())
|
|
152
|
+
return knownTestsForSuite.jest?.[this.testSuite] || []
|
|
150
153
|
}
|
|
151
154
|
|
|
152
155
|
// Add the `add_test` event we don't have the test object yet, so
|
|
@@ -201,6 +204,7 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
201
204
|
suite: this.testSuite,
|
|
202
205
|
testSourceFile: this.testSourceFile,
|
|
203
206
|
runner: 'jest-circus',
|
|
207
|
+
displayName: this.displayName,
|
|
204
208
|
testParameters,
|
|
205
209
|
frameworkVersion: jestVersion,
|
|
206
210
|
isNew: isNewTest,
|
|
@@ -252,6 +256,7 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
252
256
|
suite: this.testSuite,
|
|
253
257
|
testSourceFile: this.testSourceFile,
|
|
254
258
|
runner: 'jest-circus',
|
|
259
|
+
displayName: this.displayName,
|
|
255
260
|
frameworkVersion: jestVersion,
|
|
256
261
|
testStartLine: getTestLineStart(event.test.asyncError, this.testSuite)
|
|
257
262
|
})
|
|
@@ -559,6 +564,7 @@ function jestAdapterWrapper (jestAdapter, jestVersion) {
|
|
|
559
564
|
testSuiteStartCh.publish({
|
|
560
565
|
testSuite: environment.testSuite,
|
|
561
566
|
testEnvironmentOptions: environment.testEnvironmentOptions,
|
|
567
|
+
displayName: environment.displayName,
|
|
562
568
|
frameworkVersion: jestVersion
|
|
563
569
|
})
|
|
564
570
|
return adapter.apply(this, arguments).then(suiteResults => {
|
|
@@ -106,7 +106,10 @@ function getTestFullName (test) {
|
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
function isNewTest (test) {
|
|
109
|
-
|
|
109
|
+
const testSuite = getTestSuitePath(test.file, process.cwd())
|
|
110
|
+
const testName = removeEfdStringFromTestName(test.fullTitle())
|
|
111
|
+
const testsForSuite = knownTests.mocha?.[testSuite] || []
|
|
112
|
+
return !testsForSuite.includes(testName)
|
|
110
113
|
}
|
|
111
114
|
|
|
112
115
|
function retryTest (test) {
|
|
@@ -32,12 +32,18 @@ addHook({ name: 'mongodb', versions: ['>=4 <4.6.0'], file: 'lib/cmap/connection.
|
|
|
32
32
|
return Connection
|
|
33
33
|
})
|
|
34
34
|
|
|
35
|
-
addHook({ name: 'mongodb', versions: ['>=4.6.0'], file: 'lib/cmap/connection.js' }, Connection => {
|
|
35
|
+
addHook({ name: 'mongodb', versions: ['>=4.6.0 <6.4.0'], file: 'lib/cmap/connection.js' }, Connection => {
|
|
36
36
|
const proto = Connection.Connection.prototype
|
|
37
37
|
shimmer.wrap(proto, 'command', command => wrapConnectionCommand(command, 'command'))
|
|
38
38
|
return Connection
|
|
39
39
|
})
|
|
40
40
|
|
|
41
|
+
addHook({ name: 'mongodb', versions: ['>=6.4.0'], file: 'lib/cmap/connection.js' }, Connection => {
|
|
42
|
+
const proto = Connection.Connection.prototype
|
|
43
|
+
shimmer.wrap(proto, 'command', command => wrapConnectionCommand(command, 'command', undefined, instrumentPromise))
|
|
44
|
+
return Connection
|
|
45
|
+
})
|
|
46
|
+
|
|
41
47
|
addHook({ name: 'mongodb', versions: ['>=3.3 <4'], file: 'lib/core/wireprotocol/index.js' }, wp => wrapWp(wp))
|
|
42
48
|
|
|
43
49
|
addHook({ name: 'mongodb-core', versions: ['>=3.2'], file: 'lib/wireprotocol/index.js' }, wp => wrapWp(wp))
|
|
@@ -89,7 +95,7 @@ function wrapUnifiedCommand (command, operation, name) {
|
|
|
89
95
|
return shimmer.wrap(command, wrapped)
|
|
90
96
|
}
|
|
91
97
|
|
|
92
|
-
function wrapConnectionCommand (command, operation, name) {
|
|
98
|
+
function wrapConnectionCommand (command, operation, name, instrumentFn = instrument) {
|
|
93
99
|
const wrapped = function (ns, ops) {
|
|
94
100
|
if (!startCh.hasSubscribers) {
|
|
95
101
|
return command.apply(this, arguments)
|
|
@@ -101,7 +107,7 @@ function wrapConnectionCommand (command, operation, name) {
|
|
|
101
107
|
const topology = { s: { options } }
|
|
102
108
|
|
|
103
109
|
ns = `${ns.db}.${ns.collection}`
|
|
104
|
-
return
|
|
110
|
+
return instrumentFn(operation, command, this, arguments, topology, ns, ops, { name })
|
|
105
111
|
}
|
|
106
112
|
return shimmer.wrap(command, wrapped)
|
|
107
113
|
}
|
|
@@ -179,3 +185,28 @@ function instrument (operation, command, ctx, args, server, ns, ops, options = {
|
|
|
179
185
|
}
|
|
180
186
|
})
|
|
181
187
|
}
|
|
188
|
+
|
|
189
|
+
function instrumentPromise (operation, command, ctx, args, server, ns, ops, options = {}) {
|
|
190
|
+
const name = options.name || (ops && Object.keys(ops)[0])
|
|
191
|
+
|
|
192
|
+
const serverInfo = server && server.s && server.s.options
|
|
193
|
+
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
194
|
+
|
|
195
|
+
return asyncResource.runInAsyncScope(() => {
|
|
196
|
+
startCh.publish({ ns, ops, options: serverInfo, name })
|
|
197
|
+
|
|
198
|
+
const promise = command.apply(ctx, args)
|
|
199
|
+
|
|
200
|
+
promise.then(function (res) {
|
|
201
|
+
finishCh.publish()
|
|
202
|
+
return res
|
|
203
|
+
}, function (err) {
|
|
204
|
+
errorCh.publish(err)
|
|
205
|
+
finishCh.publish()
|
|
206
|
+
|
|
207
|
+
return Promise.reject(err)
|
|
208
|
+
})
|
|
209
|
+
|
|
210
|
+
return promise
|
|
211
|
+
})
|
|
212
|
+
}
|
|
@@ -14,6 +14,7 @@ const testSuiteFinishCh = channel('ci:playwright:test-suite:finish')
|
|
|
14
14
|
const testToAr = new WeakMap()
|
|
15
15
|
const testSuiteToAr = new Map()
|
|
16
16
|
const testSuiteToTestStatuses = new Map()
|
|
17
|
+
const testSuiteToErrors = new Map()
|
|
17
18
|
|
|
18
19
|
let startedSuites = []
|
|
19
20
|
|
|
@@ -81,7 +82,12 @@ function getRootDir (playwrightRunner) {
|
|
|
81
82
|
|
|
82
83
|
function getProjectsFromRunner (runner) {
|
|
83
84
|
const config = getPlaywrightConfig(runner)
|
|
84
|
-
return config.projects?.map((
|
|
85
|
+
return config.projects?.map((project) => {
|
|
86
|
+
if (project.project) {
|
|
87
|
+
return project.project
|
|
88
|
+
}
|
|
89
|
+
return project
|
|
90
|
+
})
|
|
85
91
|
}
|
|
86
92
|
|
|
87
93
|
function getProjectsFromDispatcher (dispatcher) {
|
|
@@ -93,13 +99,55 @@ function getProjectsFromDispatcher (dispatcher) {
|
|
|
93
99
|
return dispatcher._loader?.fullConfig()?.projects
|
|
94
100
|
}
|
|
95
101
|
|
|
96
|
-
function getBrowserNameFromProjects (projects,
|
|
97
|
-
if (!projects) {
|
|
102
|
+
function getBrowserNameFromProjects (projects, test) {
|
|
103
|
+
if (!projects || !test) {
|
|
98
104
|
return null
|
|
99
105
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
)
|
|
106
|
+
const { _projectIndex, _projectId: testProjectId } = test
|
|
107
|
+
|
|
108
|
+
if (_projectIndex !== undefined) {
|
|
109
|
+
return projects[_projectIndex]?.name
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return projects.find(({ __projectId, _id, name }) => {
|
|
113
|
+
if (__projectId !== undefined) {
|
|
114
|
+
return __projectId === testProjectId
|
|
115
|
+
}
|
|
116
|
+
if (_id !== undefined) {
|
|
117
|
+
return _id === testProjectId
|
|
118
|
+
}
|
|
119
|
+
return name === testProjectId
|
|
120
|
+
})?.name
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function formatTestHookError (error, hookType, isTimeout) {
|
|
124
|
+
let hookError = error
|
|
125
|
+
if (error) {
|
|
126
|
+
hookError.message = `Error in ${hookType} hook: ${error.message}`
|
|
127
|
+
}
|
|
128
|
+
if (!hookError && isTimeout) {
|
|
129
|
+
hookError = new Error(`${hookType} hook timed out`)
|
|
130
|
+
}
|
|
131
|
+
return hookError
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function addErrorToTestSuite (testSuiteAbsolutePath, error) {
|
|
135
|
+
if (testSuiteToErrors.has(testSuiteAbsolutePath)) {
|
|
136
|
+
testSuiteToErrors.get(testSuiteAbsolutePath).push(error)
|
|
137
|
+
} else {
|
|
138
|
+
testSuiteToErrors.set(testSuiteAbsolutePath, [error])
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function getTestSuiteError (testSuiteAbsolutePath) {
|
|
143
|
+
const errors = testSuiteToErrors.get(testSuiteAbsolutePath)
|
|
144
|
+
if (!errors) {
|
|
145
|
+
return null
|
|
146
|
+
}
|
|
147
|
+
if (errors.length === 1) {
|
|
148
|
+
return errors[0]
|
|
149
|
+
}
|
|
150
|
+
return new Error(`${errors.length} errors in this test suite:\n${errors.map(e => e.message).join('\n------\n')}`)
|
|
103
151
|
}
|
|
104
152
|
|
|
105
153
|
function testBeginHandler (test, browserName) {
|
|
@@ -131,7 +179,7 @@ function testBeginHandler (test, browserName) {
|
|
|
131
179
|
})
|
|
132
180
|
}
|
|
133
181
|
|
|
134
|
-
function testEndHandler (test, annotations, testStatus, error) {
|
|
182
|
+
function testEndHandler (test, annotations, testStatus, error, isTimeout) {
|
|
135
183
|
let annotationTags
|
|
136
184
|
if (annotations.length) {
|
|
137
185
|
annotationTags = parseAnnotations(annotations)
|
|
@@ -139,6 +187,11 @@ function testEndHandler (test, annotations, testStatus, error) {
|
|
|
139
187
|
const { _requireFile: testSuiteAbsolutePath, results, _type } = test
|
|
140
188
|
|
|
141
189
|
if (_type === 'beforeAll' || _type === 'afterAll') {
|
|
190
|
+
const hookError = formatTestHookError(error, _type, isTimeout)
|
|
191
|
+
|
|
192
|
+
if (hookError) {
|
|
193
|
+
addErrorToTestSuite(testSuiteAbsolutePath, hookError)
|
|
194
|
+
}
|
|
142
195
|
return
|
|
143
196
|
}
|
|
144
197
|
|
|
@@ -148,15 +201,20 @@ function testEndHandler (test, annotations, testStatus, error) {
|
|
|
148
201
|
testFinishCh.publish({ testStatus, steps: testResult.steps, error, extraTags: annotationTags })
|
|
149
202
|
})
|
|
150
203
|
|
|
151
|
-
if (
|
|
152
|
-
testSuiteToTestStatuses.set(testSuiteAbsolutePath, [testStatus])
|
|
153
|
-
} else {
|
|
204
|
+
if (testSuiteToTestStatuses.has(testSuiteAbsolutePath)) {
|
|
154
205
|
testSuiteToTestStatuses.get(testSuiteAbsolutePath).push(testStatus)
|
|
206
|
+
} else {
|
|
207
|
+
testSuiteToTestStatuses.set(testSuiteAbsolutePath, [testStatus])
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if (error) {
|
|
211
|
+
addErrorToTestSuite(testSuiteAbsolutePath, error)
|
|
155
212
|
}
|
|
156
213
|
|
|
157
214
|
remainingTestsByFile[testSuiteAbsolutePath] = remainingTestsByFile[testSuiteAbsolutePath]
|
|
158
215
|
.filter(currentTest => currentTest !== test)
|
|
159
216
|
|
|
217
|
+
// Last test, we finish the suite
|
|
160
218
|
if (!remainingTestsByFile[testSuiteAbsolutePath].length) {
|
|
161
219
|
const testStatuses = testSuiteToTestStatuses.get(testSuiteAbsolutePath)
|
|
162
220
|
|
|
@@ -167,9 +225,10 @@ function testEndHandler (test, annotations, testStatus, error) {
|
|
|
167
225
|
testSuiteStatus = 'skip'
|
|
168
226
|
}
|
|
169
227
|
|
|
228
|
+
const suiteError = getTestSuiteError(testSuiteAbsolutePath)
|
|
170
229
|
const testSuiteAsyncResource = testSuiteToAr.get(testSuiteAbsolutePath)
|
|
171
230
|
testSuiteAsyncResource.runInAsyncScope(() => {
|
|
172
|
-
testSuiteFinishCh.publish(testSuiteStatus)
|
|
231
|
+
testSuiteFinishCh.publish({ status: testSuiteStatus, error: suiteError })
|
|
173
232
|
})
|
|
174
233
|
}
|
|
175
234
|
}
|
|
@@ -197,7 +256,7 @@ function dispatcherHook (dispatcherExport) {
|
|
|
197
256
|
if (method === 'testBegin') {
|
|
198
257
|
const { test } = dispatcher._testById.get(params.testId)
|
|
199
258
|
const projects = getProjectsFromDispatcher(dispatcher)
|
|
200
|
-
const browser = getBrowserNameFromProjects(projects, test
|
|
259
|
+
const browser = getBrowserNameFromProjects(projects, test)
|
|
201
260
|
testBeginHandler(test, browser)
|
|
202
261
|
} else if (method === 'testEnd') {
|
|
203
262
|
const { test } = dispatcher._testById.get(params.testId)
|
|
@@ -205,7 +264,8 @@ function dispatcherHook (dispatcherExport) {
|
|
|
205
264
|
const { results } = test
|
|
206
265
|
const testResult = results[results.length - 1]
|
|
207
266
|
|
|
208
|
-
|
|
267
|
+
const isTimeout = testResult.status === 'timedOut'
|
|
268
|
+
testEndHandler(test, params.annotations, STATUS_TO_TEST_STATUS[testResult.status], testResult.error, isTimeout)
|
|
209
269
|
}
|
|
210
270
|
})
|
|
211
271
|
|
|
@@ -232,13 +292,14 @@ function dispatcherHookNew (dispatcherExport, runWrapper) {
|
|
|
232
292
|
worker.on('testBegin', ({ testId }) => {
|
|
233
293
|
const test = getTestByTestId(dispatcher, testId)
|
|
234
294
|
const projects = getProjectsFromDispatcher(dispatcher)
|
|
235
|
-
const browser = getBrowserNameFromProjects(projects, test
|
|
295
|
+
const browser = getBrowserNameFromProjects(projects, test)
|
|
236
296
|
testBeginHandler(test, browser)
|
|
237
297
|
})
|
|
238
298
|
worker.on('testEnd', ({ testId, status, errors, annotations }) => {
|
|
239
299
|
const test = getTestByTestId(dispatcher, testId)
|
|
240
300
|
|
|
241
|
-
|
|
301
|
+
const isTimeout = status === 'timedOut'
|
|
302
|
+
testEndHandler(test, annotations, STATUS_TO_TEST_STATUS[status], errors && errors[0], isTimeout)
|
|
242
303
|
})
|
|
243
304
|
|
|
244
305
|
return worker
|
|
@@ -265,7 +326,7 @@ function runnerHook (runnerExport, playwrightVersion) {
|
|
|
265
326
|
// there were tests that did not go through `testBegin` or `testEnd`,
|
|
266
327
|
// because they were skipped
|
|
267
328
|
tests.forEach(test => {
|
|
268
|
-
const browser = getBrowserNameFromProjects(projects, test
|
|
329
|
+
const browser = getBrowserNameFromProjects(projects, test)
|
|
269
330
|
testBeginHandler(test, browser)
|
|
270
331
|
testEndHandler(test, [], 'skip')
|
|
271
332
|
})
|
|
@@ -327,6 +388,7 @@ addHook({
|
|
|
327
388
|
file: 'lib/runner/runner.js',
|
|
328
389
|
versions: ['>=1.38.0']
|
|
329
390
|
}, runnerHook)
|
|
391
|
+
|
|
330
392
|
addHook({
|
|
331
393
|
name: 'playwright',
|
|
332
394
|
file: 'lib/runner/dispatcher.js',
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
const { TEXT_MAP } = require('../../../ext/formats')
|
|
4
4
|
const ConsumerPlugin = require('../../dd-trace/src/plugins/consumer')
|
|
5
|
-
const { getAmqpMessageSize
|
|
5
|
+
const { getAmqpMessageSize } = require('../../dd-trace/src/datastreams/processor')
|
|
6
|
+
const { DsmPathwayCodec } = require('../../dd-trace/src/datastreams/pathway')
|
|
6
7
|
const { getResourceName } = require('./util')
|
|
7
8
|
|
|
8
9
|
class AmqplibConsumerPlugin extends ConsumerPlugin {
|
|
@@ -29,12 +30,12 @@ class AmqplibConsumerPlugin extends ConsumerPlugin {
|
|
|
29
30
|
})
|
|
30
31
|
|
|
31
32
|
if (
|
|
32
|
-
this.config.dsmEnabled &&
|
|
33
|
-
message
|
|
33
|
+
this.config.dsmEnabled && message?.properties?.headers &&
|
|
34
|
+
DsmPathwayCodec.contextExists(message.properties.headers)
|
|
34
35
|
) {
|
|
35
36
|
const payloadSize = getAmqpMessageSize({ headers: message.properties.headers, content: message.content })
|
|
36
37
|
const queue = fields.queue ? fields.queue : fields.routingKey
|
|
37
|
-
this.tracer.decodeDataStreamsContext(message.properties.headers
|
|
38
|
+
this.tracer.decodeDataStreamsContext(message.properties.headers)
|
|
38
39
|
this.tracer
|
|
39
40
|
.setCheckpoint(['direction:in', `topic:${queue}`, 'type:rabbitmq'], span, payloadSize)
|
|
40
41
|
}
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
const { TEXT_MAP } = require('../../../ext/formats')
|
|
4
4
|
const { CLIENT_PORT_KEY } = require('../../dd-trace/src/constants')
|
|
5
5
|
const ProducerPlugin = require('../../dd-trace/src/plugins/producer')
|
|
6
|
-
const {
|
|
7
|
-
const { getAmqpMessageSize
|
|
6
|
+
const { DsmPathwayCodec } = require('../../dd-trace/src/datastreams/pathway')
|
|
7
|
+
const { getAmqpMessageSize } = require('../../dd-trace/src/datastreams/processor')
|
|
8
8
|
const { getResourceName } = require('./util')
|
|
9
9
|
|
|
10
10
|
class AmqplibProducerPlugin extends ProducerPlugin {
|
|
@@ -40,8 +40,7 @@ class AmqplibProducerPlugin extends ProducerPlugin {
|
|
|
40
40
|
.setCheckpoint(
|
|
41
41
|
['direction:out', `exchange:${fields.exchange}`, `has_routing_key:${hasRoutingKey}`, 'type:rabbitmq']
|
|
42
42
|
, span, payloadSize)
|
|
43
|
-
|
|
44
|
-
fields.headers[CONTEXT_PROPAGATION_KEY] = pathwayCtx
|
|
43
|
+
DsmPathwayCodec.encode(dataStreamsContext, fields.headers)
|
|
45
44
|
}
|
|
46
45
|
}
|
|
47
46
|
}
|
|
@@ -126,8 +126,9 @@ class BaseAwsSdkPlugin extends ClientPlugin {
|
|
|
126
126
|
if (err) {
|
|
127
127
|
span.setTag('error', err)
|
|
128
128
|
|
|
129
|
-
|
|
130
|
-
|
|
129
|
+
const requestId = err.RequestId || err.requestId
|
|
130
|
+
if (requestId) {
|
|
131
|
+
span.addTags({ 'aws.response.request_id': requestId })
|
|
131
132
|
}
|
|
132
133
|
}
|
|
133
134
|
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
const {
|
|
3
|
-
CONTEXT_PROPAGATION_KEY,
|
|
4
3
|
getSizeOrZero
|
|
5
4
|
} = require('../../../dd-trace/src/datastreams/processor')
|
|
6
|
-
const {
|
|
5
|
+
const { DsmPathwayCodec } = require('../../../dd-trace/src/datastreams/pathway')
|
|
7
6
|
const log = require('../../../dd-trace/src/log')
|
|
8
7
|
const BaseAwsSdkPlugin = require('../base')
|
|
9
8
|
const { storage } = require('../../../datadog-core')
|
|
@@ -113,13 +112,10 @@ class Kinesis extends BaseAwsSdkPlugin {
|
|
|
113
112
|
const parsedAttributes = JSON.parse(Buffer.from(record.Data).toString())
|
|
114
113
|
|
|
115
114
|
if (
|
|
116
|
-
parsedAttributes &&
|
|
117
|
-
parsedAttributes._datadog &&
|
|
118
|
-
parsedAttributes._datadog[CONTEXT_PROPAGATION_KEY] &&
|
|
119
|
-
streamName
|
|
115
|
+
parsedAttributes?._datadog && streamName && DsmPathwayCodec.contextExists(parsedAttributes._datadog)
|
|
120
116
|
) {
|
|
121
117
|
const payloadSize = getSizeOrZero(record.Data)
|
|
122
|
-
this.tracer.decodeDataStreamsContext(
|
|
118
|
+
this.tracer.decodeDataStreamsContext(parsedAttributes._datadog)
|
|
123
119
|
this.tracer
|
|
124
120
|
.setCheckpoint(['direction:in', `topic:${streamName}`, 'type:kinesis'], span, payloadSize)
|
|
125
121
|
}
|
|
@@ -182,10 +178,7 @@ class Kinesis extends BaseAwsSdkPlugin {
|
|
|
182
178
|
if (this.config.dsmEnabled) {
|
|
183
179
|
parsedData._datadog = ddInfo
|
|
184
180
|
const dataStreamsContext = this.setDSMCheckpoint(span, parsedData, stream)
|
|
185
|
-
|
|
186
|
-
const pathwayCtx = encodePathwayContext(dataStreamsContext)
|
|
187
|
-
ddInfo[CONTEXT_PROPAGATION_KEY] = pathwayCtx.toJSON()
|
|
188
|
-
}
|
|
181
|
+
DsmPathwayCodec.encode(dataStreamsContext, ddInfo)
|
|
189
182
|
}
|
|
190
183
|
|
|
191
184
|
if (Object.keys(ddInfo).length !== 0) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
|
-
const {
|
|
3
|
-
const {
|
|
2
|
+
const { getHeadersSize } = require('../../../dd-trace/src/datastreams/processor')
|
|
3
|
+
const { DsmPathwayCodec } = require('../../../dd-trace/src/datastreams/pathway')
|
|
4
4
|
const log = require('../../../dd-trace/src/log')
|
|
5
5
|
const BaseAwsSdkPlugin = require('../base')
|
|
6
6
|
|
|
@@ -94,10 +94,7 @@ class Sns extends BaseAwsSdkPlugin {
|
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
const dataStreamsContext = this.setDSMCheckpoint(span, params, topicArn)
|
|
97
|
-
|
|
98
|
-
const pathwayCtx = encodePathwayContext(dataStreamsContext)
|
|
99
|
-
ddInfo[CONTEXT_PROPAGATION_KEY] = pathwayCtx.toJSON()
|
|
100
|
-
}
|
|
97
|
+
DsmPathwayCodec.encode(dataStreamsContext, ddInfo)
|
|
101
98
|
}
|
|
102
99
|
|
|
103
100
|
if (Object.keys(ddInfo).length !== 0) {
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
const log = require('../../../dd-trace/src/log')
|
|
4
4
|
const BaseAwsSdkPlugin = require('../base')
|
|
5
5
|
const { storage } = require('../../../datadog-core')
|
|
6
|
-
const {
|
|
7
|
-
const {
|
|
6
|
+
const { getHeadersSize } = require('../../../dd-trace/src/datastreams/processor')
|
|
7
|
+
const { DsmPathwayCodec } = require('../../../dd-trace/src/datastreams/pathway')
|
|
8
8
|
|
|
9
9
|
class Sqs extends BaseAwsSdkPlugin {
|
|
10
10
|
static get id () { return 'sqs' }
|
|
@@ -192,13 +192,13 @@ class Sqs extends BaseAwsSdkPlugin {
|
|
|
192
192
|
parsedAttributes = this.parseDatadogAttributes(message.MessageAttributes._datadog)
|
|
193
193
|
}
|
|
194
194
|
}
|
|
195
|
-
if (parsedAttributes && parsedAttributes
|
|
195
|
+
if (parsedAttributes && DsmPathwayCodec.contextExists(parsedAttributes)) {
|
|
196
196
|
const payloadSize = getHeadersSize({
|
|
197
197
|
Body: message.Body,
|
|
198
198
|
MessageAttributes: message.MessageAttributes
|
|
199
199
|
})
|
|
200
200
|
const queue = params.QueueUrl.split('/').pop()
|
|
201
|
-
this.tracer.decodeDataStreamsContext(
|
|
201
|
+
this.tracer.decodeDataStreamsContext(parsedAttributes)
|
|
202
202
|
this.tracer
|
|
203
203
|
.setCheckpoint(['direction:in', `topic:${queue}`, 'type:sqs'], span, payloadSize)
|
|
204
204
|
}
|
|
@@ -252,9 +252,7 @@ class Sqs extends BaseAwsSdkPlugin {
|
|
|
252
252
|
|
|
253
253
|
const dataStreamsContext = this.setDSMCheckpoint(span, params, queueUrl)
|
|
254
254
|
if (dataStreamsContext) {
|
|
255
|
-
|
|
256
|
-
ddInfo[CONTEXT_PROPAGATION_KEY] = pathwayCtx.toJSON()
|
|
257
|
-
|
|
255
|
+
DsmPathwayCodec.encode(dataStreamsContext, ddInfo)
|
|
258
256
|
params.MessageAttributes._datadog.StringValue = JSON.stringify(ddInfo)
|
|
259
257
|
}
|
|
260
258
|
}
|
|
@@ -18,7 +18,7 @@ const {
|
|
|
18
18
|
TEST_SOURCE_FILE,
|
|
19
19
|
TEST_EARLY_FLAKE_IS_ENABLED,
|
|
20
20
|
TEST_IS_NEW,
|
|
21
|
-
|
|
21
|
+
TEST_IS_RETRY
|
|
22
22
|
} = require('../../dd-trace/src/plugins/util/test')
|
|
23
23
|
const { RESOURCE_NAME } = require('../../../ext/tags')
|
|
24
24
|
const { COMPONENT, ERROR_MESSAGE } = require('../../dd-trace/src/constants')
|
|
@@ -181,7 +181,7 @@ class CucumberPlugin extends CiPlugin {
|
|
|
181
181
|
if (isNew) {
|
|
182
182
|
span.setTag(TEST_IS_NEW, 'true')
|
|
183
183
|
if (isEfdRetry) {
|
|
184
|
-
span.setTag(
|
|
184
|
+
span.setTag(TEST_IS_RETRY, 'true')
|
|
185
185
|
}
|
|
186
186
|
}
|
|
187
187
|
|