Skip to content

Commit

Permalink
add e2e tests
Browse files Browse the repository at this point in the history
  • Loading branch information
juan-fernandez committed Feb 13, 2024
1 parent eeb082d commit ee1a5c4
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 13 deletions.
32 changes: 26 additions & 6 deletions integration-tests/ci-visibility-intake.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ let gitUploadStatus = DEFAULT_GIT_UPLOAD_STATUS
let infoResponse = DEFAULT_INFO_RESPONSE
let correlationId = DEFAULT_CORRELATION_ID
let knownTests = DEFAULT_KNOWN_TESTS
let waitingTime = null

class FakeCiVisIntake extends FakeAgent {
setKnownTests (newKnownTestsResponse) {
Expand All @@ -61,6 +62,10 @@ class FakeCiVisIntake extends FakeAgent {
settings = newSettings
}

setWaitingTime (newWaitingTime) {
waitingTime = newWaitingTime
}

async start () {
const app = express()
app.use(bodyParser.raw({ limit: Infinity, type: 'application/msgpack' }))
Expand All @@ -83,13 +88,25 @@ class FakeCiVisIntake extends FakeAgent {
})
})

// It can be slowed down with setWaitingTime
app.post(['/api/v2/citestcycle', '/evp_proxy/:version/api/v2/citestcycle'], (req, res) => {
res.status(200).send('OK')
this.emit('message', {
headers: req.headers,
payload: msgpack.decode(req.body, { codec }),
url: req.url
})
if (waitingTime) {
this.waitingTimeoutId = setTimeout(() => {
res.status(200).send('OK')
this.emit('message', {
headers: req.headers,
payload: msgpack.decode(req.body, { codec }),
url: req.url
})
}, waitingTime)
} else {
res.status(200).send('OK')
this.emit('message', {
headers: req.headers,
payload: msgpack.decode(req.body, { codec }),
url: req.url
})
}
})

app.post([
Expand Down Expand Up @@ -214,6 +231,9 @@ class FakeCiVisIntake extends FakeAgent {
gitUploadStatus = DEFAULT_GIT_UPLOAD_STATUS
infoResponse = DEFAULT_INFO_RESPONSE
this.removeAllListeners()
if (this.waitingTimeoutId) {
clearTimeout(this.waitingTimeoutId)
}
return super.stop()
}

Expand Down
78 changes: 78 additions & 0 deletions integration-tests/ci-visibility.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -783,6 +783,84 @@ testFrameworks.forEach(({
})
})
})
it('works with --forceExit and logs a warning', (done) => {
const eventsPromise = receiver
.gatherPayloadsMaxTimeout(({ url }) => url.endsWith('/api/v2/citestcycle'), (payloads) => {
assert.include(testOutput, "Jest's '--forceExit' flag has been passed")
const events = payloads.flatMap(({ payload }) => payload.events)

const testSession = events.find(event => event.type === 'test_session_end')
const testModule = events.find(event => event.type === 'test_module_end')
const testSuites = events.filter(event => event.type === 'test_suite_end')
const tests = events.filter(event => event.type === 'test')

assert.exists(testSession)
assert.exists(testModule)
assert.equal(testSuites.length, 2)
assert.equal(tests.length, 2)
})
// Needs to run with the CLI if we want --forceExit to work
childProcess = exec(
'node ./node_modules/jest/bin/jest --config config-jest.js --forceExit',
{
cwd,
env: {
...getCiVisAgentlessConfig(receiver.port),
DD_TRACE_DEBUG: '1',
DD_TRACE_LOG_LEVEL: 'warn'
},
stdio: 'inherit'
}
)
childProcess.on('exit', () => {
eventsPromise.then(() => {
done()
}).catch(done)
})
childProcess.stdout.on('data', (chunk) => {
testOutput += chunk.toString()
})
childProcess.stderr.on('data', (chunk) => {
testOutput += chunk.toString()
})
})
it('does not hang if server is not available and logs an error', (done) => {
// Very slow intake
receiver.setWaitingTime(30000)
const eventsPromise = receiver
.gatherPayloadsMaxTimeout(({ url }) => url.endsWith('/api/v2/citestcycle'), (payloads) => {
assert.include(testOutput, "Jest's '--forceExit' flag has been passed")
assert.include(testOutput, 'Timeout waiting for the tracer to flush')
const events = payloads.flatMap(({ payload }) => payload.events)

assert.equal(events.length, 0)
}, 12000)
// Needs to run with the CLI if we want --forceExit to work
childProcess = exec(
'node ./node_modules/jest/bin/jest --config config-jest.js --forceExit',
{
cwd,
env: {
...getCiVisAgentlessConfig(receiver.port),
DD_TRACE_DEBUG: '1',
DD_TRACE_LOG_LEVEL: 'warn'
},
stdio: 'inherit'
}
)
childProcess.on('exit', () => {
eventsPromise.then(() => {
receiver.setWaitingTime(0)
done()
}).catch(done)
})
childProcess.stdout.on('data', (chunk) => {
testOutput += chunk.toString()
})
childProcess.stderr.on('data', (chunk) => {
testOutput += chunk.toString()
})
})
}

it('can run tests and report spans', (done) => {
Expand Down
8 changes: 8 additions & 0 deletions integration-tests/config-jest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module.exports = {
projects: [__dirname],
testPathIgnorePatterns: ['/node_modules/'],
cache: false,
testMatch: [
'**/ci-visibility/test/ci-visibility-test*'
]
}
6 changes: 4 additions & 2 deletions integration-tests/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,8 @@ function getCiVisAgentlessConfig (port) {
DD_API_KEY: '1',
DD_CIVISIBILITY_AGENTLESS_ENABLED: 1,
DD_CIVISIBILITY_AGENTLESS_URL: `http://127.0.0.1:${port}`,
NODE_OPTIONS: '-r dd-trace/ci/init'
NODE_OPTIONS: '-r dd-trace/ci/init',
DD_INSTRUMENTATION_TELEMETRY_ENABLED: 'false'
}
}

Expand All @@ -291,7 +292,8 @@ function getCiVisEvpProxyConfig (port) {
...rest,
DD_TRACE_AGENT_PORT: port,
NODE_OPTIONS: '-r dd-trace/ci/init',
DD_CIVISIBILITY_AGENTLESS_ENABLED: '0'
DD_CIVISIBILITY_AGENTLESS_ENABLED: '0',
DD_INSTRUMENTATION_TELEMETRY_ENABLED: 'false'
}
}

Expand Down
10 changes: 7 additions & 3 deletions packages/datadog-instrumentations/src/jest.js
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ function cliWrapper (cli, jestVersion) {

const timeoutPromise = new Promise((resolve) => {
timeoutId = setTimeout(() => {
resolve()
resolve('timeout')
}, FLUSH_TIMEOUT).unref()
})

Expand All @@ -448,7 +448,11 @@ function cliWrapper (cli, jestVersion) {
onDone
})
})
await Promise.race([flushPromise, timeoutPromise])
const waitingResult = await Promise.race([flushPromise, timeoutPromise])

if (waitingResult === 'timeout') {
log.error('Timeout waiting for the tracer to flush')
}

numSkippedSuites = 0

Expand Down Expand Up @@ -568,7 +572,7 @@ function configureTestEnvironment (readConfigsResult) {
isUserCodeCoverageEnabled = !!readConfigsResult.globalConfig.collectCoverage

if (readConfigsResult.globalConfig.forceExit) {
log.warn("The '--forceExit' jest option has been found. Passing this flag may cause data to be lost.")
log.warn("Jest's '--forceExit' flag has been passed. This may cause loss of data.")
}

if (isCodeCoverageEnabled) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const {
getErrorTypeFromStatusCode
} = require('../telemetry')

const DEFAULT_NUM_RETRIES_EARLY_FLAKE_DETECTION = 2
const DEFAULT_EARLY_FLAKE_DETECTION_NUM_RETRIES = 2

function getLibraryConfiguration ({
url,
Expand Down Expand Up @@ -104,7 +104,7 @@ function getLibraryConfiguration ({
requireGit,
isEarlyFlakeDetectionEnabled: earlyFlakeDetectionConfig?.enabled ?? false,
earlyFlakeDetectionNumRetries:
earlyFlakeDetectionConfig?.slow_test_retries?.['5s'] || DEFAULT_NUM_RETRIES_EARLY_FLAKE_DETECTION
earlyFlakeDetectionConfig?.slow_test_retries?.['5s'] || DEFAULT_EARLY_FLAKE_DETECTION_NUM_RETRIES
}

log.debug(() => `Remote settings: ${JSON.stringify(settings)}`)
Expand Down

0 comments on commit ee1a5c4

Please sign in to comment.