Skip to content

Commit

Permalink
Merge commit '308e48ca0465d6cf2a307f5fce35e9d2ea531429' into native/4…
Browse files Browse the repository at this point in the history
….4.2
  • Loading branch information
anmolshres98 committed Feb 2, 2024
2 parents 55f6df4 + 308e48c commit 4d4feab
Show file tree
Hide file tree
Showing 20 changed files with 683 additions and 521 deletions.
3 changes: 1 addition & 2 deletions common/api/presentation-backend.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ import { SelectionScopeRequestOptions } from '@itwin/presentation-common';
import { SingleElementPropertiesRequestOptions } from '@itwin/presentation-common';
import { UnitSystemFormat as UnitSystemFormat_2 } from '@itwin/presentation-common';
import { UnitSystemKey } from '@itwin/core-quantity';
import { UpdateInfo } from '@itwin/presentation-common';
import { VariableValue } from '@itwin/presentation-common';
import { VariableValueTypes } from '@itwin/presentation-common';
import { WithCancelEvent } from '@itwin/presentation-common';
Expand Down Expand Up @@ -308,7 +307,7 @@ export interface PresentationManagerProps {
// @alpha
schemaContextProvider?: (imodel: IModelDb) => SchemaContext;
supplementalRulesetDirectories?: string[];
// @beta
// @beta @deprecated
updatesPollInterval?: number;
// @beta
useMmap?: boolean | number;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@itwin/core-backend",
"comment": "",
"type": "none"
}
],
"packageName": "@itwin/core-backend"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@itwin/presentation-backend",
"comment": "Refactor iModel updates' tracking to work without polling. Also, the updates are now always tracked - no additional configuration is needed.",
"type": "none"
}
],
"packageName": "@itwin/presentation-backend"
}
10 changes: 8 additions & 2 deletions core/backend/src/test/IModelTestUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { RequestNewBriefcaseArg } from "../BriefcaseManager";
import { CheckpointProps, V1CheckpointManager } from "../CheckpointManager";
import { ClassRegistry } from "../ClassRegistry";
import {
AuxCoordSystem2d, BriefcaseDb, BriefcaseManager, CategorySelector, DisplayStyle2d, DisplayStyle3d, DrawingCategory, DrawingViewDefinition,
AuxCoordSystem2d, BriefcaseDb, BriefcaseLocalValue, BriefcaseManager, CategorySelector, DisplayStyle2d, DisplayStyle3d, DrawingCategory, DrawingViewDefinition,
ECSqlStatement, Element, ElementAspect, ElementOwnsChildElements, ElementOwnsMultiAspects, ElementOwnsUniqueAspect, ElementUniqueAspect,
ExternalSource, ExternalSourceIsInRepository, FunctionalModel, FunctionalSchema, GroupModel, IModelDb, IModelHost, IModelJsFs,
InformationPartitionElement, Model, ModelSelector, OrthographicViewDefinition, PhysicalModel, PhysicalObject, PhysicalPartition,
Expand Down Expand Up @@ -144,8 +144,14 @@ export class HubWrappers {
}

/** Helper to open a briefcase db directly with the BriefcaseManager API */
public static async downloadAndOpenBriefcase(args: RequestNewBriefcaseArg): Promise<BriefcaseDb> {
public static async downloadAndOpenBriefcase(args: RequestNewBriefcaseArg & { noLock?: true }): Promise<BriefcaseDb> {
const props = await BriefcaseManager.downloadBriefcase(args);
if (args.noLock) {
const briefcase = await BriefcaseDb.open({ fileName: props.fileName });
briefcase.nativeDb.saveLocalValue(BriefcaseLocalValue.NoLocking, "true");
briefcase.saveChanges();
briefcase.close();
}
return BriefcaseDb.open({ fileName: props.fileName });
}

Expand Down
142 changes: 0 additions & 142 deletions core/backend/src/test/changesets/ChangeMerging.test.ts

This file was deleted.

109 changes: 4 additions & 105 deletions core/backend/src/test/standalone/IModelWrite.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@

import { AccessToken, DbResult, GuidString, Id64, Id64String } from "@itwin/core-bentley";
import {
Code, ColorDef, ElementAspectProps, GeometricElement2dProps, GeometryStreamProps, IModel, QueryRowFormat, RequestNewBriefcaseProps, SchemaState, SubCategoryAppearance,
Code, ColorDef,
GeometricElement2dProps, GeometryStreamProps, IModel, QueryRowFormat, RequestNewBriefcaseProps, SchemaState, SubCategoryAppearance,
} from "@itwin/core-common";
import { Arc3d, IModelJson, Point2d, Point3d } from "@itwin/core-geometry";
import * as chai from "chai";
Expand All @@ -19,7 +20,8 @@ import { DrawingCategory } from "../../Category";
import { ECSqlStatement } from "../../ECSqlStatement";
import { HubMock } from "../../HubMock";
import {
BriefcaseDb, BriefcaseManager,
BriefcaseDb,
BriefcaseManager,
DefinitionModel, DictionaryModel, DocumentListModel, Drawing, DrawingGraphic, SpatialCategory, Subject,
} from "../../core-backend";
import { IModelTestUtils, TestUserType } from "../IModelTestUtils";
Expand Down Expand Up @@ -95,109 +97,6 @@ describe("IModelWriteTest", () => {
sinon.restore();
});

it("aspect insert, update & delete requires exclusive lock", async () => {
const accessToken1 = await HubWrappers.getAccessToken(TestUserType.SuperManager);
const accessToken2 = await HubWrappers.getAccessToken(TestUserType.Regular);
const accessToken3 = await HubWrappers.getAccessToken(TestUserType.Super);

// Delete any existing iModels with the same name as the read-write test iModel
const iModelName = "TestIModel";

// Create a new empty iModel on the Hub & obtain a briefcase
const rwIModelId = await HubMock.createNewIModel({ accessToken: accessToken1, iTwinId, iModelName, description: "TestSubject", noLocks: undefined });
assert.isNotEmpty(rwIModelId);

const b1 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: accessToken1, iTwinId, iModelId: rwIModelId });
const b2 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: accessToken2, iTwinId, iModelId: rwIModelId });
const b3 = await HubWrappers.downloadAndOpenBriefcase({ accessToken: accessToken3, iTwinId, iModelId: rwIModelId });

await b1.locks.acquireLocks({ shared: IModel.repositoryModelId });
await b2.locks.acquireLocks({ shared: IModel.repositoryModelId });

// create and insert a new model with code1
const [, modelId] = IModelTestUtils.createAndInsertPhysicalPartitionAndModel(
b1,
IModelTestUtils.getUniqueModelCode(b1, "newPhysicalModel"),
true);

const dictionary: DictionaryModel = b1.models.getModel<DictionaryModel>(IModel.dictionaryId);
const newCategoryCode = IModelTestUtils.getUniqueSpatialCategoryCode(dictionary, "ThisTestSpatialCategory");

await b1.locks.acquireLocks({ shared: dictionary.id });
const spatialCategoryId = SpatialCategory.insert(
dictionary.iModel,
dictionary.id,
newCategoryCode.value,
new SubCategoryAppearance({ color: 0xff0000 }),
);
const el1 = b1.elements.insertElement(IModelTestUtils.createPhysicalObject(b1, modelId, spatialCategoryId).toJSON());
b1.saveChanges();
await b1.pushChanges({ accessToken: accessToken1, description: `inserted element ${el1}` });

await b2.pullChanges();
let aspectId: Id64String;
const insertAspectIntoB2 = () => {
aspectId = b2.elements.insertAspect({
classFullName: "BisCore:ExternalSourceAspect",
element: {
relClassName: "BisCore:ElementOwnsExternalSourceAspects",
id: el1,
},
kind: "",
identifier: "test identifier",
} as ElementAspectProps);
};

/* attempt to insert aspect without a lock */
assert.throws(insertAspectIntoB2, "Error inserting ElementAspect [exclusive lock not held on element for insert aspect (id=0x20000000004)], class: BisCore:ExternalSourceAspect");

/* acquire lock and try again */
await b2.locks.acquireLocks({ exclusive: el1 });
insertAspectIntoB2();

/* b1 cannot acquire lock on el1 as its already taken by b2 */
await expect(b1.locks.acquireLocks({ exclusive: el1 })).to.be.rejectedWith("exclusive lock is already held");

/* push changes on b2 to release lock on el1 */
b2.saveChanges();
await b2.pushChanges({ accessToken: accessToken2, description: `add aspect to element ${el1}` });

await b1.pullChanges();

const updateAspectIntoB1 = () => {
b1.elements.updateAspect({
id: aspectId,
classFullName: "BisCore:ExternalSourceAspect",
element: {
relClassName: "BisCore:ElementOwnsExternalSourceAspects",
id: el1,
},
kind: "",
identifier: "test identifier (modified)",
} as ElementAspectProps);
};

/* attempt to update aspect without a lock */
assert.throws(updateAspectIntoB1, "Error updating ElementAspect [exclusive lock not held on element for update aspect (id=0x20000000004)], id: 0x30000000001");

/* acquire lock and try again */
await b1.locks.acquireLocks({ exclusive: el1 });
updateAspectIntoB1();

/* delete the element */
b1.elements.deleteElement(el1);
b1.saveChanges();

await b1.pushChanges({ accessToken: accessToken1, description: `deleted element ${el1}` });

/* we should be able to apply all changesets */
await b3.pullChanges();

b1.close();
b2.close();
b3.close();
});

it("should handle undo/redo", async () => {
const adminAccessToken = await HubWrappers.getAccessToken(TestUserType.SuperManager);
// Delete any existing iModels with the same name as the read-write test iModel
Expand Down
Loading

0 comments on commit 4d4feab

Please sign in to comment.