query-queue.test.js
4.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
'use strict';
const chai = require('chai'),
expect = chai.expect,
Promise = require('../../../../lib/promise'),
DataTypes = require('../../../../lib/data-types'),
Support = require('../../support'),
Sequelize = require('../../../../lib/sequelize'),
ConnectionError = require('../../../../lib/errors/connection-error'),
{ AsyncQueueError } = require('../../../../lib/dialects/mssql/async-queue'),
dialect = Support.getTestDialect();
if (dialect.match(/^mssql/)) {
describe('[MSSQL Specific] Query Queue', () => {
beforeEach(function() {
const User = this.User = this.sequelize.define('User', {
username: DataTypes.STRING
});
return this.sequelize.sync({ force: true }).then(() => {
return User.create({ username: 'John' });
});
});
it('should queue concurrent requests to a connection', function() {
const User = this.User;
return expect(this.sequelize.transaction(t => {
return Promise.all([
User.findOne({
transaction: t
}),
User.findOne({
transaction: t
})
]);
})).not.to.be.rejected;
});
it('requests that reject should not affect future requests', async function() {
const User = this.User;
await expect(this.sequelize.transaction(async t => {
await expect(User.create({
username: new Date()
})).to.be.rejected;
await expect(User.findOne({
transaction: t
})).not.to.be.rejected;
})).not.to.be.rejected;
});
it('closing the connection should reject pending requests', async function() {
const User = this.User;
let promise;
await expect(this.sequelize.transaction(t =>
promise = Promise.all([
expect(this.sequelize.dialect.connectionManager.disconnect(t.connection)).to.be.fulfilled,
expect(User.findOne({
transaction: t
})).to.be.eventually.rejectedWith(ConnectionError, 'the connection was closed before this query could be executed')
.and.have.property('parent').that.instanceOf(AsyncQueueError),
expect(User.findOne({
transaction: t
})).to.be.eventually.rejectedWith(ConnectionError, 'the connection was closed before this query could be executed')
.and.have.property('parent').that.instanceOf(AsyncQueueError)
])
)).to.be.rejectedWith(ConnectionError, 'the connection was closed before this query could be executed');
await expect(promise).not.to.be.rejected;
});
it('closing the connection should reject in-progress requests', async function() {
const User = this.User;
let promise;
await expect(this.sequelize.transaction(async t => {
const wrappedExecSql = t.connection.execSql;
t.connection.execSql = (...args) => {
this.sequelize.dialect.connectionManager.disconnect(t.connection);
return wrappedExecSql(...args);
};
return promise = expect(User.findOne({
transaction: t
})).to.be.eventually.rejectedWith(ConnectionError, 'the connection was closed before this query could finish executing')
.and.have.property('parent').that.instanceOf(AsyncQueueError);
})).to.be.eventually.rejectedWith(ConnectionError, 'the connection was closed before this query could be executed')
.and.have.property('parent').that.instanceOf(AsyncQueueError);
await expect(promise).not.to.be.rejected;
});
describe('unhandled rejections', () => {
let onUnhandledRejection;
afterEach(() => {
process.removeListener('unhandledRejection', onUnhandledRejection);
});
it("unhandled rejection should occur if user doesn't catch promise returned from query", async function() {
const User = this.User;
const rejectionPromise = new Promise((resolve, reject) => {
onUnhandledRejection = reject;
});
process.on('unhandledRejection', onUnhandledRejection);
User.create({
username: new Date()
});
await expect(rejectionPromise).to.be.rejectedWith(
Sequelize.ValidationError, 'string violation: username cannot be an array or an object');
});
it('no unhandled rejections should occur as long as user catches promise returned from query', async function() {
const User = this.User;
const unhandledRejections = [];
onUnhandledRejection = error => unhandledRejections.push(error);
process.on('unhandledRejection', onUnhandledRejection);
await expect(User.create({
username: new Date()
})).to.be.rejectedWith(Sequelize.ValidationError);
expect(unhandledRejections).to.deep.equal([]);
});
});
});
}