不要怂,就是干,撸起袖子干!

Commit e92dc6f5 by Sushant Committed by GitHub

fix(mssql): reject if end was called before connect (#9037)

1 parent cdd6b599
...@@ -40,7 +40,6 @@ class ConnectionManager extends AbstractConnectionManager { ...@@ -40,7 +40,6 @@ class ConnectionManager extends AbstractConnectionManager {
} }
connect(config) { connect(config) {
return new Promise((resolve, reject) => {
const connectionConfig = { const connectionConfig = {
userName: config.username, userName: config.username,
password: config.password, password: config.password,
...@@ -67,15 +66,19 @@ class ConnectionManager extends AbstractConnectionManager { ...@@ -67,15 +66,19 @@ class ConnectionManager extends AbstractConnectionManager {
} }
} }
return new Promise((resolve, reject) => {
const connection = new this.lib.Connection(connectionConfig); const connection = new this.lib.Connection(connectionConfig);
const connectionLock = new ResourceLock(connection);
connection.lib = this.lib; connection.lib = this.lib;
const resourceLock = new ResourceLock(connection);
connection.on('end', () => {
reject(new sequelizeErrors.ConnectionError('Connection was closed by remote server'));
});
connection.on('connect', err => { connection.on('connect', err => {
if (!err) { if (!err) {
debug('connection acquired'); debug('connection acquired');
resolve(connectionLock); return resolve(resourceLock);
return;
} }
if (!err.code) { if (!err.code) {
...@@ -121,17 +124,21 @@ class ConnectionManager extends AbstractConnectionManager { ...@@ -121,17 +124,21 @@ class ConnectionManager extends AbstractConnectionManager {
switch (err.code) { switch (err.code) {
case 'ESOCKET': case 'ESOCKET':
case 'ECONNRESET': case 'ECONNRESET':
this.pool.destroy(connectionLock) this.pool.destroy(resourceLock)
.catch(/Resource not currently part of this pool/, () => {}); .catch(/Resource not currently part of this pool/, () => {});
} }
}); });
} }
}); });
} }
disconnect(connectionLock) { disconnect(connectionLock) {
const connection = connectionLock.unwrap(); /**
* Abstract connection may try to disconnect raw connection used for fetching version
*/
const connection = connectionLock.unwrap
? connectionLock.unwrap()
: connectionLock;
// Dont disconnect a connection that is already disconnected // Dont disconnect a connection that is already disconnected
if (connection.closed) { if (connection.closed) {
...@@ -146,7 +153,13 @@ class ConnectionManager extends AbstractConnectionManager { ...@@ -146,7 +153,13 @@ class ConnectionManager extends AbstractConnectionManager {
} }
validate(connectionLock) { validate(connectionLock) {
const connection = connectionLock.unwrap(); /**
* Abstract connection may try to validate raw connection used for fetching version
*/
const connection = connectionLock.unwrap
? connectionLock.unwrap()
: connectionLock;
return connection && connection.loggedIn; return connection && connection.loggedIn;
} }
} }
......
...@@ -6,17 +6,12 @@ const chai = require('chai'), ...@@ -6,17 +6,12 @@ const chai = require('chai'),
Support = require(__dirname + '/../../support'), Support = require(__dirname + '/../../support'),
dialect = Support.getTestDialect(), dialect = Support.getTestDialect(),
tedious = require('tedious'), tedious = require('tedious'),
sinon = require('sinon'), sinon = require('sinon');
connectionStub = sinon.stub(tedious, 'Connection');
connectionStub.returns({on() {}});
if (dialect === 'mssql') { if (dialect === 'mssql') {
describe('[MSSQL Specific] Connection Manager', () => { describe('[MSSQL Specific] Connection Manager', () => {
let instance, beforeEach(function() {
config; this.config = {
beforeEach(() => {
config = {
dialect: 'mssql', dialect: 'mssql',
database: 'none', database: 'none',
username: 'none', username: 'none',
...@@ -28,17 +23,49 @@ if (dialect === 'mssql') { ...@@ -28,17 +23,49 @@ if (dialect === 'mssql') {
domain: 'TEST.COM' domain: 'TEST.COM'
} }
}; };
instance = new Sequelize(config.database this.instance = new Sequelize(
, config.username this.config.database,
, config.password this.config.username,
, config); this.config.password,
this.config
);
this.connectionStub = sinon.stub(tedious, 'Connection');
});
afterEach(function() {
this.connectionStub.restore();
});
it('connectionManager._connect() does not delete `domain` from config.dialectOptions', function() {
this.connectionStub.returns({on(event, cb) {
if (event === 'connect') {
setTimeout(() => {
cb();
}, 500);
}
}});
expect(this.config.dialectOptions.domain).to.equal('TEST.COM');
return this.instance.dialect.connectionManager._connect(this.config).then(() => {
expect(this.config.dialectOptions.domain).to.equal('TEST.COM');
});
}); });
it('connectionManager._connect() Does not delete `domain` from config.dialectOptions', it('connectionManager._connect() should reject if end was called and connect was not', function() {
() => { this.connectionStub.returns({ on(event, cb) {
expect(config.dialectOptions.domain).to.equal('TEST.COM'); if (event === 'end') {
instance.dialect.connectionManager._connect(config); setTimeout(() => {
expect(config.dialectOptions.domain).to.equal('TEST.COM'); cb();
}, 500);
}
} });
return this.instance.dialect.connectionManager._connect(this.config)
.catch(err => {
expect(err.name).to.equal('SequelizeConnectionError');
expect(err.parent).to.equal('Connection was closed by remote server');
});
}); });
}); });
} }
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!