mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-24 10:27:10 +02:00
Tools: Added a few tools to make testing server easier
This commit is contained in:
parent
0eb79ba932
commit
c2e61f548f
@ -1,5 +1,5 @@
|
|||||||
import { knex, Knex } from 'knex';
|
import { knex, Knex } from 'knex';
|
||||||
import { DatabaseConfig } from './utils/types';
|
import { DatabaseConfig, DatabaseConfigClient } from './utils/types';
|
||||||
import * as pathUtils from 'path';
|
import * as pathUtils from 'path';
|
||||||
import time from '@joplin/lib/time';
|
import time from '@joplin/lib/time';
|
||||||
import Logger from '@joplin/lib/Logger';
|
import Logger from '@joplin/lib/Logger';
|
||||||
@ -112,6 +112,23 @@ export async function waitForConnection(dbConfig: DatabaseConfig): Promise<Conne
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const clientType = (db: DbConnection): DatabaseConfigClient => {
|
||||||
|
return db.client.config.client;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const isPostgres = (db: DbConnection) => {
|
||||||
|
return clientType(db) === DatabaseConfigClient.PostgreSQL;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const isSqlite = (db: DbConnection) => {
|
||||||
|
return clientType(db) === DatabaseConfigClient.SQLite;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const setCollateC = async (db: DbConnection, tableName: string, columnName: string): Promise<void> => {
|
||||||
|
if (!isPostgres(db)) return;
|
||||||
|
await db.raw(`ALTER TABLE ${tableName} ALTER COLUMN ${columnName} SET DATA TYPE character varying(32) COLLATE "C"`);
|
||||||
|
};
|
||||||
|
|
||||||
function makeSlowQueryHandler(duration: number, connection: any, sql: string, bindings: any[]) {
|
function makeSlowQueryHandler(duration: number, connection: any, sql: string, bindings: any[]) {
|
||||||
return setTimeout(() => {
|
return setTimeout(() => {
|
||||||
try {
|
try {
|
||||||
|
@ -1,15 +1,9 @@
|
|||||||
import { createUserAndSession, beforeAllDb, afterAllTests, beforeEachDb, models, expectThrow, createFolder, createItemTree3, expectNotThrow } from '../utils/testing/testUtils';
|
import { createUserAndSession, beforeAllDb, afterAllTests, beforeEachDb, models, expectThrow, createFolder, createItemTree3, expectNotThrow } from '../utils/testing/testUtils';
|
||||||
import { ChangeType, Item, Uuid } from '../services/database/types';
|
import { ChangeType } from '../services/database/types';
|
||||||
import { msleep } from '../utils/time';
|
import { msleep } from '../utils/time';
|
||||||
import { ChangePagination } from './ChangeModel';
|
import { ChangePagination } from './ChangeModel';
|
||||||
import { SqliteMaxVariableNum } from '../db';
|
import { SqliteMaxVariableNum } from '../db';
|
||||||
|
|
||||||
async function makeTestItem(userId: Uuid, num: number): Promise<Item> {
|
|
||||||
return models().item().saveForUser(userId, {
|
|
||||||
name: `${num.toString().padStart(32, '0')}.md`,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
describe('ChangeModel', function() {
|
describe('ChangeModel', function() {
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
@ -43,14 +37,14 @@ describe('ChangeModel', function() {
|
|||||||
const itemModel = models().item();
|
const itemModel = models().item();
|
||||||
const changeModel = models().change();
|
const changeModel = models().change();
|
||||||
|
|
||||||
await msleep(1); const item1 = await makeTestItem(user.id, 1); // [1] CREATE 1
|
await msleep(1); const item1 = await models().item().makeTestItem(user.id, 1); // [1] CREATE 1
|
||||||
await msleep(1); await itemModel.saveForUser(user.id, { id: item1.id, name: '0000000000000000000000000000001A.md' }); // [2] UPDATE 1a
|
await msleep(1); await itemModel.saveForUser(user.id, { id: item1.id, name: '0000000000000000000000000000001A.md' }); // [2] UPDATE 1a
|
||||||
await msleep(1); await itemModel.saveForUser(user.id, { id: item1.id, name: '0000000000000000000000000000001B.md' }); // [3] UPDATE 1b
|
await msleep(1); await itemModel.saveForUser(user.id, { id: item1.id, name: '0000000000000000000000000000001B.md' }); // [3] UPDATE 1b
|
||||||
await msleep(1); const item2 = await makeTestItem(user.id, 2); // [4] CREATE 2
|
await msleep(1); const item2 = await models().item().makeTestItem(user.id, 2); // [4] CREATE 2
|
||||||
await msleep(1); await itemModel.saveForUser(user.id, { id: item2.id, name: '0000000000000000000000000000002A.md' }); // [5] UPDATE 2a
|
await msleep(1); await itemModel.saveForUser(user.id, { id: item2.id, name: '0000000000000000000000000000002A.md' }); // [5] UPDATE 2a
|
||||||
await msleep(1); await itemModel.delete(item1.id); // [6] DELETE 1
|
await msleep(1); await itemModel.delete(item1.id); // [6] DELETE 1
|
||||||
await msleep(1); await itemModel.saveForUser(user.id, { id: item2.id, name: '0000000000000000000000000000002B.md' }); // [7] UPDATE 2b
|
await msleep(1); await itemModel.saveForUser(user.id, { id: item2.id, name: '0000000000000000000000000000002B.md' }); // [7] UPDATE 2b
|
||||||
await msleep(1); const item3 = await makeTestItem(user.id, 3); // [8] CREATE 3
|
await msleep(1); const item3 = await models().item().makeTestItem(user.id, 3); // [8] CREATE 3
|
||||||
|
|
||||||
// Check that the 8 changes were created
|
// Check that the 8 changes were created
|
||||||
const allUncompressedChanges = await changeModel.all();
|
const allUncompressedChanges = await changeModel.all();
|
||||||
@ -125,7 +119,7 @@ describe('ChangeModel', function() {
|
|||||||
const changeModel = models().change();
|
const changeModel = models().change();
|
||||||
|
|
||||||
let i = 1;
|
let i = 1;
|
||||||
await msleep(1); const item1 = await makeTestItem(user.id, 1); // CREATE 1
|
await msleep(1); const item1 = await models().item().makeTestItem(user.id, 1); // CREATE 1
|
||||||
await msleep(1); await itemModel.saveForUser(user.id, { id: item1.id, name: `test_mod${i++}` }); // UPDATE 1
|
await msleep(1); await itemModel.saveForUser(user.id, { id: item1.id, name: `test_mod${i++}` }); // UPDATE 1
|
||||||
|
|
||||||
await expectThrow(async () => changeModel.delta(user.id, { limit: 1, cursor: 'invalid' }), 'resyncRequired');
|
await expectThrow(async () => changeModel.delta(user.id, { limit: 1, cursor: 'invalid' }), 'resyncRequired');
|
||||||
@ -173,9 +167,7 @@ describe('ChangeModel', function() {
|
|||||||
|
|
||||||
const { user } = await createUserAndSession(1, true);
|
const { user } = await createUserAndSession(1, true);
|
||||||
|
|
||||||
for (let i = 0; i < 1010; i++) {
|
await models().item().makeTestItems(user.id, 1010);
|
||||||
await makeTestItem(user.id, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
let changeCount = 0;
|
let changeCount = 0;
|
||||||
await expectNotThrow(async () => {
|
await expectNotThrow(async () => {
|
||||||
|
@ -549,6 +549,22 @@ export default class ItemModel extends BaseModel<Item> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async makeTestItem(userId: Uuid, num: number) {
|
||||||
|
return this.saveForUser(userId, {
|
||||||
|
name: `${num.toString().padStart(32, '0')}.md`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public async makeTestItems(userId: Uuid, count: number) {
|
||||||
|
await this.withTransaction(async () => {
|
||||||
|
for (let i = 1; i <= count; i++) {
|
||||||
|
await this.saveForUser(userId, {
|
||||||
|
name: `${i.toString().padStart(32, '0')}.md`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, 'ItemModel::makeTestItems');
|
||||||
|
}
|
||||||
|
|
||||||
public async saveForUser(userId: Uuid, item: Item, options: SaveOptions = {}): Promise<Item> {
|
public async saveForUser(userId: Uuid, item: Item, options: SaveOptions = {}): Promise<Item> {
|
||||||
if (!userId) throw new Error('userId is required');
|
if (!userId) throw new Error('userId is required');
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user