Skip to content

Commit

Permalink
make common exporter
Browse files Browse the repository at this point in the history
  • Loading branch information
juan-fernandez committed Apr 26, 2024
1 parent f5021cc commit b89eaac
Show file tree
Hide file tree
Showing 8 changed files with 156 additions and 88 deletions.
7 changes: 4 additions & 3 deletions packages/datadog-instrumentations/src/cucumber.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const {
mergeCoverage,
fromCoverageMapToCoverage,
getTestSuitePath,
JEST_WORKER_TRACE_PAYLOAD_CODE
CUCUMBER_WORKER_TRACE_PAYLOAD_CODE
} = require('../../dd-trace/src/plugins/util/test')

const isMarkedAsUnskippable = (pickle) => {
Expand Down Expand Up @@ -459,15 +459,16 @@ function getWrappedGiveWork (giveWorkFunction) {
function getWrappedParseWorkerMessage (parseWorkerMessageFunction) {
return function (worker, message) {
// If the message is an array, it's a dd-trace message, so we need to stop cucumber processing
// Otherwise cucumber code will throw an error
// TODO: identify the message better
if (Array.isArray(message)) {
const [messageCode, payload] = message
if (messageCode === JEST_WORKER_TRACE_PAYLOAD_CODE) {
if (messageCode === CUCUMBER_WORKER_TRACE_PAYLOAD_CODE) {
sessionAsyncResource.runInAsyncScope(() => {
workerReportTraceCh.publish(payload)
})
return
}
return
}

const { jsonEnvelope } = message
Expand Down
33 changes: 0 additions & 33 deletions packages/dd-trace/src/ci-visibility/exporters/jest-worker/index.js

This file was deleted.

56 changes: 56 additions & 0 deletions packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
'use strict'

const Writer = require('./writer')
const {
JEST_WORKER_COVERAGE_PAYLOAD_CODE,
JEST_WORKER_TRACE_PAYLOAD_CODE,
CUCUMBER_WORKER_TRACE_PAYLOAD_CODE
} = require('../../../plugins/util/test')

function getInterprocessTraceCode () {
if (process.env.JEST_WORKER_ID) {
return JEST_WORKER_TRACE_PAYLOAD_CODE
}
if (process.env.CUCUMBER_WORKER_ID) {
return CUCUMBER_WORKER_TRACE_PAYLOAD_CODE
}
return null
}

// TODO: make it available with cucumber
function getInterprocessCoverageCode () {
if (process.env.JEST_WORKER_ID) {
return JEST_WORKER_COVERAGE_PAYLOAD_CODE
}
return null
}

/**
* Lightweight exporter whose writers only do simple JSON serialization
* of trace and coverage payloads, which they send to the test framework's main process.
* Currently used by Jest and Cucumber workers.
*/
class TestWorkerCiVisibilityExporter {
constructor () {
const interprocessTraceCode = getInterprocessTraceCode()
const interprocessCoverageCode = getInterprocessCoverageCode()

this._writer = new Writer(interprocessTraceCode)
this._coverageWriter = new Writer(interprocessCoverageCode)
}

export (payload) {
this._writer.append(payload)
}

exportCoverage (formattedCoverage) {
this._coverageWriter.append(formattedCoverage)
}

flush () {
this._writer.flush()
this._coverageWriter.flush()
}
}

module.exports = TestWorkerCiVisibilityExporter
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,18 @@ class Writer {
}

_sendPayload (data) {
// ## Jest
// Only available when `child_process` is used for the jest worker.
// eslint-disable-next-line
// https://github.com/facebook/jest/blob/bb39cb2c617a3334bf18daeca66bd87b7ccab28b/packages/jest-worker/README.md#experimental-worker
// If worker_threads is used, this will not work
// TODO: make it compatible with worker_threads

// ## Cucumber
// This reports to the test's main process the same way test data is reported by Cucumber
// See cucumber code:
// eslint-disable-next-line
// https://github.com/cucumber/cucumber-js/blob/5ce371870b677fe3d1a14915dc535688946f734c/src/runtime/parallel/run_worker.ts#L13
if (process.send) { // it only works if process.send is available
process.send([this._interprocessCode, data])
}
Expand Down
4 changes: 1 addition & 3 deletions packages/dd-trace/src/exporter.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,8 @@ module.exports = name => {
case exporters.AGENT_PROXY:
return require('./ci-visibility/exporters/agent-proxy')
case exporters.JEST_WORKER:
return require('./ci-visibility/exporters/jest-worker')
case exporters.CUCUMBER_WORKER:
// for the moment we'll use the same, but we have to change this!
return require('./ci-visibility/exporters/jest-worker')
return require('./ci-visibility/exporters/test-worker')
default:
return inAWSLambda && !usingLambdaExtension ? require('./exporters/log') : require('./exporters/agent')
}
Expand Down
4 changes: 4 additions & 0 deletions packages/dd-trace/src/plugins/util/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ const TEST_BROWSER_VERSION = 'test.browser.version'
const JEST_WORKER_TRACE_PAYLOAD_CODE = 60
const JEST_WORKER_COVERAGE_PAYLOAD_CODE = 61

// cucumber worker variables
const CUCUMBER_WORKER_TRACE_PAYLOAD_CODE = 70

// Early flake detection util strings
const EFD_STRING = "Retried by Datadog's Early Flake Detection"
const EFD_TEST_NAME_REGEX = new RegExp(EFD_STRING + ' \\(#\\d+\\): ', 'g')
Expand All @@ -107,6 +110,7 @@ module.exports = {
LIBRARY_VERSION,
JEST_WORKER_TRACE_PAYLOAD_CODE,
JEST_WORKER_COVERAGE_PAYLOAD_CODE,
CUCUMBER_WORKER_TRACE_PAYLOAD_CODE,
TEST_SOURCE_START,
TEST_SKIPPED_BY_ITR,
TEST_CONFIGURATION_BROWSER_NAME,
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
'use strict'

require('../../../../../dd-trace/test/setup/tap')

const TestWorkerCiVisibilityExporter = require('../../../../src/ci-visibility/exporters/test-worker')
const {
JEST_WORKER_TRACE_PAYLOAD_CODE,
JEST_WORKER_COVERAGE_PAYLOAD_CODE,
CUCUMBER_WORKER_TRACE_PAYLOAD_CODE
} = require('../../../../src/plugins/util/test')

describe('CI Visibility Test Worker Exporter', () => {
let send, originalSend
beforeEach(() => {
send = sinon.spy()
originalSend = process.send
process.send = send
})
afterEach(() => {
process.send = originalSend
})
context('when the process is a jest worker', () => {
beforeEach(() => {
process.env.JEST_WORKER_ID = '1'
})
afterEach(() => {
delete process.env.JEST_WORKER_ID
})
it('can export traces', () => {
const trace = [{ type: 'test' }]
const traceSecond = [{ type: 'test', name: 'other' }]
const jestWorkerExporter = new TestWorkerCiVisibilityExporter()
jestWorkerExporter.export(trace)
jestWorkerExporter.export(traceSecond)
jestWorkerExporter.flush()
expect(send).to.have.been.calledWith([JEST_WORKER_TRACE_PAYLOAD_CODE, JSON.stringify([trace, traceSecond])])
})
it('can export coverages', () => {
const coverage = { sessionId: '1', suiteId: '1', files: ['test.js'] }
const coverageSecond = { sessionId: '2', suiteId: '2', files: ['test2.js'] }
const jestWorkerExporter = new TestWorkerCiVisibilityExporter()
jestWorkerExporter.exportCoverage(coverage)
jestWorkerExporter.exportCoverage(coverageSecond)
jestWorkerExporter.flush()
expect(send).to.have.been.calledWith(
[JEST_WORKER_COVERAGE_PAYLOAD_CODE, JSON.stringify([coverage, coverageSecond])]
)
})
it('does not break if process.send is undefined', () => {
delete process.send
const trace = [{ type: 'test' }]
const jestWorkerExporter = new TestWorkerCiVisibilityExporter()
jestWorkerExporter.export(trace)
jestWorkerExporter.flush()
expect(send).not.to.have.been.called
})
})
context('when the process is a cucumber worker', () => {
beforeEach(() => {
process.env.CUCUMBER_WORKER_ID = '1'
})
afterEach(() => {
delete process.env.CUCUMBER_WORKER_ID
})
it('can export traces', () => {
debugger

Check failure on line 66 in packages/dd-trace/test/ci-visibility/exporters/test-worker/exporter.spec.js

View workflow job for this annotation

GitHub Actions / lint

Unexpected 'debugger' statement
const trace = [{ type: 'test' }]
const traceSecond = [{ type: 'test', name: 'other' }]
const cucumberWorkerExporter = new TestWorkerCiVisibilityExporter()
cucumberWorkerExporter.export(trace)
cucumberWorkerExporter.export(traceSecond)
cucumberWorkerExporter.flush()
expect(send).to.have.been.calledWith([CUCUMBER_WORKER_TRACE_PAYLOAD_CODE, JSON.stringify([trace, traceSecond])])
})
it('does not break if process.send is undefined', () => {
delete process.send
const trace = [{ type: 'test' }]
const cucumberWorkerExporter = new TestWorkerCiVisibilityExporter()
cucumberWorkerExporter.export(trace)
cucumberWorkerExporter.flush()
expect(send).not.to.have.been.called
})
})
})

0 comments on commit b89eaac

Please sign in to comment.