UNPKG

node-pg-connection-pool

Version:

Connection pool for node-postgres with generic-pool support

306 lines (241 loc) 8.02 kB
require("should"); const Bluebird = require("bluebird"); const url = require("url"); const PgPool = require("../index"); describe("PgPool", () => { const options = { pgOptions: process.env.DATABASE_URL|| "postgres://postgres@localhost:5432/test_db" }; describe("constructor", () => { it("should err if pg-native is not available but asked for it", () => { const pool = new PgPool(Object.assign({}, options, { pgNative: true })); return pool.acquire().should.be.rejectedWith(Error, { message: "CONN_FAILED" }); }); }); describe("acquire", () => { it("should acquire connection with valid host", () => { const pool = new PgPool(options); return pool.acquire() .should.eventually.be.ok(); }); it("should wait to acquire if all used up", () => { const poolOptions = { min: 0, max: 1 }; const pool = new PgPool(Object.assign({}, options, { poolOptions: poolOptions })); pool.availableCount().should.be.equal(poolOptions.min); pool.getPoolSize().should.be.equal(poolOptions.min); pool.pendingCount().should.be.equal(0); return pool.acquire() .then(client => { pool.availableCount().should.be.equal(poolOptions.min); pool.getPoolSize().should.be.equal(1); pool.pendingCount().should.be.equal(0); return pool.release(client); }) .then(() => pool.availableCount().should.be.equal(1)) .then(() => pool.acquire()) .then(() => { pool.availableCount().should.be.equal(0); pool.getPoolSize().should.be.equal(1); pool.pendingCount().should.be.equal(0); }) .then(() => { pool.acquire(); // this is hanging op so no return return; }) .then(() => { pool.availableCount().should.be.equal(0); pool.getPoolSize().should.be.equal(1); pool.pendingCount().should.be.equal(1); }); }); it("should not fail with many higher min connections", () => { const poolOptions = { min: 5, max: 10, }; const pool = new PgPool(Object.assign({}, options, { poolOptions: poolOptions })); pool.acquire() .should.eventually.be.ok(); }); it("should invalid host fail acquire connection", () => { const pgOptions = Object.assign({}, options.pgOptions, { host: "UNAVAILABLE_HOST" }); const pool = new PgPool(Object.assign({}, options, { pgOptions: pgOptions })); return pool.acquire().should.be.rejectedWith(Error, { message: "CONN_FAILED" }); }); it("should conn timeout fail acquire connection", () => { const poolOptions = { min : 1, acquireTimeoutMillis: 1 }; const pool = new PgPool(Object.assign({}, options, { poolOptions: poolOptions })); // make the conn is inuse pool.acquire() .then(conn => pool.release(conn)); pool.acquire().should.be.rejectedWith(Error, { name: "TimeoutError" }); }); }); describe("release", () => { const poolOptions = { min: 2, max: 4 }; const pool = new PgPool(Object.assign({}, options, { poolOptions: poolOptions })); it("should release connection with valid host", () => { pool.availableCount().should.be.equal(poolOptions.min); pool.getPoolSize().should.be.equal(poolOptions.min); pool.pendingCount().should.be.equal(0); return pool.acquire() .then(client => { pool.availableCount().should.be.equal(poolOptions.min - 1); return pool.release(client); }) .then(() => pool.availableCount().should.be.equal(poolOptions.min)); }); it("should release connection with invalid host", () => { const pgOptions = Object.assign({}, options.pgOptions, { host: "UNAVAILABLE_HOST" }); const pool = new PgPool(Object.assign({}, options, { pgOptions: pgOptions })); return pool.acquire() .catch(() => { return pool.release() .should.be.rejectedWith(/Resource not currently part of this pool/); }); }); }); describe("destroy", () => { const poolOptions = { min: 2, max: 4 }; const pool = new PgPool(Object.assign({}, options, { poolOptions: poolOptions })); it("should destroy connection with valid host", () => { pool.availableCount().should.be.equal(poolOptions.min); pool.getPoolSize().should.be.equal(poolOptions.min); pool.pendingCount().should.be.equal(0); return pool.acquire() .then(client => { pool.availableCount().should.be.equal(poolOptions.min - 1); return pool.destroy(client); }) .then(() => Bluebird.delay(100)) .then(() => pool.availableCount().should.be.equal(poolOptions.min)); }); }); describe("drain", () => { const poolOptions = { min: 2, max: 4 }; const pool = new PgPool(Object.assign({}, options, { poolOptions: poolOptions })); it("should drain all the coonections", () => { pool.availableCount().should.be.equal(poolOptions.min); pool.getPoolSize().should.be.equal(poolOptions.min); pool.pendingCount().should.be.equal(0); return pool.drain() .then(() => { pool.availableCount().should.be.equal(poolOptions.min); pool.getPoolSize().should.be.equal(poolOptions.min); }); }); }); describe("getName", () => { it("should set given name", () => { const name = "testPool"; const pool = new PgPool(Object.assign({}, options, { name: name })); pool.getName().should.be.equal(name); }); it("should set random name if not set", () => { const pool = new PgPool(options); pool.getName().should.not.be.empty(); }); }); describe("getPgOptions", () => { it("should set given postgres options", () => { const pool = new PgPool(options); const params = url.parse(options.pgOptions, true); const auth = params.auth.split(":"); const expected = { user: auth[0], password: auth[1], host: params.hostname, port: params.port, database: params.pathname.split("/")[1], ssl: params.query.ssl || true }; pool.getPgOptions().should.be.eql(expected); }); }); describe("getPoolOptions", () => { it("should set given pool options", () => { const poolOptions = { min: 2, max: 4 }; const pool = new PgPool(Object.assign({}, options, { poolOptions: poolOptions })); pool.getPoolOptions().should.be.equal(poolOptions); }); }); describe("status", () => { it("should get pool stats", () => { const name = "testPool"; const poolOptions = { min: 2, max: 4 }; const pool = new PgPool(Object.assign({}, options, { name: name, poolOptions: poolOptions })); const status = pool.status(); status.name.should.be.equal(name); status.size.should.be.equal(poolOptions.min); status.available.should.be.equal(0); status.pending.should.be.equal(0); }); }); describe("query", () => { const pool = new PgPool(options); it("should execute given query", () => { return pool.query("SELECT 1 AS number;") .then(res => res.rows[0]["number"]) .should.eventually.be.eql(1); }); it("should execute given query with arrayValues", () => { return pool.query("SELECT $1::int AS number;", ["1"]) .then(res => res.rows[0]["number"]) .should.eventually.be.eql(1); }); it("should reject when cmd failed", () => { return pool.query("SEL;") .should.be.rejectedWith(/syntax error at or near/); }); }); });