Brian C 3aba3794cf
Use github actions for CI (#2654)
This is the initial port to github actions.  Still pending are the SSL and client SSL cert tests which are currently being skipped. But perfect is the enemy of the good here, and having no CI because travis-ci keeps not working is unacceptable.
2021-11-17 10:02:22 -06:00

359 lines
11 KiB
JavaScript

'use strict'
const helper = require('../test-helper')
const assert = require('assert')
const ConnectionParameters = require('../../../lib/connection-parameters')
const defaults = require('../../../lib').defaults
const dns = require('dns')
// clear process.env
for (var key in process.env) {
delete process.env[key]
}
const suite = new helper.Suite()
suite.test('ConnectionParameters construction', function () {
assert.ok(new ConnectionParameters(), 'with null config')
assert.ok(new ConnectionParameters({ user: 'asdf' }), 'with config object')
assert.ok(new ConnectionParameters('postgres://localhost/postgres'), 'with connection string')
})
var compare = function (actual, expected, type) {
const expectedDatabase = expected.database === undefined ? expected.user : expected.database
assert.equal(actual.user, expected.user, type + ' user')
assert.equal(actual.database, expectedDatabase, type + ' database')
assert.equal(actual.port, expected.port, type + ' port')
assert.equal(actual.host, expected.host, type + ' host')
assert.equal(actual.password, expected.password, type + ' password')
assert.equal(actual.binary, expected.binary, type + ' binary')
assert.equal(actual.statement_timeout, expected.statement_timeout, type + ' statement_timeout')
assert.equal(actual.options, expected.options, type + ' options')
assert.equal(
actual.idle_in_transaction_session_timeout,
expected.idle_in_transaction_session_timeout,
type + ' idle_in_transaction_session_timeout'
)
}
suite.test('ConnectionParameters initializing from defaults', function () {
var subject = new ConnectionParameters()
compare(subject, defaults, 'defaults')
assert.ok(subject.isDomainSocket === false)
})
suite.test('ConnectionParameters initializing from defaults with connectionString set', function () {
var config = {
user: 'brians-are-the-best',
database: 'scoobysnacks',
port: 7777,
password: 'mypassword',
host: 'foo.bar.net',
binary: defaults.binary,
statement_timeout: false,
idle_in_transaction_session_timeout: false,
options: '-c geqo=off',
}
var original_value = defaults.connectionString
// Just changing this here doesn't actually work because it's no longer in scope when viewed inside of
// of ConnectionParameters() so we have to pass in the defaults explicitly to test it
defaults.connectionString =
'postgres://brians-are-the-best:mypassword@foo.bar.net:7777/scoobysnacks?options=-c geqo=off'
var subject = new ConnectionParameters(defaults)
defaults.connectionString = original_value
compare(subject, config, 'defaults-connectionString')
})
suite.test('ConnectionParameters initializing from config', function () {
var config = {
user: 'brian',
database: 'home',
port: 7777,
password: 'pizza',
binary: true,
encoding: 'utf8',
host: 'yo',
ssl: {
asdf: 'blah',
},
statement_timeout: 15000,
idle_in_transaction_session_timeout: 15000,
options: '-c geqo=off',
}
var subject = new ConnectionParameters(config)
compare(subject, config, 'config')
assert.ok(subject.isDomainSocket === false)
})
suite.test('ConnectionParameters initializing from config and config.connectionString', function () {
var subject1 = new ConnectionParameters({
connectionString: 'postgres://test@host/db',
})
var subject2 = new ConnectionParameters({
connectionString: 'postgres://test@host/db?ssl=1',
})
var subject3 = new ConnectionParameters({
connectionString: 'postgres://test@host/db',
ssl: true,
})
var subject4 = new ConnectionParameters({
connectionString: 'postgres://test@host/db?ssl=1',
ssl: false,
})
assert.equal(subject1.ssl, false)
assert.equal(subject2.ssl, true)
assert.equal(subject3.ssl, true)
assert.equal(subject4.ssl, true)
})
suite.test('escape spaces if present', function () {
var subject = new ConnectionParameters('postgres://localhost/post gres')
assert.equal(subject.database, 'post gres')
})
suite.test('do not double escape spaces', function () {
var subject = new ConnectionParameters('postgres://localhost/post%20gres')
assert.equal(subject.database, 'post gres')
})
suite.test('initializing with unix domain socket', function () {
var subject = new ConnectionParameters('/var/run/')
assert.ok(subject.isDomainSocket)
assert.equal(subject.host, '/var/run/')
assert.equal(subject.database, defaults.user)
})
suite.test('initializing with unix domain socket and a specific database, the simple way', function () {
var subject = new ConnectionParameters('/var/run/ mydb')
assert.ok(subject.isDomainSocket)
assert.equal(subject.host, '/var/run/')
assert.equal(subject.database, 'mydb')
})
suite.test('initializing with unix domain socket, the health way', function () {
var subject = new ConnectionParameters('socket:/some path/?db=my[db]&encoding=utf8')
assert.ok(subject.isDomainSocket)
assert.equal(subject.host, '/some path/')
assert.equal(subject.database, 'my[db]', 'must to be escaped and unescaped trough "my%5Bdb%5D"')
assert.equal(subject.client_encoding, 'utf8')
})
suite.test('initializing with unix domain socket, the escaped health way', function () {
var subject = new ConnectionParameters('socket:/some%20path/?db=my%2Bdb&encoding=utf8')
assert.ok(subject.isDomainSocket)
assert.equal(subject.host, '/some path/')
assert.equal(subject.database, 'my+db')
assert.equal(subject.client_encoding, 'utf8')
})
var checkForPart = function (array, part) {
assert.ok(array.indexOf(part) > -1, array.join(' ') + ' did not contain ' + part)
}
const getDNSHost = async function (host) {
return new Promise((resolve, reject) => {
dns.lookup(host, (err, addresses) => {
err ? reject(err) : resolve(addresses)
})
})
}
suite.testAsync('builds simple string', async function () {
var config = {
user: 'brian',
password: 'xyz',
port: 888,
host: 'localhost',
database: 'bam',
}
var subject = new ConnectionParameters(config)
const dnsHost = await getDNSHost(config.host)
return new Promise((resolve) => {
subject.getLibpqConnectionString(function (err, constring) {
assert(!err)
var parts = constring.split(' ')
checkForPart(parts, "user='brian'")
checkForPart(parts, "password='xyz'")
checkForPart(parts, "port='888'")
checkForPart(parts, `hostaddr='${dnsHost}'`)
checkForPart(parts, "dbname='bam'")
resolve()
})
})
})
suite.test('builds dns string', async function () {
var config = {
user: 'brian',
password: 'asdf',
port: 5432,
host: 'localhost',
}
var subject = new ConnectionParameters(config)
const dnsHost = await getDNSHost(config.host)
return new Promise((resolve) => {
subject.getLibpqConnectionString(function (err, constring) {
assert(!err)
var parts = constring.split(' ')
checkForPart(parts, "user='brian'")
checkForPart(parts, `hostaddr='${dnsHost}'`)
resolve()
})
})
})
suite.test('error when dns fails', function () {
var config = {
user: 'brian',
password: 'asf',
port: 5432,
host: 'asdlfkjasldfkksfd#!$!!!!..com',
}
var subject = new ConnectionParameters(config)
subject.getLibpqConnectionString(
assert.calls(function (err, constring) {
assert.ok(err)
assert.isNull(constring)
})
)
})
suite.test('connecting to unix domain socket', function () {
var config = {
user: 'brian',
password: 'asf',
port: 5432,
host: '/tmp/',
}
var subject = new ConnectionParameters(config)
subject.getLibpqConnectionString(
assert.calls(function (err, constring) {
assert(!err)
var parts = constring.split(' ')
checkForPart(parts, "user='brian'")
checkForPart(parts, "host='/tmp/'")
})
)
})
suite.test('config contains quotes and backslashes', function () {
var config = {
user: 'not\\brian',
password: "bad'chars",
port: 5432,
host: '/tmp/',
}
var subject = new ConnectionParameters(config)
subject.getLibpqConnectionString(
assert.calls(function (err, constring) {
assert(!err)
var parts = constring.split(' ')
checkForPart(parts, "user='not\\\\brian'")
checkForPart(parts, "password='bad\\'chars'")
})
)
})
suite.test('encoding can be specified by config', function () {
var config = {
client_encoding: 'utf-8',
}
var subject = new ConnectionParameters(config)
subject.getLibpqConnectionString(
assert.calls(function (err, constring) {
assert(!err)
var parts = constring.split(' ')
checkForPart(parts, "client_encoding='utf-8'")
})
)
})
suite.test('password contains < and/or > characters', function () {
var sourceConfig = {
user: 'brian',
password: 'hello<ther>e',
port: 5432,
host: 'localhost',
database: 'postgres',
}
var connectionString =
'postgres://' +
sourceConfig.user +
':' +
sourceConfig.password +
'@' +
sourceConfig.host +
':' +
sourceConfig.port +
'/' +
sourceConfig.database
var subject = new ConnectionParameters(connectionString)
assert.equal(subject.password, sourceConfig.password)
})
suite.test('username or password contains weird characters', function () {
var defaults = require('../../../lib/defaults')
defaults.ssl = true
var strang = 'pg://my f%irst name:is&%awesome!@localhost:9000'
var subject = new ConnectionParameters(strang)
assert.equal(subject.user, 'my f%irst name')
assert.equal(subject.password, 'is&%awesome!')
assert.equal(subject.host, 'localhost')
assert.equal(subject.ssl, true)
})
suite.test('url is properly encoded', function () {
var encoded = 'pg://bi%25na%25%25ry%20:s%40f%23@localhost/%20u%2520rl'
var subject = new ConnectionParameters(encoded)
assert.equal(subject.user, 'bi%na%%ry ')
assert.equal(subject.password, 's@f#')
assert.equal(subject.host, 'localhost')
assert.equal(subject.database, ' u%20rl')
})
suite.test('ssl is set on client', function () {
var Client = require('../../../lib/client')
var defaults = require('../../../lib/defaults')
defaults.ssl = true
var c = new Client('postgres://user@password:host/database')
assert(c.ssl, 'Client should have ssl enabled via defaults')
})
suite.test('coercing string "true" to boolean', function () {
const subject = new ConnectionParameters({ ssl: 'true' })
assert.strictEqual(subject.ssl, true)
})
suite.test('ssl is set on client', function () {
var sourceConfig = {
user: 'brian',
password: 'hello<ther>e',
port: 5432,
host: 'localhost',
database: 'postgres',
ssl: {
sslmode: 'verify-ca',
sslca: '/path/ca.pem',
sslkey: '/path/cert.key',
sslcert: '/path/cert.crt',
sslrootcert: '/path/root.crt',
},
}
var Client = require('../../../lib/client')
var defaults = require('../../../lib/defaults')
defaults.ssl = true
var c = new ConnectionParameters(sourceConfig)
c.getLibpqConnectionString(
assert.calls(function (err, pgCString) {
assert(!err)
assert.equal(
pgCString.indexOf("sslrootcert='/path/root.crt'") !== -1,
true,
'libpqConnectionString should contain sslrootcert'
)
})
)
})