From 336528ef78ea87ac570fda458d91dd43e300190c Mon Sep 17 00:00:00 2001 From: Michael Belousov Date: Tue, 2 Jan 2024 14:51:31 -0500 Subject: [PATCH 1/4] add test codifying import dynamic schema behavior --- .../test/standalone/IModelTransformer.test.ts | 95 +++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/packages/transformer/src/test/standalone/IModelTransformer.test.ts b/packages/transformer/src/test/standalone/IModelTransformer.test.ts index 933fc235..bd8c1730 100644 --- a/packages/transformer/src/test/standalone/IModelTransformer.test.ts +++ b/packages/transformer/src/test/standalone/IModelTransformer.test.ts @@ -2746,6 +2746,101 @@ describe("IModelTransformer", () => { targetDb.close(); }); + it.only("try import dynamic schemas regardless of version", async function () { + const makeDynamicSchema = (version: string, classes = [] as string[]) => ` + + + + + + ${classes.map((c) => ` + + bis:PhysicalElement + + + `)} + + `; + + const targetDbFile: string = IModelTransformerTestUtils.prepareOutputFile("IModelTransformer", "DynSchemas2-Target.bim"); + const targetDb = SnapshotDb.createEmpty(targetDbFile, { rootSubject: { name: "DynSchemasTarget" } }); + const targetVersion = "01.10.00"; + await targetDb.importSchemaStrings([makeDynamicSchema(targetVersion, ["A"])]); + targetDb.saveChanges(); + expect(() => targetDb.getMetaData("d1:A")).not.to.throw(); + + const unpadVersion = (v: string) => v.split(".").map(Number).join("."); + + // try import lesser version dynamic schema + { + const sourceDbFile = IModelTransformerTestUtils.prepareOutputFile("IModelTransformer", "DynSchemas2-Source.bim"); + const sourceDb = SnapshotDb.createEmpty(sourceDbFile, { rootSubject: { name: "DynSchemaSource" } }); + const lesserVersion = "01.07.00"; + expect(Semver.lt(unpadVersion(lesserVersion), unpadVersion(targetVersion))).to.be.true; + await sourceDb.importSchemaStrings([makeDynamicSchema(lesserVersion, ["A", "B"])]); + sourceDb.saveChanges(); + + const transformer = new IModelTransformer(sourceDb, targetDb); + // expect this to not reject, adding chai as promised makes the error less readable + await transformer.processSchemas(); + + transformer.dispose(); + sourceDb.close(); + + expect(targetDb.querySchemaVersion("Dynamic")).to.equal(unpadVersion(targetVersion)); + expect(() => targetDb.getMetaData("d1:A")).not.to.throw(); + // schema be not be exported because <= version + expect(() => targetDb.getMetaData("d1:B")).to.throw(); + } + + // try import equal version schema + { + const sourceDbFile = IModelTransformerTestUtils.prepareOutputFile("IModelTransformer", "DynSchemas2-Source2.bim"); + const sourceDb = SnapshotDb.createEmpty(sourceDbFile, { rootSubject: { name: "DynSchemaSource2" } }); + await sourceDb.importSchemaStrings([makeDynamicSchema(targetVersion, ["A", "B", "C"])]); + sourceDb.saveChanges(); + + const transformer = new IModelTransformer(sourceDb, targetDb); + // expect this to not reject, adding chai as promised makes the error less readable + await transformer.processSchemas(); + + transformer.dispose(); + sourceDb.close(); + + expect(targetDb.querySchemaVersion("Dynamic")).to.equal(unpadVersion(targetVersion)); + expect(() => targetDb.getMetaData("d1:A")).not.to.throw(); + // schema be not be exported because <= version + expect(() => targetDb.getMetaData("d1:B")).to.throw(); + expect(() => targetDb.getMetaData("d1:C")).to.throw(); + } + + // try import later dynamic schema + { + const sourceDbFile = IModelTransformerTestUtils.prepareOutputFile("IModelTransformer", "DynSchemas2-Source3.bim"); + const sourceDb = SnapshotDb.createEmpty(sourceDbFile, { rootSubject: { name: "DynSchemaSource3" } }); + const greaterVersion = "01.11.00"; + expect(Semver.gt(unpadVersion(greaterVersion), unpadVersion(targetVersion))).to.be.true; + await sourceDb.importSchemaStrings([makeDynamicSchema(greaterVersion, ["A", "B", "C", "D"])]); + sourceDb.saveChanges(); + + const transformer = new IModelTransformer(sourceDb, targetDb); + // expect this to not reject, adding chai as promised makes the error less readable + await transformer.processSchemas(); + + transformer.dispose(); + sourceDb.close(); + + expect(targetDb.querySchemaVersion("Dynamic")).to.equal(unpadVersion(greaterVersion)); + // schema will be exported and merged by ECDb because > version + expect(() => targetDb.getMetaData("d1:A")).not.to.throw(); + expect(() => targetDb.getMetaData("d1:B")).not.to.throw(); + expect(() => targetDb.getMetaData("d1:C")).not.to.throw(); + expect(() => targetDb.getMetaData("d1:D")).not.to.throw(); + } + + targetDb.close(); + }); + /** unskip to generate a javascript CPU profile on just the processAll portion of an iModel */ it.skip("should profile an IModel transformation", async function () { const sourceDbFile = IModelTransformerTestUtils.prepareOutputFile("IModelTransformer", "ProfileTransformation.bim"); From 2f92f80ec748036b8cb822a5e16e787337fba168 Mon Sep 17 00:00:00 2001 From: Michael Belousov Date: Tue, 2 Jan 2024 15:00:01 -0500 Subject: [PATCH 2/4] handle cross-version usage of internal closeIModel API --- .../src/test/standalone/IModelTransformer.test.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/transformer/src/test/standalone/IModelTransformer.test.ts b/packages/transformer/src/test/standalone/IModelTransformer.test.ts index bd8c1730..c8908878 100644 --- a/packages/transformer/src/test/standalone/IModelTransformer.test.ts +++ b/packages/transformer/src/test/standalone/IModelTransformer.test.ts @@ -1089,7 +1089,9 @@ describe("IModelTransformer", () => { nativeDb.resetBriefcaseId(BriefcaseIdValue.Unassigned); // standalone iModels should always have BriefcaseId unassigned nativeDb.saveLocalValue("StandaloneEdit", JSON.stringify({ txns: true })); nativeDb.saveChanges(); // save change to briefcaseId - nativeDb.closeIModel(); + // handle cross-version usage of internal API + (nativeDb as any)?.closeIModel(); + (nativeDb as any)?.closeFile(); } it("biscore update is valid", async () => { @@ -1108,7 +1110,9 @@ describe("IModelTransformer", () => { // StandaloneDb.upgradeStandaloneSchemas is the suggested method to handle a profile upgrade but that will also upgrade // the BisCore schema. This test is explicitly testing that the BisCore schema will be updated from the source iModel const nativeDb = StandaloneDb.openDgnDb({path: targetDbPath}, OpenMode.ReadWrite, {profile: ProfileOptions.Upgrade, schemaLockHeld: true}); - nativeDb.closeIModel(); + // handle cross-version usage of internal API + (nativeDb as any)?.closeIModel(); + (nativeDb as any)?.closeFile(); const targetDb = StandaloneDb.openFile(targetDbPath); assert( From 0f5f9a8efe73d6a9ce097f75bc998eb1cba66381 Mon Sep 17 00:00:00 2001 From: Michael Belousov Date: Wed, 3 Jan 2024 10:15:57 -0500 Subject: [PATCH 3/4] handle cross-version usage of internal API in all packages --- packages/performance-tests/test/iModelUtils.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/performance-tests/test/iModelUtils.ts b/packages/performance-tests/test/iModelUtils.ts index f56fe3a9..a9cf0265 100644 --- a/packages/performance-tests/test/iModelUtils.ts +++ b/packages/performance-tests/test/iModelUtils.ts @@ -6,7 +6,7 @@ import { BriefcaseIdValue, Code } from "@itwin/core-common"; import { initOutputFile } from "./TestUtils"; import { Point3d, YawPitchRollAngles } from "@itwin/core-geometry"; import { IModelTransformerTestUtils } from "@itwin/imodel-transformer/lib/cjs/test/IModelTransformerUtils"; -import { getTShirtSizeFromName, TestIModel } from "./TestContext"; +import { getTShirtSizeFromName, TestIModel } from "./TestContext"; const outputDir = path.join(__dirname, ".output"); @@ -27,7 +27,9 @@ export function setToStandalone(iModelPath: string) { nativeDb.resetBriefcaseId(BriefcaseIdValue.Unassigned); // standalone iModels should always have BriefcaseId unassigned nativeDb.saveLocalValue("StandaloneEdit", JSON.stringify({ txns: true })); nativeDb.saveChanges(); // save change to briefcaseId - nativeDb.closeIModel(); + // handle cross-version usage of internal API + (nativeDb as any)?.closeIModel(); + (nativeDb as any)?.closeFile(); } export function generateTestIModel(iModelParam: IModelParams): TestIModel { From 3afdd63c12d79cb256d400bde146310af34f5274 Mon Sep 17 00:00:00 2001 From: Michael Belousov Date: Wed, 3 Jan 2024 10:47:01 -0500 Subject: [PATCH 4/4] remove .only --- .../transformer/src/test/standalone/IModelTransformer.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/transformer/src/test/standalone/IModelTransformer.test.ts b/packages/transformer/src/test/standalone/IModelTransformer.test.ts index c8908878..486c5fae 100644 --- a/packages/transformer/src/test/standalone/IModelTransformer.test.ts +++ b/packages/transformer/src/test/standalone/IModelTransformer.test.ts @@ -2750,7 +2750,7 @@ describe("IModelTransformer", () => { targetDb.close(); }); - it.only("try import dynamic schemas regardless of version", async function () { + it("try import dynamic schemas regardless of version", async function () { const makeDynamicSchema = (version: string, classes = [] as string[]) => `