Skip to content

Commit b536d0d

Browse files
committed
Run tests with github actions
1 parent 0f87d5b commit b536d0d

17 files changed

+232
-124
lines changed

.github/workflows/test.yml

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
name: test
2+
3+
on: [push, pull_request]
4+
5+
jobs:
6+
test:
7+
name: Test Node v${{ matrix.node }}
8+
strategy:
9+
matrix:
10+
node: ['12', '14', '16', '17']
11+
runs-on: ubuntu-latest
12+
services:
13+
postgres:
14+
image: postgres
15+
env:
16+
POSTGRES_USER: postgres
17+
POSTGRES_HOST_AUTH_METHOD: trust
18+
ports:
19+
- 5433:5432
20+
options: >-
21+
--health-cmd pg_isready
22+
--health-interval 10s
23+
--health-timeout 5s
24+
--health-retries 5
25+
steps:
26+
- uses: actions/checkout@v3
27+
- run: |
28+
date
29+
sudo cp ./tests/pg_hba.conf /etc/postgresql/14/main/pg_hba.conf
30+
sudo sed -i 's/.*wal_level.*/wal_level = logical/' /etc/postgresql/14/main/postgresql.conf
31+
sudo sed -i 's/.*ssl = .*/ssl = on/' /etc/postgresql/14/main/postgresql.conf
32+
openssl req -new -x509 -nodes -days 365 -text -subj "/CN=localhost" -extensions v3_req -config <(cat /etc/ssl/openssl.cnf <(printf "\n[v3_req]\nbasicConstraints=critical,CA:TRUE\nkeyUsage=nonRepudiation,digitalSignature,keyEncipherment\nsubjectAltName=DNS:localhost")) -keyout server.key -out server.crt
33+
sudo cp server.key /etc/postgresql/14/main/server.key
34+
sudo cp server.crt /etc/postgresql/14/main/server.crt
35+
sudo chmod og-rwx /etc/postgresql/14/main/server.key
36+
sudo systemctl start postgresql.service
37+
pg_isready
38+
- uses: denoland/setup-deno@v1
39+
with:
40+
deno-version: v1.x
41+
- uses: actions/setup-node@v3
42+
with:
43+
node-version: ${{ matrix.node }}
44+
- run: npm test
45+
env:
46+
PGUSER: postgres
47+
PGSOCKET: /var/run/postgresql

cjs/src/connection.js

+4
Original file line numberDiff line numberDiff line change
@@ -818,12 +818,14 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
818818

819819
function CopyInResponse() {
820820
stream = new Stream.Writable({
821+
autoDestroy: true,
821822
write(chunk, encoding, callback) {
822823
socket.write(b().d().raw(chunk).end(), callback)
823824
},
824825
destroy(error, callback) {
825826
callback(error)
826827
socket.write(b().f().str(error + b.N).end())
828+
stream = null
827829
},
828830
final(callback) {
829831
socket.write(b().c().end())
@@ -843,6 +845,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
843845
/* c8 ignore next 3 */
844846
function CopyBothResponse() {
845847
stream = new Stream.Duplex({
848+
autoDestroy: true,
846849
read() { socket.resume() },
847850
/* c8 ignore next 11 */
848851
write(chunk, encoding, callback) {
@@ -851,6 +854,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
851854
destroy(error, callback) {
852855
callback(error)
853856
socket.write(b().f().str(error + b.N).end())
857+
stream = null
854858
},
855859
final(callback) {
856860
socket.write(b().c().end())

cjs/src/subscribe.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ module.exports = Subscribe;function Subscribe(postgres, options) {
6666

6767
stream.on('data', data)
6868
stream.on('error', (error) => {
69-
console.error('Logical Replication Error - Reconnecting', error)
69+
console.error('Logical Replication Error - Reconnecting', error) // eslint-disable-line
7070
sql.end()
7171
})
7272

cjs/tests/index.js

+30-28
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
/* eslint no-console: 0 */
2-
31
const { exec } = require('./bootstrap.js')
42

53
const { t, nt, ot } = require('./test.js') // eslint-disable-line
@@ -666,18 +664,19 @@ t('listen and notify with upper case', async() => {
666664

667665
t('listen reconnects', { timeout: 2 }, async() => {
668666
const sql = postgres(options)
669-
, xs = []
667+
, resolvers = {}
668+
, a = new Promise(r => resolvers.a = r)
669+
, b = new Promise(r => resolvers.b = r)
670670

671-
const { state: { pid } } = await sql.listen('test', x => xs.push(x))
672-
await delay(200)
671+
const { state: { pid } } = await sql.listen('test', x => x in resolvers && resolvers[x]())
673672
await sql.notify('test', 'a')
674-
await sql`select pg_terminate_backend(${ pid }::int)`
675-
await delay(200)
673+
await a
674+
await sql`select pg_terminate_backend(${ pid })`
675+
await delay(50)
676676
await sql.notify('test', 'b')
677-
await delay(200)
677+
await b
678678
sql.end()
679-
680-
return ['ab', xs.join('')]
679+
return [true, true]
681680
})
682681

683682

@@ -687,7 +686,7 @@ t('listen reconnects after connection error', { timeout: 3 }, async() => {
687686

688687
const { state: { pid } } = await sql.listen('test', x => xs.push(x))
689688
await sql.notify('test', 'a')
690-
await sql`select pg_terminate_backend(${ pid }::int)`
689+
await sql`select pg_terminate_backend(${ pid })`
691690
await delay(1000)
692691

693692
await sql.notify('test', 'b')
@@ -704,7 +703,7 @@ t('listen result reports correct connection state after reconnection', async() =
704703
const result = await sql.listen('test', x => xs.push(x))
705704
const initialPid = result.state.pid
706705
await sql.notify('test', 'a')
707-
await sql`select pg_terminate_backend(${ initialPid }::int)`
706+
await sql`select pg_terminate_backend(${ initialPid })`
708707
await delay(50)
709708
sql.end()
710709

@@ -852,7 +851,7 @@ t('Connection errors are caught using begin()', {
852851
}, async() => {
853852
let error
854853
try {
855-
const sql = postgres({ host: 'wat', port: 1337 })
854+
const sql = postgres({ host: 'localhost', port: 1 })
856855

857856
await sql.begin(async(sql) => {
858857
await sql`insert into test (label, value) values (${1}, ${2})`
@@ -863,8 +862,8 @@ t('Connection errors are caught using begin()', {
863862

864863
return [
865864
true,
866-
error.code === 'ENOTFOUND' ||
867-
error.message === 'failed to lookup address information: nodename nor servname provided, or not known'
865+
error.code === 'ECONNREFUSED' ||
866+
error.message === 'Connection refused (os error 61)'
868867
]
869868
})
870869

@@ -1016,8 +1015,8 @@ t('throws correct error when authentication fails', async() => {
10161015

10171016
t('notice works', async() => {
10181017
let notice
1019-
const log = console.log
1020-
console.log = function(x) {
1018+
const log = console.log // eslint-disable-line
1019+
console.log = function(x) { // eslint-disable-line
10211020
notice = x
10221021
}
10231022

@@ -1026,7 +1025,7 @@ t('notice works', async() => {
10261025
await sql`create table if not exists users()`
10271026
await sql`create table if not exists users()`
10281027

1029-
console.log = log
1028+
console.log = log // eslint-disable-line
10301029

10311030
return ['NOTICE', notice.severity]
10321031
})
@@ -1252,7 +1251,7 @@ t('Transform columns from', async() => {
12521251
t('Unix socket', async() => {
12531252
const sql = postgres({
12541253
...options,
1255-
host: '/tmp'
1254+
host: process.env.PGSOCKET || '/tmp' // eslint-disable-line
12561255
})
12571256

12581257
return [1, (await sql`select 1 as x`)[0].x]
@@ -1378,7 +1377,7 @@ t('requests works after single connect_timeout', async() => {
13781377
const sql = postgres({
13791378
...options,
13801379
...login_scram,
1381-
connect_timeout: { valueOf() { return first ? (first = false, 0.001) : 1 } }
1380+
connect_timeout: { valueOf() { return first ? (first = false, 0.0001) : 1 } }
13821381
})
13831382

13841383
return [
@@ -1538,19 +1537,22 @@ t('Multiple hosts', {
15381537
, sql = postgres('postgres://localhost:5432,localhost:5433', { idle_timeout, max: 1 })
15391538
, result = []
15401539

1540+
const id1 = (await s1`select system_identifier as x from pg_control_system()`)[0].x
1541+
const id2 = (await s2`select system_identifier as x from pg_control_system()`)[0].x
1542+
15411543
const x1 = await sql`select 1`
1542-
result.push((await sql`select setting as x from pg_settings where name = 'port'`)[0].x)
1544+
result.push((await sql`select system_identifier as x from pg_control_system()`)[0].x)
15431545
await s1`select pg_terminate_backend(${ x1.state.pid }::int)`
15441546
await delay(100)
15451547

15461548
const x2 = await sql`select 1`
1547-
result.push((await sql`select setting as x from pg_settings where name = 'port'`)[0].x)
1549+
result.push((await sql`select system_identifier as x from pg_control_system()`)[0].x)
15481550
await s2`select pg_terminate_backend(${ x2.state.pid }::int)`
15491551
await delay(100)
15501552

1551-
result.push((await sql`select setting as x from pg_settings where name = 'port'`)[0].x)
1553+
result.push((await sql`select system_identifier as x from pg_control_system()`)[0].x)
15521554

1553-
return ['5432,5433,5432', result.join(',')]
1555+
return [[id1, id2, id1].join(','), result.join(',')]
15541556
})
15551557

15561558
t('Escaping supports schemas and tables', async() => {
@@ -1762,9 +1764,9 @@ t('Cancel running query works', async() => {
17621764

17631765
t('Cancel piped query works', { timeout: 1 }, async() => {
17641766
await sql`select 1`
1765-
const last = sql`select pg_sleep(0.2)`.execute()
1767+
const last = sql`select pg_sleep(0.3)`.execute()
17661768
const query = sql`select pg_sleep(2) as dig`
1767-
setTimeout(() => query.cancel(), 100)
1769+
setTimeout(() => query.cancel(), 10)
17681770
const error = await query.catch(x => x)
17691771
await last
17701772
return ['57014', error.code]
@@ -1773,7 +1775,7 @@ t('Cancel piped query works', { timeout: 1 }, async() => {
17731775
t('Cancel queued query works', async() => {
17741776
const tx = sql.begin(sql => sql`select pg_sleep(0.2) as hej, 'hejsa'`)
17751777
const query = sql`select pg_sleep(2) as nej`
1776-
setTimeout(() => query.cancel(), 50)
1778+
setTimeout(() => query.cancel(), 100)
17771779
const error = await query.catch(x => x)
17781780
await tx
17791781
return ['57014', error.code]
@@ -1942,7 +1944,7 @@ t('Prevent premature end of connection in transaction', async() => {
19421944
]
19431945
})
19441946

1945-
t('Ensure reconnect after max_lifetime with transactions', { timeout: 5000 }, async() => {
1947+
t('Ensure reconnect after max_lifetime with transactions', { timeout: 5 }, async() => {
19461948
const sql = postgres({
19471949
max_lifetime: 0.01,
19481950
idle_timeout,

cjs/tests/pg_hba.conf

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
local all all trust
2+
host all postgres samehost trust
3+
host postgres_js_test postgres_js_test samehost trust
4+
host postgres_js_test postgres_js_test_md5 samehost md5
5+
host postgres_js_test postgres_js_test_scram samehost scram-sha-256

deno/polyfills.js

+5-4
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ export const net = {
2828
const socket = {
2929
error,
3030
success,
31+
readyState: 'closed',
3132
connect: (port, hostname) => {
32-
socket.closed = false
3333
socket.raw = null
3434
typeof port === 'string'
3535
? Deno.connect({ transport: 'unix', path: socket.path = port }).then(success, error)
@@ -79,6 +79,7 @@ export const net = {
7979

8080
async function success(raw) {
8181
const encrypted = socket.encrypted
82+
socket.readyState = 'open'
8283
socket.raw = raw
8384
socket.encrypted
8485
? call(socket.events.secureConnect)
@@ -88,7 +89,7 @@ export const net = {
8889
let result
8990

9091
try {
91-
while ((result = !socket.closed && await raw.read(b))) {
92+
while ((result = socket.readyState === 'open' && await raw.read(b))) {
9293
call(socket.events.data, Buffer.from(b.subarray(0, result)))
9394
if (!encrypted && socket.break && (socket.break = false, b[0] === 83))
9495
return socket.break = false
@@ -115,11 +116,11 @@ export const net = {
115116

116117
function closed() {
117118
socket.break = socket.encrypted = false
118-
if (socket.closed)
119+
if (socket.readyState !== 'open')
119120
return
120121

121122
call(socket.events.close)
122-
socket.closed = true
123+
socket.readyState = 'closed'
123124
}
124125

125126
function error(err) {

deno/src/connection.js

+4
Original file line numberDiff line numberDiff line change
@@ -821,12 +821,14 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
821821

822822
function CopyInResponse() {
823823
stream = new Stream.Writable({
824+
autoDestroy: true,
824825
write(chunk, encoding, callback) {
825826
socket.write(b().d().raw(chunk).end(), callback)
826827
},
827828
destroy(error, callback) {
828829
callback(error)
829830
socket.write(b().f().str(error + b.N).end())
831+
stream = null
830832
},
831833
final(callback) {
832834
socket.write(b().c().end())
@@ -846,6 +848,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
846848
/* c8 ignore next 3 */
847849
function CopyBothResponse() {
848850
stream = new Stream.Duplex({
851+
autoDestroy: true,
849852
read() { socket.resume() },
850853
/* c8 ignore next 11 */
851854
write(chunk, encoding, callback) {
@@ -854,6 +857,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
854857
destroy(error, callback) {
855858
callback(error)
856859
socket.write(b().f().str(error + b.N).end())
860+
stream = null
857861
},
858862
final(callback) {
859863
socket.write(b().c().end())

deno/src/subscribe.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ export default function Subscribe(postgres, options) {
6767

6868
stream.on('data', data)
6969
stream.on('error', (error) => {
70-
console.error('Logical Replication Error - Reconnecting', error)
70+
console.error('Logical Replication Error - Reconnecting', error) // eslint-disable-line
7171
sql.end()
7272
})
7373

0 commit comments

Comments
 (0)