1 | import tap from 'tap';
|
2 | import fs from 'fs';
|
3 | import tls from 'tls';
|
4 | import net from 'net';
|
5 | import path from 'path';
|
6 | import sslRootCas from 'ssl-root-cas';
|
7 | import Pool from '../src/index';
|
8 |
|
9 | class FakeParser extends Pool.ConnectionInterface {
|
10 | constructor(socket, ...rest) {
|
11 | super(socket, ...rest);
|
12 | socket.on('data', (data) => {
|
13 | this.emit('received', data);
|
14 | });
|
15 | }
|
16 |
|
17 |
|
18 | initializeConnection() {
|
19 | return new Promise(accept => setTimeout(accept, 100));
|
20 | }
|
21 | }
|
22 |
|
23 | const basePath = path.join(__dirname, 'certs', 'server');
|
24 | let tlsServer;
|
25 | let netServer;
|
26 |
|
27 | tap.test('Should setup dummy TLS server', (t) => {
|
28 | sslRootCas
|
29 | .inject()
|
30 | .addFile(path.join(basePath, 'my-root-ca.crt.pem'));
|
31 |
|
32 | tlsServer = tls.createServer({
|
33 | key: fs.readFileSync(path.join(basePath, 'my-server.key.pem')),
|
34 | cert: fs.readFileSync(path.join(basePath, 'my-server.crt.pem')),
|
35 | }, (socket) => {
|
36 |
|
37 | socket.pipe(socket);
|
38 |
|
39 | socket.on('error', () => null);
|
40 | });
|
41 | tlsServer.listen(0, (error) => {
|
42 | t.end(error);
|
43 | });
|
44 | });
|
45 |
|
46 | tap.test('Should setup dummy insecure server', (t) => {
|
47 | netServer = net.createServer({
|
48 | key: fs.readFileSync(path.join(basePath, 'my-server.key.pem')),
|
49 | cert: fs.readFileSync(path.join(basePath, 'my-server.crt.pem')),
|
50 | }, (socket) => {
|
51 |
|
52 | socket.pipe(socket);
|
53 |
|
54 | socket.on('error', () => null);
|
55 | });
|
56 | netServer.listen(0, (error) => {
|
57 | t.end(error);
|
58 | });
|
59 | });
|
60 |
|
61 | tap.test('Should fail to connect with invalid cert', async (t) => {
|
62 | const pool = new Pool(() => { }, {
|
63 | name: 'InvalidCert',
|
64 | host: 'localhost',
|
65 | port: tlsServer.address().port,
|
66 | min: 0,
|
67 | acquireTimeoutMillis: 500,
|
68 | });
|
69 | t.ok(pool, 'Constructor should work');
|
70 | try {
|
71 | await pool.acquire();
|
72 | t.ok(false, 'Acquire should throw');
|
73 | } catch (x) {
|
74 | t.ok(true, 'Acquire should throw');
|
75 | }
|
76 | await pool.destroyAllNow();
|
77 | t.ok(true, 'Pool should be destroyed.');
|
78 | t.end();
|
79 | });
|
80 |
|
81 | tap.test('Should make a secure pool', async (t) => {
|
82 | const pool = new Pool(FakeParser, {
|
83 | name: 'GoodCert',
|
84 | host: 'localhost',
|
85 | port: tlsServer.address().port,
|
86 | tlsOptions: {
|
87 | ca: fs.readFileSync(path.join(basePath, 'my-root-ca.crt.pem')),
|
88 | },
|
89 | max: 2,
|
90 | });
|
91 | t.ok(pool, 'Constructor should work');
|
92 | const connection = await pool.acquire();
|
93 | t.ok(connection, 'Should acquire connection.');
|
94 | const second = await pool.acquire();
|
95 | t.ok(second, 'Should acquire another.');
|
96 | pool.release(connection);
|
97 | const third = await pool.acquire();
|
98 | t.ok(third, 'Should get a third with max connections 2');
|
99 | pool.release(second);
|
100 | third.send(new Buffer('ABCD', 'ascii'));
|
101 | pool.release(third);
|
102 | const promise = new Promise((accept) => {
|
103 | third.once('received', (message) => {
|
104 | t.ok(message, 'Should receive message');
|
105 | t.equal(message.length, 4, 'Message length should be 4');
|
106 | accept();
|
107 | });
|
108 | });
|
109 | await promise;
|
110 | await pool.destroyAllNow();
|
111 | t.ok(true, 'Pool should be destroyed.');
|
112 | t.end();
|
113 | });
|
114 |
|
115 |
|
116 | tap.test('Should make an insecure pool', async (t) => {
|
117 | const pool = new Pool(FakeParser, {
|
118 | name: 'Insecure',
|
119 | host: 'localhost',
|
120 | port: netServer.address().port,
|
121 | insecure: true,
|
122 | max: 2,
|
123 | });
|
124 | t.ok(pool, 'Constructor should work');
|
125 | const connection = await pool.acquire();
|
126 | t.ok(connection, 'Should acquire connection.');
|
127 | const second = await pool.acquire();
|
128 | t.ok(second, 'Should acquire another.');
|
129 | pool.release(connection);
|
130 | const third = await pool.acquire();
|
131 | t.ok(third, 'Should get a third with max connections 2');
|
132 | pool.release(second);
|
133 | third.send(new Buffer('ABCD', 'ascii'));
|
134 | pool.release(third);
|
135 | const promise = new Promise((accept) => {
|
136 | third.once('received', (message) => {
|
137 | t.ok(message, 'Should receive message');
|
138 | t.equal(message.length, 4, 'Message length should be 4');
|
139 | accept();
|
140 | });
|
141 | });
|
142 | await promise;
|
143 | await pool.destroyAllNow();
|
144 | t.ok(true, 'Pool should be destroyed.');
|
145 | t.end();
|
146 | });
|
147 |
|
148 | tap.test('Should destroy tls server', (t) => {
|
149 | tlsServer.close(() => {
|
150 | t.end();
|
151 | });
|
152 | });
|
153 |
|
154 | tap.test('Should destroy net server', (t) => {
|
155 | netServer.close(() => {
|
156 | t.end();
|
157 | });
|
158 | });
|