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

Commit 6f74bf62 by papb

test: improve 'running queries' detection

(backport of #12885)
1 parent 3d2df28e
Showing with 52 additions and 7 deletions
'use strict';
// Store local references to `setTimeout` and `clearTimeout` asap, so that we can use them within `p-timeout`,
// avoiding to be affected unintentionally by `sinon.useFakeTimers()` called by the tests themselves.
const { setTimeout, clearTimeout } = global;
const pTimeout = require('p-timeout');
const Support = require('../support');
const runningQueries = new Set();
const CLEANUP_TIMEOUT = Number.parseInt(process.env.SEQ_TEST_CLEANUP_TIMEOUT, 10) || 10000;
let runningQueries = new Set();
before(function() {
this.sequelize.addHook('beforeQuery', (options, query) => {
......@@ -13,15 +20,53 @@ before(function() {
});
});
beforeEach(function() {
return Support.clearDatabase(this.sequelize);
beforeEach(async function() {
await Support.clearDatabase(this.sequelize);
});
afterEach(function() {
if (runningQueries.size === 0) {
return;
afterEach(async function() {
// Note: recall that throwing an error from a `beforeEach` or `afterEach` hook in Mocha causes the entire test suite to abort.
let runningQueriesProblem;
if (runningQueries.size > 0) {
runningQueriesProblem = `Expected 0 queries running after this test, but there are still ${
runningQueries.size
} queries running in the database (or, at least, the \`afterQuery\` Sequelize hook did not fire for them):\n\n${
// prettier-ignore
[...runningQueries].map(query => ` ${query.uuid}: ${query.sql}`).join('\n')
}`;
}
runningQueries = new Set();
try {
await pTimeout(
Support.clearDatabase(this.sequelize),
CLEANUP_TIMEOUT,
`Could not clear database after this test in less than ${CLEANUP_TIMEOUT}ms. This test crashed the DB, and testing cannot continue. Aborting.`,
{ customTimers: { setTimeout, clearTimeout } }
);
} catch (error) {
let message = error.message;
if (runningQueriesProblem) {
message += `\n\n Also, ${runningQueriesProblem}`;
}
message += `\n\n Full test name:\n ${this.currentTest.fullTitle()}`;
// Throw, aborting the entire Mocha execution
throw new Error(message);
}
if (runningQueriesProblem) {
if (this.test.ctx.currentTest.state === 'passed') {
// `this.test.error` is an obscure Mocha API that allows failing a test from the `afterEach` hook
// This is better than throwing because throwing would cause the entire Mocha execution to abort
this.test.error(new Error(`This test passed, but ${runningQueriesProblem}`));
} else {
console.log(` ${runningQueriesProblem}`);
}
}
throw new Error(`Expected 0 running queries. ${runningQueries.size} queries still running in ${this.currentTest.fullTitle()}`);
});
module.exports = Support;
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!