From a3cc66be50af0419cbe7970299d08fab8f5d3533 Mon Sep 17 00:00:00 2001 From: Daniel Lockyer Date: Mon, 6 Dec 2021 12:50:35 +0000 Subject: [PATCH] Copied DB for faster SQLite tests refs https://github.com/TryGhost/Toolbox/issues/136 - we nuke and reinitialize the DB many times between tests - this forms a good portion of the time taken and we shouldn't be spending so much time on just resetting the DB back to a known state - this commit switches out the knex-migrator reset + init calls for SQLite to a function which keeps a clean copy of the DB and copies the file back when we "reset" - for MySQL, existing functionality is kept - this massively speeds up tests because it saves ~700ms+ for every reset - whilst this change seems to work, it's just the start so there's a lot more refactoring needed. this change is currently gated to CI until it's deemed safe/sane enough to run on local machines without blowing up --- test/utils/db-utils.js | 29 +++++++++++++++++++++++++++++ test/utils/e2e-utils.js | 15 ++++++--------- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/test/utils/db-utils.js b/test/utils/db-utils.js index 395b50bf4c..5dc9b4c466 100644 --- a/test/utils/db-utils.js +++ b/test/utils/db-utils.js @@ -1,6 +1,7 @@ const debug = require('@tryghost/debug')('test:dbUtils'); // Utility Packages +const fs = require('fs-extra'); const Promise = require('bluebird'); const KnexMigrator = require('knex-migrator'); const knexMigrator = new KnexMigrator(); @@ -14,6 +15,34 @@ const schemaTables = Object.keys(schema); // Other Test Utilities const urlServiceUtils = require('./url-service-utils'); +const dbHash = Date.now(); + +module.exports.reset = async () => { + // Only run this copy in CI until it gets fleshed out + if (process.env.CI && config.get('database:client') === 'sqlite3') { + const filename = config.get('database:connection:filename'); + const filenameOrig = `${filename}.${dbHash}-orig`; + + const dbExists = await fs.pathExists(filenameOrig); + + if (dbExists) { + await fs.copyFile(filenameOrig, filename); + } else { + await knexMigrator.reset({force: true}); + + // Do a full database initialisation + await knexMigrator.init(); + + await fs.copyFile(filename, filenameOrig); + } + } else { + await knexMigrator.reset({force: true}); + + // Do a full database initialisation + await knexMigrator.init(); + } +}; + module.exports.initData = async () => { await knexMigrator.init(); await urlServiceUtils.reset(); diff --git a/test/utils/e2e-utils.js b/test/utils/e2e-utils.js index ac57ceff55..6e8771ec39 100644 --- a/test/utils/e2e-utils.js +++ b/test/utils/e2e-utils.js @@ -101,11 +101,12 @@ const prepareContentFolder = (options) => { // - reload affected services const restartModeGhostStart = async ({frontend}) => { debug('Reload Mode'); - // Teardown truncates all tables and also calls urlServiceUtils.reset(); - await dbUtils.teardown(); - // The tables have been truncated, this runs the fixture init task (init file 2) to re-add our default fixtures - await knexMigrator.init({only: 2}); + // TODO: figure out why we need this if we reset again later? + urlServiceUtils.reset(); + + await dbUtils.reset(); + debug('init done'); // Reset the settings cache @@ -154,17 +155,13 @@ const freshModeGhostStart = async (options) => { debug('Fresh Start Mode'); } - // Reset the DB - await knexMigrator.reset({force: true}); - // Stop the server (forceStart Mode) await stopGhost(); // Reset the settings cache and disable listeners so they don't get triggered further settingsService.shutdown(); - // Do a full database initialization - await knexMigrator.init(); + await dbUtils.reset(); await settingsService.init();