Remove test globals (#3264)

* Remove assert from globals

* Remove Client from globals

* Remove global test function

* Remove MemoryStream from globals

* Require assert in SASL integration tests

* Attempt to use a postgres with ssl?

* Use latest image

* Remove connection tests - they test internals that are better covered by testint the client
This commit is contained in:
Brian C 2024-06-19 13:46:16 -05:00 committed by GitHub
parent f7e484ed61
commit 50c06f9bc6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
81 changed files with 176 additions and 919 deletions

View File

@ -25,7 +25,7 @@ jobs:
needs: lint
services:
postgres:
image: postgres:11
image: ghcr.io/railwayapp-templates/postgres-ssl
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres

View File

@ -1,6 +1,7 @@
'use strict'
var helper = require('../test-helper')
var pg = helper.pg
const assert = require('assert')
var suite = new helper.Suite()

View File

@ -1,6 +1,7 @@
'use strict'
var helper = require('./test-helper')
var Client = helper.Client
const assert = require('assert')
var suite = new helper.Suite()

View File

@ -1,6 +1,7 @@
'use strict'
var helper = require('./test-helper')
var pg = helper.pg
const assert = require('assert')
var suite = new helper.Suite()

View File

@ -1,6 +1,7 @@
'use strict'
var helper = require('./test-helper')
var Query = helper.pg.Query
const assert = require('assert')
const suite = new helper.Suite()

View File

@ -1,6 +1,8 @@
'use strict'
var helper = require('./test-helper')
var pg = helper.pg
const assert = require('assert')
const { Client } = helper
var suite = new helper.Suite()

View File

@ -2,6 +2,7 @@
const net = require('net')
const buffers = require('../../test-buffers')
const helper = require('./test-helper')
const assert = require('assert')
const suite = new helper.Suite()

View File

@ -2,6 +2,7 @@
const helper = require('./test-helper')
const Client = helper.pg.Client
const suite = new helper.Suite()
const assert = require('assert')
const customTypes = {
getTypeParser: () => () => 'okay!',

View File

@ -1,6 +1,7 @@
'use strict'
var helper = require('./test-helper')
const suite = new helper.Suite()
const assert = require('assert')
suite.test('empty query message handling', function (done) {
const client = helper.client()

View File

@ -3,6 +3,7 @@
var helper = require('./test-helper')
var pg = helper.pg
const assert = require('assert')
const Client = pg.Client
const DatabaseError = pg.DatabaseError

View File

@ -1,6 +1,7 @@
'use strict'
var helper = require('./test-helper')
const pool = new helper.pg.Pool()
const assert = require('assert')
pool.connect(
assert.success(function (client, done) {

View File

@ -1,6 +1,7 @@
'use strict'
var helper = require('./test-helper')
var Client = helper.Client
const assert = require('assert')
var suite = new helper.Suite()

View File

@ -2,6 +2,7 @@
var buffers = require('../../test-buffers')
var helper = require('./test-helper')
var suite = new helper.Suite()
const assert = require('assert')
var net = require('net')

View File

@ -1,6 +1,7 @@
'use strict'
var helper = require('./test-helper')
const suite = new helper.Suite()
const assert = require('assert')
suite.test('noData message handling', function () {
var client = helper.client()

View File

@ -3,6 +3,7 @@ var helper = require('./test-helper')
var pg = helper.pg
const suite = new helper.Suite()
const pool = new pg.Pool()
const assert = require('assert')
suite.test('can access results when no rows are returned', function (done) {
var checkResult = function (result) {

View File

@ -3,6 +3,7 @@
var helper = require('../test-helper')
var pg = helper.pg
const suite = new helper.Suite()
const assert = require('assert')
const pool = new pg.Pool(helper.config)
suite.test('ability to turn on and off parser', function () {

View File

@ -2,6 +2,7 @@
var helper = require('./test-helper')
var Query = helper.pg.Query
const assert = require('assert')
var suite = new helper.Suite()
;(function () {

View File

@ -2,6 +2,7 @@
const helper = require('./test-helper')
const pg = helper.pg
const assert = require('assert')
const suite = new helper.Suite()

View File

@ -2,6 +2,7 @@
var bluebird = require('bluebird')
var helper = require('../test-helper')
var pg = helper.pg
const assert = require('assert')
process.on('unhandledRejection', function (e) {
console.error(e, e.stack)

View File

@ -1,6 +1,7 @@
'use strict'
var helper = require('../test-helper')
var pg = helper.pg
const assert = require('assert')
new helper.Suite().test('support for complex column names', function () {
const pool = new pg.Pool()

View File

@ -1,6 +1,8 @@
'use strict'
var helper = require('./test-helper')
var Query = helper.pg.Query
const { Client } = helper
const assert = require('assert')
var suite = new helper.Suite()

View File

@ -2,8 +2,11 @@
var helper = require('./test-helper')
var Query = helper.pg.Query
var DatabaseError = helper.pg.DatabaseError
const assert = require('assert')
const { Client } = helper
const suite = new helper.Suite()
test('error during query execution', function () {
suite.test('error during query execution', function () {
var client = new Client(helper.args)
client.connect(
assert.success(function () {
@ -60,7 +63,7 @@ if (helper.config.native) {
return
}
test('9.3 column error fields', function () {
suite.test('9.3 column error fields', function () {
var client = new Client(helper.args)
client.connect(
assert.success(function () {
@ -89,7 +92,7 @@ test('9.3 column error fields', function () {
)
})
test('9.3 constraint error fields', function () {
suite.test('9.3 constraint error fields', function () {
var client = new Client(helper.args)
client.connect(
assert.success(function () {

View File

@ -1,6 +1,7 @@
'use strict'
var helper = require('./test-helper')
var pg = helper.pg
const assert = require('assert')
const pool = new pg.Pool()
new helper.Suite().test('should return insert metadata', function () {

View File

@ -1,12 +1,14 @@
'use strict'
var util = require('util')
var helper = require('./test-helper')
const assert = require('assert')
const suite = new helper.Suite()
var Client = helper.Client
var conInfo = helper.config
test('returns results as array', function () {
suite.test('returns results as array', function () {
var client = new Client(conInfo)
var checkRow = function (row) {
assert(util.isArray(row), 'row should be an array')

View File

@ -1,5 +1,7 @@
'use strict'
var helper = require('./test-helper')
const assert = require('assert')
const suite = new helper.Suite()
var Client = helper.Client
@ -17,7 +19,7 @@ var checkResult = function (result) {
assert.equal(fields[2].dataTypeID, 25)
}
test('row descriptions on result object', function () {
suite.test('row descriptions on result object', function () {
var client = new Client(conInfo)
client.connect(
assert.success(function () {
@ -33,7 +35,7 @@ test('row descriptions on result object', function () {
)
})
test('row description on no rows', function () {
suite.test('row description on no rows', function () {
var client = new Client(conInfo)
client.connect(
assert.success(function () {

View File

@ -3,6 +3,7 @@ const helper = require('./../test-helper')
const pg = helper.pg
const suite = new helper.Suite()
const { native } = helper.args
const assert = require('assert')
/**
* This test only executes if the env variables SCRAM_TEST_PGUSER and

View File

@ -1,6 +1,9 @@
'use strict'
var helper = require('./test-helper')
var Query = helper.pg.Query
const assert = require('assert')
const suite = new helper.Suite()
const test = suite.test.bind(suite)
// before running this test make sure you run the script create-test-tables
test('simple query interface', function () {

View File

@ -1,19 +1,22 @@
'use strict'
var pg = require('../../../lib')
var config = require('./test-helper').config
test('can connect with ssl', function () {
return false
config.ssl = {
rejectUnauthorized: false,
const helper = require('./test-helper')
const assert = require('assert')
const suite = new helper.Suite()
suite.test('can connect with ssl', function () {
const config = {
...helper.config,
ssl: {
rejectUnauthorized: false,
},
}
pg.connect(
config,
assert.success(function (client) {
return false
const client = new helper.pg.Client(config)
client.connect(
assert.success(function () {
client.query(
'SELECT NOW()',
assert.success(function () {
pg.end()
client.end()
})
)
})

View File

@ -2,6 +2,7 @@
var helper = require('./test-helper')
var Client = helper.Client
const assert = require('assert')
var suite = new helper.Suite()
var conInfo = helper.config

View File

@ -1,5 +1,6 @@
'use strict'
var helper = require('./../test-helper')
const assert = require('assert')
var oldTz = process.env.TZ
process.env.TZ = 'Europe/Berlin'

View File

@ -2,6 +2,7 @@
var helper = require('./test-helper')
const suite = new helper.Suite()
const pg = helper.pg
const assert = require('assert')
const client = new pg.Client()
client.connect(

View File

@ -2,6 +2,7 @@
var helper = require('./test-helper')
var pg = helper.pg
const suite = new helper.Suite()
const assert = require('assert')
var testForTypeCoercion = function (type) {
const pool = new pg.Pool()

View File

@ -1,5 +1,6 @@
'use strict'
var helper = require('./test-helper')
const assert = require('assert')
function testTypeParser(client, expectedResult, done) {
var boolValue = true

View File

@ -5,7 +5,7 @@ const assert = require('assert')
const suite = new helper.Suite()
const testPoolSize = function (max) {
suite.testAsync(`test ${max} queries executed on a pool rapidly`, () => {
suite.testAsync(`test ${max} queries executed on a pool rapidly`, async () => {
const pool = new helper.pg.Pool({ max: 10 })
let count = 0

View File

@ -2,6 +2,7 @@
var helper = require('./test-helper')
const pg = helper.pg
const native = helper.args.native
const assert = require('assert')
const suite = new helper.Suite()
suite.test('connecting to invalid port', (cb) => {

View File

@ -1,5 +1,6 @@
'use strict'
var helper = require('./test-helper')
const assert = require('assert')
new helper.Suite().test('idle timeout', function () {
const config = Object.assign({}, helper.config, { idleTimeoutMillis: 50 })

View File

@ -2,6 +2,7 @@
var helper = require('./../test-helper')
var pg = helper.pg
var native = helper.args.native
const assert = require('assert')
var pool = new pg.Pool()

View File

@ -1,6 +1,7 @@
'use strict'
var helper = require('./test-helper')
var co = require('co')
const assert = require('assert')
const pool = new helper.pg.Pool()
new helper.Suite().test(

View File

@ -1,58 +0,0 @@
'use strict'
var helper = require('./test-helper')
// http://developer.postgresql.org/pgdocs/postgres/protocol-flow.html#PROTOCOL-FLOW-EXT-QUERY
test('flushing once', function () {
helper.connect(function (con) {
con.parse({
text: 'select * from ids',
})
con.bind()
con.execute()
con.flush()
assert.emits(con, 'parseComplete')
assert.emits(con, 'bindComplete')
assert.emits(con, 'dataRow')
assert.emits(con, 'commandComplete', function () {
con.sync()
})
assert.emits(con, 'readyForQuery', function () {
con.end()
})
})
})
test('sending many flushes', function () {
helper.connect(function (con) {
assert.emits(con, 'parseComplete', function () {
con.bind()
con.flush()
})
assert.emits(con, 'bindComplete', function () {
con.execute()
con.flush()
})
assert.emits(con, 'dataRow', function (msg) {
assert.equal(msg.fields[0], 1)
assert.emits(con, 'dataRow', function (msg) {
assert.equal(msg.fields[0], 2)
assert.emits(con, 'commandComplete', function () {
con.sync()
})
assert.emits(con, 'readyForQuery', function () {
con.end()
})
})
})
con.parse({
text: 'select * from ids order by id',
})
con.flush()
})
})

View File

@ -1,43 +0,0 @@
'use strict'
var helper = require('./test-helper')
var assert = require('assert')
test('COPY FROM events check', function () {
helper.connect(function (con) {
con.query('COPY person FROM STDIN')
con.on('copyInResponse', function () {
con.endCopyFrom()
})
assert.emits(
con,
'copyInResponse',
function () {
con.endCopyFrom()
},
'backend should emit copyInResponse after COPY FROM query'
)
assert.emits(
con,
'commandComplete',
function () {
con.end()
},
'backend should emit commandComplete after COPY FROM stream ends'
)
})
})
test('COPY TO events check', function () {
helper.connect(function (con) {
con.query('COPY person TO STDOUT')
assert.emits(con, 'copyOutResponse', function () {}, 'backend should emit copyOutResponse after COPY TO query')
assert.emits(con, 'copyData', function () {}, 'backend should emit copyData on every data row')
assert.emits(
con,
'copyDone',
function () {
con.end()
},
'backend should emit copyDone after all data rows'
)
})
})

View File

@ -1,119 +0,0 @@
'use strict'
const assert = require('assert')
const helper = require('./../test-helper')
const suite = new helper.Suite()
const pg = require('../../../lib/index')
const Client = pg.Client
const password = process.env.PGPASSWORD || null
const sleep = (millis) => new Promise((resolve) => setTimeout(resolve, millis))
if (!password) {
// skip these tests; no password will be requested
return
}
suite.testAsync('Get password from a sync function', () => {
let wasCalled = false
function getPassword() {
wasCalled = true
return password
}
const client = new Client({
password: getPassword,
})
return client.connect().then(() => {
assert.ok(wasCalled, 'Our password function should have been called')
return client.end()
})
})
suite.testAsync('Throw error from a sync function', () => {
let wasCalled = false
const myError = new Error('Oops!')
function getPassword() {
wasCalled = true
throw myError
}
const client = new Client({
password: getPassword,
})
let wasThrown = false
return client
.connect()
.catch((err) => {
assert.equal(err, myError, 'Our sync error should have been thrown')
wasThrown = true
})
.then(() => {
assert.ok(wasCalled, 'Our password function should have been called')
assert.ok(wasThrown, 'Our error should have been thrown')
return client.end()
})
})
suite.testAsync('Get password from a function asynchronously', () => {
let wasCalled = false
function getPassword() {
wasCalled = true
return sleep(100).then(() => password)
}
const client = new Client({
password: getPassword,
})
return client.connect().then(() => {
assert.ok(wasCalled, 'Our password function should have been called')
return client.end()
})
})
suite.testAsync('Throw error from an async function', () => {
let wasCalled = false
const myError = new Error('Oops!')
function getPassword() {
wasCalled = true
return sleep(100).then(() => {
throw myError
})
}
const client = new Client({
password: getPassword,
})
let wasThrown = false
return client
.connect()
.catch((err) => {
assert.equal(err, myError, 'Our async error should have been thrown')
wasThrown = true
})
.then(() => {
assert.ok(wasCalled, 'Our password function should have been called')
assert.ok(wasThrown, 'Our error should have been thrown')
return client.end()
})
})
suite.testAsync('Password function must return a string', () => {
let wasCalled = false
function getPassword() {
wasCalled = true
// Return a password that is not a string
return 12345
}
const client = new Client({
password: getPassword,
})
let wasThrown = false
return client
.connect()
.catch((err) => {
assert.ok(err instanceof TypeError, 'A TypeError should have been thrown')
assert.equal(err.message, 'Password must be a string')
wasThrown = true
})
.then(() => {
assert.ok(wasCalled, 'Our password function should have been called')
assert.ok(wasThrown, 'Our error should have been thrown')
return client.end()
})
})

View File

@ -1,16 +0,0 @@
'use strict'
var helper = require('./test-helper')
// http://www.postgresql.org/docs/8.3/static/libpq-notify.html
test('recieves notification from same connection with no payload', function () {
helper.connect(function (con) {
con.query('LISTEN boom')
assert.emits(con, 'readyForQuery', function () {
con.query('NOTIFY boom')
assert.emits(con, 'notification', function (msg) {
assert.equal(msg.payload, '')
assert.equal(msg.channel, 'boom')
con.end()
})
})
})
})

View File

@ -1,26 +0,0 @@
'use strict'
var helper = require('./test-helper')
var assert = require('assert')
var rows = []
// testing the low level 1-1 mapping api of client to postgres messages
// it's cumbersome to use the api this way
test('simple query', function () {
helper.connect(function (con) {
con.query('select * from ids')
assert.emits(con, 'dataRow')
con.on('dataRow', function (msg) {
rows.push(msg.fields)
})
assert.emits(con, 'readyForQuery', function () {
con.end()
})
})
})
process.on('exit', function () {
assert.equal(rows.length, 2)
assert.equal(rows[0].length, 1)
assert.strictEqual(String(rows[0][0]), '1')
assert.strictEqual(String(rows[1][0]), '2')
})

View File

@ -1,40 +0,0 @@
'use strict'
var net = require('net')
var helper = require('../test-helper')
var Connection = require('../../../lib/connection')
const crypto = require('../../../lib/crypto/utils')
var connect = function (callback) {
var username = helper.args.user
var database = helper.args.database
var con = new Connection({ stream: new net.Stream() })
con.on('error', function (error) {
console.log(error)
throw new Error('Connection error')
})
con.connect(helper.args.port || '5432', helper.args.host || 'localhost')
con.once('connect', function () {
con.startup({
user: username,
database: database,
})
con.once('authenticationCleartextPassword', function () {
con.password(helper.args.password)
})
con.once('authenticationMD5Password', async function (msg) {
con.password(await crypto.postgresMd5PasswordHash(helper.args.user, helper.args.password, msg.salt))
})
con.once('readyForQuery', function () {
con.query('create temp table ids(id integer)')
con.once('readyForQuery', function () {
con.query('insert into ids(id) values(1); insert into ids(id) values(2);')
con.once('readyForQuery', function () {
callback(con)
})
})
})
})
}
module.exports = {
connect: connect,
}

View File

@ -4,6 +4,7 @@ var helper = require('./test-helper')
var Query = helper.pg.Query
var suite = new helper.Suite()
const assert = require('assert')
const Pool = helper.pg.Pool
suite.test('no domain', function (cb) {

View File

@ -1,6 +1,7 @@
'use strict'
var helper = require('../test-helper')
var exec = require('child_process').exec
const assert = require('assert')
helper.pg.defaults.poolIdleTimeout = 1000

View File

@ -1,6 +1,7 @@
'use strict'
var helper = require('../test-helper')
var pg = helper.pg
const assert = require('assert')
var suite = new helper.Suite()

View File

@ -1,6 +1,7 @@
'use strict'
var helper = require('../test-helper')
var client = helper.client()
const assert = require('assert')
client.query('CREATE TEMP TABLE arrtest (n integer, s varchar)')
client.query("INSERT INTO arrtest VALUES (4, 'foo'), (5, 'bar'), (6, 'baz');")

View File

@ -2,6 +2,7 @@
const pg = require('../../../lib')
const helper = require('../test-helper')
const assert = require('assert')
const suite = new helper.Suite()

View File

@ -1,4 +1,5 @@
const helper = require('../test-helper')
const assert = require('assert')
const suite = new helper.Suite()

View File

@ -1,6 +1,7 @@
'use strict'
const net = require('net')
const helper = require('./../test-helper')
const assert = require('assert')
const suite = new helper.Suite()

View File

@ -1,6 +1,7 @@
'use strict'
var helper = require('../test-helper')
var pg = helper.pg
const assert = require('assert')
new helper.Suite().test('parsing array results', function (cb) {
const pool = new pg.Pool()

View File

@ -2,6 +2,7 @@
var async = require('async')
var helper = require('../test-helper')
const suite = new helper.Suite()
const assert = require('assert')
var db = helper.client()

View File

@ -1,5 +1,7 @@
'use strict'
var helper = require('./../test-helper')
let { Client } = helper
const assert = require('assert')
if (helper.args.native) {
Client = require('./../../lib/native')

View File

@ -3,6 +3,7 @@ var domain = require('domain')
var helper = require('./../test-helper')
var Client = require('./../../lib/native')
const suite = new helper.Suite()
const assert = require('assert')
suite.test('fires callback with results', function (done) {
var client = new Client(helper.config)

View File

@ -2,6 +2,9 @@
var helper = require('../test-helper')
var Client = require('../../lib/native')
var Query = Client.Query
const assert = require('assert')
const suite = new helper.Suite()
const test = suite.test.bind(suite)
var setupClient = function () {
var client = new Client(helper.config)

View File

@ -2,6 +2,7 @@
var helper = require('../test-helper')
var Client = require('../../lib/native')
const suite = new helper.Suite()
const assert = require('assert')
suite.test('respects nativeConnectionString in config', function (done) {
const realPort = helper.config.port

View File

@ -2,8 +2,10 @@
var helper = require('../test-helper')
var Client = require('../../lib/native')
var Query = Client.Query
const assert = require('assert')
const suite = new helper.Suite()
test('many rows', function () {
suite.test('many rows', function () {
var client = new Client(helper.config)
client.connect()
var q = client.query(new Query('SELECT * FROM person'))
@ -17,7 +19,7 @@ test('many rows', function () {
})
})
test('many queries', function () {
suite.test('many queries', function () {
var client = new Client(helper.config)
client.connect()
var count = 0
@ -34,7 +36,7 @@ test('many queries', function () {
})
})
test('many clients', function () {
suite.test('many clients', function () {
var clients = []
for (var i = 0; i < 10; i++) {
clients.push(new Client(helper.config))

View File

@ -1,12 +1,11 @@
'use strict'
// make assert a global...
global.assert = require('assert')
const assert = require('assert')
var sys = require('util')
const Suite = require('./suite')
const args = require('./cli')
global.Client = require('./../lib').Client
const Client = require('./../lib').Client
process.on('uncaughtException', function (d) {
if ('stack' in d && 'message' in d) {
@ -157,17 +156,6 @@ assert.isNull = function (item, message) {
assert.ok(item === null, message)
}
global.test = function (name, action) {
test.testCount++
test[name] = action
var result = test[name]()
if (result === false) {
process.stdout.write('?')
} else {
process.stdout.write('.')
}
}
// print out the filename
process.stdout.write(require('path').basename(process.argv[1]))
if (args.binary) process.stdout.write(' (binary)')

View File

@ -2,29 +2,30 @@
const helper = require('./test-helper')
const createClient = require('./test-helper').createClient
const assert = require('assert')
const suite = new helper.Suite()
const { MemoryStream } = helper
test('cleartext password authentication', function () {
test('responds with password', function () {
var client = createClient()
client.password = '!'
client.connection.stream.packets = []
client.connection.emit('authenticationCleartextPassword')
var packets = client.connection.stream.packets
assert.lengthIs(packets, 1)
var packet = packets[0]
assert.equalBuffers(packet, [0x70, 0, 0, 0, 6, 33, 0])
})
test('does not crash with null password using pg-pass', function () {
process.env.PGPASSFILE = `${__dirname}/pgpass.file`
var client = new helper.Client({
host: 'foo',
port: 5432,
database: 'bar',
user: 'baz',
stream: new MemoryStream(),
})
client.connect()
client.connection.emit('authenticationCleartextPassword')
})
suite.test('cleartext password auth responds with password', function () {
var client = createClient()
client.password = '!'
client.connection.stream.packets = []
client.connection.emit('authenticationCleartextPassword')
var packets = client.connection.stream.packets
assert.lengthIs(packets, 1)
var packet = packets[0]
assert.equalBuffers(packet, [0x70, 0, 0, 0, 6, 33, 0])
})
suite.test('cleartext password auth does not crash with null password using pg-pass', function () {
process.env.PGPASSFILE = `${__dirname}/pgpass.file`
var client = new helper.Client({
host: 'foo',
port: 5432,
database: 'bar',
user: 'baz',
stream: new MemoryStream(),
})
client.connect()
client.connection.emit('authenticationCleartextPassword')
})

View File

@ -1,6 +1,9 @@
'use strict'
require('./test-helper')
const helper = require('./test-helper')
const { Client } = helper
var assert = require('assert')
const suite = new helper.Suite()
const test = suite.test.bind(suite)
var pguser = process.env['PGUSER'] || process.env.USER
var pgdatabase = process.env['PGDATABASE'] || process.env.USER

View File

@ -2,6 +2,7 @@
require('./test-helper')
var net = require('net')
var pg = require('../../../lib/index.js')
const assert = require('assert')
/* console.log() messages show up in `make test` output. TODO: fix it. */
var server = net.createServer(function (c) {

View File

@ -1,6 +1,10 @@
'use strict'
var helper = require('./test-helper')
var utils = require('../../../lib/utils')
const assert = require('assert')
const { Client, Suite } = helper
const suite = new Suite()
const test = suite.test.bind(suite)
var testLit = function (testName, input, expected) {
test(testName, function () {

View File

@ -2,6 +2,9 @@
var helper = require('./test-helper')
const BufferList = require('../../buffer-list')
var crypto = require('../../../lib/crypto/utils')
const assert = require('assert')
const suite = new helper.Suite()
const test = suite.test.bind(suite)
test('md5 authentication', async function () {
var client = helper.createClient()

View File

@ -1,7 +1,9 @@
'use strict'
var helper = require('./test-helper')
const assert = require('assert')
const suite = new helper.Suite()
test('passes connection notification', function () {
suite.test('passes connection notification', function () {
var client = helper.client()
assert.emits(client, 'notice', function (msg) {
assert.equal(msg, 'HAY!!')

View File

@ -1,8 +1,11 @@
'use strict'
var helper = require('./test-helper')
var Query = require('../../../lib/query')
const assert = require('assert')
var client = helper.client()
const suite = new helper.Suite()
const test = suite.test.bind(suite)
var con = client.connection
var parseArg = null
con.parse = function (arg) {

View File

@ -1,6 +1,10 @@
'use strict'
require('./test-helper')
const helper = require('./test-helper')
const { Client } = helper
var Connection = require('../../../lib/connection')
const assert = require('assert')
const suite = new helper.Suite()
const test = suite.test.bind(suite)
test('drain', function () {
var con = new Connection({ stream: 'NO' })
@ -19,34 +23,16 @@ test('drain', function () {
client.query('hello')
client.query('sup')
client.query('boom')
assert.equal(raisedDrain, false)
con.emit('readyForQuery')
test('with pending queries', function () {
test('does not emit drain', function () {
assert.equal(raisedDrain, false)
})
})
assert.equal(raisedDrain, false)
con.emit('readyForQuery')
con.emit('readyForQuery')
assert.equal(raisedDrain, false)
con.emit('readyForQuery')
test('after some queries executed', function () {
con.emit('readyForQuery')
test('does not emit drain', function () {
assert.equal(raisedDrain, false)
})
})
test('when all queries are sent', function () {
con.emit('readyForQuery')
con.emit('readyForQuery')
test('does not emit drain', function () {
assert.equal(raisedDrain, false)
})
})
test('after last query finishes', function () {
con.emit('readyForQuery')
test('emits drain', function () {
process.nextTick(function () {
assert.ok(raisedDrain)
})
})
process.nextTick(function () {
assert.ok(raisedDrain)
})
})

View File

@ -1,5 +1,8 @@
'use strict'
var helper = require('./test-helper')
const assert = require('assert')
const suite = new helper.Suite()
const test = suite.test.bind(suite)
var testForTag = function (tagText, callback) {
test('includes command tag data for tag ' + tagText, function () {

View File

@ -1,5 +1,6 @@
'use strict'
const helper = require('./test-helper')
const assert = require('assert')
var sasl = require('../../../lib/crypto/sasl')

View File

@ -2,6 +2,7 @@
const net = require('net')
const pg = require('../../../lib/index.js')
const helper = require('./test-helper')
const assert = require('assert')
const suite = new helper.Suite()

View File

@ -1,6 +1,9 @@
'use strict'
var helper = require('./test-helper')
var Query = require('../../../lib/query')
const assert = require('assert')
const suite = new helper.Suite()
const test = suite.test.bind(suite)
test('executing query', function () {
test('queing query', function () {
@ -112,14 +115,6 @@ test('executing query', function () {
test('removes itself after another readyForQuery message', function () {
return false
assert.emits(query, 'end', function (msg) {
// TODO do we want to check the complete messages?
})
con.emit('readyForQuery')
// this would never actually happen
;['dataRow', 'rowDescription', 'commandComplete'].forEach(function (msg) {
assert.equal(con.emit(msg), false, "Should no longer be picking up '" + msg + "' messages")
})
})
})

View File

@ -1,9 +1,11 @@
'use strict'
require('./test-helper')
const helper = require('./test-helper')
var Connection = require('../../../lib/connection')
var Client = require('../../../lib/client')
const assert = require('assert')
const suite = new helper.Suite()
test('emits end when not in query', function () {
suite.test('emits end when not in query', function () {
var stream = new (require('events').EventEmitter)()
stream.setNoDelay = () => {}
stream.connect = function () {

View File

@ -1,6 +1,7 @@
'use strict'
var helper = require('../test-helper')
var Connection = require('../../../lib/connection')
const { Client } = helper
var makeClient = function () {
var connection = new Connection({ stream: 'no' })

View File

@ -2,6 +2,7 @@
var helper = require('./test-helper')
var Query = require('../../../lib/query')
var types = require('pg-types')
const assert = require('assert')
const suite = new helper.Suite()

View File

@ -2,8 +2,9 @@
const assert = require('assert')
const helper = require('../test-helper')
const suite = new helper.Suite()
test('pool with copied settings includes password', () => {
suite.test('pool with copied settings includes password', () => {
const original = new helper.pg.Pool({
password: 'original',
})

View File

@ -2,8 +2,10 @@
var helper = require('./test-helper')
var Connection = require('../../../lib/connection')
var net = require('net')
const assert = require('assert')
const suite = new helper.Suite()
const { MemoryStream } = helper
suite.test('connection emits stream errors', function (done) {
var con = new Connection({ stream: new MemoryStream() })

View File

@ -1,496 +0,0 @@
'use strict'
require('./test-helper')
const BufferList = require('../../buffer-list')
var Connection = require('../../../lib/connection')
var buffers = require('../../test-buffers')
var authOkBuffer = buffers.authenticationOk()
var paramStatusBuffer = buffers.parameterStatus('client_encoding', 'UTF8')
var readyForQueryBuffer = buffers.readyForQuery()
var backendKeyDataBuffer = buffers.backendKeyData(1, 2)
var commandCompleteBuffer = buffers.commandComplete('SELECT 3')
var parseCompleteBuffer = buffers.parseComplete()
var bindCompleteBuffer = buffers.bindComplete()
var portalSuspendedBuffer = buffers.portalSuspended()
var row1 = {
name: 'id',
tableID: 1,
attributeNumber: 2,
dataTypeID: 3,
dataTypeSize: 4,
typeModifier: 5,
formatCode: 0,
}
var oneRowDescBuff = new buffers.rowDescription([row1])
row1.name = 'bang'
var twoRowBuf = new buffers.rowDescription([
row1,
{
name: 'whoah',
tableID: 10,
attributeNumber: 11,
dataTypeID: 12,
dataTypeSize: 13,
typeModifier: 14,
formatCode: 0,
},
])
var emptyRowFieldBuf = new BufferList().addInt16(0).join(true, 'D')
var emptyRowFieldBuf = buffers.dataRow()
var oneFieldBuf = new BufferList()
.addInt16(1) // number of fields
.addInt32(5) // length of bytes of fields
.addCString('test')
.join(true, 'D')
var oneFieldBuf = buffers.dataRow(['test'])
var expectedAuthenticationOkayMessage = {
name: 'authenticationOk',
length: 8,
}
var expectedParameterStatusMessage = {
name: 'parameterStatus',
parameterName: 'client_encoding',
parameterValue: 'UTF8',
length: 25,
}
var expectedBackendKeyDataMessage = {
name: 'backendKeyData',
processID: 1,
secretKey: 2,
}
var expectedReadyForQueryMessage = {
name: 'readyForQuery',
length: 5,
status: 'I',
}
var expectedCommandCompleteMessage = {
length: 13,
text: 'SELECT 3',
}
var emptyRowDescriptionBuffer = new BufferList()
.addInt16(0) // number of fields
.join(true, 'T')
var expectedEmptyRowDescriptionMessage = {
name: 'rowDescription',
length: 6,
fieldCount: 0,
}
var expectedOneRowMessage = {
name: 'rowDescription',
length: 27,
fieldCount: 1,
}
var expectedTwoRowMessage = {
name: 'rowDescription',
length: 53,
fieldCount: 2,
}
var testForMessage = function (buffer, expectedMessage) {
var lastMessage = {}
test('recieves and parses ' + expectedMessage.name, function () {
var stream = new MemoryStream()
var client = new Connection({
stream: stream,
})
client.connect()
client.on('message', function (msg) {
lastMessage = msg
})
client.on(expectedMessage.name, function () {
client.removeAllListeners(expectedMessage.name)
})
stream.emit('data', buffer)
assert.same(lastMessage, expectedMessage)
})
return lastMessage
}
var plainPasswordBuffer = buffers.authenticationCleartextPassword()
var md5PasswordBuffer = buffers.authenticationMD5Password()
var SASLBuffer = buffers.authenticationSASL()
var SASLContinueBuffer = buffers.authenticationSASLContinue()
var SASLFinalBuffer = buffers.authenticationSASLFinal()
var expectedPlainPasswordMessage = {
name: 'authenticationCleartextPassword',
}
var expectedMD5PasswordMessage = {
name: 'authenticationMD5Password',
}
var expectedSASLMessage = {
name: 'authenticationSASL',
}
var expectedSASLContinueMessage = {
name: 'authenticationSASLContinue',
data: 'data',
}
var expectedSASLFinalMessage = {
name: 'authenticationSASLFinal',
data: 'data',
}
var notificationResponseBuffer = buffers.notification(4, 'hi', 'boom')
var expectedNotificationResponseMessage = {
name: 'notification',
processId: 4,
channel: 'hi',
payload: 'boom',
}
test('Connection', function () {
testForMessage(authOkBuffer, expectedAuthenticationOkayMessage)
testForMessage(plainPasswordBuffer, expectedPlainPasswordMessage)
var msgMD5 = testForMessage(md5PasswordBuffer, expectedMD5PasswordMessage)
test('md5 has right salt', function () {
assert.equalBuffers(msgMD5.salt, Buffer.from([1, 2, 3, 4]))
})
var msgSASL = testForMessage(SASLBuffer, expectedSASLMessage)
test('SASL has the right mechanisms', function () {
assert.deepStrictEqual(msgSASL.mechanisms, ['SCRAM-SHA-256'])
})
testForMessage(SASLContinueBuffer, expectedSASLContinueMessage)
testForMessage(SASLFinalBuffer, expectedSASLFinalMessage)
testForMessage(paramStatusBuffer, expectedParameterStatusMessage)
testForMessage(backendKeyDataBuffer, expectedBackendKeyDataMessage)
testForMessage(readyForQueryBuffer, expectedReadyForQueryMessage)
testForMessage(commandCompleteBuffer, expectedCommandCompleteMessage)
testForMessage(notificationResponseBuffer, expectedNotificationResponseMessage)
test('empty row message', function () {
var message = testForMessage(emptyRowDescriptionBuffer, expectedEmptyRowDescriptionMessage)
test('has no fields', function () {
assert.equal(message.fields.length, 0)
})
})
test('no data message', function () {
testForMessage(Buffer.from([0x6e, 0, 0, 0, 4]), {
name: 'noData',
})
})
test('one row message', function () {
var message = testForMessage(oneRowDescBuff, expectedOneRowMessage)
test('has one field', function () {
assert.equal(message.fields.length, 1)
})
test('has correct field info', function () {
assert.same(message.fields[0], {
name: 'id',
tableID: 1,
columnID: 2,
dataTypeID: 3,
dataTypeSize: 4,
dataTypeModifier: 5,
format: 'text',
})
})
})
test('two row message', function () {
var message = testForMessage(twoRowBuf, expectedTwoRowMessage)
test('has two fields', function () {
assert.equal(message.fields.length, 2)
})
test('has correct first field', function () {
assert.same(message.fields[0], {
name: 'bang',
tableID: 1,
columnID: 2,
dataTypeID: 3,
dataTypeSize: 4,
dataTypeModifier: 5,
format: 'text',
})
})
test('has correct second field', function () {
assert.same(message.fields[1], {
name: 'whoah',
tableID: 10,
columnID: 11,
dataTypeID: 12,
dataTypeSize: 13,
dataTypeModifier: 14,
format: 'text',
})
})
})
test('parsing rows', function () {
test('parsing empty row', function () {
var message = testForMessage(emptyRowFieldBuf, {
name: 'dataRow',
fieldCount: 0,
})
test('has 0 fields', function () {
assert.equal(message.fields.length, 0)
})
})
test('parsing data row with fields', function () {
var message = testForMessage(oneFieldBuf, {
name: 'dataRow',
fieldCount: 1,
})
test('has 1 field', function () {
assert.equal(message.fields.length, 1)
})
test('field is correct', function () {
assert.equal(message.fields[0], 'test')
})
})
})
test('notice message', function () {
// this uses the same logic as error message
var buff = buffers.notice([{ type: 'C', value: 'code' }])
testForMessage(buff, {
name: 'notice',
code: 'code',
})
})
test('error messages', function () {
test('with no fields', function () {
testForMessage(buffers.error(), {
name: 'error',
})
})
test('with all the fields', function () {
var buffer = buffers.error([
{
type: 'S',
value: 'ERROR',
},
{
type: 'C',
value: 'code',
},
{
type: 'M',
value: 'message',
},
{
type: 'D',
value: 'details',
},
{
type: 'H',
value: 'hint',
},
{
type: 'P',
value: '100',
},
{
type: 'p',
value: '101',
},
{
type: 'q',
value: 'query',
},
{
type: 'W',
value: 'where',
},
{
type: 'F',
value: 'file',
},
{
type: 'L',
value: 'line',
},
{
type: 'R',
value: 'routine',
},
{
type: 'Z', // ignored
value: 'alsdkf',
},
])
testForMessage(buffer, {
name: 'error',
severity: 'ERROR',
code: 'code',
message: 'message',
detail: 'details',
hint: 'hint',
position: '100',
internalPosition: '101',
internalQuery: 'query',
where: 'where',
file: 'file',
line: 'line',
routine: 'routine',
})
})
})
test('parses parse complete command', function () {
testForMessage(parseCompleteBuffer, {
name: 'parseComplete',
})
})
test('parses bind complete command', function () {
testForMessage(bindCompleteBuffer, {
name: 'bindComplete',
})
})
test('parses portal suspended message', function () {
testForMessage(portalSuspendedBuffer, {
name: 'portalSuspended',
})
})
test('parses replication start message', function () {
testForMessage(Buffer.from([0x57, 0x00, 0x00, 0x00, 0x04]), {
name: 'replicationStart',
length: 4,
})
})
})
// since the data message on a stream can randomly divide the incomming
// tcp packets anywhere, we need to make sure we can parse every single
// split on a tcp message
test('split buffer, single message parsing', function () {
var fullBuffer = buffers.dataRow([null, 'bang', 'zug zug', null, '!'])
var stream = new MemoryStream()
var client = new Connection({
stream: stream,
})
client.connect()
var message = null
client.on('message', function (msg) {
message = msg
})
test('parses when full buffer comes in', function () {
stream.emit('data', fullBuffer)
assert.lengthIs(message.fields, 5)
assert.equal(message.fields[0], null)
assert.equal(message.fields[1], 'bang')
assert.equal(message.fields[2], 'zug zug')
assert.equal(message.fields[3], null)
assert.equal(message.fields[4], '!')
})
var testMessageRecievedAfterSpiltAt = function (split) {
var firstBuffer = Buffer.alloc(fullBuffer.length - split)
var secondBuffer = Buffer.alloc(fullBuffer.length - firstBuffer.length)
fullBuffer.copy(firstBuffer, 0, 0)
fullBuffer.copy(secondBuffer, 0, firstBuffer.length)
stream.emit('data', firstBuffer)
stream.emit('data', secondBuffer)
assert.lengthIs(message.fields, 5)
assert.equal(message.fields[0], null)
assert.equal(message.fields[1], 'bang')
assert.equal(message.fields[2], 'zug zug')
assert.equal(message.fields[3], null)
assert.equal(message.fields[4], '!')
}
test('parses when split in the middle', function () {
testMessageRecievedAfterSpiltAt(6)
})
test('parses when split at end', function () {
testMessageRecievedAfterSpiltAt(2)
})
test('parses when split at beginning', function () {
testMessageRecievedAfterSpiltAt(fullBuffer.length - 2)
testMessageRecievedAfterSpiltAt(fullBuffer.length - 1)
testMessageRecievedAfterSpiltAt(fullBuffer.length - 5)
})
})
test('split buffer, multiple message parsing', function () {
var dataRowBuffer = buffers.dataRow(['!'])
var readyForQueryBuffer = buffers.readyForQuery()
var fullBuffer = Buffer.alloc(dataRowBuffer.length + readyForQueryBuffer.length)
dataRowBuffer.copy(fullBuffer, 0, 0)
readyForQueryBuffer.copy(fullBuffer, dataRowBuffer.length, 0)
var messages = []
var stream = new MemoryStream()
var client = new Connection({
stream: stream,
})
client.connect()
client.on('message', function (msg) {
messages.push(msg)
})
var verifyMessages = function () {
assert.lengthIs(messages, 2)
assert.same(messages[0], {
name: 'dataRow',
fieldCount: 1,
})
assert.equal(messages[0].fields[0], '!')
assert.same(messages[1], {
name: 'readyForQuery',
})
messages = []
}
// sanity check
test('recieves both messages when packet is not split', function () {
stream.emit('data', fullBuffer)
verifyMessages()
})
var splitAndVerifyTwoMessages = function (split) {
var firstBuffer = Buffer.alloc(fullBuffer.length - split)
var secondBuffer = Buffer.alloc(fullBuffer.length - firstBuffer.length)
fullBuffer.copy(firstBuffer, 0, 0)
fullBuffer.copy(secondBuffer, 0, firstBuffer.length)
stream.emit('data', firstBuffer)
stream.emit('data', secondBuffer)
}
test('recieves both messages when packet is split', function () {
test('in the middle', function () {
splitAndVerifyTwoMessages(11)
})
test('at the front', function () {
splitAndVerifyTwoMessages(fullBuffer.length - 1)
splitAndVerifyTwoMessages(fullBuffer.length - 4)
splitAndVerifyTwoMessages(fullBuffer.length - 6)
})
test('at the end', function () {
splitAndVerifyTwoMessages(8)
splitAndVerifyTwoMessages(1)
})
})
})

View File

@ -1,6 +1,10 @@
'use strict'
require('./test-helper')
const helper = require('./test-helper')
const assert = require('assert')
var Connection = require('../../../lib/connection')
const suite = new helper.Suite()
const test = suite.test.bind(suite)
const { MemoryStream } = helper
test('connection can take existing stream', function () {
var stream = new MemoryStream()
var con = new Connection({ stream: stream })

View File

@ -3,8 +3,9 @@ var EventEmitter = require('events').EventEmitter
var helper = require('../test-helper')
var Connection = require('../../lib/connection')
const { Client } = helper
global.MemoryStream = function () {
const MemoryStream = function () {
EventEmitter.call(this)
this.packets = []
}
@ -45,4 +46,5 @@ const createClient = function () {
module.exports = Object.assign({}, helper, {
createClient: createClient,
MemoryStream: MemoryStream,
})

View File

@ -2,6 +2,9 @@
var helper = require('./test-helper')
var utils = require('./../../lib/utils')
var defaults = require('./../../lib').defaults
const assert = require('assert')
const suite = new helper.Suite()
const test = suite.test.bind(suite)
test('ensure types is exported on root object', function () {
var pg = require('../../lib')
@ -10,23 +13,6 @@ test('ensure types is exported on root object', function () {
assert(pg.types.setTypeParser)
})
// this tests the monkey patching
// to ensure comptability with older
// versions of node
test('EventEmitter.once', function (t) {
// an event emitter
var stream = new MemoryStream()
var callCount = 0
stream.once('single', function () {
callCount++
})
stream.emit('single')
stream.emit('single')
assert.equal(callCount, 1)
})
test('normalizing query configs', function () {
var config
var callback = function () {}

View File

@ -6,6 +6,7 @@ const path = require('path')
const { unstable_dev } = require('wrangler')
var suite = new helper.Suite()
const assert = require('assert')
suite.testAsync('Can run in Cloudflare Worker?', test())