Skip to content

Commit f2bfce6

Browse files
author
denshikov-vovan
committed
[ #154578064 ] - Additional tests for pg.io module
1 parent 5238aa3 commit f2bfce6

File tree

7 files changed

+119
-44
lines changed

7 files changed

+119
-44
lines changed

tests/helpers.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1+
import * as net from 'net';
12
import {Client, ConnectionConfig} from 'pg';
23
import {buildLogger, Logger} from '../lib/util';
34
import {ConnectionPool, PoolOptions} from '../lib/Pool';
45
import {settings} from './settings';
56

7+
export const PROXY_SERVER_PORT = 3000;
8+
69
export function createNewPool(poolOptions: PoolOptions = {}, connectionOptions: ConnectionConfig = {}, logger?: Logger): ConnectionPool {
710
const poolSettings = Object.assign({}, settings.pool, poolOptions);
811
const connectionSettings = Object.assign({}, settings.connection, connectionOptions);
@@ -18,3 +21,38 @@ export function wait(time) {
1821
export function createClient(pool: ConnectionPool): Promise<Client> {
1922
return new Promise((resolve, reject) => pool.acquire((err, client) => err ? reject(err) : resolve(client)));
2023
}
24+
25+
export function pgProxyServer(timeout: number, cb): net.Server {
26+
const server = net.createServer(proxySocket => {
27+
const pgSocket = new net.Socket();
28+
29+
pgSocket.connect(settings.connection.port, settings.connection.host);
30+
31+
proxySocket.on('data', data => {
32+
setTimeout(() => {
33+
const flushed = pgSocket.write(data);
34+
35+
!flushed && proxySocket.pause();
36+
}, timeout);
37+
});
38+
39+
pgSocket.on('data', data => {
40+
const flushed = proxySocket.write(data);
41+
42+
!flushed && pgSocket.pause();
43+
});
44+
45+
proxySocket.on('drain', () => pgSocket.resume());
46+
47+
pgSocket.on('drain', () => proxySocket.resume());
48+
49+
proxySocket.on('close', () => pgSocket.end());
50+
51+
pgSocket.on('close', () => proxySocket.end());
52+
53+
});
54+
55+
server.listen(PROXY_SERVER_PORT, cb);
56+
57+
return server;
58+
}

tests/pool.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ describe('Pool;', () => {
3434
});
3535

3636
it('does not pass client to error callback', done => {
37-
const pool = createNewPool({}, {port: 53922});
37+
const pool = createNewPool({}, {port: 8080});
3838

3939
pool.acquire((err, client) => {
4040
expect(client).to.be.undefined;

tests/poolConnectionTimeout.spec.ts

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,42 @@
11
import {expect} from 'chai';
22

33
import {ConnectionError} from '../lib/errors';
4-
import {createNewPool} from './helpers';
4+
import {createNewPool, pgProxyServer, PROXY_SERVER_PORT} from './helpers';
5+
6+
const connectionOptions = {port: PROXY_SERVER_PORT};
7+
8+
let server;
59

610
describe('Pool connection timeout;', () => {
11+
before(done => {
12+
server = pgProxyServer(250, done);
13+
});
14+
15+
after(done => {
16+
server.close(done);
17+
});
718

819
it('should callback with an error if timeout is passed', done => {
9-
const pool = createNewPool({connectionTimeout: 2});
20+
const pool = createNewPool({connectionTimeout: 150}, connectionOptions);
1021

1122
pool.acquire((err, client) => {
12-
expect(err).to.be.an.instanceof(ConnectionError);
13-
expect(err.message).to.contain('Connection request has timed out');
14-
expect(pool.idleCount).to.equal(0);
15-
expect(pool.totalCount).to.equal(1);
16-
expect(client).to.be.undefined;
23+
try {
24+
expect(err).to.be.an.instanceof(ConnectionError);
25+
expect(err.message).to.contain('Connection request has timed out');
26+
expect(pool.idleCount).to.equal(0);
27+
expect(pool.totalCount).to.equal(1);
28+
expect(client).to.be.undefined;
1729

18-
pool.shutdown(done);
30+
pool.shutdown(done);
31+
} catch (err) {
32+
pool.shutdown(() => done(err));
33+
}
1934
});
2035
});
2136

2237
it('should handle multiple timeouts', async done => {
2338
const iterations = 15;
24-
const pool = createNewPool({connectionTimeout: 2, maxSize: iterations});
39+
const pool = createNewPool({connectionTimeout: 150, maxSize: iterations}, connectionOptions);
2540
const errors = [];
2641

2742
try {
@@ -44,33 +59,36 @@ describe('Pool connection timeout;', () => {
4459
expect(pool.totalCount).to.equal(15);
4560

4661
pool.shutdown(done);
47-
} catch (e) {
48-
done(e);
62+
} catch (err) {
63+
pool.shutdown(() => done(err));
4964
}
5065
});
5166

5267
it('should timeout on checkout of used connection', done => {
53-
const pool = createNewPool({connectionTimeout: 100, maxSize: 1});
54-
55-
pool.acquire((err, client) => {
56-
expect(err).to.be.undefined;
57-
expect(client).to.not.be.undefined;
58-
expect(pool.totalCount).to.equal(1);
59-
68+
const pool = createNewPool({connectionTimeout: 400, maxSize: 1}, connectionOptions);
69+
try {
6070
pool.acquire((err, client) => {
61-
expect(err).to.be.an.instanceof(ConnectionError);
62-
expect(err.message).to.contain('Connection request has timed out');
63-
expect(client).to.be.undefined;
71+
expect(err).to.be.undefined;
72+
expect(client).to.not.be.undefined;
6473
expect(pool.totalCount).to.equal(1);
6574

66-
(pool as any).clients.entries().next().value[0].release();
67-
pool.shutdown(done);
75+
pool.acquire((err, client) => {
76+
expect(err).to.be.an.instanceof(ConnectionError);
77+
expect(err.message).to.contain('Connection request has timed out');
78+
expect(client).to.be.undefined;
79+
expect(pool.totalCount).to.equal(1);
80+
81+
(pool as any).clients.entries().next().value[0].release();
82+
pool.shutdown(done);
83+
});
6884
});
69-
});
85+
} catch (err) {
86+
pool.shutdown(() => done(err));
87+
}
7088
});
7189

7290
it('should timeout on query if all clients are busy', done => {
73-
const pool = createNewPool({connectionTimeout: 100, maxSize: 1});
91+
const pool = createNewPool({connectionTimeout: 400, maxSize: 1}, connectionOptions);
7492

7593
pool.acquire((err, client) => {
7694
expect(err).to.be.undefined;
@@ -91,7 +109,7 @@ describe('Pool connection timeout;', () => {
91109
});
92110

93111
it('should recover from timeout errors', done => {
94-
const pool = createNewPool({connectionTimeout: 100, maxSize: 1});
112+
const pool = createNewPool({connectionTimeout: 400, maxSize: 1}, connectionOptions);
95113

96114
pool.acquire((err, client) => {
97115
expect(err).to.be.undefined;

tests/poolIdleTimeout.spec.ts

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,19 @@ import {expect} from 'chai';
22

33
import {CLOSED_EVENT} from '../lib/Pool';
44
import {ConnectionError} from '../lib/errors';
5-
import {createNewPool, createClient, wait} from './helpers';
5+
import {createNewPool, pgProxyServer, createClient, wait, PROXY_SERVER_PORT} from './helpers';
6+
7+
let server;
68

79
describe('Pool idle timeout;', () => {
10+
before(done => {
11+
server = pgProxyServer(250, done);
12+
});
13+
14+
after(done => {
15+
server.close(done);
16+
});
17+
818
it('should timeout and remove the client', done => {
919
const pool = createNewPool({idleTimeout: 10});
1020

@@ -126,8 +136,8 @@ describe('Pool idle timeout;', () => {
126136
});
127137

128138
it('should removes client after timeout error', async done => {
129-
const idleTimeout = 50;
130-
const pool = createNewPool({connectionTimeout: 2, idleTimeout});
139+
const idleTimeout = 150;
140+
const pool = createNewPool({connectionTimeout: 150, idleTimeout}, {port: PROXY_SERVER_PORT});
131141
let client, timeoutError;
132142

133143
try {
@@ -144,7 +154,7 @@ describe('Pool idle timeout;', () => {
144154
expect(pool.idleCount).to.equal(0);
145155
expect(pool.totalCount).to.equal(1);
146156

147-
await wait(5);
157+
await wait(200);
148158

149159
expect(pool.idleCount).to.equal(1);
150160
expect(pool.totalCount).to.equal(1);
@@ -156,14 +166,14 @@ describe('Pool idle timeout;', () => {
156166

157167
pool.shutdown(done);
158168
} catch (err) {
159-
done(err);
169+
pool.shutdown(() => done(err));
160170
}
161171
});
162172

163173
it('should removes client after multiple timeout errors', async done => {
164174
const idleTimeout = 50;
165175
const iterations = 15;
166-
const pool = createNewPool({connectionTimeout: 2, idleTimeout, maxSize: iterations});
176+
const pool = createNewPool({connectionTimeout: 150, idleTimeout, maxSize: iterations}, {port: PROXY_SERVER_PORT});
167177
const errors = [];
168178

169179
try {
@@ -187,7 +197,7 @@ describe('Pool idle timeout;', () => {
187197
expect(pool.idleCount).to.equal(0);
188198
expect(pool.totalCount).to.equal(iterations);
189199

190-
await wait(idleTimeout/2);
200+
await wait(200);
191201

192202
expect(pool.idleCount).to.equal(iterations);
193203
expect(pool.totalCount).to.equal(iterations);
@@ -199,7 +209,7 @@ describe('Pool idle timeout;', () => {
199209

200210
pool.shutdown(done);
201211
} catch (err) {
202-
done(err);
212+
pool.shutdown(() => done(err));
203213
}
204214
});
205215
});

tests/poolSizing.spec.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,18 @@
11
import {expect} from 'chai';
22

3-
import {createNewPool, createClient, wait} from './helpers';
3+
import {createNewPool, createClient, wait, pgProxyServer, PROXY_SERVER_PORT} from './helpers';
4+
5+
let server;
6+
7+
describe('Pool size of 1;', () => {
8+
before(done => {
9+
server = pgProxyServer(250, done);
10+
});
11+
12+
after(done => {
13+
server.close(done);
14+
});
415

5-
describe('pool size of 1', () => {
616
it('can create a single client and use it once', async done => {
717
const pool = createNewPool({maxSize: 1});
818

@@ -21,12 +31,12 @@ describe('pool size of 1', () => {
2131

2232
pool.shutdown(done);
2333
} catch (err) {
24-
done(err);
34+
pool.shutdown(() => done(err));
2535
}
2636
});
2737

2838
it('can create a single client and use it multiple times', async done => {
29-
const pool = createNewPool({maxSize: 1, connectionTimeout: 50});
39+
const pool = createNewPool({maxSize: 1, connectionTimeout: 300}, {port: PROXY_SERVER_PORT});
3040
let clientA, clientB;
3141

3242
try {
@@ -48,7 +58,7 @@ describe('pool size of 1', () => {
4858

4959
clientA.release();
5060

51-
await wait(5);
61+
await wait(100);
5262

5363
clientB = await createClient(pool);
5464

tests/settings.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export const settings = {
88
},
99
pool: {
1010
maxSize : 10,
11-
idleTimeout : 2000,
11+
idleTimeout : 1000,
1212
connectionTimeout: 1000
1313
}
1414
};

tests/testFile.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,8 @@ function sendResult(res, isError) {
8181
function showPgPoolData() {
8282
setTimeout(() => {
8383
console.log('PgPool info');
84-
console.log(`All clients - [${database.pgPool._clients.map(c => c.processID).join(',')}]`);
85-
console.log(`Idle clients - [${database.pgPool._idle.map(c => c.processID).join(',')}]`);
86-
console.log(`Waiting clients - [${database.pgPool._pendingQueue.map(c => c.processID).join(',')}]`);
84+
console.log(`All clients - [${[ ...database.pool.clients ].map(c => c.processID).join(',')}]`);
85+
console.log(`Idle clients - [${[ ...database.pool.idle.keys() ].map(c => c.processID).join(',')}]`);
8786
console.log('--------------------');
8887
}, 1000);
8988
}

0 commit comments

Comments
 (0)