a8bd44a6ec
There was some nasty global-ish variable reference updating happening when the native module 'initializes' after its require with `require('pg').native` This fixes the issue by making sure both `require('pg')` and `require('pg').native` each initialize their own context in isolation and no weird global-ish references are used & subsequently stomped on.
215 lines
5.8 KiB
JavaScript
215 lines
5.8 KiB
JavaScript
var util = require('util');
|
|
var EventEmitter = require('events').EventEmitter;
|
|
|
|
var libDir = __dirname + '/../../../lib';
|
|
var poolsFactory = require(libDir + '/pool')
|
|
var defaults = require(libDir + '/defaults');
|
|
var poolId = 0;
|
|
|
|
require(__dirname + '/../../test-helper');
|
|
|
|
var FakeClient = function() {
|
|
EventEmitter.call(this);
|
|
}
|
|
|
|
util.inherits(FakeClient, EventEmitter);
|
|
|
|
FakeClient.prototype.connect = function(cb) {
|
|
process.nextTick(cb);
|
|
}
|
|
|
|
FakeClient.prototype.end = function() {
|
|
this.endCalled = true;
|
|
}
|
|
var pools = poolsFactory(FakeClient);
|
|
|
|
//Hangs the event loop until 'end' is called on client
|
|
var HangingClient = function(config) {
|
|
EventEmitter.call(this);
|
|
this.config = config;
|
|
}
|
|
|
|
util.inherits(HangingClient, EventEmitter);
|
|
|
|
HangingClient.prototype.connect = function(cb) {
|
|
this.intervalId = setInterval(function() {
|
|
console.log('hung client...');
|
|
}, 1000);
|
|
process.nextTick(cb);
|
|
}
|
|
|
|
HangingClient.prototype.end = function() {
|
|
clearInterval(this.intervalId);
|
|
}
|
|
|
|
test('no pools exist', function() {
|
|
assert.empty(Object.keys(pools.all));
|
|
});
|
|
|
|
test('pool creates pool on miss', function() {
|
|
var p = pools.getOrCreate();
|
|
assert.ok(p);
|
|
assert.equal(Object.keys(pools.all).length, 1);
|
|
var p2 = pools.getOrCreate();
|
|
assert.equal(p, p2);
|
|
assert.equal(Object.keys(pools.all).length, 1);
|
|
var p3 = pools.getOrCreate("postgres://postgres:password@localhost:5432/postgres");
|
|
assert.notEqual(p, p3);
|
|
assert.equal(Object.keys(pools.all).length, 2);
|
|
});
|
|
|
|
test('pool follows defaults', function() {
|
|
var p = pools.getOrCreate(poolId++);
|
|
for(var i = 0; i < 100; i++) {
|
|
p.acquire(function(err, client) {
|
|
});
|
|
}
|
|
assert.equal(p.getPoolSize(), defaults.poolSize);
|
|
});
|
|
|
|
test('pool#connect with 3 parameters', function() {
|
|
var p = pools.getOrCreate(poolId++);
|
|
var tid = setTimeout(function() {
|
|
throw new Error("Connection callback was never called");
|
|
}, 100);
|
|
p.connect(function(err, client, done) {
|
|
clearTimeout(tid);
|
|
assert.ifError(err, null);
|
|
assert.ok(client);
|
|
assert.equal(p.availableObjectsCount(), 0);
|
|
assert.equal(p.getPoolSize(), 1);
|
|
client.emit('drain');
|
|
assert.equal(p.availableObjectsCount(), 0);
|
|
assert.equal(p.getPoolSize(), 1);
|
|
done();
|
|
assert.equal(p.availableObjectsCount(), 1);
|
|
assert.equal(p.getPoolSize(), 1);
|
|
p.destroyAllNow();
|
|
});
|
|
});
|
|
|
|
test('on client error, client is removed from pool', function() {
|
|
var p = pools.getOrCreate(poolId++);
|
|
p.connect(assert.success(function(client, done) {
|
|
assert.ok(client);
|
|
done();
|
|
assert.equal(p.availableObjectsCount(), 1);
|
|
assert.equal(p.getPoolSize(), 1);
|
|
//error event fires on pool BEFORE pool.destroy is called with client
|
|
assert.emits(p, 'error', function(err) {
|
|
assert.equal(err.message, 'test error');
|
|
assert.ok(!client.endCalled);
|
|
assert.equal(p.availableObjectsCount(), 1);
|
|
assert.equal(p.getPoolSize(), 1);
|
|
//after we're done in our callback, pool.destroy is called
|
|
process.nextTick(function() {
|
|
assert.ok(client.endCalled);
|
|
assert.equal(p.availableObjectsCount(), 0);
|
|
assert.equal(p.getPoolSize(), 0);
|
|
p.destroyAllNow();
|
|
});
|
|
});
|
|
client.emit('error', new Error('test error'));
|
|
}));
|
|
});
|
|
|
|
test('pool with connection error on connection', function() {
|
|
var errorPools = poolsFactory(function() {
|
|
return {
|
|
connect: function(cb) {
|
|
process.nextTick(function() {
|
|
cb(new Error('Could not connect'));
|
|
});
|
|
},
|
|
on: Function.prototype
|
|
};
|
|
})
|
|
|
|
test('two parameters', function() {
|
|
var p = errorPools.getOrCreate(poolId++);
|
|
p.connect(assert.calls(function(err, client) {
|
|
assert.ok(err);
|
|
assert.equal(client, null);
|
|
//client automatically removed
|
|
assert.equal(p.availableObjectsCount(), 0);
|
|
assert.equal(p.getPoolSize(), 0);
|
|
}));
|
|
});
|
|
test('three parameters', function() {
|
|
var p = errorPools.getOrCreate(poolId++);
|
|
var tid = setTimeout(function() {
|
|
assert.fail('Did not call connect callback');
|
|
}, 100);
|
|
p.connect(function(err, client, done) {
|
|
clearTimeout(tid);
|
|
assert.ok(err);
|
|
assert.equal(client, null);
|
|
//done does nothing
|
|
done(new Error('OH NOOOO'));
|
|
done();
|
|
assert.equal(p.availableObjectsCount(), 0);
|
|
assert.equal(p.getPoolSize(), 0);
|
|
});
|
|
});
|
|
});
|
|
|
|
test('returnning an error to done()', function() {
|
|
var p = pools.getOrCreate(poolId++);
|
|
p.connect(function(err, client, done) {
|
|
assert.equal(err, null);
|
|
assert(client);
|
|
done(new Error("BROKEN"));
|
|
assert.equal(p.availableObjectsCount(), 0);
|
|
assert.equal(p.getPoolSize(), 0);
|
|
});
|
|
});
|
|
|
|
test('fetching pool by object', function() {
|
|
var p = pools.getOrCreate({
|
|
user: 'brian',
|
|
host: 'localhost',
|
|
password: 'password'
|
|
});
|
|
var p2 = pools.getOrCreate({
|
|
user: 'brian',
|
|
host: 'localhost',
|
|
password: 'password'
|
|
});
|
|
assert.equal(p, p2);
|
|
});
|
|
|
|
|
|
test('pool#connect client.poolCount', function() {
|
|
var p = pools.getOrCreate(poolId++);
|
|
var tid;
|
|
|
|
setConnectTimeout = function() {
|
|
tid = setTimeout(function() {
|
|
throw new Error("Connection callback was never called");
|
|
}, 100);
|
|
}
|
|
|
|
setConnectTimeout();
|
|
p.connect(function(err, client, done) {
|
|
clearTimeout(tid);
|
|
assert.equal(client.poolCount, 1,
|
|
'after connect, poolCount should be 1');
|
|
done();
|
|
assert.equal(client.poolCount, 1,
|
|
'after returning client to pool, poolCount should still be 1');
|
|
setConnectTimeout();
|
|
p.connect(function(err, client, done) {
|
|
clearTimeout(tid);
|
|
assert.equal(client.poolCount, 2,
|
|
'after second connect, poolCount should be 2');
|
|
done();
|
|
setConnectTimeout();
|
|
p.destroyAllNow(function() {
|
|
clearTimeout(tid);
|
|
assert.equal(client.poolCount, undefined,
|
|
'after pool is destroyed, count should be undefined');
|
|
});
|
|
})
|
|
});
|
|
});
|