Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move HubMock to core-backend #3770

Merged
merged 2 commits into from
Jun 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
188 changes: 188 additions & 0 deletions common/api/core-backend.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -2188,6 +2188,69 @@ export class GroupModel extends GroupInformationModel {
static insert(iModelDb: IModelDb, parentSubjectId: Id64String, name: string): Id64String;
}

// @internal
export class HubMock {
// (undocumented)
static acquireLocks(arg: BriefcaseDbArg, locks: LockMap): Promise<void>;
// (undocumented)
static acquireNewBriefcaseId(arg: AcquireNewBriefcaseIdArg): Promise<number>;
static createNewIModel(arg: CreateNewIModelProps): Promise<GuidString>;
// (undocumented)
static deleteIModel(arg: IModelIdArg & {
iTwinId: GuidString;
}): Promise<void>;
static destroy(iModelId: GuidString): void;
// (undocumented)
static downloadChangeset(arg: ChangesetArg & {
targetDir: LocalDirName;
}): Promise<ChangesetFileProps>;
// (undocumented)
static downloadChangesets(arg: ChangesetRangeArg & {
targetDir: LocalDirName;
}): Promise<ChangesetFileProps[]>;
// (undocumented)
static downloadV1Checkpoint(arg: CheckpointArg): Promise<ChangesetIndexAndId>;
// (undocumented)
static downloadV2Checkpoint(arg: CheckpointArg): Promise<ChangesetIndexAndId>;
// (undocumented)
static findLocalHub(iModelId: GuidString): LocalHub;
static getChangesetFromNamedVersion(arg: IModelIdArg & {
versionName: string;
}): Promise<ChangesetProps>;
// (undocumented)
static getChangesetFromVersion(arg: IModelIdArg & {
version: IModelVersion;
}): Promise<ChangesetProps>;
// (undocumented)
static getLatestChangeset(arg: IModelIdArg): Promise<ChangesetProps>;
// (undocumented)
static getMyBriefcaseIds(arg: IModelIdArg): Promise<number[]>;
static get isValid(): boolean;
// (undocumented)
static get iTwinId(): string;
// (undocumented)
static pushChangeset(arg: IModelIdArg & {
changesetProps: ChangesetFileProps;
}): Promise<ChangesetIndex>;
// (undocumented)
static queryAllLocks(_arg: BriefcaseDbArg): Promise<LockProps[]>;
// (undocumented)
static queryChangeset(arg: ChangesetArg): Promise<ChangesetProps>;
// (undocumented)
static queryChangesets(arg: IModelIdArg & {
range?: ChangesetRange;
}): Promise<ChangesetProps[]>;
// (undocumented)
static queryIModelByName(arg: IModelNameArg): Promise<GuidString | undefined>;
// (undocumented)
static queryV2Checkpoint(_arg: CheckpointProps): Promise<V2CheckpointAccessProps | undefined>;
// (undocumented)
static releaseAllLocks(arg: BriefcaseDbArg): Promise<void>;
static releaseBriefcase(arg: BriefcaseIdArg): Promise<void>;
static shutdown(): void;
static startup(mockName: LocalDirName, outputDir: string): void;
}

// @beta
export class IModelCloneContext {
constructor(sourceDb: IModelDb, targetDb?: IModelDb);
Expand Down Expand Up @@ -3024,6 +3087,111 @@ export interface LocalhostIpcHostOpts {
socketPort?: number;
}

// @internal
export class LocalHub {
constructor(rootDir: LocalDirName, arg: LocalHubProps);
// (undocumented)
acquireLock(props: LockProps, briefcase: BriefcaseIdAndChangeset): void;
acquireLocks(locks: LockMap, briefcase: BriefcaseIdAndChangeset): void;
acquireNewBriefcaseId(user: string, alias?: string): BriefcaseId;
addChangeset(changeset: ChangesetFileProps): ChangesetIndex;
addNamedVersion(arg: {
versionName: string;
csIndex: ChangesetIndex;
}): void;
// (undocumented)
get changesetDir(): string;
// (undocumented)
get checkpointDir(): string;
// (undocumented)
checkpointNameFromIndex(csIndex: ChangesetIndex): string;
// (undocumented)
cleanup(): void;
// (undocumented)
countLocks(): number;
// (undocumented)
countSharedLocks(): number;
deleteNamedVersion(versionName: string): void;
// (undocumented)
readonly description?: string;
downloadChangeset(arg: {
index: ChangesetIndex;
targetDir: LocalDirName;
}): ChangesetFileProps;
downloadChangesets(arg: {
range?: ChangesetRange;
targetDir: LocalDirName;
}): ChangesetFileProps[];
downloadCheckpoint(arg: {
changeset: ChangesetIndexOrId;
targetFile: LocalFileName;
}): {
index: number;
id: string;
};
findNamedVersion(versionName: string): ChangesetProps;
// (undocumented)
getBriefcase(id: BriefcaseId): MockBriefcaseIdProps;
getBriefcaseIds(user: string): BriefcaseId[];
getBriefcases(onlyAssigned?: boolean): MockBriefcaseIdProps[];
getChangesetById(id: ChangesetId): ChangesetProps;
getChangesetByIndex(index: ChangesetIndex): ChangesetProps;
// (undocumented)
getChangesetId(index: ChangesetIndex): ChangesetId;
getChangesetIndex(id: ChangesetId): ChangesetIndex;
getCheckpoints(range?: ChangesetRange): ChangesetIndex[];
// (undocumented)
getIndexFromChangeset(changeset: ChangesetIndexOrId): ChangesetIndex;
// (undocumented)
getLatestChangeset(): ChangesetProps;
// (undocumented)
getParentId(index: ChangesetIndex): ChangesetId;
// (undocumented)
getPreviousIndex(index: ChangesetIndex): number;
// (undocumented)
readonly iModelId: GuidString;
// (undocumented)
readonly iModelName: string;
// (undocumented)
readonly iTwinId: GuidString;
// (undocumented)
get latestChangesetIndex(): number;
// (undocumented)
get mockDbName(): string;
// (undocumented)
queryAllLocks(briefcaseId: BriefcaseId): LockProps[];
// (undocumented)
queryAllSharedLocks(): {
id: Id64String;
briefcaseId: BriefcaseId;
}[];
queryChangesets(range?: ChangesetRange): ChangesetProps[];
// (undocumented)
queryLocks(): LocksEntry[];
// (undocumented)
queryLockStatus(elementId: Id64String): LockStatus;
queryPreviousCheckpoint(changesetIndex: ChangesetIndex): ChangesetIndex;
// (undocumented)
releaseAllLocks(arg: {
briefcaseId: BriefcaseId;
changesetIndex: ChangesetIndex;
}): void;
releaseBriefcaseId(id: BriefcaseId): void;
// (undocumented)
releaseLocks(locks: LockProps[], arg: {
briefcaseId: BriefcaseId;
changesetIndex: ChangesetIndex;
}): void;
// (undocumented)
removeDir(dirName: string): void;
// (undocumented)
readonly rootDir: LocalDirName;
uploadCheckpoint(arg: {
changesetIndex: ChangesetIndex;
localFile: LocalFileName;
}): string;
}

// @beta
export class LockConflict extends IModelError {
constructor(
Expand Down Expand Up @@ -3069,6 +3237,26 @@ export enum LockState {
Shared = 1
}

// @internal (undocumented)
export interface LockStatusExclusive {
// (undocumented)
briefcaseId: BriefcaseId;
// (undocumented)
lastCsIndex?: ChangesetIndex;
// (undocumented)
state: LockState.Exclusive;
}

// @internal (undocumented)
export interface LockStatusShared {
// (undocumented)
lastCsIndex?: ChangesetIndex;
// (undocumented)
sharedBy: Set<BriefcaseId>;
// (undocumented)
state: LockState.Shared;
}

// @internal
export class MetaDataRegistry {
add(classFullName: string, metaData: EntityMetaData): void;
Expand Down
4 changes: 4 additions & 0 deletions common/api/summary/core-backend.exports.csv
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ public;class GroupInformationElement
public;class GroupInformationModel
public;GroupInformationPartition
public;GroupModel
internal;HubMock
beta;IModelCloneContext
public;class IModelDb
public;IModelDb
Expand Down Expand Up @@ -216,11 +217,14 @@ public;LinkModel
public;LinkPartition
internal;LocalhostIpcHost
internal;LocalhostIpcHostOpts
internal;LocalHub
beta;LockConflict
beta;LockControl
internal;LockMap = Map
beta;LockProps
public;LockState
internal;LockStatusExclusive
internal;LockStatusShared
internal;MetaDataRegistry
public;Model
public;ModelSelector
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@itwin/core-backend",
"comment": "move HubMock to core-backend",
"type": "none"
}
],
"packageName": "@itwin/core-backend"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@itwin/core-transformer",
"comment": "move HubMock to core-backend",
"type": "none"
}
],
"packageName": "@itwin/core-transformer"
}
22 changes: 11 additions & 11 deletions core/backend/src/test/HubMock.ts → core/backend/src/HubMock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ import {
ChangesetFileProps, ChangesetIndex, ChangesetIndexAndId, ChangesetProps, ChangesetRange, IModelVersion, LocalDirName,
} from "@itwin/core-common";
import {
AcquireNewBriefcaseIdArg,
BackendHubAccess, BriefcaseDbArg, BriefcaseIdArg, ChangesetArg, ChangesetRangeArg, CheckpointArg, CreateNewIModelProps, IModelIdArg, IModelNameArg,
LockMap, LockProps, V2CheckpointAccessProps,
} from "../BackendHubAccess";
import { CheckpointProps } from "../CheckpointManager";
import { AcquireNewBriefcaseIdArg, TokenArg } from "../core-backend";
import { IModelHost } from "../IModelHost";
import { IModelJsFs } from "../IModelJsFs";
import { LocalHub } from "../LocalHub";
import { KnownTestLocations } from "./KnownTestLocations";
} from "./BackendHubAccess";
import { CheckpointProps } from "./CheckpointManager";
import { IModelHost } from "./IModelHost";
import { IModelJsFs } from "./IModelJsFs";
import { LocalHub } from "./LocalHub";
import { TokenArg } from "./IModelDb";

/**
* Mocks iModelHub for testing creating Briefcases, downloading checkpoints, and simulating multiple users pushing and pulling changesets, etc.
Expand Down Expand Up @@ -67,19 +67,17 @@ export class HubMock {
return this._iTwinId;
}

protected static get knownTestLocations(): { outputDir: string, assetsDir: string } { return KnownTestLocations; }

/**
* Begin mocking IModelHub access. After this call, all access to IModelHub will be directed to a [[LocalHub]].
* @param mockName a unique name (e.g. "MyTest") for this HubMock to disambiguate tests when more than one is simultaneously active.
* It is used to create a private directory used by the HubMock for a test. That directory is removed when [[shutdown]] is called.
*/
public static startup(mockName: LocalDirName) {
public static startup(mockName: LocalDirName, outputDir: string) {
if (this.isValid)
throw new Error("Either a previous test did not call HubMock.shutdown() properly, or more than one test is simultaneously attempting to use HubMock, which is not allowed");

this.hubs.clear();
this.mockRoot = join(this.knownTestLocations.outputDir, "HubMock", mockName);
this.mockRoot = join(outputDir, "HubMock", mockName);
IModelJsFs.recursiveMkDirSync(this.mockRoot);
IModelJsFs.purgeDirSync(this.mockRoot);
this._saveHubAccess = IModelHost.getHubAccess();
Expand All @@ -100,7 +98,9 @@ export class HubMock {
hub[1].cleanup();

this.hubs.clear();
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
IModelJsFs.purgeDirSync(this.mockRoot!);
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
IModelJsFs.removeSync(this.mockRoot!);
sinon.restore();
IModelHost.setHubAccess(this._saveHubAccess);
Expand Down
2 changes: 2 additions & 0 deletions core/backend/src/core-backend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ export * from "./ElementAspect";
export * from "./Entity";
export * from "./ExportGraphics";
export * from "./ExternalSource";
export * from "./LocalHub";
export * from "./HubMock";
export * from "./IModelJsFs";
export * from "./BackendHubAccess";
export * from "./Relationship";
Expand Down
2 changes: 1 addition & 1 deletion core/backend/src/test/IModelTestUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import { DefinitionModel, DocumentListModel, DrawingModel, InformationRecordMode
import { DrawingGraphicRepresentsElement, ElementDrivesElement, Relationship, RelationshipProps } from "../Relationship";
import { DownloadAndOpenArgs, RpcBriefcaseUtility } from "../rpc-impl/RpcBriefcaseUtility";
import { Schema, Schemas } from "../Schema";
import { HubMock } from "./HubMock";
import { HubMock } from "../HubMock";
import { KnownTestLocations } from "./KnownTestLocations";
import { BackendHubAccess } from "../BackendHubAccess";

Expand Down
4 changes: 2 additions & 2 deletions core/backend/src/test/TestChangeSetUtility.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
import { AccessToken, GuidString } from "@itwin/core-bentley";
import { ColorDef, IModel, SubCategoryAppearance } from "@itwin/core-common";
import { BriefcaseDb, IModelHost, SpatialCategory } from "../core-backend";
import { HubWrappers } from "./IModelTestUtils";
import { HubMock, IModelTestUtils } from "./index";
import { HubMock } from "../HubMock";
import { HubWrappers, IModelTestUtils } from "./IModelTestUtils";

/** Test utility to push an iModel and ChangeSets */
export class TestChangeSetUtility {
Expand Down
17 changes: 9 additions & 8 deletions core/backend/src/test/hubaccess/BriefcaseManager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
import { assert } from "chai";
import { Guid } from "@itwin/core-bentley";
import { BriefcaseIdValue } from "@itwin/core-common";
import { HubWrappers, TestChangeSetUtility } from "..";
import { Element } from "../../Element";
import { HubMock } from "../HubMock";
import { IModelTestUtils } from "../IModelTestUtils";
import { HubWrappers, IModelTestUtils } from "../IModelTestUtils";
import { KnownTestLocations } from "../KnownTestLocations";
import { HubMock } from "../../HubMock";
import { TestChangeSetUtility } from "../TestChangeSetUtility";

describe("BriefcaseManager", async () => {
const testITwinId: string = Guid.createValue();
Expand All @@ -20,7 +21,7 @@ describe("BriefcaseManager", async () => {
afterEach(() => HubMock.shutdown());

it("Open iModels with various names causing potential issues on Windows/Unix", async () => {
HubMock.startup("bad names");
HubMock.startup("bad names", KnownTestLocations.outputDir);
let iModelName = "iModel Name With Spaces";
let iModelId = await HubWrappers.createIModel(managerAccessToken, testITwinId, iModelName);
const args = { accessToken, iTwinId: testITwinId, iModelId };
Expand Down Expand Up @@ -49,7 +50,7 @@ describe("BriefcaseManager", async () => {
});

it("should set appropriate briefcase ids for FixedVersion, PullOnly and PullAndPush workflows", async () => {
HubMock.startup("briefcaseIds");
HubMock.startup("briefcaseIds", KnownTestLocations.outputDir);
const iModelId = await HubWrappers.createIModel(accessToken, testITwinId, "imodel1");
const args = { accessToken, iTwinId: testITwinId, iModelId, deleteFirst: true };
const iModel1 = await HubWrappers.openCheckpointUsingRpc(args);
Expand All @@ -68,7 +69,7 @@ describe("BriefcaseManager", async () => {
});

it("should reuse a briefcaseId when re-opening iModels for pullAndPush workflows", async () => {
HubMock.startup("briefcaseIdsReopen");
HubMock.startup("briefcaseIdsReopen", KnownTestLocations.outputDir);
const iModelId = await HubWrappers.createIModel(accessToken, testITwinId, "imodel1");

const args = { accessToken, iTwinId: testITwinId, iModelId, deleteFirst: false };
Expand All @@ -85,7 +86,7 @@ describe("BriefcaseManager", async () => {
});

it("should reuse a briefcaseId when re-opening iModels of different versions for pullAndPush and pullOnly workflows", async () => {
HubMock.startup("workflow");
HubMock.startup("workflow", KnownTestLocations.outputDir);
const userToken1 = "manager token";
const userToken2 = "super manager token";

Expand Down Expand Up @@ -129,7 +130,7 @@ describe("BriefcaseManager", async () => {
});

it("should be able to edit a PullAndPush briefcase, reopen it as of a new version, and then push changes", async () => {
HubMock.startup("pullPush");
HubMock.startup("pullPush", KnownTestLocations.outputDir);
const userToken1 = "manager token"; // User1 is just used to create and update the iModel
const userToken2 = "super manager token"; // User2 is used for the test

Expand Down
Loading