Socket
Socket
Sign inDemoInstall

dd-trace

Package Overview
Dependencies
18
Maintainers
3
Versions
558
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.6.0-beta.2 to 0.6.0

ext/kinds.js

2

benchmark/benchmark.js

@@ -7,3 +7,3 @@ 'use strict'

Benchmark.options.maxTime = 0.5
Benchmark.options.maxTime = 0.1
Benchmark.options.minSamples = 5

@@ -10,0 +10,0 @@

@@ -31,3 +31,2 @@ 'use strict'

let sampler
let queue

@@ -81,17 +80,2 @@ const traceStub = require('./stubs/trace')

})
.add('Writer#flush (1000 items)', {
onStart () {
writer = new Writer({}, 1001)
for (let i = 0; i < 1000; i++) {
writer.append(spanStub)
}
queue = writer._queue
},
fn () {
writer._queue = queue
writer.flush()
}
})
.add('Sampler#isSampled', {

@@ -98,0 +82,0 @@ onStart () {

'use strict'
const benchmark = require('../benchmark')
const Buffer = require('safe-buffer').Buffer
const platform = require('../../src/platform')

@@ -12,4 +11,2 @@ const node = require('../../src/platform/node')

let data
const traceStub = require('../stubs/trace')

@@ -28,22 +25,2 @@

})
.add('request', {
onStart () {
data = Buffer.alloc(1000000)
},
fn () {
platform
.request({
protocol: 'http:',
hostname: 'test',
port: '8080',
path: '/v0.4/traces',
method: 'PUT',
headers: {
'Content-Type': 'application/msgpack'
},
data
})
.catch(() => {})
}
})
.add('msgpack#prefix', {

@@ -50,0 +27,0 @@ fn () {

@@ -184,2 +184,21 @@ <h1 id="home">Datadog JavaScript Tracer API</h1>

<h3 id="hapi">hapi</h3>
<h5 id="hapi-tags">Tags</h5>
| Tag | Description |
|------------------|-----------------------------------------------------------|
| http.url | The complete URL of the request. |
| http.method | The HTTP method of the request. |
| http.status_code | The HTTP status code of the response. |
| http.headers.* | A recorded HTTP header. |
<h5 id="hapi-config">Configuration Options</h5>
| Option | Default | Description |
|------------------|---------------------------|----------------------------------------|
| service | *Service name of the app* | The service name for this integration. |
| validateStatus | `code => code < 500` | Callback function to determine if there was an error. It should take a status code as its only parameter and return `true` for success or `false` for errors. |
| headers | `[]` | An array of headers to include in the span metadata. |
<h3 id="http">http / https</h3>

@@ -202,2 +221,53 @@

<h3 id="ioredis">ioredis</h3>
<h5 id="ioredis-tags">Tags</h5>
| Tag | Description |
|------------------|-----------------------------------------------------------|
| db.name | The index of the queried database. |
| out.host | The host of the Redis server. |
| out.port | The port of the Redis server. |
<h5 id="ioredis-config">Configuration Options</h5>
| Option | Default | Description |
|------------------|------------------|----------------------------------------|
| service | redis | The service name for this integration. |
<h3 id="koa">koa</h3>
<h5 id="koa-tags">Tags</h5>
| Tag | Description |
|------------------|-----------------------------------------------------------|
| http.url | The complete URL of the request. |
| http.method | The HTTP method of the request. |
| http.status_code | The HTTP status code of the response. |
| http.headers.* | A recorded HTTP header. |
<h5 id="koa-config">Configuration Options</h5>
| Option | Default | Description |
|------------------|---------------------------|----------------------------------------|
| service | *Service name of the app* | The service name for this integration. |
| validateStatus | `code => code < 500` | Callback function to determine if there was an error. It should take a status code as its only parameter and return `true` for success or `false` for errors. |
| headers | `[]` | An array of headers to include in the span metadata. |
<h3 id="memcached">memcached</h3>
<h5 id="memcached-tags">Tags</h5>
| Tag | Description |
|------------------|-----------------------------------------------------------|
| memcached.query | The query sent to the server. |
| out.host | The host of the Memcached server. |
| out.port | The port of the Memcached server. |
<h5 id="memcached-config">Configuration Options</h5>
| Option | Default | Description |
|------------------|------------------|----------------------------------------|
| service | memcached | The service name for this integration. |
<h3 id="mongodb-core">mongodb-core</h3>

@@ -287,2 +357,22 @@

<h3 id="restify">restify</h3>
<h5 id="restify-tags">Tags</h5>
| Tag | Description |
|------------------|-----------------------------------------------------------|
| http.url | The complete URL of the request. |
| http.method | The HTTP method of the request. |
| http.status_code | The HTTP status code of the response. |
| http.headers.* | A recorded HTTP header. |
<h5 id="restify-config">Configuration Options</h5>
| Option | Default | Description |
|------------------|---------------------------|----------------------------------------|
| service | *Service name of the app* | The service name for this integration. |
| validateStatus | `code => code < 500` | Callback function to determine if there was an error. It should take a status code as its only parameter and return `true` for success or `false` for errors. |
| headers | `[]` | An array of headers to include in the span metadata. |
<h2 id="advanced-configuration">Advanced Configuration</h2>

@@ -289,0 +379,0 @@

'use strict'
module.exports = {
// Common
SERVICE_NAME: 'service.name',
RESOURCE_NAME: 'resource.name',
SPAN_TYPE: 'span.type',
SAMPLING_PRIORITY: 'sampling.priority'
SPAN_KIND: 'span.kind',
SAMPLING_PRIORITY: 'sampling.priority',
ERROR: 'error',
// HTTP
HTTP_URL: 'http.url',
HTTP_METHOD: 'http.method',
HTTP_STATUS_CODE: 'http.status_code',
HTTP_HEADERS: 'http.headers'
}

@@ -1,1 +0,1 @@

module.exports = '0.6.0-beta.2'
module.exports = '0.6.0'
{
"name": "dd-trace",
"version": "0.6.0-beta.2",
"version": "0.6.0",
"description": "Datadog APM tracing client for JavaScript",

@@ -13,3 +13,3 @@ "main": "index.js",

"test": "node ./scripts/install_plugin_modules && nyc --reporter text --reporter lcov mocha 'test/**/*.spec.js'",
"leak": "node --no-warnings ./node_modules/.bin/tape 'test/leak/**/*.js'"
"leak": "(cd test/leak && yarn) && NODE_PATH=./test/leak/node_modules node --no-warnings ./node_modules/.bin/tape 'test/leak/{,!(node_modules)/**/}/*.js'"
},

@@ -78,2 +78,3 @@ "repository": {

"jsdoc": "^3.5.5",
"memcached": "^2.2.2",
"mocha": "^5.2.0",

@@ -90,9 +91,7 @@ "mongodb-core": "^3.0.7",

"retry": "^0.10.1",
"selfsigned": "^1.10.3",
"sinon": "^4.2.1",
"sinon-chai": "^2.14.0",
"tape": "^4.9.1"
},
"optionalDependencies": {
"@airbnb/node-memwatch": "^1.0.2"
}
}

@@ -9,5 +9,5 @@ 'use strict'

const filePath = path.join(__dirname, '..', '/LICENSE-3rdparty.csv')
const deps = Object.keys(pkg.dependencies)
.concat(Object.keys(pkg.devDependencies))
.concat(Object.keys(pkg.optionalDependencies))
const deps = Object.keys(pkg.dependencies || {})
.concat(Object.keys(pkg.devDependencies || {}))
.concat(Object.keys(pkg.optionalDependencies || {}))
.sort()

@@ -14,0 +14,0 @@

@@ -10,2 +10,3 @@ 'use strict'

const plugins = requireDir('../src/plugins')
const externals = require('../test/plugins/externals')

@@ -23,10 +24,13 @@ const workspaces = new Set()

function assertVersions () {
Object.keys(plugins).filter(key => key !== 'index').forEach(key => {
[].concat(plugins[key]).forEach(instrumentation => {
[].concat(instrumentation.versions).forEach(version => {
if (version) {
assertModules(instrumentation.name, version)
assertModules(instrumentation.name, semver.coerce(version).version)
}
})
const internals = Object.keys(plugins)
.filter(key => key !== 'index')
.map(key => plugins[key])
.reduce((prev, next) => prev.concat(next), [])
internals.concat(externals).forEach(instrumentation => {
[].concat(instrumentation.versions).forEach(version => {
if (version) {
assertModules(instrumentation.name, version)
assertModules(instrumentation.name, semver.coerce(version).version)
}
})

@@ -33,0 +37,0 @@ })

'use strict'
const Uint64BE = require('int64-buffer').Uint64BE
const Int64BE = require('int64-buffer').Int64BE
const DatadogSpanContext = require('../span_context')

@@ -15,4 +14,4 @@

inject (spanContext, carrier) {
carrier[traceKey] = new Int64BE(spanContext.traceId.toBuffer()).toString()
carrier[spanKey] = new Int64BE(spanContext.spanId.toBuffer()).toString()
carrier[traceKey] = spanContext.traceId.toString()
carrier[spanKey] = spanContext.spanId.toString()

@@ -19,0 +18,0 @@ this._injectSamplingPriority(spanContext, carrier)

'use strict'
const Buffer = require('safe-buffer').Buffer
const Uint64BE = require('int64-buffer').Uint64BE
const randomBytes = require('crypto').randomBytes
module.exports = () => new Uint64BE(randomBytes(8))
// Cryptographically secure local seeds to mitigate Math.random() seed reuse.
const hiSeed = randomBytes(4).readUInt32BE()
const loSeed = randomBytes(4).readUInt32BE()
// Simple pseudo-random 64-bit ID generator.
function pseudoRandom () {
const buffer = Buffer.allocUnsafe(8)
const hi = randomUInt32(hiSeed) & 0x7FFFFFFF // only positive int64
const lo = randomUInt32(loSeed)
writeUInt32BE(buffer, hi, 0)
writeUInt32BE(buffer, lo, 4)
return buffer
}
// Generate a random unsigned 32-bit integer.
function randomUInt32 (seed) {
return seed ^ Math.floor(Math.random() * (0xFFFFFFFF + 1))
}
// Write unsigned integer bytes to a buffer. Faster than Buffer.writeUInt32BE().
function writeUInt32BE (buffer, value, offset) {
buffer[3 + offset] = value & 255
value = value >> 8
buffer[2 + offset] = value & 255
value = value >> 8
buffer[1 + offset] = value & 255
value = value >> 8
buffer[0 + offset] = value & 255
}
module.exports = () => new Uint64BE(pseudoRandom())
'use strict'
const opentracing = require('opentracing')
const Tags = opentracing.Tags
const FORMAT_HTTP_HEADERS = opentracing.FORMAT_HTTP_HEADERS
const METHODS = require('methods').concat('use', 'route', 'param', 'all')
const pathToRegExp = require('path-to-regexp')
const log = require('../log')
const web = require('./util/web')
const OPERATION_NAME = 'express.request'
function createWrapMethod (tracer, config) {
const headersToRecord = getHeadersToRecord(config)
const validateStatus = getStatusValidator(config)
config = web.normalizeConfig(config)
function ddTrace (req, res, next) {
if (req._datadog.span) return next()
if (web.active(req)) return next()
const url = `${req.protocol}://${req.get('host')}${req.originalUrl}`
const childOf = tracer.extract(FORMAT_HTTP_HEADERS, req.headers)
web.instrument(tracer, config, req, res, 'express.request')
const span = tracer.startSpan(OPERATION_NAME, {
childOf,
tags: {
[Tags.SPAN_KIND]: Tags.SPAN_KIND_RPC_SERVER,
[Tags.HTTP_URL]: url,
[Tags.HTTP_METHOD]: req.method
}
})
const originalEnd = res.end
res.end = function () {
if (req._datadog.finished) return originalEnd.apply(this, arguments)
const returned = originalEnd.apply(this, arguments)
const path = req._datadog.paths.join('')
const resource = [req.method].concat(path).filter(val => val).join(' ')
span.setTag('resource.name', resource)
span.setTag('service.name', config.service || tracer._service)
span.setTag('span.type', 'http')
span.setTag(Tags.HTTP_STATUS_CODE, res.statusCode)
if (!validateStatus(res.statusCode)) {
span.setTag(Tags.ERROR, true)
}
headersToRecord.forEach(key => {
const value = req.headers[key]
if (value) {
span.setTag(`http.headers.${key}`, value)
}
})
span.finish()
req._datadog.scope && req._datadog.scope.close()
req._datadog.finished = true
return returned
}
req._datadog.span = span
next()

@@ -83,7 +32,3 @@ }

return function handleWithTracer (req) {
if (!req._datadog) {
Object.defineProperty(req, '_datadog', {
value: { paths: [] }
})
}
web.patch(req)

@@ -106,3 +51,3 @@ return handle.apply(this, arguments)

if (matchers[i].test(layer.path)) {
req._datadog.paths.push(matchers[i].path)
web.enterRoute(req, matchers[i].path)

@@ -148,3 +93,3 @@ break

function wrapNext (tracer, layer, req, next) {
if (!req._datadog.span) {
if (!web.active(req)) {
return next

@@ -155,8 +100,7 @@ }

req._datadog.scope && req._datadog.scope.close()
req._datadog.scope = tracer.scopeManager().activate(req._datadog.span)
web.reactivate(req)
return function (error) {
if (!error && layer.path && !isFastStar(layer)) {
req._datadog.paths.pop()
web.exitRoute(req)
}

@@ -170,24 +114,2 @@

function getHeadersToRecord (config) {
if (Array.isArray(config.headers)) {
try {
return config.headers.map(key => key.toLowerCase())
} catch (err) {
log.error(err)
}
} else if (config.hasOwnProperty('headers')) {
log.error('Expected `headers` to be an array of strings.')
}
return []
}
function getStatusValidator (config) {
if (typeof config.validateStatus === 'function') {
return config.validateStatus
} else if (config.hasOwnProperty('validateStatus')) {
log.error('Expected `validateStatus` to be a function.')
}
return code => code < 500
}
function extractMatchers (fn) {

@@ -194,0 +116,0 @@ const arg = flatten([].concat(fn))

@@ -5,2 +5,3 @@ 'use strict'

const opentracing = require('opentracing')
const semver = require('semver')

@@ -10,17 +11,17 @@ const Tags = opentracing.Tags

function patch (http, tracer, config) {
this.wrap(http, 'request', request => makeRequestTrace(request))
this.wrap(http, 'get', get => makeRequestTrace(get))
function patch (http, methodName, tracer, config) {
this.wrap(http, methodName, fn => makeRequestTrace(fn))
function makeRequestTrace (request) {
return function requestTrace (options, callback) {
const uri = extractUrl(options)
const method = (options.method || 'GET').toUpperCase()
return function requestTrace () {
const args = normalizeArgs.apply(null, arguments)
const uri = args.uri
const options = args.options
const callback = args.callback
if (uri === `${tracer._url.href}/v0.4/traces`) {
return request.apply(this, [options, callback])
return request.call(this, options, callback)
}
options = typeof options === 'string' ? url.parse(uri) : Object.assign({}, options)
options.headers = options.headers || {}
const method = (options.method || 'GET').toUpperCase()

@@ -85,2 +86,14 @@ const parentScope = tracer.scopeManager().active()

}
function normalizeArgs (inputURL, inputOptions, callback) {
let options = typeof inputURL === 'string' ? url.parse(inputURL) : Object.assign({}, inputURL)
options.headers = options.headers || {}
if (typeof inputOptions === 'function') {
callback = inputOptions
} else if (typeof inputOptions === 'object') {
options = Object.assign(options, inputOptions)
}
const uri = extractUrl(options)
return { uri, options, callback }
}
}

@@ -144,3 +157,12 @@

name: 'http',
patch,
patch: function (http, tracer, config) {
patch.call(this, http, 'request', tracer, config)
if (semver.satisfies(process.version, '>=8')) {
/**
* In newer Node versions references internal to modules, such as `http(s).get` calling `http(s).request`, do
* not use externally patched versions, which is why we need to also patch `get` here separately.
*/
patch.call(this, http, 'get', tracer, config)
}
},
unpatch

@@ -150,5 +172,16 @@ },

name: 'https',
patch,
patch: function (http, tracer, config) {
if (semver.satisfies(process.version, '>=9')) {
patch.call(this, http, 'request', tracer, config)
patch.call(this, http, 'get', tracer, config)
} else {
/**
* Below Node v9 the `https` module invokes `http.request`, which would end up counting requests twice.
* So rather then patch the `https` module, we ensure the `http` module is patched and we count only there.
*/
require('http')
}
},
unpatch
}
]

@@ -9,3 +9,7 @@ 'use strict'

'graphql': require('./graphql'),
'hapi': require('./hapi'),
'http': require('./http'),
'ioredis': require('./ioredis'),
'koa': require('./koa'),
'memcached': require('./memcached'),
'mongodb-core': require('./mongodb-core'),

@@ -15,3 +19,4 @@ 'mysql': require('./mysql'),

'pg': require('./pg'),
'redis': require('./redis')
'redis': require('./redis'),
'restify': require('./restify')
}

@@ -17,3 +17,3 @@ 'use strict'

'x-datadog-trace-id': '123',
'x-datadog-parent-id': '-456',
'x-datadog-parent-id': '18446744073709551160', // -456 casted to uint64
'ot-baggage-foo': 'bar'

@@ -38,3 +38,3 @@ }

expect(carrier).to.have.property('x-datadog-trace-id', '123')
expect(carrier).to.have.property('x-datadog-parent-id', '-456')
expect(carrier).to.have.property('x-datadog-parent-id', '18446744073709551160') // -456 casted to uint64
expect(carrier).to.have.property('ot-baggage-foo', 'bar')

@@ -41,0 +41,0 @@ })

@@ -65,3 +65,10 @@ 'use strict'

beforeEach(() => {
randomBytes = sinon.stub()
const seed = Buffer.alloc(4)
seed.writeUInt32BE(0xFF000000)
randomBytes = sinon.stub().returns(seed)
sinon.stub(Math, 'random')
id = proxyquire('../src/platform/node/id', {

@@ -72,10 +79,10 @@ 'crypto': { randomBytes }

it('should return a random 64bit ID', () => {
const buffer = Buffer.alloc(8)
buffer.writeUInt32BE(0x12345678)
buffer.writeUInt32BE(0x87654321, 4)
afterEach(() => {
Math.random.restore()
})
randomBytes.returns(buffer)
it('should return a random 63bit ID', () => {
Math.random.returns(0x0000FF00 / (0xFFFFFFFF + 1))
expect(id().toString('16')).to.equal('1234567887654321')
expect(id().toBuffer().toString('hex')).to.equal('7f00ff00ff00ff00')
})

@@ -82,0 +89,0 @@ })

@@ -11,10 +11,10 @@ 'use strict'

const handlers = new Set()
let agent = null
let server = null
let listener = null
let tracer = null
let handlers = []
let promise
let skip = []
module.exports = {
// Load the plugin on the tracer with an optional config and start a mock agent.
load (plugin, pluginName, config) {

@@ -32,10 +32,3 @@ tracer = require('../..')

res.status(200).send('OK')
if (skip[0]) {
skip[0].resolve()
skip.shift()
} else if (handlers[0]) {
handlers[0](req.body)
handlers.shift()
}
handlers.forEach(handler => handler(req.body))
})

@@ -45,3 +38,3 @@

return new Promise((resolve, reject) => {
const server = http.createServer(agent)
server = http.createServer(agent)

@@ -67,35 +60,58 @@ listener = server.listen(port, 'localhost', resolve)

use (callback, count) {
count = count || 1
promise = Promise.reject(new Error('No request was expected.'))
// Register a callback with expectations to be run on every agent call.
use (callback) {
const deferred = {}
const promise = new Promise((resolve, reject) => {
deferred.resolve = resolve
deferred.reject = reject
})
for (let i = 0; i < count; i++) {
promise = promise.catch(() => new Promise((resolve, reject) => {
handlers.push(function () {
try {
callback.apply(null, arguments)
resolve()
} catch (e) {
reject(e)
}
})
}))
const timeout = setTimeout(() => {
if (error) {
deferred.reject(error)
}
}, 1000)
let error
const handler = function () {
try {
callback.apply(null, arguments)
handlers.delete(handler)
clearTimeout(timeout)
deferred.resolve()
} catch (e) {
error = error || e
}
}
handler.promise = promise
handlers.add(handler)
return promise
},
skip (count) {
for (let i = 0; i < count; i++) {
const defer = {}
// Return a promise that will resolve when all expectations have run.
promise () {
const promises = Array.from(handlers)
.map(handler => handler.promise.catch(e => e))
defer.promise = new Promise((resolve, reject) => {
defer.resolve = resolve
defer.reject = reject
})
return Promise.all(promises)
.then(results => results.find(e => e instanceof Error))
},
skip.push(defer)
// Unregister any outstanding expectation callbacks.
reset () {
handlers.clear()
},
// Wrap a callback so it will only be called when all expectations have run.
wrap (callback) {
return error => {
this.promise()
.then(err => callback(error || err))
}
},
// Return the current active span.
currentSpan () {

@@ -106,19 +122,22 @@ const scope = tracer.scopeManager().active()

// Stop the mock agent, reset all expectations and wipe the require cache.
close () {
const timeout = setTimeout(() => {
skip.forEach(defer => defer.resolve())
}, 1000)
this.wipe()
return Promise.all(skip.map(defer => defer.promise))
.then(() => {
clearTimeout(timeout)
listener.close()
listener = null
agent = null
handlers = []
skip = []
delete require.cache[require.resolve('../..')]
listener.close()
listener = null
agent = null
handlers.clear()
delete require.cache[require.resolve('../..')]
return new Promise((resolve, reject) => {
server.on('close', () => {
server = null
resolve()
})
})
},
// Wipe the require cache.
wipe () {

@@ -125,0 +144,0 @@ const basedir = path.join(__dirname, 'versions')

@@ -21,26 +21,28 @@ 'use strict'

connection.close()
agent.close()
agent.wipe()
})
describe('without configuration', () => {
before(() => {
return agent.load(plugin, 'amqplib')
})
after(() => {
return agent.close()
})
describe('when using a callback', () => {
beforeEach(done => {
agent.load(plugin, 'amqplib')
.then(() => {
require(`./versions/amqplib@${version}`).get('amqplib/callback_api')
.connect((err, conn) => {
connection = conn
require(`./versions/amqplib@${version}`).get('amqplib/callback_api')
.connect((err, conn) => {
connection = conn
if (err != null) {
return done(err)
}
if (err != null) {
return done(err)
}
conn.createChannel((err, ch) => {
channel = ch
done(err)
})
})
conn.createChannel((err, ch) => {
channel = ch
done(err)
})
})
.catch(done)
})

@@ -219,4 +221,3 @@

beforeEach(() => {
return agent.load(plugin, 'amqplib')
.then(() => require(`./versions/amqplib@${version}`).get().connect())
return require(`./versions/amqplib@${version}`).get().connect()
.then(conn => (connection = conn))

@@ -241,20 +242,24 @@ .then(conn => conn.createChannel())

describe('with configuration', () => {
before(() => {
return agent.load(plugin, 'amqplib', { service: 'test' })
})
after(() => {
return agent.close()
})
beforeEach(done => {
agent.load(plugin, 'amqplib', { service: 'test' })
.then(() => {
require(`./versions/amqplib@${version}`).get('amqplib/callback_api')
.connect((err, conn) => {
connection = conn
require(`./versions/amqplib@${version}`).get('amqplib/callback_api')
.connect((err, conn) => {
connection = conn
if (err !== null) {
return done(err)
}
if (err !== null) {
return done(err)
}
conn.createChannel((err, ch) => {
channel = ch
done(err)
})
})
conn.createChannel((err, ch) => {
channel = ch
done(err)
})
})
.catch(done)
})

@@ -261,0 +266,0 @@

@@ -18,20 +18,20 @@ 'use strict'

afterEach(() => {
agent.close()
agent.wipe()
})
describe('without configuration', () => {
let client
beforeEach(() => {
before(() => {
return agent.load(plugin, 'elasticsearch')
.then(() => {
elasticsearch = require(`./versions/elasticsearch@${version}`).get()
client = new elasticsearch.Client({
host: 'localhost:9200'
})
})
})
after(() => {
return agent.close()
})
beforeEach(() => {
elasticsearch = require(`./versions/elasticsearch@${version}`).get()
client = new elasticsearch.Client({
host: 'localhost:9200'
})
})
it('should sanitize the resource name', done => {

@@ -226,12 +226,17 @@ agent

beforeEach(() => {
before(() => {
return agent.load(plugin, 'elasticsearch', { service: 'test' })
.then(() => {
elasticsearch = require(`./versions/elasticsearch@${version}`).get()
client = new elasticsearch.Client({
host: 'localhost:9200'
})
})
})
after(() => {
return agent.close()
})
beforeEach(() => {
elasticsearch = require(`./versions/elasticsearch@${version}`).get()
client = new elasticsearch.Client({
host: 'localhost:9200'
})
})
it('should be configured with the correct values', done => {

@@ -238,0 +243,0 @@ agent

@@ -22,3 +22,2 @@ 'use strict'

afterEach(() => {
agent.close()
appListener.close()

@@ -28,9 +27,14 @@ })

describe('without configuration', () => {
beforeEach(() => {
before(() => {
return agent.load(plugin, 'express')
.then(() => {
express = require(`./versions/express@${version}`).get()
})
})
after(() => {
return agent.close()
})
beforeEach(() => {
express = require(`./versions/express@${version}`).get()
})
it('should do automatic instrumentation on app routes', done => {

@@ -481,7 +485,2 @@ const app = express()

axios.get(`http://localhost:${port}/app/user/123`)
.then(res => {
expect(res.status).to.equal(200)
expect(res.data).to.be.empty
done()
})
.catch(done)

@@ -553,17 +552,18 @@ })

describe('with configuration', () => {
let config
beforeEach(() => {
config = {
before(() => {
return agent.load(plugin, 'express', {
service: 'custom',
validateStatus: code => code < 400,
headers: ['User-Agent']
}
})
})
return agent.load(plugin, 'express', config)
.then(() => {
express = require(`./versions/express@${version}`).get()
})
after(() => {
return agent.close()
})
beforeEach(() => {
express = require(`./versions/express@${version}`).get()
})
it('should be configured with the correct service name', done => {

@@ -570,0 +570,0 @@ const app = express()

@@ -143,15 +143,10 @@ 'use strict'

withVersions(plugin, 'graphql', version => {
beforeEach(() => {
tracer = require('../..')
before(() => {
sort = spans => spans.sort((a, b) => a.start.toString() >= b.start.toString() ? 1 : -1)
})
afterEach(() => {
agent.close()
agent.wipe()
})
describe('without configuration', () => {
before(() => {
tracer = require('../..')
describe('without configuration', () => {
beforeEach(() => {
return agent.load(plugin, 'graphql')

@@ -164,2 +159,6 @@ .then(() => {

after(() => {
return agent.close()
})
it('should instrument operations', done => {

@@ -477,5 +476,4 @@ const source = `query MyQuery { hello(name: "world") }`

expect(result.data.human.pets[0].owner.name).to.equal('test')
done()
})
.then(done)
.catch(done)

@@ -782,12 +780,20 @@ })

describe('with configuration', () => {
beforeEach(() => {
before(() => {
tracer = require('../..')
return agent.load(plugin, 'graphql', {
service: 'test',
variables: variables => Object.assign({}, variables, { who: 'REDACTED' })
}).then(() => {
graphql = require(`./versions/graphql@${version}`).get()
buildSchema()
})
})
after(() => {
return agent.close()
})
beforeEach(() => {
graphql = require(`./versions/graphql@${version}`).get()
buildSchema()
})
it('should be configured with the correct values', done => {

@@ -831,10 +837,17 @@ const source = `{ hello(name: "world") }`

describe('with a depth of 0', () => {
beforeEach(() => {
before(() => {
tracer = require('../..')
return agent.load(plugin, 'graphql', { depth: 0 })
.then(() => {
graphql = require(`./versions/graphql@${version}`).get()
buildSchema()
})
})
after(() => {
return agent.close()
})
beforeEach(() => {
graphql = require(`./versions/graphql@${version}`).get()
buildSchema()
})
it('should only instrument the operation', done => {

@@ -871,10 +884,17 @@ const source = `

describe('with a depth >=1', () => {
beforeEach(() => {
before(() => {
tracer = require('../..')
return agent.load(plugin, 'graphql', { depth: 2 })
.then(() => {
graphql = require(`./versions/graphql@${version}`).get()
buildSchema()
})
})
after(() => {
return agent.close()
})
beforeEach(() => {
graphql = require(`./versions/graphql@${version}`).get()
buildSchema()
})
it('should only instrument up to the specified depth', done => {

@@ -881,0 +901,0 @@ const source = `

@@ -5,2 +5,3 @@ 'use strict'

const agent = require('./agent')
const semver = require('semver')

@@ -15,445 +16,583 @@ wrapIt()

let tracer
let pems
describe('http', () => {
beforeEach(() => {
plugin = require('../../src/plugins/http')
tracer = require('../..')
})
['http', 'https'].forEach(protocol => {
describe(protocol, () => {
function server (app, port, listener) {
let server
if (protocol === 'https') {
if (!pems) {
// Generate self-signed cert
pems = require('selfsigned').generate([{ name: 'commonName', value: 'datadoghq.com' }], { days: 365 })
// We're fine with self-signed certs for this test
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'
}
server = require('https').createServer({ key: pems.private, cert: pems.cert }, app)
} else {
server = require('http').createServer(app)
}
server.listen(port, 'localhost', listener)
return server
}
afterEach(() => {
appListener.close()
return agent.close()
})
describe('without configuration', () => {
beforeEach(() => {
return agent.load(plugin, 'http')
.then(() => {
http = require('http')
express = require('express')
})
plugin = require('../../src/plugins/http')
tracer = require('../..')
appListener = null
})
it('should do automatic instrumentation', done => {
const app = express()
afterEach(() => {
if (appListener) {
appListener.close()
}
return agent.close()
})
app.get('/user', (req, res) => {
res.status(200).send()
describe('without configuration', () => {
beforeEach(() => {
return agent.load(plugin, 'http')
.then(() => {
http = require(protocol)
express = require('express')
})
})
getPort().then(port => {
agent
.use(traces => {
expect(traces[0][0]).to.have.property('service', 'test-http-client')
expect(traces[0][0]).to.have.property('type', 'web')
expect(traces[0][0]).to.have.property('resource', 'GET')
expect(traces[0][0].meta).to.have.property('span.kind', 'client')
expect(traces[0][0].meta).to.have.property('http.url', `http://localhost:${port}/user`)
expect(traces[0][0].meta).to.have.property('http.method', 'GET')
expect(traces[0][0].meta).to.have.property('http.status_code', '200')
})
.then(done)
.catch(done)
it('should do automatic instrumentation', done => {
const app = express()
appListener = app.listen(port, 'localhost', () => {
const req = http.request(`http://localhost:${port}/user`, res => {
res.on('data', () => {})
app.get('/user', (req, res) => {
res.status(200).send()
})
getPort().then(port => {
agent
.use(traces => {
expect(traces[0][0]).to.have.property('service', 'test-http-client')
expect(traces[0][0]).to.have.property('type', 'web')
expect(traces[0][0]).to.have.property('resource', 'GET')
expect(traces[0][0].meta).to.have.property('span.kind', 'client')
expect(traces[0][0].meta).to.have.property('http.url', `${protocol}://localhost:${port}/user`)
expect(traces[0][0].meta).to.have.property('http.method', 'GET')
expect(traces[0][0].meta).to.have.property('http.status_code', '200')
})
.then(done)
.catch(done)
appListener = server(app, port, () => {
const req = http.request(`${protocol}://localhost:${port}/user`, res => {
res.on('data', () => {})
})
req.end()
})
req.end()
})
})
})
it('should also support http.get', done => {
const app = express()
it(`should also support get()`, done => {
const app = express()
app.get('/user', (req, res) => {
res.status(200).send()
})
app.get('/user', (req, res) => {
res.status(200).send()
})
getPort().then(port => {
agent
.use(traces => {
expect(traces[0][0]).to.not.be.undefined
})
.then(done)
.catch(done)
getPort().then(port => {
agent
.use(traces => {
expect(traces[0][0]).to.not.be.undefined
})
.then(done)
.catch(done)
appListener = app.listen(port, 'localhost', () => {
const req = http.get(`http://localhost:${port}/user`, res => {
res.on('data', () => {})
appListener = server(app, port, () => {
const req = http.get(`${protocol}://localhost:${port}/user`, res => {
res.on('data', () => {})
})
req.end()
})
req.end()
})
})
})
it('should support configuration as an URL object', done => {
getPort().then(port => {
agent
.use(traces => {
expect(traces[0][0].meta).to.have.property('http.url', `http://localhost:${port}/user`)
})
.then(done)
.catch(done)
it('should support configuration as an URL object', done => {
const app = express()
const uri = {
hostname: 'localhost',
port,
pathname: '/user'
}
app.get('/user', (req, res) => {
res.status(200).send()
})
const req = http.request(uri)
getPort().then(port => {
agent
.use(traces => {
expect(traces[0][0].meta).to.have.property('http.url', `${protocol}://localhost:${port}/user`)
})
.then(done)
.catch(done)
req.end()
const uri = {
protocol: `${protocol}:`,
hostname: 'localhost',
port,
pathname: '/user'
}
appListener = server(app, port, () => {
const req = http.request(uri)
req.end()
})
})
})
})
it('should use the correct defaults when not specified', done => {
getPort().then(port => {
agent
.use(traces => {
expect(traces[0][0].meta).to.have.property('http.url', `http://localhost:${port}/`)
if (semver.satisfies(process.version, '>=10')) {
it('should support a string URL and an options object, which merges and takes precedence', done => {
const app = express()
app.get('/user', (req, res) => {
res.status(200).send()
})
.then(done)
.catch(done)
const req = http.request({
port
getPort().then(port => {
agent
.use(traces => {
expect(traces[0][0].meta).to.have.property('http.url', `${protocol}://localhost:${port}/user`)
})
.then(done)
.catch(done)
appListener = server(app, port, () => {
const req = http.request(`${protocol}://localhost:${port}/another-path`, { path: '/user' })
req.end()
})
})
})
req.end()
})
})
it('should support a URL object and an options object, which merges and takes precedence', done => {
const app = express()
it('should not require consuming the data', done => {
const app = express()
app.get('/user', (req, res) => {
res.status(200).send()
})
app.get('/user', (req, res) => {
res.status(200).send()
})
getPort().then(port => {
agent
.use(traces => {
expect(traces[0][0].meta).to.have.property('http.url', `${protocol}://localhost:${port}/user`)
})
.then(done)
.catch(done)
getPort().then(port => {
agent
.use(traces => {
expect(traces[0][0]).to.not.be.undefined
const uri = {
protocol: `${protocol}:`,
hostname: 'localhost',
port,
pathname: '/another-path'
}
appListener = server(app, port, () => {
const req = http.request(uri, { path: '/user' })
req.end()
})
})
.then(done)
.catch(done)
})
}
appListener = app.listen(port, 'localhost', () => {
const req = http.request(`http://localhost:${port}/user`)
it('should use the correct defaults when not specified', done => {
const app = express()
req.end()
app.get('/user', (req, res) => {
res.status(200).send()
})
})
})
it('should wait for other listeners before resuming the response stream', done => {
const app = express()
getPort().then(port => {
agent
.use(traces => {
expect(traces[0][0].meta).to.have.property('http.url', `${protocol}://localhost:${port}/`)
})
.then(done)
.catch(done)
app.get('/user', (req, res) => {
res.status(200).send('OK')
})
appListener = server(app, port, () => {
const req = http.request({
protocol: `${protocol}:`,
port
})
getPort().then(port => {
appListener = app.listen(port, 'localhost', () => {
const req = http.request(`http://localhost:${port}/user`, res => {
setTimeout(() => {
res.on('data', () => done())
})
req.end()
})
req.end()
})
})
})
it('should inject its parent span in the headers', done => {
const app = express()
it('should not require consuming the data', done => {
const app = express()
app.get('/user', (req, res) => {
expect(req.get('x-datadog-trace-id')).to.be.a('string')
expect(req.get('x-datadog-parent-id')).to.be.a('string')
app.get('/user', (req, res) => {
res.status(200).send()
})
res.status(200).send()
})
getPort().then(port => {
agent
.use(traces => {
expect(traces[0][0]).to.not.be.undefined
})
.then(done)
.catch(done)
getPort().then(port => {
agent
.use(traces => {
expect(traces[0][0].meta).to.have.property('http.status_code', '200')
appListener = server(app, port, () => {
const req = http.request(`${protocol}://localhost:${port}/user`)
req.end()
})
.then(done)
.catch(done)
})
})
appListener = app.listen(port, 'localhost', () => {
const req = http.request(`http://localhost:${port}/user`)
it('should wait for other listeners before resuming the response stream', done => {
const app = express()
req.end()
app.get('/user', (req, res) => {
res.status(200).send('OK')
})
getPort().then(port => {
appListener = server(app, port, () => {
const req = http.request(`${protocol}://localhost:${port}/user`, res => {
setTimeout(() => {
res.on('data', () => done())
})
})
req.end()
})
})
})
})
it('should skip injecting if the Authorization header contains an AWS signature', done => {
const app = express()
it('should inject its parent span in the headers', done => {
const app = express()
app.get('/', (req, res) => {
try {
expect(req.get('x-datadog-trace-id')).to.be.undefined
expect(req.get('x-datadog-parent-id')).to.be.undefined
app.get('/user', (req, res) => {
expect(req.get('x-datadog-trace-id')).to.be.a('string')
expect(req.get('x-datadog-parent-id')).to.be.a('string')
res.status(200).send()
})
done()
} catch (e) {
done(e)
}
})
getPort().then(port => {
agent
.use(traces => {
expect(traces[0][0].meta).to.have.property('http.status_code', '200')
})
.then(done)
.catch(done)
getPort().then(port => {
appListener = app.listen(port, 'localhost', () => {
const req = http.request({
port,
headers: {
Authorization: 'AWS4-HMAC-SHA256 ...'
}
appListener = server(app, port, () => {
const req = http.request(`${protocol}://localhost:${port}/user`)
req.end()
})
req.end()
})
})
})
it('should skip injecting if one of the Authorization headers contains an AWS signature', done => {
const app = express()
it('should skip injecting if the Authorization header contains an AWS signature', done => {
const app = express()
app.get('/', (req, res) => {
try {
expect(req.get('x-datadog-trace-id')).to.be.undefined
expect(req.get('x-datadog-parent-id')).to.be.undefined
app.get('/', (req, res) => {
try {
expect(req.get('x-datadog-trace-id')).to.be.undefined
expect(req.get('x-datadog-parent-id')).to.be.undefined
res.status(200).send()
res.status(200).send()
done()
} catch (e) {
done(e)
}
})
done()
} catch (e) {
done(e)
}
})
getPort().then(port => {
appListener = app.listen(port, 'localhost', () => {
const req = http.request({
port,
headers: {
Authorization: ['AWS4-HMAC-SHA256 ...']
}
getPort().then(port => {
appListener = server(app, port, () => {
const req = http.request({
port,
headers: {
Authorization: 'AWS4-HMAC-SHA256 ...'
}
})
req.end()
})
req.end()
})
})
})
it('should skip injecting if the X-Amz-Signature header is set', done => {
const app = express()
it('should skip injecting if one of the Authorization headers contains an AWS signature', done => {
const app = express()
app.get('/', (req, res) => {
try {
expect(req.get('x-datadog-trace-id')).to.be.undefined
expect(req.get('x-datadog-parent-id')).to.be.undefined
app.get('/', (req, res) => {
try {
expect(req.get('x-datadog-trace-id')).to.be.undefined
expect(req.get('x-datadog-parent-id')).to.be.undefined
res.status(200).send()
res.status(200).send()
done()
} catch (e) {
done(e)
}
})
done()
} catch (e) {
done(e)
}
})
getPort().then(port => {
appListener = app.listen(port, 'localhost', () => {
const req = http.request({
port,
headers: {
'X-Amz-Signature': 'abc123'
}
getPort().then(port => {
appListener = server(app, port, () => {
const req = http.request({
port,
headers: {
Authorization: ['AWS4-HMAC-SHA256 ...']
}
})
req.end()
})
req.end()
})
})
})
it('should skip injecting if the X-Amz-Signature query param is set', done => {
const app = express()
it('should skip injecting if the X-Amz-Signature header is set', done => {
const app = express()
app.get('/', (req, res) => {
try {
expect(req.get('x-datadog-trace-id')).to.be.undefined
expect(req.get('x-datadog-parent-id')).to.be.undefined
app.get('/', (req, res) => {
try {
expect(req.get('x-datadog-trace-id')).to.be.undefined
expect(req.get('x-datadog-parent-id')).to.be.undefined
res.status(200).send()
res.status(200).send()
done()
} catch (e) {
done(e)
}
})
done()
} catch (e) {
done(e)
}
})
getPort().then(port => {
appListener = app.listen(port, 'localhost', () => {
const req = http.request({
port,
path: '/?X-Amz-Signature=abc123'
getPort().then(port => {
appListener = server(app, port, () => {
const req = http.request({
port,
headers: {
'X-Amz-Signature': 'abc123'
}
})
req.end()
})
req.end()
})
})
})
it('should run the callback in the parent context', done => {
if (process.env.DD_CONTEXT_PROPAGATION === 'false') return done()
it('should skip injecting if the X-Amz-Signature query param is set', done => {
const app = express()
const app = express()
app.get('/', (req, res) => {
try {
expect(req.get('x-datadog-trace-id')).to.be.undefined
expect(req.get('x-datadog-parent-id')).to.be.undefined
app.get('/user', (req, res) => {
res.status(200).send('OK')
})
res.status(200).send()
getPort().then(port => {
appListener = app.listen(port, 'localhost', () => {
const req = http.request(`http://localhost:${port}/user`, res => {
expect(tracer.scopeManager().active()).to.be.null
done()
} catch (e) {
done(e)
}
})
getPort().then(port => {
appListener = server(app, port, () => {
const req = http.request({
port,
path: '/?X-Amz-Signature=abc123'
})
req.end()
})
req.end()
})
})
})
it('should run the event listeners in the parent context', done => {
if (process.env.DD_CONTEXT_PROPAGATION === 'false') return done()
it('should run the callback in the parent context', done => {
if (process.env.DD_CONTEXT_PROPAGATION === 'false') return done()
const app = express()
const app = express()
app.get('/user', (req, res) => {
res.status(200).send('OK')
})
app.get('/user', (req, res) => {
res.status(200).send('OK')
})
getPort().then(port => {
appListener = app.listen(port, 'localhost', () => {
const req = http.request(`http://localhost:${port}/user`, res => {
res.on('data', () => {})
res.on('end', () => {
getPort().then(port => {
appListener = server(app, port, () => {
const req = http.request(`${protocol}://localhost:${port}/user`, res => {
expect(tracer.scopeManager().active()).to.be.null
done()
})
req.end()
})
req.end()
})
})
})
it('should handle errors', done => {
getPort().then(port => {
agent
.use(traces => {
expect(traces[0][0].meta).to.have.property('error.type', 'Error')
expect(traces[0][0].meta).to.have.property('error.msg', `connect ECONNREFUSED 127.0.0.1:${port}`)
expect(traces[0][0].meta).to.have.property('error.stack')
it('should run the event listeners in the parent context', done => {
if (process.env.DD_CONTEXT_PROPAGATION === 'false') return done()
const app = express()
app.get('/user', (req, res) => {
res.status(200).send('OK')
})
getPort().then(port => {
appListener = server(app, port, () => {
const req = http.request(`${protocol}://localhost:${port}/user`, res => {
res.on('data', () => {})
res.on('end', () => {
expect(tracer.scopeManager().active()).to.be.null
done()
})
})
req.end()
})
.then(done)
.catch(done)
})
})
const req = http.request(`http://localhost:${port}/user`)
it('should handle errors', done => {
getPort().then(port => {
agent
.use(traces => {
expect(traces[0][0].meta).to.have.property('error.type', 'Error')
expect(traces[0][0].meta).to.have.property('error.msg', `connect ECONNREFUSED 127.0.0.1:${port}`)
expect(traces[0][0].meta).to.have.property('error.stack')
})
.then(done)
.catch(done)
req.end()
const req = http.request(`${protocol}://localhost:${port}/user`)
req.end()
})
})
})
})
describe('with service configuration', () => {
let config
it('should only record a request once', done => {
// Make sure both plugins are loaded, which could cause double-counting.
require('http')
require('https')
beforeEach(() => {
config = {
service: 'custom'
}
const app = express()
return agent.load(plugin, 'http', config)
.then(() => {
http = require('http')
express = require('express')
app.get('/user', (req, res) => {
res.status(200).send()
})
})
it('should be configured with the correct values', done => {
const app = express()
getPort().then(port => {
agent
.use(traces => {
const spans = traces[0]
expect(spans.length).to.equal(3)
})
.then(done)
.catch(done)
app.get('/user', (req, res) => {
res.status(200).send()
})
appListener = server(app, port, () => {
// Activate a new parent span so we capture any double counting that may happen, otherwise double-counts
// would be siblings and our test would only capture 1 as a false positive.
const span = tracer.startSpan('http-test')
tracer.scopeManager().activate(span)
getPort().then(port => {
agent
.use(traces => {
expect(traces[0][0]).to.have.property('service', 'custom')
})
.then(done)
.catch(done)
// Test `http(s).request
const req = http.request(`${protocol}://localhost:${port}/user?test=request`, res => {
res.on('data', () => {})
})
req.end()
appListener = app.listen(port, 'localhost', () => {
const req = http.request(`http://localhost:${port}/user`, res => {
res.on('data', () => {})
// Test `http(s).get`
http.get(`${protocol}://localhost:${port}/user?test=get`, res => {
res.on('data', () => {})
})
span.finish()
})
req.end()
})
})
})
})
describe('with splitByDomain configuration', () => {
let config
describe('with service configuration', () => {
let config
beforeEach(() => {
config = {
splitByDomain: true
}
beforeEach(() => {
config = {
service: 'custom'
}
return agent.load(plugin, 'http', config)
.then(() => {
http = require('http')
express = require('express')
return agent.load(plugin, 'http', config)
.then(() => {
http = require(protocol)
express = require('express')
})
})
it('should be configured with the correct values', done => {
const app = express()
app.get('/user', (req, res) => {
res.status(200).send()
})
})
it('should use the remote endpoint as the service name', done => {
const app = express()
getPort().then(port => {
agent
.use(traces => {
expect(traces[0][0]).to.have.property('service', 'custom')
})
.then(done)
.catch(done)
app.get('/user', (req, res) => {
res.status(200).send()
})
appListener = server(app, port, () => {
const req = http.request(`${protocol}://localhost:${port}/user`, res => {
res.on('data', () => {})
})
getPort().then(port => {
agent
.use(traces => {
expect(traces[0][0]).to.have.property('service', `localhost:${port}`)
req.end()
})
.then(done)
.catch(done)
})
})
})
appListener = app.listen(port, 'localhost', () => {
const req = http.request(`http://localhost:${port}/user`, res => {
res.on('data', () => {})
describe('with splitByDomain configuration', () => {
let config
beforeEach(() => {
config = {
splitByDomain: true
}
return agent.load(plugin, 'http', config)
.then(() => {
http = require(protocol)
express = require('express')
})
})
req.end()
it('should use the remote endpoint as the service name', done => {
const app = express()
app.get('/user', (req, res) => {
res.status(200).send()
})
getPort().then(port => {
agent
.use(traces => {
expect(traces[0][0]).to.have.property('service', `localhost:${port}`)
})
.then(done)
.catch(done)
appListener = server(app, port, () => {
const req = http.request(`${protocol}://localhost:${port}/user`, res => {
res.on('data', () => {})
})
req.end()
})
})
})

@@ -460,0 +599,0 @@ })

@@ -26,3 +26,2 @@ 'use strict'

afterEach(() => {
agent.close()
server.destroy()

@@ -32,19 +31,23 @@ })

describe('without configuration', () => {
before(() => {
return agent.load(plugin, 'mongodb-core')
})
after(() => {
return agent.close()
})
beforeEach(done => {
agent.load(plugin, 'mongodb-core')
.then(() => {
mongo = require(`./versions/mongodb-core@${version}`).get()
mongo = require(`./versions/mongodb-core@${version}`).get()
server = new mongo.Server({
host: 'localhost',
port: 27017,
reconnect: false
})
server = new mongo.Server({
host: 'localhost',
port: 27017,
reconnect: false
})
server.on('connect', () => done())
server.on('error', done)
server.on('connect', () => done())
server.on('error', done)
server.connect()
})
.catch(done)
server.connect()
})

@@ -290,25 +293,23 @@

describe('with configuration', () => {
let config
before(() => {
return agent.load(plugin, 'mongodb-core', { service: 'custom' })
})
after(() => {
return agent.close()
})
beforeEach(done => {
config = {
service: 'custom'
}
mongo = require(`./versions/mongodb-core@${version}`).get()
agent.load(plugin, 'mongodb-core', config)
.then(() => {
mongo = require(`./versions/mongodb-core@${version}`).get()
server = new mongo.Server({
host: 'localhost',
port: 27017,
reconnect: false
})
server = new mongo.Server({
host: 'localhost',
port: 27017,
reconnect: false
})
server.on('connect', () => done())
server.on('error', done)
server.on('connect', () => done())
server.on('error', done)
server.connect()
})
.catch(done)
server.connect()
})

@@ -315,0 +316,0 @@

@@ -18,23 +18,23 @@ 'use strict'

afterEach(() => {
agent.close()
agent.wipe()
})
describe('without configuration', () => {
let connection
beforeEach(() => {
before(() => {
return agent.load(plugin, 'mysql')
.then(() => {
mysql = require(`./versions/mysql@${version}`).get()
})
connection = mysql.createConnection({
host: 'localhost',
user: 'root',
database: 'db'
})
after(() => {
return agent.close()
})
connection.connect()
})
beforeEach(() => {
mysql = require(`./versions/mysql@${version}`).get()
connection = mysql.createConnection({
host: 'localhost',
user: 'root',
database: 'db'
})
connection.connect()
})

@@ -126,21 +126,21 @@

let connection
let config
before(() => {
return agent.load(plugin, 'mysql', { service: 'custom' })
})
after(() => {
return agent.close()
})
beforeEach(() => {
config = {
service: 'custom'
}
mysql = require(`./versions/mysql@${version}`).get()
return agent.load(plugin, 'mysql', config)
.then(() => {
mysql = require(`./versions/mysql@${version}`).get()
connection = mysql.createConnection({
host: 'localhost',
user: 'root',
database: 'db'
})
connection = mysql.createConnection({
host: 'localhost',
user: 'root',
database: 'db'
})
connection.connect()
})
connection.connect()
})

@@ -165,16 +165,21 @@

beforeEach(() => {
before(() => {
return agent.load(plugin, 'mysql')
.then(() => {
mysql = require(`./versions/mysql@${version}`).get()
})
pool = mysql.createPool({
connectionLimit: 10,
host: 'localhost',
user: 'root',
database: 'db'
})
})
after(() => {
return agent.close()
})
beforeEach(() => {
mysql = require(`./versions/mysql@${version}`).get()
pool = mysql.createPool({
connectionLimit: 10,
host: 'localhost',
user: 'root',
database: 'db'
})
})
afterEach(done => {

@@ -181,0 +186,0 @@ pool.end(done)

@@ -18,23 +18,23 @@ 'use strict'

afterEach(() => {
agent.close()
agent.wipe()
})
describe('without configuration', () => {
let connection
beforeEach(() => {
before(() => {
return agent.load(plugin, 'mysql2')
.then(() => {
mysql2 = require(`./versions/mysql2@${version}`).get()
})
connection = mysql2.createConnection({
host: 'localhost',
user: 'root',
database: 'db'
})
after(() => {
return agent.close()
})
connection.connect()
})
beforeEach(() => {
mysql2 = require(`./versions/mysql2@${version}`).get()
connection = mysql2.createConnection({
host: 'localhost',
user: 'root',
database: 'db'
})
connection.connect()
})

@@ -129,21 +129,21 @@

let connection
let config
before(() => {
return agent.load(plugin, 'mysql2', { service: 'custom' })
})
after(() => {
return agent.close()
})
beforeEach(() => {
config = {
service: 'custom'
}
mysql2 = require(`./versions/mysql2@${version}`).get()
return agent.load(plugin, 'mysql2', config)
.then(() => {
mysql2 = require(`./versions/mysql2@${version}`).get()
connection = mysql2.createConnection({
host: 'localhost',
user: 'root',
database: 'db'
})
connection = mysql2.createConnection({
host: 'localhost',
user: 'root',
database: 'db'
})
connection.connect()
})
connection.connect()
})

@@ -170,15 +170,20 @@

beforeEach(() => {
before(() => {
return agent.load(plugin, 'mysql2')
.then(() => {
mysql2 = require(`./versions/mysql2@${version}`).get()
})
pool = mysql2.createPool({
connectionLimit: 10,
host: 'localhost',
user: 'root'
})
})
after(() => {
return agent.close()
})
beforeEach(() => {
mysql2 = require(`./versions/mysql2@${version}`).get()
pool = mysql2.createPool({
connectionLimit: 10,
host: 'localhost',
user: 'root'
})
})
afterEach(done => {

@@ -185,0 +190,0 @@ pool.end(done)

@@ -19,22 +19,22 @@ 'use strict'

afterEach(() => {
agent.close()
})
describe('when using a client', () => {
before(() => {
return agent.load(plugin, 'pg')
})
describe('when using a client', () => {
after(() => {
return agent.close()
})
beforeEach(done => {
agent.load(plugin, 'pg')
.then(() => {
pg = require(`./versions/pg@${version}`).get()
pg = require(`./versions/pg@${version}`).get()
client = new pg.Client({
user: 'postgres',
password: 'postgres',
database: 'postgres',
application_name: 'test'
})
client = new pg.Client({
user: 'postgres',
password: 'postgres',
database: 'postgres',
application_name: 'test'
})
client.connect(err => done(err))
})
.catch(done)
client.connect(err => done(err))
})

@@ -121,20 +121,24 @@

before(() => {
return agent.load(plugin, 'pg')
})
after(() => {
return agent.close()
})
beforeEach(done => {
agent.load(plugin, 'pg')
.then(() => {
pg = require('pg')
pg = require('pg')
pool = new pg.Pool({
user: 'postgres',
password: 'postgres',
database: 'postgres',
application_name: 'test'
})
pool = new pg.Pool({
user: 'postgres',
password: 'postgres',
database: 'postgres',
application_name: 'test'
})
pool.connect((err, c) => {
client = c
done(err)
})
})
.catch(done)
pool.connect((err, c) => {
client = c
done(err)
})
})

@@ -165,22 +169,20 @@

describe('with configuration', () => {
let config
before(() => {
return agent.load(plugin, 'pg', { service: 'custom' })
})
after(() => {
return agent.close()
})
beforeEach(done => {
config = {
service: 'custom'
}
pg = require('pg')
agent.load(plugin, 'pg', config)
.then(() => {
pg = require('pg')
client = new pg.Client({
user: 'postgres',
password: 'postgres',
database: 'postgres'
})
client = new pg.Client({
user: 'postgres',
password: 'postgres',
database: 'postgres'
})
client.connect(err => done(err))
})
.catch(done)
client.connect(err => done(err))
})

@@ -187,0 +189,0 @@

@@ -21,14 +21,18 @@ 'use strict'

client.quit()
agent.close()
})
describe('without configuration', () => {
beforeEach(() => {
before(() => {
return agent.load(plugin, 'redis')
.then(() => {
redis = require(`./versions/redis@${version}`).get()
client = redis.createClient()
})
})
after(() => {
return agent.close()
})
beforeEach(() => {
redis = require(`./versions/redis@${version}`).get()
client = redis.createClient()
})
it('should do automatic instrumentation when using callbacks', done => {

@@ -112,14 +116,13 @@ client.on('error', done)

describe('with configuration', () => {
let config
before(() => {
return agent.load(plugin, 'redis', { service: 'custom' })
})
after(() => {
return agent.close()
})
beforeEach(() => {
config = {
service: 'custom'
}
return agent.load(plugin, 'redis', config)
.then(() => {
redis = require(`./versions/redis@${version}`).get()
client = redis.createClient()
})
redis = require(`./versions/redis@${version}`).get()
client = redis.createClient()
})

@@ -126,0 +129,0 @@

@@ -15,5 +15,6 @@ 'use strict'

const mongo = require('mongodb-core')
const elasticsearch = require('elasticsearch')
const axios = require('axios')
const amqplib = require('amqplib/callback_api')
const amqp = require('amqp10')
const Memcached = require('memcached')
const platform = require('../src/platform')

@@ -23,2 +24,3 @@ const node = require('../src/platform/node')

const agent = require('./plugins/agent')
const externals = require('./plugins/externals.json')

@@ -50,2 +52,6 @@ const scopeManager = new ScopeManager()

afterEach(() => {
agent.reset()
})
waitForServices()

@@ -65,3 +71,4 @@ .then(run)

waitForRabbitMQ(),
waitForQpid()
waitForQpid(),
waitForMemcached()
])

@@ -176,12 +183,9 @@ }

operation.attempt(currentAttempt => {
const client = new elasticsearch.Client({
host: 'localhost:9200'
})
client.ping((err) => {
if (retryOperation(operation, err)) return
if (err) return reject(err)
resolve()
})
// Not using ES client because it's buggy for initial connection.
axios.get('http://localhost:9200/_cluster/health?wait_for_status=green&local=true&timeout=100ms')
.then(() => resolve())
.catch(err => {
if (retryOperation(operation, err)) return
reject(err)
})
})

@@ -227,2 +231,20 @@ })

function waitForMemcached () {
return new Promise((resolve, reject) => {
const operation = createOperation('memcached')
operation.attempt(currentAttempt => {
const memcached = new Memcached('localhost:11211', { retries: 0 })
memcached.version((err, version) => {
if (retryOperation(operation, err)) return
if (err) return reject(err)
memcached.end()
resolve()
})
})
})
}
function withoutScope (fn) {

@@ -250,3 +272,3 @@ return function () {

return it.call(this, title, function (done) {
arguments[0] = withoutScope(done)
arguments[0] = withoutScope(agent.wrap(done))

@@ -263,5 +285,7 @@ return fn.apply(this, arguments)

.catch(withoutScope(err => Promise.reject(err)))
.then(() => agent.promise())
}
return result
return agent.promise()
.then(() => result)
})

@@ -273,3 +297,3 @@ }

function withVersions (plugin, moduleName, range, cb) {
const instrumentations = [].concat(plugin)
const instrumentations = [].concat(plugin, externals)
const testVersions = new Map()

@@ -287,6 +311,4 @@

.forEach(version => {
const min = semver.coerce(version).version
const max = require(`./plugins/versions/${moduleName}@${version}`).version()
try {
const min = semver.coerce(version).version
require(`./plugins/versions/${moduleName}@${min}`).get()

@@ -298,3 +320,6 @@ testVersions.set(min, { range: version, test: min })

agent.wipe()
try {
const max = require(`./plugins/versions/${moduleName}@${version}`).version()
require(`./plugins/versions/${moduleName}@${version}`).get()

@@ -305,2 +330,4 @@ testVersions.set(max, { range: version, test: version })

}
agent.wipe()
})

@@ -307,0 +334,0 @@ })

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc