Browse Source

feat(testing): Improved sqlite support and added retry logic in tableUpdate in sqlite client due it popping up on high number of writes in sqlite and configured WAL mode for meta db in testing

pull/3848/head
Muhammed Mustafa 2 years ago
parent
commit
01d6bd0e77
  1. 2
      packages/nocodb/.gitignore
  2. 80
      packages/nocodb/src/lib/db/sql-client/lib/sqlite/SqliteClient.ts
  3. 29
      packages/nocodb/src/lib/services/test/TestResetService/resetMetaSakilaSqliteProject.ts
  4. 4
      packages/nocodb/src/lib/utils/NcConfigFactory.ts
  5. 4
      scripts/playwright/playwright.config.ts

2
packages/nocodb/.gitignore vendored

@ -18,4 +18,6 @@ noco.db*
/docker/main.js /docker/main.js
test_meta.db test_meta.db
test_sakila.db test_sakila.db
test_noco.db-shm
test_noco.db-wal
.env .env

80
packages/nocodb/src/lib/db/sql-client/lib/sqlite/SqliteClient.ts

@ -1443,39 +1443,9 @@ class SqliteClient extends KnexClient {
return result; return result;
} }
/** private async _tableUpdate(args) {
*
* @param {Object} - args
* @param {String} - args.table
* @param {String} - args.table
* @param {Object[]} - args.columns
* @param {String} - args.columns[].tn
* @param {String} - args.columns[].cn
* @param {String} - args.columns[].dt
* @param {String} - args.columns[].np
* @param {String} - args.columns[].ns -
* @param {String} - args.columns[].clen -
* @param {String} - args.columns[].dp -
* @param {String} - args.columns[].cop -
* @param {String} - args.columns[].pk -
* @param {String} - args.columns[].nrqd -
* @param {String} - args.columns[].not_nullable -
* @param {String} - args.columns[].ct -
* @param {String} - args.columns[].un -
* @param {String} - args.columns[].ai -
* @param {String} - args.columns[].unique -
* @param {String} - args.columns[].cdf -
* @param {String} - args.columns[].cc -
* @param {String} - args.columns[].csn -
* @param {Number} - args.columns[].altered - 1,2,4 = addition,edited,deleted
* @returns {Promise<{upStatement, downStatement}>}
*/
async tableUpdate(args) {
const _func = this.tableUpdate.name;
const result = new Result(); const result = new Result();
log.api(`${_func}:args:`, args);
try {
args.table = args.tn; args.table = args.tn;
const originalColumns = args.originalColumns; const originalColumns = args.originalColumns;
args.connectionConfig = this._connectionConfig; args.connectionConfig = this._connectionConfig;
@ -1570,11 +1540,57 @@ class SqliteClient extends KnexClient {
], ],
downStatement: [{ sql: ';' }], downStatement: [{ sql: ';' }],
}; };
return result;
}
/**
*
* @param {Object} - args
* @param {String} - args.table
* @param {String} - args.table
* @param {Object[]} - args.columns
* @param {String} - args.columns[].tn
* @param {String} - args.columns[].cn
* @param {String} - args.columns[].dt
* @param {String} - args.columns[].np
* @param {String} - args.columns[].ns -
* @param {String} - args.columns[].clen -
* @param {String} - args.columns[].dp -
* @param {String} - args.columns[].cop -
* @param {String} - args.columns[].pk -
* @param {String} - args.columns[].nrqd -
* @param {String} - args.columns[].not_nullable -
* @param {String} - args.columns[].ct -
* @param {String} - args.columns[].un -
* @param {String} - args.columns[].ai -
* @param {String} - args.columns[].unique -
* @param {String} - args.columns[].cdf -
* @param {String} - args.columns[].cc -
* @param {String} - args.columns[].csn -
* @param {Number} - args.columns[].altered - 1,2,4 = addition,edited,deleted
* @returns {Promise<{upStatement, downStatement}>}
*/
async tableUpdate(args) {
const _func = this.tableUpdate.name;
log.api(`${_func}:args:`, args);
for (let retry = 0; retry < 3; retry++) {
try {
return await this._tableUpdate(args);
} catch (e) {
console.log('retrying:tableUpdate', e);
}
// Wait for 300ms
await new Promise((resolve) => setTimeout(resolve, 300));
}
try {
return await this._tableUpdate(args);
} catch (e) { } catch (e) {
log.ppe(e, _func); log.ppe(e, _func);
throw e; throw e;
} }
return result;
} }
/** /**

29
packages/nocodb/src/lib/services/test/TestResetService/resetMetaSakilaSqliteProject.ts

@ -16,20 +16,16 @@ const sqliteSakilaSqlViews = [
]; ];
const dropTablesAndViews = async (metaKnex: Knex, prefix: string) => { const dropTablesAndViews = async (metaKnex: Knex, prefix: string) => {
for (const view of sqliteSakilaSqlViews) {
try { try {
for (const view of sqliteSakilaSqlViews) {
await metaKnex.raw(`DROP VIEW IF EXISTS ${prefix}${view}`); await metaKnex.raw(`DROP VIEW IF EXISTS ${prefix}${view}`);
} catch (e) {
console.log('Error dropping sqlite view', e);
}
} }
for (const table of sakilaTableNames) { for (const table of sakilaTableNames) {
try {
await metaKnex.raw(`DROP TABLE IF EXISTS ${prefix}${table}`); await metaKnex.raw(`DROP TABLE IF EXISTS ${prefix}${table}`);
} catch (e) {
console.log('Error dropping sqlite table', e);
} }
} catch (e) {
console.error('Error dropping tables and views', e);
} }
}; };
@ -58,31 +54,34 @@ const resetMetaSakilaSqlite = async (metaKnex: Knex, prefix: string) => {
'/tests' '/tests'
); );
const trx = await metaKnex.transaction();
try { try {
const schemaFile = await fs.readFile( const schemaFile = await fs.readFile(
`${testsDir}/sqlite-sakila-db/03-sqlite-prefix-sakila-schema.sql` `${testsDir}/sqlite-sakila-db/03-sqlite-prefix-sakila-schema.sql`
); );
const schemaFileStr = schemaFile.toString().replace(/prefix___/g, prefix); const schemaFileStr = schemaFile.toString().replace(/prefix___/g, prefix);
const dataFile = await fs.readFile(
`${testsDir}/sqlite-sakila-db/04-sqlite-prefix-sakila-insert-data.sql`
);
const dataFileStr = dataFile.toString().replace(/prefix___/g, prefix);
const schemaSqlQueries = schemaFileStr.split(';'); const schemaSqlQueries = schemaFileStr.split(';');
for (const sqlQuery of schemaSqlQueries) { for (const sqlQuery of schemaSqlQueries) {
if (sqlQuery.trim().length > 0) { if (sqlQuery.trim().length > 0) {
await trx.raw( await metaKnex.raw(
sqlQuery sqlQuery
.trim() .trim()
.replace(/WHERE rowid = new.rowid/g, 'WHERE rowid = new.rowid;') .replace(/WHERE rowid = new.rowid/g, 'WHERE rowid = new.rowid;')
); );
} }
} }
} catch (e) {
console.error('Error resetting meta sakila sqlite:db', e);
}
const trx = await metaKnex.transaction();
try {
const dataFile = await fs.readFile(
`${testsDir}/sqlite-sakila-db/04-sqlite-prefix-sakila-insert-data.sql`
);
const dataFileStr = dataFile.toString().replace(/prefix___/g, prefix);
const dataSqlQueries = dataFileStr.split(';'); const dataSqlQueries = dataFileStr.split(';');
for (const sqlQuery of dataSqlQueries) { for (const sqlQuery of dataSqlQueries) {
if (sqlQuery.trim().length > 0) { if (sqlQuery.trim().length > 0) {
await trx.raw(sqlQuery.trim()); await trx.raw(sqlQuery.trim());

4
packages/nocodb/src/lib/utils/NcConfigFactory.ts

@ -590,6 +590,10 @@ export default class NcConfigFactory implements NcConfig {
...args.meta.db, ...args.meta.db,
connection: args.meta.db, connection: args.meta.db,
}); });
if (process.env['TEST'] === 'true') {
await metaSqlClient.raw('PRAGMA journal_mode=WAL');
await metaSqlClient.raw('PRAGMA busy_timeout=60000');
}
await metaSqlClient.createDatabaseIfNotExists({ await metaSqlClient.createDatabaseIfNotExists({
database: args.meta.db?.connection?.filename, database: args.meta.db?.connection?.filename,
}); });

4
scripts/playwright/playwright.config.ts

@ -26,9 +26,9 @@ const config: PlaywrightTestConfig = {
/* Fail the build on CI if you accidentally left test.only in the source code. */ /* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: !!process.env.CI, forbidOnly: !!process.env.CI,
/* Retry on CI only */ /* Retry on CI only */
retries: process.env.CI ? 2 : 0, retries: 2,
/* Opt out of parallel tests on CI. */ /* Opt out of parallel tests on CI. */
workers: process.env.CI ? 1 : 2, workers: process.env.CI ? 2 : 4,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */ /* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: 'html', reporter: 'html',
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */

Loading…
Cancel
Save