Skip to content

Commit

Permalink
add test
Browse files Browse the repository at this point in the history
  • Loading branch information
khanaffan committed Jan 23, 2025
1 parent eeff84c commit 0cff296
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 6 deletions.
2 changes: 1 addition & 1 deletion common/api/core-common.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -1988,7 +1988,7 @@ export interface DbBlobResponse extends DbResponse {

// @internal (undocumented)
export interface DbQueryConfig {
autoShutdowWhenIdealForSeconds?: number;
autoShutdowWhenIdlelForSeconds?: number;
// (undocumented)
doNotUsePrimaryConnToPrepare?: boolean;
// (undocumented)
Expand Down
9 changes: 5 additions & 4 deletions core/backend/src/test/ecdb/ConcurrentQueryLoad.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,23 +120,24 @@ describe.skip("ConcurrentQueryLoad", () => {
it("should run", async () => {
Logger.initializeToConsole();
Logger.setLevel("ECDb.ConcurrentQuery", LogLevel.Trace);
// const defaultConfig: {
// {
// workerThreads: 4,
// requestQueueSize: 2000,
// ignorePriority: false,
// ignoreDelay: true,
// doNotUsePrimaryConnToPrepare: false,
// autoShutdowWhenIdealForSeconds: 120,
// autoShutdowWhenIdlelForSeconds: 300,
// statementCacheSizePerWorker: 40,
// monitorPollInterval: 1000,
// memoryMapFileSize: 0,
// allowTestingArgs: false,
// globalQuota: { time: 60, memory: 8388608 }
// };
// }

const senario: ISenario = {
name: "ConcurrentQueryLoad",
config: {
autoShutdowWhenIdealForSeconds: 10,

},
totalBatches: 1,
taskPerBatch: 1,
Expand Down
53 changes: 53 additions & 0 deletions core/backend/src/test/ecdb/ECSqlQuery.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,60 @@ describe("ECSql Query", () => {
assert.isTrue(hasRow, "imodel1.query() must return latest one row");
}
});
// new new addon build
it("ecsql interrupt check", async () => {
let cancelled = 0;
let successful = 0;
let rowCount = 0;
try {
ConcurrentQuery.shutdown(imodel1[_nativeDb]);
ConcurrentQuery.resetConfig(imodel1[_nativeDb], { allowTestingArgs: true });
const scheduleQuery = async () => {
return new Promise<void>(async (resolve, reject) => {
try {
const options = new QueryOptionsBuilder();
options.setTestingArgs({ interrupt: true });
options.setDelay(1000);
const reader = imodel1.createQueryReader(`
WITH sequence(n) AS (
SELECT 1
UNION ALL
SELECT n + 1 FROM sequence WHERE n < 10000
)
SELECT COUNT(*)
FROM bis.SpatialIndex i, sequence s`, undefined, options.getOptions());
while (await reader.step()) {
rowCount++;
}
successful++;
resolve();
} catch (err: any) {
// we expect query to be cancelled
if (err.errorNumber === DbResult.BE_SQLITE_INTERRUPT) {
cancelled++;
resolve();
} else {
reject(new Error("rejected"));
}
}
});
};

const queries = [];
for (let i = 0; i < 100; i++) {
queries.push(scheduleQuery());
}

await Promise.all(queries);
// We expect at least one query to be cancelled
assert.equal(successful, 100, "success should be 100");
assert.equal(rowCount, 100, "expect 100 rows");
assert.isAtLeast(cancelled, 0, "should not have any cancelled query");
} finally {
ConcurrentQuery.shutdown(imodel1[_nativeDb]);
ConcurrentQuery.resetConfig(imodel1[_nativeDb]);
}
});
// new new addon build
it("ecsql with blob", async () => {
let rows = await executeQuery(imodel1, "SELECT ECInstanceId,GeometryStream FROM bis.GeometricElement3d WHERE GeometryStream IS NOT NULL LIMIT 1");
Expand Down
24 changes: 23 additions & 1 deletion core/common/src/ConcurrentQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ export interface BaseReaderOptions {
* concurrent query is configure to honour it.
*/
delay?: number;
/**
* @internal
*/
testingArgs?: TestingArgs;
}

/**
Expand Down Expand Up @@ -252,6 +256,16 @@ export class QueryOptionsBuilder {
this._options.delay = val;
return this;
}
/**
* @internal
* Use for testing internal logic. This parameter is ignored by default unless concurrent query is configure to not ignore it.
* @param val Testing arguments.
* @returns @type QueryOptionsBuilder for fluent interface.
*/
public setTestingArgs(val: TestingArgs) {
this._options.testingArgs = val;
return this;
}
}
/** @beta */
export class BlobOptionsBuilder {
Expand Down Expand Up @@ -674,6 +688,11 @@ export enum DbResponseStatus {
Error_BlobIO_OutOfRange = Error + 6, /* range specified is invalid based on size of blob.*/
}

/** @internal */
export interface TestingArgs {
interrupt?: boolean
}

/** @internal */
export enum DbValueFormat {
ECSqlNames = 0,
Expand All @@ -683,6 +702,7 @@ export enum DbValueFormat {
/** @internal */
export interface DbRequest extends BaseReaderOptions {
kind?: DbRequestKind;
testingArgs?: TestingArgs
}

/** @internal */
Expand Down Expand Up @@ -753,11 +773,13 @@ export interface DbQueryConfig {
workerThreads?: number;
doNotUsePrimaryConnToPrepare?: boolean;
/** After no activity for given time concurrenty query will automatically shutdown */
autoShutdowWhenIdealForSeconds?: number;
autoShutdowWhenIdlelForSeconds?: number;
/** Maximum number of statement cache per worker. Default to 40 */
statementCacheSizePerWorker?: number;
/* Monitor poll interval in milliseconds. Its responsable for cancelling queries that pass quota. It can be set between 1000 and Max time quota for query */
monitorPollInterval?: number;
/** Set memory map io for each worker connection size in bytes. Default to zero mean do not use mmap io */
memoryMapFileSize?: number;
/** Used by test to simulate certain test cases. Its is false by default. */
allowTestingArgs?: boolean;
}

0 comments on commit 0cff296

Please sign in to comment.