Comparing version 6.0.0-pre-c3e3d62 to 6.0.0-pre-efcd0a3
{ | ||
"name": "dd-trace", | ||
"version": "6.0.0-pre-c3e3d62", | ||
"version": "6.0.0-pre-efcd0a3", | ||
"description": "Datadog APM tracing client for JavaScript", | ||
@@ -72,7 +72,7 @@ "main": "index.js", | ||
"dependencies": { | ||
"@datadog/native-appsec": "7.1.0", | ||
"@datadog/native-appsec": "7.1.1", | ||
"@datadog/native-iast-rewriter": "2.3.0", | ||
"@datadog/native-iast-taint-tracking": "1.7.0", | ||
"@datadog/native-metrics": "^2.0.0", | ||
"@datadog/pprof": "5.1.0", | ||
"@datadog/pprof": "5.2.0", | ||
"@datadog/sketches-js": "^2.1.0", | ||
@@ -99,3 +99,3 @@ "@opentelemetry/api": "^1.0.0", | ||
"path-to-regexp": "^0.1.2", | ||
"pprof-format": "^2.0.7", | ||
"pprof-format": "^2.1.0", | ||
"protobufjs": "^7.2.5", | ||
@@ -102,0 +102,0 @@ "retry": "^0.13.1", |
@@ -295,2 +295,4 @@ 'use strict' | ||
knownTests = knownTestsResponse.knownTests | ||
} else { | ||
isEarlyFlakeDetectionEnabled = false | ||
} | ||
@@ -297,0 +299,0 @@ } |
@@ -47,2 +47,5 @@ 'use strict' | ||
// Message sent by jest's main process to workers to run a test suite (=test file) | ||
// https://github.com/jestjs/jest/blob/1d682f21c7a35da4d3ab3a1436a357b980ebd0fa/packages/jest-worker/src/types.ts#L37 | ||
const CHILD_MESSAGE_CALL = 1 | ||
// Maximum time we'll wait for the tracer to flush | ||
@@ -52,3 +55,3 @@ const FLUSH_TIMEOUT = 10000 | ||
let skippableSuites = [] | ||
let knownTests = [] | ||
let knownTests = {} | ||
let isCodeCoverageEnabled = false | ||
@@ -78,2 +81,3 @@ let isSuitesSkippingEnabled = false | ||
const retriedTestsToNumAttempts = new Map() | ||
const newTestsTestStatuses = new Map() | ||
@@ -107,2 +111,9 @@ // based on https://github.com/facebook/jest/blob/main/packages/jest-circus/src/formatNodeAssertErrors.ts#L41 | ||
function getEfdStats (testStatuses) { | ||
return testStatuses.reduce((acc, testStatus) => { | ||
acc[testStatus]++ | ||
return acc | ||
}, { pass: 0, fail: 0 }) | ||
} | ||
function getWrappedEnvironment (BaseEnvironment, jestVersion) { | ||
@@ -130,5 +141,8 @@ return class DatadogEnvironment extends BaseEnvironment { | ||
if (this.isEarlyFlakeDetectionEnabled) { | ||
const hasKnownTests = !!knownTests.jest | ||
earlyFlakeDetectionNumRetries = this.testEnvironmentOptions._ddEarlyFlakeDetectionNumRetries | ||
try { | ||
this.knownTestsForThisSuite = this.getKnownTestsForSuite(this.testEnvironmentOptions._ddKnownTests) | ||
this.knownTestsForThisSuite = hasKnownTests | ||
? (knownTests.jest[this.testSuite] || []) | ||
: this.getKnownTestsForSuite(this.testEnvironmentOptions._ddKnownTests) | ||
} catch (e) { | ||
@@ -153,3 +167,3 @@ // If there has been an error parsing the tests, we'll disable Early Flake Deteciton | ||
} | ||
return knownTestsForSuite.jest?.[this.testSuite] || [] | ||
return knownTestsForSuite | ||
} | ||
@@ -251,2 +265,15 @@ | ||
event.test.fn = originalTestFns.get(event.test) | ||
// We'll store the test statuses of the retries | ||
if (this.isEarlyFlakeDetectionEnabled) { | ||
const testName = getJestTestName(event.test) | ||
const originalTestName = removeEfdStringFromTestName(testName) | ||
const isNewTest = retriedTestsToNumAttempts.has(originalTestName) | ||
if (isNewTest) { | ||
if (newTestsTestStatuses.has(originalTestName)) { | ||
newTestsTestStatuses.get(originalTestName).push(status) | ||
} else { | ||
newTestsTestStatuses.set(originalTestName, [status]) | ||
} | ||
} | ||
} | ||
}) | ||
@@ -411,2 +438,5 @@ } | ||
knownTests = receivedKnownTests | ||
} else { | ||
// We disable EFD if there has been an error in the known tests request | ||
isEarlyFlakeDetectionEnabled = false | ||
} | ||
@@ -516,2 +546,24 @@ } catch (err) { | ||
/** | ||
* If Early Flake Detection (EFD) is enabled the logic is as follows: | ||
* - If all attempts for a test are failing, the test has failed and we will let the test process fail. | ||
* - If just a single attempt passes, we will prevent the test process from failing. | ||
* The rationale behind is the following: you may still be able to block your CI pipeline by gating | ||
* on flakiness (the test will be considered flaky), but you may choose to unblock the pipeline too. | ||
*/ | ||
if (isEarlyFlakeDetectionEnabled) { | ||
let numFailedTestsToIgnore = 0 | ||
for (const testStatuses of newTestsTestStatuses.values()) { | ||
const { pass, fail } = getEfdStats(testStatuses) | ||
if (pass > 0) { // as long as one passes, we'll consider the test passed | ||
numFailedTestsToIgnore += fail | ||
} | ||
} | ||
// If every test that failed was an EFD retry, we'll consider the suite passed | ||
if (numFailedTestsToIgnore !== 0 && result.results.numFailedTests === numFailedTestsToIgnore) { | ||
result.results.success = true | ||
} | ||
} | ||
return result | ||
@@ -628,3 +680,2 @@ }) | ||
config.testEnvironmentOptions._ddTestCodeCoverageEnabled = isCodeCoverageEnabled | ||
config.testEnvironmentOptions._ddKnownTests = knownTests | ||
}) | ||
@@ -805,2 +856,34 @@ | ||
const ChildProcessWorker = childProcessWorker.default | ||
shimmer.wrap(ChildProcessWorker.prototype, 'send', send => function (request) { | ||
if (!isEarlyFlakeDetectionEnabled) { | ||
return send.apply(this, arguments) | ||
} | ||
const [type] = request | ||
// eslint-disable-next-line | ||
// https://github.com/jestjs/jest/blob/1d682f21c7a35da4d3ab3a1436a357b980ebd0fa/packages/jest-worker/src/workers/ChildProcessWorker.ts#L424 | ||
if (type === CHILD_MESSAGE_CALL) { | ||
// This is the message that the main process sends to the worker to run a test suite (=test file). | ||
// In here we modify the config.testEnvironmentOptions to include the known tests for the suite. | ||
// This way the suite only knows about the tests that are part of it. | ||
const args = request[request.length - 1] | ||
if (args.length > 1) { | ||
return send.apply(this, arguments) | ||
} | ||
if (!args[0]?.config) { | ||
return send.apply(this, arguments) | ||
} | ||
const [{ globalConfig, config, path: testSuiteAbsolutePath }] = args | ||
const testSuite = getTestSuitePath(testSuiteAbsolutePath, globalConfig.rootDir || process.cwd()) | ||
const suiteKnownTests = knownTests.jest?.[testSuite] || [] | ||
args[0].config = { | ||
...config, | ||
testEnvironmentOptions: { | ||
...config.testEnvironmentOptions, | ||
_ddKnownTests: suiteKnownTests | ||
} | ||
} | ||
} | ||
return send.apply(this, arguments) | ||
}) | ||
shimmer.wrap(ChildProcessWorker.prototype, '_onMessage', _onMessage => function () { | ||
@@ -807,0 +890,0 @@ const [code, data] = arguments[0] |
@@ -24,3 +24,3 @@ 'use strict' | ||
addHook({ name: 'oracledb', versions: ['5'] }, oracledb => { | ||
addHook({ name: 'oracledb', versions: ['>=5'] }, oracledb => { | ||
shimmer.wrap(oracledb.Connection.prototype, 'execute', execute => { | ||
@@ -27,0 +27,0 @@ return function wrappedExecute (dbQuery, ...args) { |
@@ -39,3 +39,3 @@ const semver = require('semver') | ||
let earlyFlakeDetectionNumRetries = 0 | ||
let knownTests = [] | ||
let knownTests = {} | ||
let rootDir = '' | ||
@@ -411,2 +411,4 @@ const MINIMUM_SUPPORTED_VERSION_EFD = '1.38.0' | ||
knownTests = receivedKnownTests | ||
} else { | ||
isEarlyFlakeDetectionEnabled = false | ||
} | ||
@@ -439,3 +441,7 @@ } catch (err) { | ||
testSessionAsyncResource.runInAsyncScope(() => { | ||
testSessionFinishCh.publish({ status: STATUS_TO_TEST_STATUS[sessionStatus], onDone }) | ||
testSessionFinishCh.publish({ | ||
status: STATUS_TO_TEST_STATUS[sessionStatus], | ||
isEarlyFlakeDetectionEnabled, | ||
onDone | ||
}) | ||
}) | ||
@@ -442,0 +448,0 @@ await flushWait |
@@ -330,2 +330,3 @@ const { | ||
log.error(knownTestsResponse.err) | ||
this.isEarlyFlakeDetectionEnabled = false | ||
} else { | ||
@@ -332,0 +333,0 @@ // We use TEST_FRAMEWORK_NAME for the name of the module |
@@ -16,3 +16,4 @@ 'use strict' | ||
TEST_IS_NEW, | ||
TEST_IS_RETRY | ||
TEST_IS_RETRY, | ||
TEST_EARLY_FLAKE_IS_ENABLED | ||
} = require('../../dd-trace/src/plugins/util/test') | ||
@@ -39,6 +40,10 @@ const { RESOURCE_NAME } = require('../../../ext/tags') | ||
this.addSub('ci:playwright:session:finish', ({ status, onDone }) => { | ||
this.addSub('ci:playwright:session:finish', ({ status, isEarlyFlakeDetectionEnabled, onDone }) => { | ||
this.testModuleSpan.setTag(TEST_STATUS, status) | ||
this.testSessionSpan.setTag(TEST_STATUS, status) | ||
if (isEarlyFlakeDetectionEnabled) { | ||
this.testSessionSpan.setTag(TEST_EARLY_FLAKE_IS_ENABLED, 'true') | ||
} | ||
if (this.numFailedSuites > 0) { | ||
@@ -45,0 +50,0 @@ let errorMessage = `Test suites failed: ${this.numFailedSuites}.` |
@@ -23,7 +23,11 @@ 'use strict' | ||
'sqreen/lib/package-reader/index.js', | ||
'ws/lib/websocket-server.js' | ||
'ws/lib/websocket-server.js', | ||
'google-gax/build/src/grpc.js', | ||
'cookie-signature/index.js' | ||
) | ||
const EXCLUDED_PATHS_FROM_STACK = [ | ||
path.join('node_modules', 'object-hash', path.sep) | ||
path.join('node_modules', 'object-hash', path.sep), | ||
path.join('node_modules', 'aws-sdk', 'lib', 'util.js'), | ||
path.join('node_modules', 'keygrip', path.sep) | ||
] | ||
@@ -30,0 +34,0 @@ class WeakHashAnalyzer extends Analyzer { |
@@ -30,2 +30,3 @@ 'use strict' | ||
const defaultWafObfuscatorValueRegex = '(?i)(?:p(?:ass)?w(?:or)?d|pass(?:_?phrase)?|secret|(?:api_?|private_?|public_?|access_?|secret_?)key(?:_?id)?|token|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)(?:\\s*=[^;]|"\\s*:\\s*"[^"]+")|bearer\\s+[a-z0-9\\._\\-]+|token:[a-z0-9]{13}|gh[opsu]_[0-9a-zA-Z]{36}|ey[I-L][\\w=-]+\\.ey[I-L][\\w=-]+(?:\\.[\\w.+\\/=-]+)?|[\\-]{5}BEGIN[a-z\\s]+PRIVATE\\sKEY[\\-]{5}[^\\-]+[\\-]{5}END[a-z\\s]+PRIVATE\\sKEY|ssh-rsa\\s*[a-z0-9\\/\\.+]{100,}' | ||
const runtimeId = uuid() | ||
@@ -295,3 +296,3 @@ function maybeFile (filepath) { | ||
version: this.version, | ||
'runtime-id': uuid() | ||
'runtime-id': runtimeId | ||
}) | ||
@@ -828,2 +829,3 @@ | ||
tagger.add(tags, options.tracing_tags) | ||
if (Object.keys(tags).length) tags['runtime-id'] = runtimeId | ||
@@ -830,0 +832,0 @@ this._setUnit(opts, 'sampleRate', options.tracing_sampling_rate) |
@@ -126,2 +126,3 @@ const { | ||
log.error(`Known tests could not be fetched. ${err.message}`) | ||
this.libraryConfig.isEarlyFlakeDetectionEnabled = false | ||
} | ||
@@ -128,0 +129,0 @@ onDone({ err, knownTests }) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1681726
48913
+ Added@datadog/native-appsec@7.1.1(transitive)
+ Added@datadog/pprof@5.2.0(transitive)
- Removed@datadog/native-appsec@7.1.0(transitive)
- Removed@datadog/pprof@5.1.0(transitive)
Updated@datadog/native-appsec@7.1.1
Updated@datadog/pprof@5.2.0
Updatedpprof-format@^2.1.0