Skip to content

Commit

Permalink
test on a swath of versions, in CI only
Browse files Browse the repository at this point in the history
  • Loading branch information
bengl committed Jun 21, 2024
1 parent 98620da commit 9ea925f
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 103 deletions.
14 changes: 14 additions & 0 deletions .github/workflows/project.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,20 @@ jobs:
- run: sudo sysctl -w kernel.core_pattern='|/bin/false'
- run: yarn test:integration

# We'll run these separately for earlier (i.e. unsupported) versions
integration-guardrails:
strategy:
matrix:
version: [12, 14, 16]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v3
with:
node-version: ${{ matrix.version }}
- run: yarn install
- run: node node_modules/.bin/mocha --colors --timeout 30000 -r packages/dd-trace/test/setup/core.js integration-tests/init.spec.js

integration-ci:
strategy:
matrix:
Expand Down
20 changes: 14 additions & 6 deletions init.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,24 @@
const path = require('path')
const Module = require('module')
const telemetry = require('./packages/dd-trace/src/telemetry/init-telemetry')
const Config = require('./packages/dd-trace/src/config')
const log = require('./packages/dd-trace/src/log')
const semver = require('semver')

// eslint-disable-next-line no-new
new Config() // we need this to initialize the logger
function isTrue(envVar) {

Check failure on line 8 in init.js

View workflow job for this annotation

GitHub Actions / lint

Missing space before function parentheses
return ['1', 'true', 'True'].includes(envVar)
}

let log = { info: isTrue(process.env.DD_TRACE_DEBUG) ? console.log : () => {}}

Check failure on line 12 in init.js

View workflow job for this annotation

GitHub Actions / lint

Unexpected console statement

Check failure on line 12 in init.js

View workflow job for this annotation

GitHub Actions / lint

A space is required before '}'
if (semver.satisfies(process.versions.node, '>=16')) {
const Config = require('./packages/dd-trace/src/config')
log = require('./packages/dd-trace/src/log')

// eslint-disable-next-line no-new
new Config() // we need this to initialize the logger
}

let initBailout = false
let clobberBailout = false
const forced = ['1', 'true', 'True'].includes(process.env.DD_INJECT_FORCE)
const forced = isTrue(process.env.DD_INJECT_FORCE)

if (process.env.DD_INJECTION_ENABLED) {
// If we're running via single-step install, and we're not in the app's
Expand All @@ -36,7 +45,6 @@ if (process.env.DD_INJECTION_ENABLED) {
if (!clobberBailout) {
const { engines } = require('./package.json')
const version = process.versions.node
const semver = require('semver')
if (!semver.satisfies(version, engines.node)) {
initBailout = true
telemetry([
Expand Down
13 changes: 8 additions & 5 deletions initialize.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,12 @@ export async function getSource (...args) {
}

if (isMainThread) {
await import('./init.js')
const { register } = await import('node:module')
if (register) {
register('./loader-hook.mjs', import.meta.url)
}
// Need this IIFE for versions of Node.js without top-level await.
(async () => {
await import('./init.js')
const { register } = await import('node:module')
if (register) {
register('./loader-hook.mjs', import.meta.url)
}
})()
}
48 changes: 15 additions & 33 deletions integration-tests/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ const msgpack = require('msgpack-lite')
const codec = msgpack.createCodec({ int64: true })
const EventEmitter = require('events')
const childProcess = require('child_process')
const { fork, spawn, execSync } = childProcess
const { fork, spawn } = childProcess
const exec = promisify(childProcess.exec)
const http = require('http')
const fs = require('fs/promises')
const fs = require('fs')
const os = require('os')
const path = require('path')
const rimraf = promisify(require('rimraf'))
Expand Down Expand Up @@ -163,24 +163,16 @@ class FakeAgent extends EventEmitter {
}
}

let nodeBinary = process.argv[0]

async function runAndCheckOutput (filename, cwd, expectedOut) {
const oldOpts = process.env.NODE_OPTIONS
delete process.env.NODE_OPTIONS
const nodeVersion = nodeBinary === process.argv[0]
? process.versions.node
: execSync(`${nodeBinary} -p process.versions.node`).toString().trim()
process.env.NODE_OPTIONS = oldOpts

const proc = spawn(nodeBinary, [filename], { cwd, stdio: 'pipe' })
const proc = spawn('node', [filename], { cwd, stdio: 'pipe' })
const pid = proc.pid
let out = await new Promise((resolve, reject) => {
proc.on('error', reject)
let out = Buffer.alloc(0)
proc.stdout.on('data', data => {
out = Buffer.concat([out, data])
})
proc.stderr.pipe(process.stdout)
proc.on('exit', () => resolve(out.toString('utf8')))
setTimeout(() => {
if (proc.exitCode === null) proc.kill()
Expand All @@ -195,7 +187,7 @@ async function runAndCheckOutput (filename, cwd, expectedOut) {
}
assert.strictEqual(out, expectedOut)
}
return [pid, nodeVersion]
return pid
}

// This is set by the useSandbox function
Expand All @@ -205,7 +197,7 @@ let sandbox
async function runAndCheckWithTelemetry (filename, expectedOut, ...expectedTelemetryPoints) {
const cwd = sandbox.folder
const cleanup = telemetryForwarder(expectedTelemetryPoints)
const [pid, nodeVersion] = await runAndCheckOutput(filename, cwd, expectedOut)
const pid = await runAndCheckOutput(filename, cwd, expectedOut)
const msgs = await cleanup()
if (expectedTelemetryPoints.length === 0) {
// assert no telemetry sent
Expand Down Expand Up @@ -251,9 +243,9 @@ async function runAndCheckWithTelemetry (filename, expectedOut, ...expectedTelem
function meta (pid) {
return {
language_name: 'nodejs',
language_version: nodeVersion,
language_version: process.versions.node,
runtime_name: 'nodejs',
runtime_version: nodeVersion,
runtime_version: process.versions.node,
tracer_version: require('../package.json').version,
pid: Number(pid)
}
Expand Down Expand Up @@ -303,9 +295,9 @@ async function createSandbox (dependencies = [], isGitRepo = false,
// We might use NODE_OPTIONS to init the tracer. We don't want this to affect this operations
const { NODE_OPTIONS, ...restOfEnv } = process.env

await fs.mkdir(folder)
fs.mkdirSync(folder)
await exec(`yarn pack --filename ${out}`, { env: restOfEnv }) // TODO: cache this
await exec(`npm install ${allDependencies.join(' ')}`, { cwd: folder, env: restOfEnv })
await exec(`yarn add ${allDependencies.join(' ')} --ignore-engines`, { cwd: folder, env: restOfEnv })

for (const path of integrationTestsPaths) {
if (process.platform === 'win32') {
Expand All @@ -327,7 +319,7 @@ async function createSandbox (dependencies = [], isGitRepo = false,

if (isGitRepo) {
await exec('git init', { cwd: folder })
await fs.writeFile(path.join(folder, '.gitignore'), 'node_modules/', { flush: true })
fs.writeFileSync(path.join(folder, '.gitignore'), 'node_modules/', { flush: true })
await exec('git config user.email "[email protected]"', { cwd: folder })
await exec('git config user.name "John Doe"', { cwd: folder })
await exec('git config commit.gpgsign false', { cwd: folder })
Expand Down Expand Up @@ -356,10 +348,10 @@ function telemetryForwarder (expectedTelemetryPoints) {
return cleanup()
}

const cleanup = async function () {
const cleanup = function () {
let msgs
try {
msgs = (await fs.readFile(process.env.FORWARDER_OUT, 'utf8')).trim().split('\n')
msgs = fs.readFileSync(process.env.FORWARDER_OUT, 'utf8').trim().split('\n')
} catch (e) {
if (expectedTelemetryPoints.length && e.code === 'ENOENT' && retries < 10) {
return tryAgain()
Expand All @@ -382,7 +374,7 @@ function telemetryForwarder (expectedTelemetryPoints) {
}
msgs[i] = [telemetryType, parsed]
}
await fs.unlink(process.env.FORWARDER_OUT)
fs.unlinkSync(process.env.FORWARDER_OUT)
delete process.env.FORWARDER_OUT
delete process.env.DD_TELEMETRY_FORWARDER_PATH
return msgs
Expand Down Expand Up @@ -484,15 +476,6 @@ function sandboxCwd () {
return sandbox.folder
}

function useSandboxedNode () {
before(() => {
nodeBinary = path.join(sandbox.folder, 'node_modules/.bin/node')
})
after(() => {
nodeBinary = process.argv[0]
})
}

module.exports = {
FakeAgent,
spawnProc,
Expand All @@ -506,6 +489,5 @@ module.exports = {
spawnPluginIntegrationTestProc,
useEnv,
useSandbox,
sandboxCwd,
useSandboxedNode
sandboxCwd
}
Loading

0 comments on commit 9ea925f

Please sign in to comment.