Skip to content

Commit

Permalink
test, refactor: simplify pg.test.js (#3392)
Browse files Browse the repository at this point in the history
Node.js has had native Promise since v0.12.
  • Loading branch information
trentm authored May 31, 2023
1 parent 5225c1a commit 5c372b6
Showing 1 changed file with 102 additions and 107 deletions.
209 changes: 102 additions & 107 deletions test/instrumentation/modules/pg/pg.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,10 @@ var findObjInArray = require('../../../_utils').findObjInArray

var queryable, connectionDone
var factories = [
[createClient, 'client']
[createClient, 'client'],
[createPoolAndConnect, 'pool']
]

// In pg@6 native promises are required for pool operations
if (global.Promise || semver.satisfies(pgVersion, '<6')) factories.push([createPoolAndConnect, 'pool'])

factories.forEach(function (f) {
var factory = f[0]
var type = f[1]
Expand Down Expand Up @@ -219,7 +217,7 @@ factories.forEach(function (f) {
t.end()
})

if (semver.gte(pgVersion, '5.1.0') && global.Promise) {
if (semver.gte(pgVersion, '5.1.0')) {
t.test('basic query promise', function (t) {
t.test(type + '.query(sql)', function (t) {
resetAgent(function (data) {
Expand Down Expand Up @@ -392,140 +390,137 @@ factories.forEach(function (f) {
})
})

// In pg@6 native promises are required for pool operations
if (global.Promise || semver.satisfies(pgVersion, '<6')) {
test('simultaneous queries on different connections', function (t) {
t.on('end', teardown)
resetAgent(4, function (data) {
t.strictEqual(data.transactions.length, 1)
t.strictEqual(data.spans.length, 3)

var trans = data.transactions[0]
test('simultaneous queries on different connections', function (t) {
t.on('end', teardown)
resetAgent(4, function (data) {
t.strictEqual(data.transactions.length, 1)
t.strictEqual(data.spans.length, 3)

t.strictEqual(trans.name, 'foo')
data.spans.forEach(function (span) {
assertSpan(t, span, sql)
t.equal(span.parent_id, trans.id, 'each span is a child of the transaction')
})
var trans = data.transactions[0]

t.end()
t.strictEqual(trans.name, 'foo')
data.spans.forEach(function (span) {
assertSpan(t, span, sql)
t.equal(span.parent_id, trans.id, 'each span is a child of the transaction')
})

var sql = 'SELECT 1 + $1 AS solution'
t.end()
})

createPool(function (connector) {
var n = 0
var trans = agent.startTransaction('foo')
var sql = 'SELECT 1 + $1 AS solution'

connector(function (err, client, release) {
createPool(function (connector) {
var n = 0
var trans = agent.startTransaction('foo')

connector(function (err, client, release) {
t.error(err)
client.query(sql, [1], function (err, result, fields) {
t.error(err)
client.query(sql, [1], function (err, result, fields) {
t.error(err)
t.strictEqual(result.rows[0].solution, 2)
if (++n === 3) done()
release()
})
t.strictEqual(result.rows[0].solution, 2)
if (++n === 3) done()
release()
})
connector(function (err, client, release) {
})
connector(function (err, client, release) {
t.error(err)
client.query(sql, [2], function (err, result, fields) {
t.error(err)
client.query(sql, [2], function (err, result, fields) {
t.error(err)
t.strictEqual(result.rows[0].solution, 3)
if (++n === 3) done()
release()
})
t.strictEqual(result.rows[0].solution, 3)
if (++n === 3) done()
release()
})
connector(function (err, client, release) {
})
connector(function (err, client, release) {
t.error(err)
client.query(sql, [3], function (err, result, fields) {
t.error(err)
client.query(sql, [3], function (err, result, fields) {
t.error(err)
t.strictEqual(result.rows[0].solution, 4)
if (++n === 3) done()
release()
})
t.strictEqual(result.rows[0].solution, 4)
if (++n === 3) done()
release()
})

function done () {
trans.end()
}
})

function done () {
trans.end()
}
})
})

test('connection.release()', function (t) {
t.on('end', teardown)
resetAgent(function (data) {
assertBasicQuery(t, sql, data)
t.end()
})
test('connection.release()', function (t) {
t.on('end', teardown)
resetAgent(function (data) {
assertBasicQuery(t, sql, data)
t.end()
})

var sql = 'SELECT 1 + 1 AS solution'
var sql = 'SELECT 1 + 1 AS solution'

createPool(function (connector) {
agent.startTransaction('foo')
createPool(function (connector) {
agent.startTransaction('foo')

connector(function (err, client, release) {
t.error(err)
release()

connector(function (err, client, release) {
t.error(err)
release()

connector(function (err, client, release) {
t.error(err)
client.query(sql, basicQueryCallback(t))
t.ok(agent.currentSpan === null, 'no currentSpan in sync code after pg .query')
client.query(sql, basicQueryCallback(t))
t.ok(agent.currentSpan === null, 'no currentSpan in sync code after pg .query')

if (semver.gte(pgVersion, '7.5.0')) {
release()
} else {
// Race-condition: Wait a bit so the query callback isn't called
// with a "Connection terminated by user" error
setTimeout(release, 100)
}
})
if (semver.gte(pgVersion, '7.5.0')) {
release()
} else {
// Race-condition: Wait a bit so the query callback isn't called
// with a "Connection terminated by user" error
setTimeout(release, 100)
}
})
})
})
})

// The same guard logic as from the instrumentation module
//
// https://github.com/elastic/apm-agent-nodejs/blob/8a5e908b8e9ee83bb1b828a3bef980388ea6e08e/lib/instrumentation/modules/pg.js#L91
//
// ensures this tests runs when ending a span via promise.then
if (typeof pg.Client.prototype.query.on !== 'function' &&
// The same guard logic as from the instrumentation module
//
// https://github.com/elastic/apm-agent-nodejs/blob/8a5e908b8e9ee83bb1b828a3bef980388ea6e08e/lib/instrumentation/modules/pg.js#L91
//
// ensures this tests runs when ending a span via promise.then
if (typeof pg.Client.prototype.query.on !== 'function' &&
typeof pg.Client.prototype.query.then === 'function') {
test.test('handles promise rejections from pg', function (t) {
function unhandledRejection (e) {
t.fail('had unhandledRejection')
}
process.once('unhandledRejection', unhandledRejection)
t.on('end', function () {
process.removeListener('unhandledRejection', unhandledRejection)
teardown()
})
test.test('handles promise rejections from pg', function (t) {
function unhandledRejection (e) {
t.fail('had unhandledRejection')
}
process.once('unhandledRejection', unhandledRejection)
t.on('end', function () {
process.removeListener('unhandledRejection', unhandledRejection)
teardown()
})

var sql = 'select \'not-a-uuid\' = \'00000000-0000-0000-0000-000000000000\'::uuid'
var sql = 'select \'not-a-uuid\' = \'00000000-0000-0000-0000-000000000000\'::uuid'

createPool(function (connector) {
agent.startTransaction('foo')
createPool(function (connector) {
agent.startTransaction('foo')

connector(function (err, client, release) {
t.error(err)
connector(function (err, client, release) {
t.error(err)

client.query(sql)
.then(function () {
t.fail('query should have rejected')
})
.catch(function () {
t.ok(agent.currentSpan === null, 'no currentSpan in promise catch after pg .query')
})
.then(function () {
setTimeout(function () {
release()
t.end()
}, 100)
})
})
client.query(sql)
.then(function () {
t.fail('query should have rejected')
})
.catch(function () {
t.ok(agent.currentSpan === null, 'no currentSpan in promise catch after pg .query')
})
.then(function () {
setTimeout(function () {
release()
t.end()
}, 100)
})
})
})
}
})
}

function basicQueryCallback (t) {
Expand Down

0 comments on commit 5c372b6

Please sign in to comment.