@fluidframework/test-utils 2.74.0 → 2.81.0-374083
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/dist/loaderContainerTracker.d.ts.map +1 -1
- package/dist/loaderContainerTracker.js +1 -0
- package/dist/loaderContainerTracker.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/testObjectProvider.d.ts +1 -1
- package/dist/testObjectProvider.d.ts.map +1 -1
- package/dist/testObjectProvider.js +4 -0
- package/dist/testObjectProvider.js.map +1 -1
- package/eslint.config.mts +4 -4
- package/lib/loaderContainerTracker.d.ts.map +1 -1
- package/lib/loaderContainerTracker.js +1 -0
- package/lib/loaderContainerTracker.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.d.ts.map +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/testObjectProvider.d.ts +1 -1
- package/lib/testObjectProvider.d.ts.map +1 -1
- package/lib/testObjectProvider.js +4 -0
- package/lib/testObjectProvider.js.map +1 -1
- package/package.json +31 -31
- package/src/loaderContainerTracker.ts +1 -0
- package/src/packageVersion.ts +1 -1
- package/src/testObjectProvider.ts +5 -1
- package/.eslintrc.cjs +0 -17
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testObjectProvider.js","sourceRoot":"","sources":["../src/testObjectProvider.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITestDriver, TestDriverTypes } from \"@fluid-internal/test-driver-definitions\";\nimport {\n\tIContainer,\n\tIFluidCodeDetails,\n\tIHostLoader,\n\tILoader,\n} from \"@fluidframework/container-definitions/internal\";\nimport {\n\tILoaderProps,\n\tLoader,\n\twaitContainerToCatchUp as waitContainerToCatchUp_original,\n} from \"@fluidframework/container-loader/internal\";\nimport { type IContainerRuntimeOptionsInternal } from \"@fluidframework/container-runtime/internal\";\nimport {\n\tIRequestHeader,\n\tITelemetryBaseEvent,\n\tITelemetryBaseLogger,\n\tITelemetryBaseProperties,\n\tTelemetryBaseEventPropertyType,\n} from \"@fluidframework/core-interfaces\";\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport {\n\tIDocumentServiceFactory,\n\tIResolvedUrl,\n\tIUrlResolver,\n} from \"@fluidframework/driver-definitions/internal\";\nimport { isOdspResolvedUrl } from \"@fluidframework/odsp-driver/internal\";\nimport type { MinimumVersionForCollab } from \"@fluidframework/runtime-definitions/internal\";\nimport {\n\ttype ITelemetryGenericEventExt,\n\tcreateChildLogger,\n\tcreateMultiSinkLogger,\n\ttype ITelemetryLoggerPropertyBags,\n\tTelemetryDataTag,\n\ttagData,\n} from \"@fluidframework/telemetry-utils/internal\";\nimport { v4 as uuid } from \"uuid\";\n\nimport { LoaderContainerTracker } from \"./loaderContainerTracker.js\";\nimport { LocalCodeLoader, fluidEntryPoint } from \"./localCodeLoader.js\";\nimport { createAndAttachContainer } from \"./localLoader.js\";\nimport { isNonEmptyArray } from \"./nonEmptyArrayType.js\";\nimport { ChannelFactoryRegistry } from \"./testFluidObject.js\";\n\nconst defaultCodeDetails: IFluidCodeDetails = {\n\tpackage: \"defaultTestPackage\",\n\tconfig: {},\n};\n\n/**\n * Exposes fine-grained control over the Container's inbound and outbound op queues\n *\n * @legacy @beta\n */\nexport interface IOpProcessingController {\n\t/**\n\t * Process all ops sitting in the inbound queue, leaving the inbound queue paused afterwards\n\t * @param containers - optional subset of all open containers\n\t */\n\tprocessIncoming(...containers: IContainer[]): Promise<void>;\n\t/**\n\t * Process all ops sitting in the outbound queue, leaving the inbound queue paused afterwards.\n\t * Also waits for the outbound ops to arrive in the inbound queue.\n\t * @param containers - optional subset of all open containers\n\t */\n\tprocessOutgoing(...containers: IContainer[]): Promise<void>;\n\t/**\n\t * Process all queue activities, to prepare for fine-grained control via processIncoming and processOutgoing\n\t * @param containers - optional subset of all open containers\n\t */\n\tpauseProcessing(...containers: IContainer[]): Promise<void>;\n\t/**\n\t * Resume all queue activities for normal operation of the container\n\t * @param containers - optional subset of all open containers\n\t */\n\tresumeProcessing(...containers: IContainer[]): void;\n}\n\n/**\n * @internal\n */\nexport interface ITestObjectProvider {\n\t/**\n\t * Indicates which type of test object provider is being used.\n\t */\n\ttype: \"TestObjectProvider\" | \"TestObjectProviderWithVersionedLoad\";\n\n\t/**\n\t * The document id to retrieve or create containers\n\t */\n\tdocumentId: string;\n\n\t/**\n\t * Creates the document service after extracting different endpoints URLs from a resolved URL.\n\t */\n\tdocumentServiceFactory: IDocumentServiceFactory;\n\n\t/**\n\t * Test driver used to create the IDocumentServiceFactory. Varies depending on the test type.\n\t */\n\tdriver: ITestDriver;\n\n\t/**\n\t * Logger used to track expected and unexpected events.\n\t */\n\tlogger: ITelemetryBaseLogger;\n\n\t/**\n\t * Logger used to track expected and unexpected events.\n\t */\n\ttracker: IEventAndErrorTrackingLogger;\n\n\t/**\n\t * Used to create a url for the created container with any data store path given in the relative url.\n\t */\n\turlResolver: IUrlResolver;\n\n\t/**\n\t * Default IFluidCodeDetails used to create containers.\n\t */\n\tdefaultCodeDetails: IFluidCodeDetails;\n\n\t/**\n\t * Contains functions to pause/resume op processing.\n\t */\n\topProcessingController: IOpProcessingController;\n\n\t/**\n\t * Represents the entry point for a Fluid container.\n\t */\n\tcreateFluidEntryPoint: (testContainerConfig?: ITestContainerConfig) => fluidEntryPoint;\n\n\t/**\n\t * Create a loader. Containers created/loaded through this loader will be added to the OpProcessingController.\n\t *\n\t * Only the version of the loader will vary based on compat config. The version of\n\t * containerRuntime/dataRuntime used in fluidEntryPoint will be used as is from what is passed in.\n\t *\n\t * @param packageEntries - list of code details and fluidEntryPoint pairs.\n\t * @param loaderProps - Optional loader properties\n\t * @param forceUseCreateVersion - For Cross-Client compat testing, create a loader based on the create version\n\t */\n\tcreateLoader(\n\t\tpackageEntries: Iterable<[IFluidCodeDetails, fluidEntryPoint]>,\n\t\tloaderProps?: Partial<ILoaderProps>,\n\t\tforceUseCreateVersion?: boolean,\n\t): IHostLoader;\n\n\t/**\n\t * Create a container using a default document id and code details.\n\t * Container created is automatically added to the OpProcessingController to manage op flow\n\t *\n\t * Only the version of the loader will vary based on compat config. The version of\n\t * containerRuntime/dataRuntime used in fluidEntryPoint will be used as is from what is passed in.\n\t *\n\t * @param packageEntries - list of code details and fluidEntryPoint pairs.\n\t */\n\n\tcreateContainer(\n\t\tentryPoint: fluidEntryPoint,\n\t\tloaderProps?: Partial<ILoaderProps>,\n\t): Promise<IContainer>;\n\n\t/**\n\t * Create a detached container much like createContainer, but without attaching it to the document service.\n\t */\n\tcreateDetachedContainer(\n\t\tentryPoint: fluidEntryPoint,\n\t\tloaderProps?: Partial<ILoaderProps>,\n\t): Promise<IContainer>;\n\n\t/**\n\t * Attaches a detached container to the document service.\n\t */\n\tattachDetachedContainer(container: IContainer): Promise<void>;\n\n\t/**\n\t * Loads a container using the default document id\n\t */\n\tloadContainer(\n\t\tentryPoint: fluidEntryPoint,\n\t\tloaderProps?: Partial<ILoaderProps>,\n\t\trequestHeader?: IRequestHeader,\n\t\tpendingLocalState?: string,\n\t): Promise<IContainer>;\n\n\t/**\n\t * Make a test loader. Containers created/loaded through this loader will be added to the OpProcessingController.\n\t * The version of the loader/containerRuntime/dataRuntime may vary based on compat config of the current run\n\t * @param testContainerConfig - optional configuring the test Container\n\t */\n\tmakeTestLoader(testContainerConfig?: ITestContainerConfig): IHostLoader;\n\n\t/**\n\t * Make a container using a default document id and code details\n\t * Container loaded is automatically added to the OpProcessingController to manage op flow\n\t * @param testContainerConfig - optional configuring the test Container\n\t */\n\tmakeTestContainer(testContainerConfig?: ITestContainerConfig): Promise<IContainer>;\n\n\t/**\n\t * Load a container using a default document id and code details.\n\t * IContainer loaded is automatically added to the OpProcessingController to manage op flow\n\t * @param testContainerConfig - optional configuring the test Container\n\t * @param requestHeader - optional headers to be supplied to the loader\n\t */\n\tloadTestContainer(\n\t\ttestContainerConfig?: ITestContainerConfig,\n\t\trequestHeader?: IRequestHeader,\n\t\tpendingLocalState?: string,\n\t): Promise<IContainer>;\n\n\t/**\n\t * Update the document ID from the resolved container's URL and reset the ID property\n\t */\n\tupdateDocumentId(url: IResolvedUrl | undefined): void;\n\n\t/**\n\t * Make sure all the tracked containers are synchronized.\n\t */\n\tensureSynchronized(...containers: IContainer[]): Promise<void>;\n\n\t/**\n\t * Reset the tracker, closing all containers and stop tracking them.\n\t */\n\tresetLoaderContainerTracker(syncSummarizerClients?: boolean);\n\n\t/**\n\t * Resets and closes all tracked containers and class states.\n\t */\n\treset(): void;\n}\n\n/**\n * @internal\n */\nexport enum DataObjectFactoryType {\n\tPrimed, // default\n\tTest,\n}\n\n/**\n * @internal\n */\nexport interface ITestContainerConfig {\n\t/** TestFluidDataObject instead of PrimedDataStore */\n\tfluidDataObjectType?: DataObjectFactoryType;\n\n\t/** An array of channel name and DDS factory pair to create on container creation time */\n\tregistry?: ChannelFactoryRegistry;\n\n\t/** Container runtime options for the container instance */\n\truntimeOptions?: IContainerRuntimeOptionsInternal;\n\n\t/** Whether this runtime should be instantiated using a mixed-in attributor class */\n\tenableAttribution?: boolean;\n\n\t/** For Cross-Client compat testing, load using the create version (e.g. use this to get a Summarizer on the create version) */\n\tforceUseCreateVersion?: true;\n\n\t/** Loader options for the loader used to create containers */\n\tloaderProps?: Partial<ILoaderProps>;\n\n\t/**\n\t * Minimum version of the FF runtime that is required to collaborate on new documents.\n\t * See {@link @fluidframework/container-runtime#LoadContainerRuntimeParams.minVersionForCollab} for more details.\n\t */\n\tminVersionForCollab?: MinimumVersionForCollab | undefined;\n}\n\n/**\n * @internal\n */\nexport const createDocumentId = (): string => uuid();\n\n/**\n * Used to retrieve, update, and reset document id based on the type of driver being used.\n *\n * @internal\n */\nexport interface IDocumentIdStrategy {\n\t/**\n\t * Get document id\n\t */\n\tget(): string;\n\t/**\n\t * Update the document ID from the resolved container's URL and reset the ID property\n\t */\n\tupdate(resolvedUrl?: IResolvedUrl): void;\n\t/**\n\t * Reset document id to a new document id\n\t */\n\treset(): void;\n}\n\n/**\n * Document ID is treated differently by test drivers. The key difference is in generating\n * a new container ID and accessing the container in multi-instance test cases.\n */\nfunction getDocumentIdStrategy(type?: TestDriverTypes): IDocumentIdStrategy {\n\tlet documentId = createDocumentId();\n\tswitch (type) {\n\t\tcase \"odsp\":\n\t\t\treturn {\n\t\t\t\tget: () => documentId,\n\t\t\t\tupdate: () => {}, // do not update the document ID in odsp test cases\n\t\t\t\treset: () => {\n\t\t\t\t\tdocumentId = createDocumentId();\n\t\t\t\t},\n\t\t\t};\n\t\tdefault:\n\t\t\treturn {\n\t\t\t\tget: () => documentId,\n\t\t\t\tupdate: (resolvedUrl?: IResolvedUrl) => {\n\t\t\t\t\t// Extract the document ID from the resolved container's URL and reset the ID property\n\t\t\t\t\tdocumentId = resolvedUrl?.id ?? documentId;\n\t\t\t\t},\n\t\t\t\treset: () => {\n\t\t\t\t\tdocumentId = createDocumentId();\n\t\t\t\t},\n\t\t\t};\n\t}\n}\n\n/** @internal */\nexport interface IEventAndErrorTrackingLogger {\n\tregisterExpectedEvent: (...orderedExpectedEvents: ITelemetryGenericEventExt[]) => void;\n\treportAndClearTrackedEvents: () => {\n\t\texpectedNotFound: { index: number; event: ITelemetryGenericEventExt }[];\n\t\tunexpectedErrors: ITelemetryBaseEvent[];\n\t};\n}\n\n/**\n * This class tracks events. It allows specifying expected events, which will be looked for in order.\n * It also tracks all unexpected errors.\n * At any point you call reportAndClearTrackedEvents which will provide all unexpected errors, and\n * any expected events that have not occurred.\n * @internal\n */\nexport class EventAndErrorTrackingLogger\n\timplements ITelemetryBaseLogger, IEventAndErrorTrackingLogger\n{\n\t/**\n\t * Even if these error events are logged, tests should still be allowed to pass\n\t * Additionally, if downgrade is true, then log as generic (e.g. to avoid polluting the e2e test logs)\n\t */\n\tprivate readonly allowedErrors: { eventName: string; downgrade?: true }[] = [\n\t\t// This log was removed in current version as unnecessary, but it's still present in previous versions\n\t\t{\n\t\t\teventName: \"fluid:telemetry:Container:NoRealStorageInDetachedContainer\",\n\t\t\tdowngrade: true,\n\t\t},\n\t\t// This log's category changes depending on the op latency. test results shouldn't be affected but if we see lots we'd like an alert from the logs.\n\t\t{ eventName: \"fluid:telemetry:OpRoundtripTime\" },\n\t];\n\n\tconstructor(private readonly baseLogger?: ITelemetryBaseLogger) {}\n\n\tprivate readonly expectedEvents: { index: number; event: ITelemetryGenericEventExt }[] = [];\n\tprivate readonly unexpectedErrors: ITelemetryBaseEvent[] = [];\n\n\tpublic registerExpectedEvent(...orderedExpectedEvents: ITelemetryGenericEventExt[]): void {\n\t\tif (this.expectedEvents.length !== 0) {\n\t\t\t// we don't have to error here. just no reason not to. given the events must be\n\t\t\t// ordered it could be tricky to figure out problems around multiple registrations.\n\t\t\tthrow new Error(\n\t\t\t\t\"Expected events already registered.\\n\" +\n\t\t\t\t\t\"Call reportAndClearTrackedEvents to clear them before registering more\",\n\t\t\t);\n\t\t}\n\t\tthis.expectedEvents.push(\n\t\t\t...orderedExpectedEvents.map((event, index) => ({ index, event })),\n\t\t);\n\t}\n\n\tsend(event: ITelemetryBaseEvent): void {\n\t\tif (isNonEmptyArray(this.expectedEvents)) {\n\t\t\tconst ee = this.expectedEvents[0].event;\n\t\t\tif (ee.eventName === event.eventName) {\n\t\t\t\tlet matches = true;\n\t\t\t\tfor (const key of Object.keys(ee)) {\n\t\t\t\t\tif (ee[key] !== event[key]) {\n\t\t\t\t\t\tmatches = false;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (matches) {\n\t\t\t\t\t// we found an expected event\n\t\t\t\t\t// so remove it from the list of expected events\n\t\t\t\t\t// and if it is an error, change it to generic\n\t\t\t\t\t// this helps keep our telemetry clear of\n\t\t\t\t\t// expected errors.\n\t\t\t\t\tthis.expectedEvents.shift();\n\t\t\t\t\tif (event.category === \"error\") {\n\t\t\t\t\t\tevent.category = \"generic\";\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (event.category === \"error\") {\n\t\t\t// Check to see if this error is allowed and if its category should be downgraded\n\t\t\tconst allowedError = this.allowedErrors.find(\n\t\t\t\t({ eventName }) => eventName === event.eventName,\n\t\t\t);\n\n\t\t\tif (allowedError === undefined) {\n\t\t\t\tthis.unexpectedErrors.push(event);\n\t\t\t} else if (allowedError.downgrade) {\n\t\t\t\tevent.category = \"generic\";\n\t\t\t}\n\t\t}\n\n\t\tthis.baseLogger?.send(event);\n\t}\n\n\tpublic reportAndClearTrackedEvents(): {\n\t\texpectedNotFound: { index: number; event: ITelemetryGenericEventExt }[];\n\t\tunexpectedErrors: ITelemetryBaseEvent[];\n\t} {\n\t\tconst expectedNotFound = this.expectedEvents.splice(0, this.expectedEvents.length);\n\t\tconst unexpectedErrors = this.unexpectedErrors.splice(0, this.unexpectedErrors.length);\n\t\treturn {\n\t\t\texpectedNotFound,\n\t\t\tunexpectedErrors,\n\t\t};\n\t}\n}\n\n/**\n * Shared base class for test object provider. Contain code for loader and container creation and loading\n * @internal\n */\nexport class TestObjectProvider implements ITestObjectProvider {\n\t/**\n\t * {@inheritDoc ITestObjectProvider.\"type\"}\n\t */\n\tpublic readonly type = \"TestObjectProvider\";\n\tprivate _loaderContainerTracker = new LoaderContainerTracker();\n\tprivate _documentServiceFactory: IDocumentServiceFactory | undefined;\n\tprivate _urlResolver: IUrlResolver | undefined;\n\tprivate _logger: ITelemetryBaseLogger | undefined;\n\tprivate _tracker: EventAndErrorTrackingLogger | undefined;\n\tprivate readonly _documentIdStrategy: IDocumentIdStrategy;\n\t// Since documentId doesn't change we can only create/make one container. Call the load functions instead.\n\tprivate _documentCreated = false;\n\n\t/**\n\t * Manage objects for loading and creating container, including the driver, loader, and OpProcessingController\n\t * @param createFluidEntryPoint - callback to create a fluidEntryPoint, with an optional set of channel name\n\t * and factory for TestFluidObject\n\t */\n\tconstructor(\n\t\tprivate readonly LoaderConstructor: typeof Loader,\n\t\t/**\n\t\t * {@inheritDoc ITestObjectProvider.driver}\n\t\t */\n\t\tpublic readonly driver: ITestDriver,\n\t\t/**\n\t\t * {@inheritDoc ITestObjectProvider.createFluidEntryPoint}\n\t\t */\n\t\tpublic readonly createFluidEntryPoint: (\n\t\t\ttestContainerConfig?: ITestContainerConfig,\n\t\t) => fluidEntryPoint,\n\t) {\n\t\tthis._documentIdStrategy = getDocumentIdStrategy(driver.type);\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.logger}\n\t */\n\tpublic get logger(): ITelemetryBaseLogger {\n\t\tif (this._logger === undefined) {\n\t\t\tthis._tracker = new EventAndErrorTrackingLogger(getTestLogger?.());\n\t\t\tthis._logger = createChildLogger({\n\t\t\t\tlogger: this._tracker,\n\t\t\t\tproperties: {\n\t\t\t\t\tall: {\n\t\t\t\t\t\ttestType: this.type,\n\t\t\t\t\t\tdriverType: this.driver.type,\n\t\t\t\t\t\tdriverEndpointName: this.driver.endpointName,\n\t\t\t\t\t\tdriverTenantName: this.driver.tenantName,\n\t\t\t\t\t\tdriverUserIndex: this.driver.userIndex,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t\treturn this._logger;\n\t}\n\n\tpublic get tracker(): EventAndErrorTrackingLogger {\n\t\tvoid this.logger;\n\t\tassert(this._tracker !== undefined, \"should be initialized\");\n\t\treturn this._tracker;\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.documentServiceFactory}\n\t */\n\tpublic get documentServiceFactory(): IDocumentServiceFactory {\n\t\tif (!this._documentServiceFactory) {\n\t\t\tthis._documentServiceFactory = this.driver.createDocumentServiceFactory();\n\t\t}\n\t\treturn this._documentServiceFactory;\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.urlResolver}\n\t */\n\tpublic get urlResolver(): IUrlResolver {\n\t\tif (!this._urlResolver) {\n\t\t\tthis._urlResolver = this.driver.createUrlResolver();\n\t\t}\n\t\treturn this._urlResolver;\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.documentId}\n\t */\n\tpublic get documentId(): string {\n\t\treturn this._documentIdStrategy.get();\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.defaultCodeDetails}\n\t */\n\tpublic get defaultCodeDetails(): IFluidCodeDetails {\n\t\treturn defaultCodeDetails;\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.opProcessingController}\n\t */\n\tpublic get opProcessingController(): IOpProcessingController {\n\t\treturn this._loaderContainerTracker;\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.createLoader}\n\t */\n\tpublic createLoader(\n\t\tpackageEntries: Iterable<[IFluidCodeDetails, fluidEntryPoint]>,\n\t\tloaderProps?: Partial<ILoaderProps>,\n\t): Loader {\n\t\tconst logger = createMultiSinkLogger({\n\t\t\tloggers: [this.logger, loaderProps?.logger],\n\t\t});\n\n\t\tconst loader = new this.LoaderConstructor({\n\t\t\t...loaderProps,\n\t\t\tlogger,\n\t\t\tcodeLoader: loaderProps?.codeLoader ?? new LocalCodeLoader(packageEntries),\n\t\t\turlResolver: loaderProps?.urlResolver ?? this.urlResolver,\n\t\t\tdocumentServiceFactory:\n\t\t\t\tloaderProps?.documentServiceFactory ?? this.documentServiceFactory,\n\t\t});\n\t\tthis._loaderContainerTracker.add(loader);\n\t\treturn loader;\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.createContainer}\n\t */\n\tpublic async createContainer(\n\t\tentryPoint: fluidEntryPoint,\n\t\tloaderProps?: Partial<ILoaderProps>,\n\t): Promise<IContainer> {\n\t\tif (this._documentCreated) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Only one container/document can be created. To load the container/document use loadContainer\",\n\t\t\t);\n\t\t}\n\t\tconst loader = this.createLoader([[defaultCodeDetails, entryPoint]], loaderProps);\n\t\tconst container = await createAndAttachContainer(\n\t\t\tdefaultCodeDetails,\n\t\t\tloader,\n\t\t\tthis.driver.createCreateNewRequest(this.documentId),\n\t\t);\n\t\tthis._documentCreated = true;\n\t\t// r11s driver will generate a new ID for the new container.\n\t\t// update the document ID with the actual ID of the attached container.\n\t\tthis.updateDocumentId(container.resolvedUrl);\n\t\treturn container;\n\t}\n\n\t/**\n\t * {@inheritdoc ITestObjectProvider.createDetachedContainer}\n\t */\n\tpublic async createDetachedContainer(\n\t\tentryPoint: fluidEntryPoint,\n\t\tloaderProps?: Partial<ILoaderProps> | undefined,\n\t): Promise<IContainer> {\n\t\tif (this._documentCreated) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Only one container/document can be created. To load the container/document use loadContainer\",\n\t\t\t);\n\t\t}\n\t\tconst loader = this.createLoader([[defaultCodeDetails, entryPoint]], loaderProps);\n\t\treturn loader.createDetachedContainer(defaultCodeDetails);\n\t}\n\n\t/**\n\t * {@inheritdoc ITestObjectProvider.attachDetachedContainer}\n\t */\n\tpublic async attachDetachedContainer(container: IContainer): Promise<void> {\n\t\tif (this._documentCreated) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Only one container/document can be created. To load the container/document use loadContainer\",\n\t\t\t);\n\t\t}\n\t\tawait container.attach(this.driver.createCreateNewRequest(this.documentId));\n\t\tthis._documentCreated = true;\n\t\tthis.updateDocumentId(container.resolvedUrl);\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.loadContainer}\n\t */\n\tpublic async loadContainer(\n\t\tentryPoint: fluidEntryPoint,\n\t\tloaderProps?: Partial<ILoaderProps>,\n\t\trequestHeader?: IRequestHeader,\n\t\tpendingState?: string,\n\t): Promise<IContainer> {\n\t\tconst loader = this.createLoader([[defaultCodeDetails, entryPoint]], loaderProps);\n\t\treturn this.resolveContainer(loader, requestHeader, pendingState);\n\t}\n\n\tprivate async resolveContainer(\n\t\tloader: ILoader,\n\t\theaders?: IRequestHeader,\n\t\tpendingLocalState?: string,\n\t): Promise<IContainer> {\n\t\treturn loader.resolve(\n\t\t\t{\n\t\t\t\turl: await this.driver.createContainerUrl(this.documentId),\n\t\t\t\theaders,\n\t\t\t},\n\t\t\tpendingLocalState,\n\t\t);\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.makeTestLoader}\n\t */\n\tpublic makeTestLoader(testContainerConfig?: ITestContainerConfig): Loader {\n\t\treturn this.createLoader(\n\t\t\t[[defaultCodeDetails, this.createFluidEntryPoint(testContainerConfig)]],\n\t\t\ttestContainerConfig?.loaderProps,\n\t\t);\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.makeTestContainer}\n\t */\n\tpublic async makeTestContainer(\n\t\ttestContainerConfig?: ITestContainerConfig,\n\t): Promise<IContainer> {\n\t\tif (this._documentCreated) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Only one container/document can be created. To load the container/document use loadTestContainer\",\n\t\t\t);\n\t\t}\n\t\tconst loader = this.makeTestLoader(testContainerConfig);\n\t\tconst container = await createAndAttachContainer(\n\t\t\tdefaultCodeDetails,\n\t\t\tloader,\n\t\t\tthis.driver.createCreateNewRequest(this.documentId),\n\t\t);\n\t\tthis._documentCreated = true;\n\t\t// r11s driver will generate a new ID for the new container.\n\t\t// update the document ID with the actual ID of the attached container.\n\t\tthis.updateDocumentId(container.resolvedUrl);\n\t\treturn container;\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.loadTestContainer}\n\t */\n\tpublic async loadTestContainer(\n\t\ttestContainerConfig?: ITestContainerConfig,\n\t\trequestHeader?: IRequestHeader,\n\t\tpendingLocalState?: string,\n\t): Promise<IContainer> {\n\t\tconst loader = this.makeTestLoader(testContainerConfig);\n\n\t\tconst container = await this.resolveContainer(loader, requestHeader, pendingLocalState);\n\t\tawait this.waitContainerToCatchUp(container);\n\n\t\treturn container;\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.reset}\n\t */\n\tpublic reset(): void {\n\t\tthis._loaderContainerTracker.reset();\n\t\tthis._documentServiceFactory = undefined;\n\t\tthis._urlResolver = undefined;\n\t\tthis._documentIdStrategy.reset();\n\t\tconst logError = getUnexpectedLogErrorException(this._tracker);\n\t\tif (logError) {\n\t\t\tthrow logError;\n\t\t}\n\t\tthis._logger = undefined;\n\t\tthis._tracker = undefined;\n\t\tthis._documentCreated = false;\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.ensureSynchronized}\n\t */\n\tpublic async ensureSynchronized(...containers: IContainer[]): Promise<void> {\n\t\treturn this._loaderContainerTracker.ensureSynchronized(...containers);\n\t}\n\n\tprivate async waitContainerToCatchUp(container: IContainer): Promise<boolean> {\n\t\t// The original waitContainerToCatchUp() from container loader uses either Container.resume()\n\t\t// or Container.connect() as part of its implementation. However, resume() was deprecated\n\t\t// and eventually replaced with connect(). To avoid issues during LTS compatibility testing\n\t\t// with older container versions issues, we use resume() when connect() is unavailable.\n\t\tif ((container as any).connect === undefined) {\n\t\t\t(container as any).connect = (container as any).resume;\n\t\t}\n\n\t\treturn waitContainerToCatchUp_original(container);\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.updateDocumentId}\n\t */\n\tpublic updateDocumentId(resolvedUrl: IResolvedUrl | undefined): void {\n\t\tthis._documentIdStrategy.update(resolvedUrl);\n\t\tthis.logger.send({\n\t\t\tcategory: \"generic\",\n\t\t\teventName: \"DocumentIdUpdated\",\n\t\t\t...getUrlTelemetryProps(resolvedUrl),\n\t\t});\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.resetLoaderContainerTracker}\n\t */\n\tpublic resetLoaderContainerTracker(syncSummarizerClients: boolean = false): void {\n\t\tthis._loaderContainerTracker.reset();\n\t\tthis._loaderContainerTracker = new LoaderContainerTracker(syncSummarizerClients);\n\t}\n}\n\n/**\n * Implements {@link ITestObjectProvider}, but uses different versions to create and load containers.\n *\n * @internal\n */\nexport class TestObjectProviderWithVersionedLoad implements ITestObjectProvider {\n\t/**\n\t * {@inheritDoc ITestObjectProvider.\"type\"}\n\t */\n\tpublic readonly type = \"TestObjectProviderWithVersionedLoad\";\n\tprivate _loaderContainerTracker = new LoaderContainerTracker();\n\tprivate _logger: ITelemetryBaseLogger | undefined;\n\tprivate _tracker: EventAndErrorTrackingLogger | undefined;\n\tprivate readonly _documentIdStrategy: IDocumentIdStrategy;\n\tprivate _documentServiceFactory: IDocumentServiceFactory | undefined;\n\tprivate _urlResolver: IUrlResolver | undefined;\n\t// Since documentId doesn't change we can only create/make one container. Call the load functions instead.\n\tprivate _documentCreated = false;\n\n\t/**\n\t * Used to determine which APIs to use when creating a loader.\n\t *\n\t * The first load will always use the create APIs, and then useCreateApi will be set to false to ensure all\n\t * subsequent loads use the load APIs.\n\t */\n\tprivate useCreateApi: boolean = true;\n\n\tconstructor(\n\t\tprivate readonly LoaderConstructorForCreating: typeof Loader,\n\t\tprivate readonly LoaderConstructorForLoading: typeof Loader,\n\t\tprivate readonly driverForCreating: ITestDriver,\n\t\tprivate readonly driverForLoading: ITestDriver,\n\t\tprivate readonly createFluidEntryPointForCreating: (\n\t\t\ttestContainerConfig?: ITestContainerConfig,\n\t\t) => fluidEntryPoint,\n\t\tprivate readonly createFluidEntryPointForLoading: (\n\t\t\ttestContainerConfig?: ITestContainerConfig,\n\t\t) => fluidEntryPoint,\n\t\tprivate readonly telemetryProps?: ITelemetryLoggerPropertyBags,\n\t) {\n\t\tthis._documentIdStrategy = getDocumentIdStrategy(driverForCreating.type);\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.logger}\n\t */\n\tpublic get logger(): ITelemetryBaseLogger {\n\t\tif (this._logger === undefined) {\n\t\t\tthis._tracker = new EventAndErrorTrackingLogger(getTestLogger?.());\n\t\t\tthis._logger = createChildLogger({\n\t\t\t\tlogger: this._tracker,\n\t\t\t\tproperties: this.telemetryProps,\n\t\t\t});\n\t\t}\n\t\treturn this._logger;\n\t}\n\n\tpublic get tracker(): EventAndErrorTrackingLogger {\n\t\tvoid this.logger;\n\t\tassert(this._tracker !== undefined, \"should be initialized\");\n\t\treturn this._tracker;\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.documentServiceFactory}\n\t */\n\tpublic get documentServiceFactory(): IDocumentServiceFactory {\n\t\tif (!this._documentServiceFactory) {\n\t\t\tthis._documentServiceFactory = this.driverForCreating.createDocumentServiceFactory();\n\t\t}\n\t\treturn this._documentServiceFactory;\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.urlResolver}\n\t */\n\tpublic get urlResolver(): IUrlResolver {\n\t\tif (!this._urlResolver) {\n\t\t\tthis._urlResolver = this.driverForCreating.createUrlResolver();\n\t\t}\n\t\treturn this._urlResolver;\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.documentId}\n\t */\n\tpublic get documentId(): string {\n\t\treturn this._documentIdStrategy.get();\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.defaultCodeDetails}\n\t */\n\tpublic get defaultCodeDetails(): IFluidCodeDetails {\n\t\treturn defaultCodeDetails;\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.opProcessingController}\n\t */\n\tpublic get opProcessingController(): IOpProcessingController {\n\t\treturn this._loaderContainerTracker;\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.driver}\n\t */\n\tpublic get driver(): ITestDriver {\n\t\treturn this.useCreateApi ? this.driverForCreating : this.driverForLoading;\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.createFluidEntryPoint}\n\t */\n\tpublic get createFluidEntryPoint(): (\n\t\ttestContainerConfig?: ITestContainerConfig,\n\t) => fluidEntryPoint {\n\t\treturn this.useCreateApi\n\t\t\t? this.createFluidEntryPointForCreating\n\t\t\t: this.createFluidEntryPointForLoading;\n\t}\n\n\tprivate createLoaderForCreating(\n\t\tpackageEntries: Iterable<[IFluidCodeDetails, fluidEntryPoint]>,\n\t\tloaderProps?: Partial<ILoaderProps>,\n\t): Loader {\n\t\tconst logger = createMultiSinkLogger({\n\t\t\tloggers: [this.logger, loaderProps?.logger],\n\t\t});\n\n\t\tconst loader = new this.LoaderConstructorForCreating({\n\t\t\t...loaderProps,\n\t\t\tlogger,\n\t\t\tcodeLoader: loaderProps?.codeLoader ?? new LocalCodeLoader(packageEntries),\n\t\t\turlResolver: loaderProps?.urlResolver ?? this.urlResolver,\n\t\t\tdocumentServiceFactory:\n\t\t\t\tloaderProps?.documentServiceFactory ?? this.documentServiceFactory,\n\t\t});\n\n\t\tthis._loaderContainerTracker.add(loader);\n\t\treturn loader;\n\t}\n\n\tprivate createLoaderForLoading(\n\t\tpackageEntries: Iterable<[IFluidCodeDetails, fluidEntryPoint]>,\n\t\tloaderProps?: Partial<ILoaderProps>,\n\t): Loader {\n\t\tconst logger = createMultiSinkLogger({\n\t\t\tloggers: [this.logger, loaderProps?.logger],\n\t\t});\n\n\t\tconst loader = new this.LoaderConstructorForLoading({\n\t\t\t...loaderProps,\n\t\t\tlogger,\n\t\t\tcodeLoader: loaderProps?.codeLoader ?? new LocalCodeLoader(packageEntries),\n\t\t\turlResolver: loaderProps?.urlResolver ?? this.urlResolver,\n\t\t\tdocumentServiceFactory:\n\t\t\t\tloaderProps?.documentServiceFactory ?? this.documentServiceFactory,\n\t\t});\n\n\t\tthis._loaderContainerTracker.add(loader);\n\t\treturn loader;\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.createLoader}\n\t */\n\tpublic createLoader(\n\t\tpackageEntries: Iterable<[IFluidCodeDetails, fluidEntryPoint]>,\n\t\tloaderProps?: Partial<ILoaderProps>,\n\t\tforceUseCreateVersion = false,\n\t): Loader {\n\t\tconst useCreateVersion = forceUseCreateVersion === true || this.useCreateApi;\n\t\tif (this.useCreateApi) {\n\t\t\t// After we create the first loader, we can set this.useCreateApi to false.\n\t\t\tthis.useCreateApi = false;\n\t\t}\n\t\tif (useCreateVersion) {\n\t\t\treturn this.createLoaderForCreating(packageEntries, loaderProps);\n\t\t}\n\t\treturn this.createLoaderForLoading(packageEntries, loaderProps);\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.createContainer}\n\t */\n\tpublic async createContainer(\n\t\tentryPoint: fluidEntryPoint,\n\t\tloaderProps?: Partial<ILoaderProps>,\n\t): Promise<IContainer> {\n\t\tif (this._documentCreated) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Only one container/document can be created. To load the container/document use loadContainer\",\n\t\t\t);\n\t\t}\n\t\tconst loader = this.createLoader([[defaultCodeDetails, entryPoint]], loaderProps);\n\t\tconst container = await createAndAttachContainer(\n\t\t\tdefaultCodeDetails,\n\t\t\tloader,\n\t\t\tthis.driverForCreating.createCreateNewRequest(this.documentId),\n\t\t);\n\t\tthis._documentCreated = true;\n\t\t// r11s driver will generate a new ID for the new container.\n\t\t// update the document ID with the actual ID of the attached container.\n\t\tthis.updateDocumentId(container.resolvedUrl);\n\t\treturn container;\n\t}\n\n\t/**\n\t * {@inheritdoc ITestObjectProvider.createDetachedContainer}\n\t */\n\tpublic async createDetachedContainer(\n\t\tentryPoint: fluidEntryPoint,\n\t\tloaderProps?: Partial<ILoaderProps> | undefined,\n\t): Promise<IContainer> {\n\t\tif (this._documentCreated) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Only one container/document can be created. To load the container/document use loadContainer\",\n\t\t\t);\n\t\t}\n\t\tconst loader = this.createLoader([[defaultCodeDetails, entryPoint]], loaderProps);\n\t\treturn loader.createDetachedContainer(defaultCodeDetails);\n\t}\n\n\t/**\n\t * {@inheritdoc ITestObjectProvider.attachDetachedContainer}\n\t */\n\tpublic async attachDetachedContainer(container: IContainer): Promise<void> {\n\t\tif (this._documentCreated) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Only one container/document can be created. To load the container/document use loadContainer\",\n\t\t\t);\n\t\t}\n\t\tawait container.attach(this.driver.createCreateNewRequest(this.documentId));\n\t\tthis._documentCreated = true;\n\t\tthis.updateDocumentId(container.resolvedUrl);\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.loadContainer}\n\t */\n\tpublic async loadContainer(\n\t\tentryPoint: fluidEntryPoint,\n\t\tloaderProps?: Partial<ILoaderProps>,\n\t\trequestHeader?: IRequestHeader,\n\t\tpendingState?: string,\n\t): Promise<IContainer> {\n\t\tconst driver = this.useCreateApi ? this.driverForCreating : this.driverForLoading;\n\t\tconst loader = this.createLoader([[defaultCodeDetails, entryPoint]], loaderProps);\n\t\treturn this.resolveContainer(loader, requestHeader, driver, pendingState);\n\t}\n\n\tprivate async resolveContainer(\n\t\tloader: ILoader,\n\t\theaders?: IRequestHeader,\n\t\tdriver?: ITestDriver,\n\t\tpendingLocalState?: string,\n\t): Promise<IContainer> {\n\t\treturn loader.resolve(\n\t\t\t{\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\turl: await driver!.createContainerUrl(this.documentId),\n\t\t\t\theaders,\n\t\t\t},\n\t\t\tpendingLocalState,\n\t\t);\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.makeTestLoader}\n\t */\n\tpublic makeTestLoader(testContainerConfig?: ITestContainerConfig): Loader {\n\t\treturn this.createLoader(\n\t\t\t[[defaultCodeDetails, this.createFluidEntryPoint(testContainerConfig)]],\n\t\t\ttestContainerConfig?.loaderProps,\n\t\t\ttestContainerConfig?.forceUseCreateVersion,\n\t\t);\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.makeTestContainer}\n\t */\n\tpublic async makeTestContainer(\n\t\ttestContainerConfig?: ITestContainerConfig,\n\t): Promise<IContainer> {\n\t\tif (this._documentCreated) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Only one container/document can be created. To load the container/document use loadTestContainer\",\n\t\t\t);\n\t\t}\n\t\tconst loader = this.createLoader(\n\t\t\t[[defaultCodeDetails, this.createFluidEntryPoint(testContainerConfig)]],\n\t\t\ttestContainerConfig?.loaderProps,\n\t\t);\n\t\tconst container = await createAndAttachContainer(\n\t\t\tdefaultCodeDetails,\n\t\t\tloader,\n\t\t\tthis.driverForCreating.createCreateNewRequest(this.documentId),\n\t\t);\n\t\tthis._documentCreated = true;\n\t\t// r11s driver will generate a new ID for the new container.\n\t\t// update the document ID with the actual ID of the attached container.\n\t\tthis.updateDocumentId(container.resolvedUrl);\n\t\treturn container;\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.loadTestContainer}\n\t */\n\tpublic async loadTestContainer(\n\t\ttestContainerConfig?: ITestContainerConfig,\n\t\trequestHeader?: IRequestHeader,\n\t\tpendingLocalState?: string,\n\t): Promise<IContainer> {\n\t\t// Keep track of which Loader we are about to use so we can pass the correct driver through\n\t\tconst driver = this.useCreateApi ? this.driverForCreating : this.driverForLoading;\n\t\tconst loader = this.makeTestLoader(testContainerConfig);\n\t\tconst container = await this.resolveContainer(\n\t\t\tloader,\n\t\t\trequestHeader,\n\t\t\tdriver,\n\t\t\tpendingLocalState,\n\t\t);\n\t\tawait this.waitContainerToCatchUp(container);\n\n\t\treturn container;\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.reset}\n\t */\n\tpublic reset(): void {\n\t\tthis.useCreateApi = true;\n\t\tthis._loaderContainerTracker.reset();\n\t\tthis._logger = undefined;\n\t\tthis._tracker = undefined;\n\t\tthis._documentServiceFactory = undefined;\n\t\tthis._urlResolver = undefined;\n\t\tthis._documentIdStrategy.reset();\n\t\tconst logError = getUnexpectedLogErrorException(this._tracker);\n\t\tif (logError) {\n\t\t\tthrow logError;\n\t\t}\n\t\tthis._documentCreated = false;\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.ensureSynchronized}\n\t */\n\tpublic async ensureSynchronized(...containers: IContainer[]): Promise<void> {\n\t\treturn this._loaderContainerTracker.ensureSynchronized(...containers);\n\t}\n\n\tprivate async waitContainerToCatchUp(container: IContainer): Promise<boolean> {\n\t\t// The original waitContainerToCatchUp() from container loader uses either Container.resume()\n\t\t// or Container.connect() as part of its implementation. However, resume() was deprecated\n\t\t// and eventually replaced with connect(). To avoid issues during LTS compatibility testing\n\t\t// with older container versions issues, we use resume() when connect() is unavailable.\n\t\tif ((container as any).connect === undefined) {\n\t\t\t(container as any).connect = (container as any).resume;\n\t\t}\n\n\t\treturn waitContainerToCatchUp_original(container);\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.updateDocumentId}\n\t */\n\tpublic updateDocumentId(resolvedUrl: IResolvedUrl | undefined): void {\n\t\tthis._documentIdStrategy.update(resolvedUrl);\n\t\tthis.logger.send({\n\t\t\tcategory: \"generic\",\n\t\t\teventName: \"DocumentIdUpdated\",\n\t\t\t...getUrlTelemetryProps(resolvedUrl),\n\t\t});\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.resetLoaderContainerTracker}\n\t */\n\tpublic resetLoaderContainerTracker(syncSummarizerClients: boolean = false): void {\n\t\tthis._loaderContainerTracker.reset();\n\t\tthis._loaderContainerTracker = new LoaderContainerTracker(syncSummarizerClients);\n\t}\n}\n\n/**\n * Get identifying information for a resolved URL.\n * @remarks BEWARE: this function is only appropriate for usage in tests, as it logs unhashed document IDs,\n * which is a privacy concern for production scenarios.\n */\nfunction getUrlTelemetryProps(\n\tresolvedUrl: IResolvedUrl | undefined,\n): ITelemetryBaseProperties {\n\tif (!resolvedUrl) {\n\t\treturn {};\n\t}\n\n\tconst props: Record<string, TelemetryBaseEventPropertyType> = {\n\t\turl: resolvedUrl.url,\n\t\tid: resolvedUrl.id,\n\t};\n\n\tif (isOdspResolvedUrl(resolvedUrl)) {\n\t\tObject.assign(props, {\n\t\t\tsiteUrl: resolvedUrl.siteUrl,\n\t\t\tdriveId: resolvedUrl.driveId,\n\t\t\titemId: resolvedUrl.itemId,\n\t\t});\n\t}\n\n\treturn tagData(TelemetryDataTag.UserData, props);\n}\n\n/** Summarize the event with just the primary properties, for succinct output in case of test failure */\nconst primaryEventProps = ({\n\tcategory,\n\teventName,\n\terror,\n\terrorType,\n}: ITelemetryBaseEvent): Partial<ITelemetryBaseEvent> => ({\n\tcategory,\n\teventName,\n\terror,\n\terrorType,\n\t[\"...\"]: \"*** Additional properties not shown, see full log for details ***\",\n});\n\n/**\n * @internal\n */\nexport function getUnexpectedLogErrorException(\n\tlogger: IEventAndErrorTrackingLogger | undefined,\n\tprefix?: string,\n): Error | undefined {\n\tif (logger === undefined) {\n\t\treturn;\n\t}\n\tconst results = logger.reportAndClearTrackedEvents();\n\tif (results.unexpectedErrors.length > 0) {\n\t\treturn new Error(\n\t\t\t`${prefix ?? \"\"}Unexpected Errors in Logs:\\n${JSON.stringify(\n\t\t\t\tresults.unexpectedErrors.map(primaryEventProps),\n\t\t\t\tundefined,\n\t\t\t\t2,\n\t\t\t)}`,\n\t\t);\n\t}\n\tif (results.expectedNotFound.length > 0) {\n\t\treturn new Error(\n\t\t\t`${prefix ?? \"\"}Expected Events not found:\\n${JSON.stringify(\n\t\t\t\tresults.expectedNotFound,\n\t\t\t\tundefined,\n\t\t\t\t2,\n\t\t\t)}`,\n\t\t);\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"testObjectProvider.js","sourceRoot":"","sources":["../src/testObjectProvider.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITestDriver, TestDriverTypes } from \"@fluid-internal/test-driver-definitions\";\nimport {\n\tIContainer,\n\tIFluidCodeDetails,\n\tIHostLoader,\n\tILoader,\n} from \"@fluidframework/container-definitions/internal\";\nimport {\n\tILoaderProps,\n\tLoader,\n\twaitContainerToCatchUp as waitContainerToCatchUp_original,\n} from \"@fluidframework/container-loader/internal\";\nimport type { IContainerRuntimeOptionsInternal } from \"@fluidframework/container-runtime/internal\";\nimport {\n\tIRequestHeader,\n\tITelemetryBaseEvent,\n\tITelemetryBaseLogger,\n\tITelemetryBaseProperties,\n\tTelemetryBaseEventPropertyType,\n} from \"@fluidframework/core-interfaces\";\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport {\n\tIDocumentServiceFactory,\n\tIResolvedUrl,\n\tIUrlResolver,\n} from \"@fluidframework/driver-definitions/internal\";\nimport { isOdspResolvedUrl } from \"@fluidframework/odsp-driver/internal\";\nimport type { MinimumVersionForCollab } from \"@fluidframework/runtime-definitions/internal\";\nimport {\n\ttype ITelemetryGenericEventExt,\n\tcreateChildLogger,\n\tcreateMultiSinkLogger,\n\ttype ITelemetryLoggerPropertyBags,\n\tTelemetryDataTag,\n\ttagData,\n} from \"@fluidframework/telemetry-utils/internal\";\nimport { v4 as uuid } from \"uuid\";\n\nimport { LoaderContainerTracker } from \"./loaderContainerTracker.js\";\nimport { LocalCodeLoader, fluidEntryPoint } from \"./localCodeLoader.js\";\nimport { createAndAttachContainer } from \"./localLoader.js\";\nimport { isNonEmptyArray } from \"./nonEmptyArrayType.js\";\nimport { ChannelFactoryRegistry } from \"./testFluidObject.js\";\n\nconst defaultCodeDetails: IFluidCodeDetails = {\n\tpackage: \"defaultTestPackage\",\n\tconfig: {},\n};\n\n/**\n * Exposes fine-grained control over the Container's inbound and outbound op queues\n *\n * @legacy @beta\n */\nexport interface IOpProcessingController {\n\t/**\n\t * Process all ops sitting in the inbound queue, leaving the inbound queue paused afterwards\n\t * @param containers - optional subset of all open containers\n\t */\n\tprocessIncoming(...containers: IContainer[]): Promise<void>;\n\t/**\n\t * Process all ops sitting in the outbound queue, leaving the inbound queue paused afterwards.\n\t * Also waits for the outbound ops to arrive in the inbound queue.\n\t * @param containers - optional subset of all open containers\n\t */\n\tprocessOutgoing(...containers: IContainer[]): Promise<void>;\n\t/**\n\t * Process all queue activities, to prepare for fine-grained control via processIncoming and processOutgoing\n\t * @param containers - optional subset of all open containers\n\t */\n\tpauseProcessing(...containers: IContainer[]): Promise<void>;\n\t/**\n\t * Resume all queue activities for normal operation of the container\n\t * @param containers - optional subset of all open containers\n\t */\n\tresumeProcessing(...containers: IContainer[]): void;\n}\n\n/**\n * @internal\n */\nexport interface ITestObjectProvider {\n\t/**\n\t * Indicates which type of test object provider is being used.\n\t */\n\ttype: \"TestObjectProvider\" | \"TestObjectProviderWithVersionedLoad\";\n\n\t/**\n\t * The document id to retrieve or create containers\n\t */\n\tdocumentId: string;\n\n\t/**\n\t * Creates the document service after extracting different endpoints URLs from a resolved URL.\n\t */\n\tdocumentServiceFactory: IDocumentServiceFactory;\n\n\t/**\n\t * Test driver used to create the IDocumentServiceFactory. Varies depending on the test type.\n\t */\n\tdriver: ITestDriver;\n\n\t/**\n\t * Logger used to track expected and unexpected events.\n\t */\n\tlogger: ITelemetryBaseLogger;\n\n\t/**\n\t * Logger used to track expected and unexpected events.\n\t */\n\ttracker: IEventAndErrorTrackingLogger;\n\n\t/**\n\t * Used to create a url for the created container with any data store path given in the relative url.\n\t */\n\turlResolver: IUrlResolver;\n\n\t/**\n\t * Default IFluidCodeDetails used to create containers.\n\t */\n\tdefaultCodeDetails: IFluidCodeDetails;\n\n\t/**\n\t * Contains functions to pause/resume op processing.\n\t */\n\topProcessingController: IOpProcessingController;\n\n\t/**\n\t * Represents the entry point for a Fluid container.\n\t */\n\tcreateFluidEntryPoint: (testContainerConfig?: ITestContainerConfig) => fluidEntryPoint;\n\n\t/**\n\t * Create a loader. Containers created/loaded through this loader will be added to the OpProcessingController.\n\t *\n\t * Only the version of the loader will vary based on compat config. The version of\n\t * containerRuntime/dataRuntime used in fluidEntryPoint will be used as is from what is passed in.\n\t *\n\t * @param packageEntries - list of code details and fluidEntryPoint pairs.\n\t * @param loaderProps - Optional loader properties\n\t * @param forceUseCreateVersion - For Cross-Client compat testing, create a loader based on the create version\n\t */\n\tcreateLoader(\n\t\tpackageEntries: Iterable<[IFluidCodeDetails, fluidEntryPoint]>,\n\t\tloaderProps?: Partial<ILoaderProps>,\n\t\tforceUseCreateVersion?: boolean,\n\t): IHostLoader;\n\n\t/**\n\t * Create a container using a default document id and code details.\n\t * Container created is automatically added to the OpProcessingController to manage op flow\n\t *\n\t * Only the version of the loader will vary based on compat config. The version of\n\t * containerRuntime/dataRuntime used in fluidEntryPoint will be used as is from what is passed in.\n\t *\n\t * @param packageEntries - list of code details and fluidEntryPoint pairs.\n\t */\n\n\tcreateContainer(\n\t\tentryPoint: fluidEntryPoint,\n\t\tloaderProps?: Partial<ILoaderProps>,\n\t): Promise<IContainer>;\n\n\t/**\n\t * Create a detached container much like createContainer, but without attaching it to the document service.\n\t */\n\tcreateDetachedContainer(\n\t\tentryPoint: fluidEntryPoint,\n\t\tloaderProps?: Partial<ILoaderProps>,\n\t): Promise<IContainer>;\n\n\t/**\n\t * Attaches a detached container to the document service.\n\t */\n\tattachDetachedContainer(container: IContainer): Promise<void>;\n\n\t/**\n\t * Loads a container using the default document id\n\t */\n\tloadContainer(\n\t\tentryPoint: fluidEntryPoint,\n\t\tloaderProps?: Partial<ILoaderProps>,\n\t\trequestHeader?: IRequestHeader,\n\t\tpendingLocalState?: string,\n\t): Promise<IContainer>;\n\n\t/**\n\t * Make a test loader. Containers created/loaded through this loader will be added to the OpProcessingController.\n\t * The version of the loader/containerRuntime/dataRuntime may vary based on compat config of the current run\n\t * @param testContainerConfig - optional configuring the test Container\n\t */\n\tmakeTestLoader(testContainerConfig?: ITestContainerConfig): IHostLoader;\n\n\t/**\n\t * Make a container using a default document id and code details\n\t * Container loaded is automatically added to the OpProcessingController to manage op flow\n\t * @param testContainerConfig - optional configuring the test Container\n\t */\n\tmakeTestContainer(testContainerConfig?: ITestContainerConfig): Promise<IContainer>;\n\n\t/**\n\t * Load a container using a default document id and code details.\n\t * IContainer loaded is automatically added to the OpProcessingController to manage op flow\n\t * @param testContainerConfig - optional configuring the test Container\n\t * @param requestHeader - optional headers to be supplied to the loader\n\t */\n\tloadTestContainer(\n\t\ttestContainerConfig?: ITestContainerConfig,\n\t\trequestHeader?: IRequestHeader,\n\t\tpendingLocalState?: string,\n\t): Promise<IContainer>;\n\n\t/**\n\t * Update the document ID from the resolved container's URL and reset the ID property\n\t */\n\tupdateDocumentId(url: IResolvedUrl | undefined): void;\n\n\t/**\n\t * Make sure all the tracked containers are synchronized.\n\t */\n\tensureSynchronized(...containers: IContainer[]): Promise<void>;\n\n\t/**\n\t * Reset the tracker, closing all containers and stop tracking them.\n\t */\n\tresetLoaderContainerTracker(syncSummarizerClients?: boolean);\n\n\t/**\n\t * Resets and closes all tracked containers and class states.\n\t */\n\treset(): void;\n}\n\n/**\n * @internal\n */\nexport enum DataObjectFactoryType {\n\tPrimed, // default\n\tTest,\n}\n\n/**\n * @internal\n */\nexport interface ITestContainerConfig {\n\t/** TestFluidDataObject instead of PrimedDataStore */\n\tfluidDataObjectType?: DataObjectFactoryType;\n\n\t/** An array of channel name and DDS factory pair to create on container creation time */\n\tregistry?: ChannelFactoryRegistry;\n\n\t/** Container runtime options for the container instance */\n\truntimeOptions?: IContainerRuntimeOptionsInternal;\n\n\t/** Whether this runtime should be instantiated using a mixed-in attributor class */\n\tenableAttribution?: boolean;\n\n\t/** For Cross-Client compat testing, load using the create version (e.g. use this to get a Summarizer on the create version) */\n\tforceUseCreateVersion?: true;\n\n\t/** Loader options for the loader used to create containers */\n\tloaderProps?: Partial<ILoaderProps>;\n\n\t/**\n\t * Minimum version of the FF runtime that is required to collaborate on new documents.\n\t * See {@link @fluidframework/container-runtime#LoadContainerRuntimeParams.minVersionForCollab} for more details.\n\t */\n\tminVersionForCollab?: MinimumVersionForCollab | undefined;\n}\n\n/**\n * @internal\n */\nexport const createDocumentId = (): string => uuid();\n\n/**\n * Used to retrieve, update, and reset document id based on the type of driver being used.\n *\n * @internal\n */\nexport interface IDocumentIdStrategy {\n\t/**\n\t * Get document id\n\t */\n\tget(): string;\n\t/**\n\t * Update the document ID from the resolved container's URL and reset the ID property\n\t */\n\tupdate(resolvedUrl?: IResolvedUrl): void;\n\t/**\n\t * Reset document id to a new document id\n\t */\n\treset(): void;\n}\n\n/**\n * Document ID is treated differently by test drivers. The key difference is in generating\n * a new container ID and accessing the container in multi-instance test cases.\n */\nfunction getDocumentIdStrategy(type?: TestDriverTypes): IDocumentIdStrategy {\n\tlet documentId = createDocumentId();\n\tswitch (type) {\n\t\tcase \"odsp\":\n\t\t\treturn {\n\t\t\t\tget: () => documentId,\n\t\t\t\tupdate: () => {}, // do not update the document ID in odsp test cases\n\t\t\t\treset: () => {\n\t\t\t\t\tdocumentId = createDocumentId();\n\t\t\t\t},\n\t\t\t};\n\t\tdefault:\n\t\t\treturn {\n\t\t\t\tget: () => documentId,\n\t\t\t\tupdate: (resolvedUrl?: IResolvedUrl) => {\n\t\t\t\t\t// Extract the document ID from the resolved container's URL and reset the ID property\n\t\t\t\t\tdocumentId = resolvedUrl?.id ?? documentId;\n\t\t\t\t},\n\t\t\t\treset: () => {\n\t\t\t\t\tdocumentId = createDocumentId();\n\t\t\t\t},\n\t\t\t};\n\t}\n}\n\n/** @internal */\nexport interface IEventAndErrorTrackingLogger {\n\tregisterExpectedEvent: (...orderedExpectedEvents: ITelemetryGenericEventExt[]) => void;\n\treportAndClearTrackedEvents: () => {\n\t\texpectedNotFound: { index: number; event: ITelemetryGenericEventExt }[];\n\t\tunexpectedErrors: ITelemetryBaseEvent[];\n\t};\n}\n\n/**\n * This class tracks events. It allows specifying expected events, which will be looked for in order.\n * It also tracks all unexpected errors.\n * At any point you call reportAndClearTrackedEvents which will provide all unexpected errors, and\n * any expected events that have not occurred.\n * @internal\n */\nexport class EventAndErrorTrackingLogger\n\timplements ITelemetryBaseLogger, IEventAndErrorTrackingLogger\n{\n\t/**\n\t * Even if these error events are logged, tests should still be allowed to pass\n\t * Additionally, if downgrade is true, then log as generic (e.g. to avoid polluting the e2e test logs)\n\t */\n\tprivate readonly allowedErrors: { eventName: string; downgrade?: true }[] = [\n\t\t// This log was removed in current version as unnecessary, but it's still present in previous versions\n\t\t{\n\t\t\teventName: \"fluid:telemetry:Container:NoRealStorageInDetachedContainer\",\n\t\t\tdowngrade: true,\n\t\t},\n\t\t// This log's category changes depending on the op latency. test results shouldn't be affected but if we see lots we'd like an alert from the logs.\n\t\t{ eventName: \"fluid:telemetry:OpRoundtripTime\" },\n\t];\n\n\tconstructor(private readonly baseLogger?: ITelemetryBaseLogger) {}\n\n\tprivate readonly expectedEvents: { index: number; event: ITelemetryGenericEventExt }[] = [];\n\tprivate readonly unexpectedErrors: ITelemetryBaseEvent[] = [];\n\n\tpublic registerExpectedEvent(...orderedExpectedEvents: ITelemetryGenericEventExt[]): void {\n\t\tif (this.expectedEvents.length !== 0) {\n\t\t\t// we don't have to error here. just no reason not to. given the events must be\n\t\t\t// ordered it could be tricky to figure out problems around multiple registrations.\n\t\t\tthrow new Error(\n\t\t\t\t\"Expected events already registered.\\n\" +\n\t\t\t\t\t\"Call reportAndClearTrackedEvents to clear them before registering more\",\n\t\t\t);\n\t\t}\n\t\tthis.expectedEvents.push(\n\t\t\t...orderedExpectedEvents.map((event, index) => ({ index, event })),\n\t\t);\n\t}\n\n\tsend(event: ITelemetryBaseEvent): void {\n\t\tif (isNonEmptyArray(this.expectedEvents)) {\n\t\t\tconst ee = this.expectedEvents[0].event;\n\t\t\tif (ee.eventName === event.eventName) {\n\t\t\t\tlet matches = true;\n\t\t\t\tfor (const key of Object.keys(ee)) {\n\t\t\t\t\tif (ee[key] !== event[key]) {\n\t\t\t\t\t\tmatches = false;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (matches) {\n\t\t\t\t\t// we found an expected event\n\t\t\t\t\t// so remove it from the list of expected events\n\t\t\t\t\t// and if it is an error, change it to generic\n\t\t\t\t\t// this helps keep our telemetry clear of\n\t\t\t\t\t// expected errors.\n\t\t\t\t\tthis.expectedEvents.shift();\n\t\t\t\t\tif (event.category === \"error\") {\n\t\t\t\t\t\tevent.category = \"generic\";\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (event.category === \"error\") {\n\t\t\t// Check to see if this error is allowed and if its category should be downgraded\n\t\t\tconst allowedError = this.allowedErrors.find(\n\t\t\t\t({ eventName }) => eventName === event.eventName,\n\t\t\t);\n\n\t\t\tif (allowedError === undefined) {\n\t\t\t\tthis.unexpectedErrors.push(event);\n\t\t\t} else if (allowedError.downgrade) {\n\t\t\t\tevent.category = \"generic\";\n\t\t\t}\n\t\t}\n\n\t\tthis.baseLogger?.send(event);\n\t}\n\n\tpublic reportAndClearTrackedEvents(): {\n\t\texpectedNotFound: { index: number; event: ITelemetryGenericEventExt }[];\n\t\tunexpectedErrors: ITelemetryBaseEvent[];\n\t} {\n\t\tconst expectedNotFound = this.expectedEvents.splice(0, this.expectedEvents.length);\n\t\tconst unexpectedErrors = this.unexpectedErrors.splice(0, this.unexpectedErrors.length);\n\t\treturn {\n\t\t\texpectedNotFound,\n\t\t\tunexpectedErrors,\n\t\t};\n\t}\n}\n\n/**\n * Shared base class for test object provider. Contain code for loader and container creation and loading\n * @internal\n */\nexport class TestObjectProvider implements ITestObjectProvider {\n\t/**\n\t * {@inheritDoc ITestObjectProvider.\"type\"}\n\t */\n\tpublic readonly type = \"TestObjectProvider\";\n\tprivate _loaderContainerTracker = new LoaderContainerTracker();\n\tprivate _documentServiceFactory: IDocumentServiceFactory | undefined;\n\tprivate _urlResolver: IUrlResolver | undefined;\n\tprivate _logger: ITelemetryBaseLogger | undefined;\n\tprivate _tracker: EventAndErrorTrackingLogger | undefined;\n\tprivate readonly _documentIdStrategy: IDocumentIdStrategy;\n\t// Since documentId doesn't change we can only create/make one container. Call the load functions instead.\n\tprivate _documentCreated = false;\n\n\t/**\n\t * Manage objects for loading and creating container, including the driver, loader, and OpProcessingController\n\t * @param createFluidEntryPoint - callback to create a fluidEntryPoint, with an optional set of channel name\n\t * and factory for TestFluidObject\n\t */\n\tconstructor(\n\t\tprivate readonly LoaderConstructor: typeof Loader,\n\t\t/**\n\t\t * {@inheritDoc ITestObjectProvider.driver}\n\t\t */\n\t\tpublic readonly driver: ITestDriver,\n\t\t/**\n\t\t * {@inheritDoc ITestObjectProvider.createFluidEntryPoint}\n\t\t */\n\t\tpublic readonly createFluidEntryPoint: (\n\t\t\ttestContainerConfig?: ITestContainerConfig,\n\t\t) => fluidEntryPoint,\n\t) {\n\t\tthis._documentIdStrategy = getDocumentIdStrategy(driver.type);\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.logger}\n\t */\n\tpublic get logger(): ITelemetryBaseLogger {\n\t\tif (this._logger === undefined) {\n\t\t\tthis._tracker = new EventAndErrorTrackingLogger(getTestLogger?.());\n\t\t\tthis._logger = createChildLogger({\n\t\t\t\tlogger: this._tracker,\n\t\t\t\tproperties: {\n\t\t\t\t\tall: {\n\t\t\t\t\t\ttestType: this.type,\n\t\t\t\t\t\tdriverType: this.driver.type,\n\t\t\t\t\t\tdriverEndpointName: this.driver.endpointName,\n\t\t\t\t\t\tdriverTenantName: this.driver.tenantName,\n\t\t\t\t\t\tdriverUserIndex: this.driver.userIndex,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t\treturn this._logger;\n\t}\n\n\tpublic get tracker(): EventAndErrorTrackingLogger {\n\t\tvoid this.logger;\n\t\tassert(this._tracker !== undefined, \"should be initialized\");\n\t\treturn this._tracker;\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.documentServiceFactory}\n\t */\n\tpublic get documentServiceFactory(): IDocumentServiceFactory {\n\t\t// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions, @typescript-eslint/prefer-nullish-coalescing -- intentional behavior\n\t\tif (!this._documentServiceFactory) {\n\t\t\tthis._documentServiceFactory = this.driver.createDocumentServiceFactory();\n\t\t}\n\t\treturn this._documentServiceFactory;\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.urlResolver}\n\t */\n\tpublic get urlResolver(): IUrlResolver {\n\t\t// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions, @typescript-eslint/prefer-nullish-coalescing -- intentional behavior\n\t\tif (!this._urlResolver) {\n\t\t\tthis._urlResolver = this.driver.createUrlResolver();\n\t\t}\n\t\treturn this._urlResolver;\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.documentId}\n\t */\n\tpublic get documentId(): string {\n\t\treturn this._documentIdStrategy.get();\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.defaultCodeDetails}\n\t */\n\tpublic get defaultCodeDetails(): IFluidCodeDetails {\n\t\treturn defaultCodeDetails;\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.opProcessingController}\n\t */\n\tpublic get opProcessingController(): IOpProcessingController {\n\t\treturn this._loaderContainerTracker;\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.createLoader}\n\t */\n\tpublic createLoader(\n\t\tpackageEntries: Iterable<[IFluidCodeDetails, fluidEntryPoint]>,\n\t\tloaderProps?: Partial<ILoaderProps>,\n\t): Loader {\n\t\tconst logger = createMultiSinkLogger({\n\t\t\tloggers: [this.logger, loaderProps?.logger],\n\t\t});\n\n\t\tconst loader = new this.LoaderConstructor({\n\t\t\t...loaderProps,\n\t\t\tlogger,\n\t\t\tcodeLoader: loaderProps?.codeLoader ?? new LocalCodeLoader(packageEntries),\n\t\t\turlResolver: loaderProps?.urlResolver ?? this.urlResolver,\n\t\t\tdocumentServiceFactory:\n\t\t\t\tloaderProps?.documentServiceFactory ?? this.documentServiceFactory,\n\t\t});\n\t\tthis._loaderContainerTracker.add(loader);\n\t\treturn loader;\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.createContainer}\n\t */\n\tpublic async createContainer(\n\t\tentryPoint: fluidEntryPoint,\n\t\tloaderProps?: Partial<ILoaderProps>,\n\t): Promise<IContainer> {\n\t\tif (this._documentCreated) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Only one container/document can be created. To load the container/document use loadContainer\",\n\t\t\t);\n\t\t}\n\t\tconst loader = this.createLoader([[defaultCodeDetails, entryPoint]], loaderProps);\n\t\tconst container = await createAndAttachContainer(\n\t\t\tdefaultCodeDetails,\n\t\t\tloader,\n\t\t\tthis.driver.createCreateNewRequest(this.documentId),\n\t\t);\n\t\tthis._documentCreated = true;\n\t\t// r11s driver will generate a new ID for the new container.\n\t\t// update the document ID with the actual ID of the attached container.\n\t\tthis.updateDocumentId(container.resolvedUrl);\n\t\treturn container;\n\t}\n\n\t/**\n\t * {@inheritdoc ITestObjectProvider.createDetachedContainer}\n\t */\n\tpublic async createDetachedContainer(\n\t\tentryPoint: fluidEntryPoint,\n\t\tloaderProps?: Partial<ILoaderProps> | undefined,\n\t): Promise<IContainer> {\n\t\tif (this._documentCreated) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Only one container/document can be created. To load the container/document use loadContainer\",\n\t\t\t);\n\t\t}\n\t\tconst loader = this.createLoader([[defaultCodeDetails, entryPoint]], loaderProps);\n\t\treturn loader.createDetachedContainer(defaultCodeDetails);\n\t}\n\n\t/**\n\t * {@inheritdoc ITestObjectProvider.attachDetachedContainer}\n\t */\n\tpublic async attachDetachedContainer(container: IContainer): Promise<void> {\n\t\tif (this._documentCreated) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Only one container/document can be created. To load the container/document use loadContainer\",\n\t\t\t);\n\t\t}\n\t\tawait container.attach(this.driver.createCreateNewRequest(this.documentId));\n\t\tthis._documentCreated = true;\n\t\tthis.updateDocumentId(container.resolvedUrl);\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.loadContainer}\n\t */\n\tpublic async loadContainer(\n\t\tentryPoint: fluidEntryPoint,\n\t\tloaderProps?: Partial<ILoaderProps>,\n\t\trequestHeader?: IRequestHeader,\n\t\tpendingState?: string,\n\t): Promise<IContainer> {\n\t\tconst loader = this.createLoader([[defaultCodeDetails, entryPoint]], loaderProps);\n\t\treturn this.resolveContainer(loader, requestHeader, pendingState);\n\t}\n\n\tprivate async resolveContainer(\n\t\tloader: ILoader,\n\t\theaders?: IRequestHeader,\n\t\tpendingLocalState?: string,\n\t): Promise<IContainer> {\n\t\treturn loader.resolve(\n\t\t\t{\n\t\t\t\turl: await this.driver.createContainerUrl(this.documentId),\n\t\t\t\theaders,\n\t\t\t},\n\t\t\tpendingLocalState,\n\t\t);\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.makeTestLoader}\n\t */\n\tpublic makeTestLoader(testContainerConfig?: ITestContainerConfig): Loader {\n\t\treturn this.createLoader(\n\t\t\t[[defaultCodeDetails, this.createFluidEntryPoint(testContainerConfig)]],\n\t\t\ttestContainerConfig?.loaderProps,\n\t\t);\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.makeTestContainer}\n\t */\n\tpublic async makeTestContainer(\n\t\ttestContainerConfig?: ITestContainerConfig,\n\t): Promise<IContainer> {\n\t\tif (this._documentCreated) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Only one container/document can be created. To load the container/document use loadTestContainer\",\n\t\t\t);\n\t\t}\n\t\tconst loader = this.makeTestLoader(testContainerConfig);\n\t\tconst container = await createAndAttachContainer(\n\t\t\tdefaultCodeDetails,\n\t\t\tloader,\n\t\t\tthis.driver.createCreateNewRequest(this.documentId),\n\t\t);\n\t\tthis._documentCreated = true;\n\t\t// r11s driver will generate a new ID for the new container.\n\t\t// update the document ID with the actual ID of the attached container.\n\t\tthis.updateDocumentId(container.resolvedUrl);\n\t\treturn container;\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.loadTestContainer}\n\t */\n\tpublic async loadTestContainer(\n\t\ttestContainerConfig?: ITestContainerConfig,\n\t\trequestHeader?: IRequestHeader,\n\t\tpendingLocalState?: string,\n\t): Promise<IContainer> {\n\t\tconst loader = this.makeTestLoader(testContainerConfig);\n\n\t\tconst container = await this.resolveContainer(loader, requestHeader, pendingLocalState);\n\t\tawait this.waitContainerToCatchUp(container);\n\n\t\treturn container;\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.reset}\n\t */\n\tpublic reset(): void {\n\t\tthis._loaderContainerTracker.reset();\n\t\tthis._documentServiceFactory = undefined;\n\t\tthis._urlResolver = undefined;\n\t\tthis._documentIdStrategy.reset();\n\t\tconst logError = getUnexpectedLogErrorException(this._tracker);\n\t\tif (logError) {\n\t\t\tthrow logError;\n\t\t}\n\t\tthis._logger = undefined;\n\t\tthis._tracker = undefined;\n\t\tthis._documentCreated = false;\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.ensureSynchronized}\n\t */\n\tpublic async ensureSynchronized(...containers: IContainer[]): Promise<void> {\n\t\treturn this._loaderContainerTracker.ensureSynchronized(...containers);\n\t}\n\n\tprivate async waitContainerToCatchUp(container: IContainer): Promise<boolean> {\n\t\t// The original waitContainerToCatchUp() from container loader uses either Container.resume()\n\t\t// or Container.connect() as part of its implementation. However, resume() was deprecated\n\t\t// and eventually replaced with connect(). To avoid issues during LTS compatibility testing\n\t\t// with older container versions issues, we use resume() when connect() is unavailable.\n\t\tif ((container as any).connect === undefined) {\n\t\t\t(container as any).connect = (container as any).resume;\n\t\t}\n\n\t\treturn waitContainerToCatchUp_original(container);\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.updateDocumentId}\n\t */\n\tpublic updateDocumentId(resolvedUrl: IResolvedUrl | undefined): void {\n\t\tthis._documentIdStrategy.update(resolvedUrl);\n\t\tthis.logger.send({\n\t\t\tcategory: \"generic\",\n\t\t\teventName: \"DocumentIdUpdated\",\n\t\t\t...getUrlTelemetryProps(resolvedUrl),\n\t\t});\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.resetLoaderContainerTracker}\n\t */\n\tpublic resetLoaderContainerTracker(syncSummarizerClients: boolean = false): void {\n\t\tthis._loaderContainerTracker.reset();\n\t\tthis._loaderContainerTracker = new LoaderContainerTracker(syncSummarizerClients);\n\t}\n}\n\n/**\n * Implements {@link ITestObjectProvider}, but uses different versions to create and load containers.\n *\n * @internal\n */\nexport class TestObjectProviderWithVersionedLoad implements ITestObjectProvider {\n\t/**\n\t * {@inheritDoc ITestObjectProvider.\"type\"}\n\t */\n\tpublic readonly type = \"TestObjectProviderWithVersionedLoad\";\n\tprivate _loaderContainerTracker = new LoaderContainerTracker();\n\tprivate _logger: ITelemetryBaseLogger | undefined;\n\tprivate _tracker: EventAndErrorTrackingLogger | undefined;\n\tprivate readonly _documentIdStrategy: IDocumentIdStrategy;\n\tprivate _documentServiceFactory: IDocumentServiceFactory | undefined;\n\tprivate _urlResolver: IUrlResolver | undefined;\n\t// Since documentId doesn't change we can only create/make one container. Call the load functions instead.\n\tprivate _documentCreated = false;\n\n\t/**\n\t * Used to determine which APIs to use when creating a loader.\n\t *\n\t * The first load will always use the create APIs, and then useCreateApi will be set to false to ensure all\n\t * subsequent loads use the load APIs.\n\t */\n\tprivate useCreateApi: boolean = true;\n\n\tconstructor(\n\t\tprivate readonly LoaderConstructorForCreating: typeof Loader,\n\t\tprivate readonly LoaderConstructorForLoading: typeof Loader,\n\t\tprivate readonly driverForCreating: ITestDriver,\n\t\tprivate readonly driverForLoading: ITestDriver,\n\t\tprivate readonly createFluidEntryPointForCreating: (\n\t\t\ttestContainerConfig?: ITestContainerConfig,\n\t\t) => fluidEntryPoint,\n\t\tprivate readonly createFluidEntryPointForLoading: (\n\t\t\ttestContainerConfig?: ITestContainerConfig,\n\t\t) => fluidEntryPoint,\n\t\tprivate readonly telemetryProps?: ITelemetryLoggerPropertyBags,\n\t) {\n\t\tthis._documentIdStrategy = getDocumentIdStrategy(driverForCreating.type);\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.logger}\n\t */\n\tpublic get logger(): ITelemetryBaseLogger {\n\t\tif (this._logger === undefined) {\n\t\t\tthis._tracker = new EventAndErrorTrackingLogger(getTestLogger?.());\n\t\t\tthis._logger = createChildLogger({\n\t\t\t\tlogger: this._tracker,\n\t\t\t\tproperties: this.telemetryProps,\n\t\t\t});\n\t\t}\n\t\treturn this._logger;\n\t}\n\n\tpublic get tracker(): EventAndErrorTrackingLogger {\n\t\tvoid this.logger;\n\t\tassert(this._tracker !== undefined, \"should be initialized\");\n\t\treturn this._tracker;\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.documentServiceFactory}\n\t */\n\tpublic get documentServiceFactory(): IDocumentServiceFactory {\n\t\t// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions, @typescript-eslint/prefer-nullish-coalescing -- intentional behavior\n\t\tif (!this._documentServiceFactory) {\n\t\t\tthis._documentServiceFactory = this.driverForCreating.createDocumentServiceFactory();\n\t\t}\n\t\treturn this._documentServiceFactory;\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.urlResolver}\n\t */\n\tpublic get urlResolver(): IUrlResolver {\n\t\t// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions, @typescript-eslint/prefer-nullish-coalescing -- intentional behavior\n\t\tif (!this._urlResolver) {\n\t\t\tthis._urlResolver = this.driverForCreating.createUrlResolver();\n\t\t}\n\t\treturn this._urlResolver;\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.documentId}\n\t */\n\tpublic get documentId(): string {\n\t\treturn this._documentIdStrategy.get();\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.defaultCodeDetails}\n\t */\n\tpublic get defaultCodeDetails(): IFluidCodeDetails {\n\t\treturn defaultCodeDetails;\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.opProcessingController}\n\t */\n\tpublic get opProcessingController(): IOpProcessingController {\n\t\treturn this._loaderContainerTracker;\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.driver}\n\t */\n\tpublic get driver(): ITestDriver {\n\t\treturn this.useCreateApi ? this.driverForCreating : this.driverForLoading;\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.createFluidEntryPoint}\n\t */\n\tpublic get createFluidEntryPoint(): (\n\t\ttestContainerConfig?: ITestContainerConfig,\n\t) => fluidEntryPoint {\n\t\treturn this.useCreateApi\n\t\t\t? this.createFluidEntryPointForCreating\n\t\t\t: this.createFluidEntryPointForLoading;\n\t}\n\n\tprivate createLoaderForCreating(\n\t\tpackageEntries: Iterable<[IFluidCodeDetails, fluidEntryPoint]>,\n\t\tloaderProps?: Partial<ILoaderProps>,\n\t): Loader {\n\t\tconst logger = createMultiSinkLogger({\n\t\t\tloggers: [this.logger, loaderProps?.logger],\n\t\t});\n\n\t\tconst loader = new this.LoaderConstructorForCreating({\n\t\t\t...loaderProps,\n\t\t\tlogger,\n\t\t\tcodeLoader: loaderProps?.codeLoader ?? new LocalCodeLoader(packageEntries),\n\t\t\turlResolver: loaderProps?.urlResolver ?? this.urlResolver,\n\t\t\tdocumentServiceFactory:\n\t\t\t\tloaderProps?.documentServiceFactory ?? this.documentServiceFactory,\n\t\t});\n\n\t\tthis._loaderContainerTracker.add(loader);\n\t\treturn loader;\n\t}\n\n\tprivate createLoaderForLoading(\n\t\tpackageEntries: Iterable<[IFluidCodeDetails, fluidEntryPoint]>,\n\t\tloaderProps?: Partial<ILoaderProps>,\n\t): Loader {\n\t\tconst logger = createMultiSinkLogger({\n\t\t\tloggers: [this.logger, loaderProps?.logger],\n\t\t});\n\n\t\tconst loader = new this.LoaderConstructorForLoading({\n\t\t\t...loaderProps,\n\t\t\tlogger,\n\t\t\tcodeLoader: loaderProps?.codeLoader ?? new LocalCodeLoader(packageEntries),\n\t\t\turlResolver: loaderProps?.urlResolver ?? this.urlResolver,\n\t\t\tdocumentServiceFactory:\n\t\t\t\tloaderProps?.documentServiceFactory ?? this.documentServiceFactory,\n\t\t});\n\n\t\tthis._loaderContainerTracker.add(loader);\n\t\treturn loader;\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.createLoader}\n\t */\n\tpublic createLoader(\n\t\tpackageEntries: Iterable<[IFluidCodeDetails, fluidEntryPoint]>,\n\t\tloaderProps?: Partial<ILoaderProps>,\n\t\tforceUseCreateVersion = false,\n\t): Loader {\n\t\tconst useCreateVersion = forceUseCreateVersion === true || this.useCreateApi;\n\t\tif (this.useCreateApi) {\n\t\t\t// After we create the first loader, we can set this.useCreateApi to false.\n\t\t\tthis.useCreateApi = false;\n\t\t}\n\t\tif (useCreateVersion) {\n\t\t\treturn this.createLoaderForCreating(packageEntries, loaderProps);\n\t\t}\n\t\treturn this.createLoaderForLoading(packageEntries, loaderProps);\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.createContainer}\n\t */\n\tpublic async createContainer(\n\t\tentryPoint: fluidEntryPoint,\n\t\tloaderProps?: Partial<ILoaderProps>,\n\t): Promise<IContainer> {\n\t\tif (this._documentCreated) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Only one container/document can be created. To load the container/document use loadContainer\",\n\t\t\t);\n\t\t}\n\t\tconst loader = this.createLoader([[defaultCodeDetails, entryPoint]], loaderProps);\n\t\tconst container = await createAndAttachContainer(\n\t\t\tdefaultCodeDetails,\n\t\t\tloader,\n\t\t\tthis.driverForCreating.createCreateNewRequest(this.documentId),\n\t\t);\n\t\tthis._documentCreated = true;\n\t\t// r11s driver will generate a new ID for the new container.\n\t\t// update the document ID with the actual ID of the attached container.\n\t\tthis.updateDocumentId(container.resolvedUrl);\n\t\treturn container;\n\t}\n\n\t/**\n\t * {@inheritdoc ITestObjectProvider.createDetachedContainer}\n\t */\n\tpublic async createDetachedContainer(\n\t\tentryPoint: fluidEntryPoint,\n\t\tloaderProps?: Partial<ILoaderProps> | undefined,\n\t): Promise<IContainer> {\n\t\tif (this._documentCreated) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Only one container/document can be created. To load the container/document use loadContainer\",\n\t\t\t);\n\t\t}\n\t\tconst loader = this.createLoader([[defaultCodeDetails, entryPoint]], loaderProps);\n\t\treturn loader.createDetachedContainer(defaultCodeDetails);\n\t}\n\n\t/**\n\t * {@inheritdoc ITestObjectProvider.attachDetachedContainer}\n\t */\n\tpublic async attachDetachedContainer(container: IContainer): Promise<void> {\n\t\tif (this._documentCreated) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Only one container/document can be created. To load the container/document use loadContainer\",\n\t\t\t);\n\t\t}\n\t\tawait container.attach(this.driver.createCreateNewRequest(this.documentId));\n\t\tthis._documentCreated = true;\n\t\tthis.updateDocumentId(container.resolvedUrl);\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.loadContainer}\n\t */\n\tpublic async loadContainer(\n\t\tentryPoint: fluidEntryPoint,\n\t\tloaderProps?: Partial<ILoaderProps>,\n\t\trequestHeader?: IRequestHeader,\n\t\tpendingState?: string,\n\t): Promise<IContainer> {\n\t\tconst driver = this.useCreateApi ? this.driverForCreating : this.driverForLoading;\n\t\tconst loader = this.createLoader([[defaultCodeDetails, entryPoint]], loaderProps);\n\t\treturn this.resolveContainer(loader, requestHeader, driver, pendingState);\n\t}\n\n\tprivate async resolveContainer(\n\t\tloader: ILoader,\n\t\theaders?: IRequestHeader,\n\t\tdriver?: ITestDriver,\n\t\tpendingLocalState?: string,\n\t): Promise<IContainer> {\n\t\treturn loader.resolve(\n\t\t\t{\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\turl: await driver!.createContainerUrl(this.documentId),\n\t\t\t\theaders,\n\t\t\t},\n\t\t\tpendingLocalState,\n\t\t);\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.makeTestLoader}\n\t */\n\tpublic makeTestLoader(testContainerConfig?: ITestContainerConfig): Loader {\n\t\treturn this.createLoader(\n\t\t\t[[defaultCodeDetails, this.createFluidEntryPoint(testContainerConfig)]],\n\t\t\ttestContainerConfig?.loaderProps,\n\t\t\ttestContainerConfig?.forceUseCreateVersion,\n\t\t);\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.makeTestContainer}\n\t */\n\tpublic async makeTestContainer(\n\t\ttestContainerConfig?: ITestContainerConfig,\n\t): Promise<IContainer> {\n\t\tif (this._documentCreated) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Only one container/document can be created. To load the container/document use loadTestContainer\",\n\t\t\t);\n\t\t}\n\t\tconst loader = this.createLoader(\n\t\t\t[[defaultCodeDetails, this.createFluidEntryPoint(testContainerConfig)]],\n\t\t\ttestContainerConfig?.loaderProps,\n\t\t);\n\t\tconst container = await createAndAttachContainer(\n\t\t\tdefaultCodeDetails,\n\t\t\tloader,\n\t\t\tthis.driverForCreating.createCreateNewRequest(this.documentId),\n\t\t);\n\t\tthis._documentCreated = true;\n\t\t// r11s driver will generate a new ID for the new container.\n\t\t// update the document ID with the actual ID of the attached container.\n\t\tthis.updateDocumentId(container.resolvedUrl);\n\t\treturn container;\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.loadTestContainer}\n\t */\n\tpublic async loadTestContainer(\n\t\ttestContainerConfig?: ITestContainerConfig,\n\t\trequestHeader?: IRequestHeader,\n\t\tpendingLocalState?: string,\n\t): Promise<IContainer> {\n\t\t// Keep track of which Loader we are about to use so we can pass the correct driver through\n\t\tconst driver = this.useCreateApi ? this.driverForCreating : this.driverForLoading;\n\t\tconst loader = this.makeTestLoader(testContainerConfig);\n\t\tconst container = await this.resolveContainer(\n\t\t\tloader,\n\t\t\trequestHeader,\n\t\t\tdriver,\n\t\t\tpendingLocalState,\n\t\t);\n\t\tawait this.waitContainerToCatchUp(container);\n\n\t\treturn container;\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.reset}\n\t */\n\tpublic reset(): void {\n\t\tthis.useCreateApi = true;\n\t\tthis._loaderContainerTracker.reset();\n\t\tthis._logger = undefined;\n\t\tthis._tracker = undefined;\n\t\tthis._documentServiceFactory = undefined;\n\t\tthis._urlResolver = undefined;\n\t\tthis._documentIdStrategy.reset();\n\t\tconst logError = getUnexpectedLogErrorException(this._tracker);\n\t\tif (logError) {\n\t\t\tthrow logError;\n\t\t}\n\t\tthis._documentCreated = false;\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.ensureSynchronized}\n\t */\n\tpublic async ensureSynchronized(...containers: IContainer[]): Promise<void> {\n\t\treturn this._loaderContainerTracker.ensureSynchronized(...containers);\n\t}\n\n\tprivate async waitContainerToCatchUp(container: IContainer): Promise<boolean> {\n\t\t// The original waitContainerToCatchUp() from container loader uses either Container.resume()\n\t\t// or Container.connect() as part of its implementation. However, resume() was deprecated\n\t\t// and eventually replaced with connect(). To avoid issues during LTS compatibility testing\n\t\t// with older container versions issues, we use resume() when connect() is unavailable.\n\t\tif ((container as any).connect === undefined) {\n\t\t\t(container as any).connect = (container as any).resume;\n\t\t}\n\n\t\treturn waitContainerToCatchUp_original(container);\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.updateDocumentId}\n\t */\n\tpublic updateDocumentId(resolvedUrl: IResolvedUrl | undefined): void {\n\t\tthis._documentIdStrategy.update(resolvedUrl);\n\t\tthis.logger.send({\n\t\t\tcategory: \"generic\",\n\t\t\teventName: \"DocumentIdUpdated\",\n\t\t\t...getUrlTelemetryProps(resolvedUrl),\n\t\t});\n\t}\n\n\t/**\n\t * {@inheritDoc ITestObjectProvider.resetLoaderContainerTracker}\n\t */\n\tpublic resetLoaderContainerTracker(syncSummarizerClients: boolean = false): void {\n\t\tthis._loaderContainerTracker.reset();\n\t\tthis._loaderContainerTracker = new LoaderContainerTracker(syncSummarizerClients);\n\t}\n}\n\n/**\n * Get identifying information for a resolved URL.\n * @remarks BEWARE: this function is only appropriate for usage in tests, as it logs unhashed document IDs,\n * which is a privacy concern for production scenarios.\n */\nfunction getUrlTelemetryProps(\n\tresolvedUrl: IResolvedUrl | undefined,\n): ITelemetryBaseProperties {\n\tif (!resolvedUrl) {\n\t\treturn {};\n\t}\n\n\tconst props: Record<string, TelemetryBaseEventPropertyType> = {\n\t\turl: resolvedUrl.url,\n\t\tid: resolvedUrl.id,\n\t};\n\n\tif (isOdspResolvedUrl(resolvedUrl)) {\n\t\tObject.assign(props, {\n\t\t\tsiteUrl: resolvedUrl.siteUrl,\n\t\t\tdriveId: resolvedUrl.driveId,\n\t\t\titemId: resolvedUrl.itemId,\n\t\t});\n\t}\n\n\treturn tagData(TelemetryDataTag.UserData, props);\n}\n\n/** Summarize the event with just the primary properties, for succinct output in case of test failure */\nconst primaryEventProps = ({\n\tcategory,\n\teventName,\n\terror,\n\terrorType,\n}: ITelemetryBaseEvent): Partial<ITelemetryBaseEvent> => ({\n\tcategory,\n\teventName,\n\terror,\n\terrorType,\n\t[\"...\"]: \"*** Additional properties not shown, see full log for details ***\",\n});\n\n/**\n * @internal\n */\nexport function getUnexpectedLogErrorException(\n\tlogger: IEventAndErrorTrackingLogger | undefined,\n\tprefix?: string,\n): Error | undefined {\n\tif (logger === undefined) {\n\t\treturn;\n\t}\n\tconst results = logger.reportAndClearTrackedEvents();\n\tif (results.unexpectedErrors.length > 0) {\n\t\treturn new Error(\n\t\t\t`${prefix ?? \"\"}Unexpected Errors in Logs:\\n${JSON.stringify(\n\t\t\t\tresults.unexpectedErrors.map(primaryEventProps),\n\t\t\t\tundefined,\n\t\t\t\t2,\n\t\t\t)}`,\n\t\t);\n\t}\n\tif (results.expectedNotFound.length > 0) {\n\t\treturn new Error(\n\t\t\t`${prefix ?? \"\"}Expected Events not found:\\n${JSON.stringify(\n\t\t\t\tresults.expectedNotFound,\n\t\t\t\tundefined,\n\t\t\t\t2,\n\t\t\t)}`,\n\t\t);\n\t}\n}\n"]}
|
package/eslint.config.mts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
*
|
|
4
|
-
* To regenerate: pnpm tsx scripts/generate-flat-eslint-configs.ts --typescript
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
5
4
|
*/
|
|
5
|
+
|
|
6
6
|
import type { Linter } from "eslint";
|
|
7
7
|
import { minimalDeprecated } from "../../../common/build/eslint-config-fluid/flat.mts";
|
|
8
8
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loaderContainerTracker.d.ts","sourceRoot":"","sources":["../src/loaderContainerTracker.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAEN,UAAU,EACV,KAAK,WAAW,EAChB,MAAM,gDAAgD,CAAC;AAkBxD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAuBvE;;GAEG;AACH,qBAAa,sBAAuB,YAAW,uBAAuB;IAIzD,OAAO,CAAC,QAAQ,CAAC,qBAAqB;IAHlD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA0C;IACrE,OAAO,CAAC,kBAAkB,CAAa;gBAEV,qBAAqB,GAAE,OAAe;IAEnE;;;OAGG;IACI,GAAG,CAAC,UAAU,SAAS,WAAW,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI;IAmBpE;;;;OAIG;IACI,YAAY,CAAC,SAAS,EAAE,UAAU,GAAG,IAAI;IAoDhD;;;;;;OAMG;IACH,OAAO,CAAC,kBAAkB;IAwC1B,OAAO,CAAC,iBAAiB;IAQzB;;OAEG;IACI,KAAK,IAAI,IAAI;IAapB;;;;;;;;;;;;;;;OAeG;IACU,kBAAkB,CAAC,GAAG,UAAU,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IA2E3E;;;;;OAKG;IACH,OAAO,CAAC,iBAAiB;IA2BzB;;;;;OAKG;IACH,OAAO,CAAC,6BAA6B;IAqErC,OAAO,CAAC,qBAAqB;IAO7B;;;;;;;OAOG;YACW,qBAAqB;IAoCnC;;;OAGG;YACW,oBAAoB;IAclC;;OAEG;IACI,gBAAgB,CAAC,GAAG,UAAU,EAAE,UAAU,EAAE,GAAG,UAAU,EAAE;IAqBlE;;;;;;;;OAQG;IACU,eAAe,CAAC,GAAG,UAAU,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"loaderContainerTracker.d.ts","sourceRoot":"","sources":["../src/loaderContainerTracker.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAEN,UAAU,EACV,KAAK,WAAW,EAChB,MAAM,gDAAgD,CAAC;AAkBxD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAuBvE;;GAEG;AACH,qBAAa,sBAAuB,YAAW,uBAAuB;IAIzD,OAAO,CAAC,QAAQ,CAAC,qBAAqB;IAHlD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA0C;IACrE,OAAO,CAAC,kBAAkB,CAAa;gBAEV,qBAAqB,GAAE,OAAe;IAEnE;;;OAGG;IACI,GAAG,CAAC,UAAU,SAAS,WAAW,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI;IAmBpE;;;;OAIG;IACI,YAAY,CAAC,SAAS,EAAE,UAAU,GAAG,IAAI;IAoDhD;;;;;;OAMG;IACH,OAAO,CAAC,kBAAkB;IAwC1B,OAAO,CAAC,iBAAiB;IAQzB;;OAEG;IACI,KAAK,IAAI,IAAI;IAapB;;;;;;;;;;;;;;;OAeG;IACU,kBAAkB,CAAC,GAAG,UAAU,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IA2E3E;;;;;OAKG;IACH,OAAO,CAAC,iBAAiB;IA2BzB;;;;;OAKG;IACH,OAAO,CAAC,6BAA6B;IAqErC,OAAO,CAAC,qBAAqB;IAO7B;;;;;;;OAOG;YACW,qBAAqB;IAoCnC;;;OAGG;YACW,oBAAoB;IAclC;;OAEG;IACI,gBAAgB,CAAC,GAAG,UAAU,EAAE,UAAU,EAAE,GAAG,UAAU,EAAE;IAqBlE;;;;;;;;OAQG;IACU,eAAe,CAAC,GAAG,UAAU,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBxE;;;;;;;;OAQG;YACW,cAAc;IAyD5B;;;;;;OAMG;IACU,eAAe,CAAC,GAAG,UAAU,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAOxE;;;;;;OAMG;IACU,eAAe,CAAC,GAAG,UAAU,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAOxE;;OAEG;YACW,YAAY;IAgD1B;;;;;;OAMG;IACH,OAAO,CAAC,iBAAiB;IA+BzB;;OAEG;IACH,OAAO,CAAC,UAAU;IAuElB;;;;OAIG;IACH,OAAO,CAAC,aAAa;CAKrB"}
|
|
@@ -406,6 +406,7 @@ export class LoaderContainerTracker {
|
|
|
406
406
|
for (const container of containersToApply) {
|
|
407
407
|
const record = this.containers.get(container);
|
|
408
408
|
if (record !== undefined && !record.paused) {
|
|
409
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions, @typescript-eslint/prefer-nullish-coalescing -- intentional behavior
|
|
409
410
|
if (record.pauseP === undefined) {
|
|
410
411
|
record.pauseP = this.pauseContainer(container, record);
|
|
411
412
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loaderContainerTracker.js","sourceRoot":"","sources":["../src/loaderContainerTracker.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n\tIDeltaQueue,\n\tIContainer,\n\ttype IHostLoader,\n} from \"@fluidframework/container-definitions/internal\";\nimport { ConnectionState } from \"@fluidframework/container-loader\";\nimport {\n\tIContainerCreateProps,\n\tIContainerLoadProps,\n\t// eslint-disable-next-line import-x/no-internal-modules\n} from \"@fluidframework/container-loader/internal/test/container\";\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport {\n\tIDocumentMessage,\n\tMessageType,\n\tISequencedDocumentMessage,\n} from \"@fluidframework/driver-definitions/internal\";\nimport { canBeCoalescedByService } from \"@fluidframework/driver-utils/internal\";\n\nimport { toIDeltaManagerFull, waitForContainerConnection } from \"./containerUtils.js\";\nimport { debug } from \"./debug.js\";\nimport { isNonEmptyArray, type NonEmptyArray } from \"./nonEmptyArrayType.js\";\nimport type { IOpProcessingController } from \"./testObjectProvider.js\";\nimport { timeoutAwait, timeoutPromise } from \"./timeoutUtils.js\";\n\nconst debugOp = debug.extend(\"ops\");\nconst debugWait = debug.extend(\"wait\");\n\ninterface ContainerRecord {\n\t// A short number for debug output\n\tindex: number;\n\n\t// LoaderContainerTracker paused state\n\tpaused: boolean;\n\tpauseP?: Promise<void>; // promise for for the pause that is in progress\n\n\t// Tracking trailing no-op that may or may be acked by the server so we can discount them\n\t// See issue #5629\n\tstartTrailingNoOps: number;\n\ttrailingNoOps: number;\n\n\t// Track last proposal to ensure no unresolved proposal\n\tlastProposal: number;\n}\n\n/**\n * @legacy @beta\n */\nexport class LoaderContainerTracker implements IOpProcessingController {\n\tprivate readonly containers = new Map<IContainer, ContainerRecord>();\n\tprivate lastProposalSeqNum: number = 0;\n\n\tconstructor(private readonly syncSummarizerClients: boolean = false) {}\n\n\t/**\n\t * Add a loader to start to track any container created from them\n\t * @param loader - loader to start tracking any container created.\n\t */\n\tpublic add<LoaderType extends IHostLoader>(loader: LoaderType): void {\n\t\t// TODO: Expose Loader API to able to intercept container creation (See issue #5114)\n\t\tconst patch = <T, C extends IContainer>(fn: (...args) => Promise<C>) => {\n\t\t\tconst boundFn = fn.bind(loader);\n\t\t\treturn async (...args: T[]) => {\n\t\t\t\tconst container = await boundFn(...args);\n\t\t\t\tthis.addContainer(container);\n\t\t\t\treturn container;\n\t\t\t};\n\t\t};\n\t\t/* eslint-disable @typescript-eslint/unbound-method */\n\t\tloader.resolve = patch(loader.resolve);\n\t\tloader.createDetachedContainer = patch(loader.createDetachedContainer);\n\t\tloader.rehydrateDetachedContainerFromSnapshot = patch(\n\t\t\tloader.rehydrateDetachedContainerFromSnapshot,\n\t\t);\n\t\t/* eslint-enable @typescript-eslint/unbound-method */\n\t}\n\n\t/**\n\t * Utility function to add container to be tracked.\n\t *\n\t * @param container - container to add\n\t */\n\tpublic addContainer(container: IContainer): void {\n\t\t// don't add container that is already tracked\n\t\tif (this.containers.has(container)) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Container has a `clone` method that can be used to create another container without going through\n\t\t// the Loader. Such containers won't be added by the `add` method so do it here. For example, summarizer\n\t\t// containers are created via the `clone` method.\n\t\t// Created a type with clone (which is not on IContainer and is readonly) rather than typing to any.\n\t\ttype ContainerWithClone = IContainer & {\n\t\t\tclone: (\n\t\t\t\tloadProps: IContainerLoadProps,\n\t\t\t\tcreateParamOverrides: Partial<IContainerCreateProps>,\n\t\t\t) => Promise<IContainer>;\n\t\t};\n\t\tconst containerWithClone = container as ContainerWithClone;\n\n\t\t// back-compat: Check for undefined because this function was added recently and older containers won't have it.\n\t\tif (containerWithClone.clone !== undefined) {\n\t\t\tconst patch = <T, C extends IContainer>(fn: (...args) => Promise<C>) => {\n\t\t\t\tconst boundFn = fn.bind(containerWithClone);\n\t\t\t\treturn async (...args: T[]) => {\n\t\t\t\t\tconst newContainer = await boundFn(...args);\n\t\t\t\t\tthis.addContainer(newContainer);\n\t\t\t\t\treturn newContainer;\n\t\t\t\t};\n\t\t\t};\n\t\t\tcontainerWithClone.clone = patch(containerWithClone.clone);\n\t\t}\n\n\t\t// ignore summarizer\n\t\tif (\n\t\t\t!container.deltaManager.clientDetails.capabilities.interactive &&\n\t\t\t!this.syncSummarizerClients\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst record = {\n\t\t\tindex: this.containers.size,\n\t\t\tpaused: false,\n\t\t\tstartTrailingNoOps: 0,\n\t\t\ttrailingNoOps: 0,\n\t\t\tlastProposal: 0,\n\t\t};\n\t\tthis.containers.set(container, record);\n\t\tthis.trackTrailingNoOps(container, record);\n\t\tthis.trackLastProposal(container);\n\t\tthis.setupTrace(container, record.index);\n\t}\n\n\t/**\n\t * Keep track of the trailing NoOp that was sent so we can discount them in the clientSequenceNumber tracking.\n\t * The server might coalesce them with other ops, or a single NoOp, or delay it if it don't think it is necessary.\n\t *\n\t * @param container - the container to track\n\t * @param record - the record to update the trailing op information\n\t */\n\tprivate trackTrailingNoOps(container: IContainer, record: ContainerRecord): void {\n\t\tconst deltaManagerFull = toIDeltaManagerFull(container.deltaManager);\n\t\tdeltaManagerFull.outbound.on(\"op\", (messages) => {\n\t\t\tfor (const msg of messages) {\n\t\t\t\tif (canBeCoalescedByService(msg)) {\n\t\t\t\t\t// Track the NoOp that was sent.\n\t\t\t\t\tif (record.trailingNoOps === 0) {\n\t\t\t\t\t\t// record the starting sequence number of the trailing no ops if we haven't been tracking yet.\n\t\t\t\t\t\trecord.startTrailingNoOps = msg.clientSequenceNumber;\n\t\t\t\t\t}\n\t\t\t\t\trecord.trailingNoOps++;\n\t\t\t\t} else {\n\t\t\t\t\t// Other ops has been sent. We would like to see those ack'ed, so no more need to track NoOps\n\t\t\t\t\trecord.trailingNoOps = 0;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tdeltaManagerFull.inbound.on(\"push\", (message) => {\n\t\t\t// Received the no op back, update the record if we are tracking\n\t\t\tif (\n\t\t\t\tcanBeCoalescedByService(message) &&\n\t\t\t\tmessage.clientId === container.clientId &&\n\t\t\t\trecord.trailingNoOps !== 0 &&\n\t\t\t\trecord.startTrailingNoOps <= message.clientSequenceNumber\n\t\t\t) {\n\t\t\t\t// NoOp might have coalesced and skipped ahead some sequence number\n\t\t\t\t// update the record and skip ahead as well\n\t\t\t\tconst oldStartTrailingNoOps = record.startTrailingNoOps;\n\t\t\t\trecord.startTrailingNoOps = message.clientSequenceNumber + 1;\n\t\t\t\trecord.trailingNoOps -= record.startTrailingNoOps - oldStartTrailingNoOps;\n\t\t\t}\n\t\t});\n\n\t\tcontainer.on(\"disconnected\", () => {\n\t\t\t// reset on disconnect.\n\t\t\trecord.trailingNoOps = 0;\n\t\t});\n\t}\n\n\tprivate trackLastProposal(container: IContainer): void {\n\t\tcontainer.on(\"codeDetailsProposed\", (value, proposal) => {\n\t\t\tif (proposal.sequenceNumber > this.lastProposalSeqNum) {\n\t\t\t\tthis.lastProposalSeqNum = proposal.sequenceNumber;\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Reset the tracker, closing all containers and stop tracking them.\n\t */\n\tpublic reset(): void {\n\t\tthis.lastProposalSeqNum = 0;\n\t\tfor (const container of this.containers.keys()) {\n\t\t\tcontainer.close();\n\t\t\t// Optional chaining here is because containers made with LTS loaders don't have a dispose method or process\n\t\t\t// and this package is used with various previous versions of Fluid layers in our compat testing.\n\t\t\tcontainer.dispose?.();\n\t\t}\n\t\tthis.containers.clear();\n\n\t\t// REVIEW: do we need to unpatch the loaders?\n\t}\n\n\t/**\n\t * Make sure all the tracked containers are synchronized.\n\t *\n\t * No isDirty (non-readonly) containers\n\t * No extra clientId in quorum of any container that is not tracked and still opened.\n\t * - i.e. no pending Join/Leave message.\n\t * No unresolved proposal (minSeqNum \\>= lastProposalSeqNum)\n\t * lastSequenceNumber of all container is the same\n\t * clientSequenceNumberObserved is the same as clientSequenceNumber sent\n\t * - this overlaps with !isDirty, but include task scheduler ops.\n\t * - Trailing NoOp is tracked and don't count as pending ops.\n\t *\n\t * Containers that are already pause will resume process and paused again once\n\t * everything is synchronized. Containers that aren't paused will remain unpaused when this\n\t * function returns.\n\t */\n\tpublic async ensureSynchronized(...containers: IContainer[]): Promise<void> {\n\t\tconst resumed = this.resumeProcessing(...containers);\n\n\t\tlet waitingSequenceNumberSynchronized: string | undefined;\n\t\t// eslint-disable-next-line no-constant-condition\n\t\twhile (true) {\n\t\t\t// yield a turn to allow side effect of resuming or the ops we just processed execute before we check\n\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\tsetTimeout(resolve, 0);\n\t\t\t});\n\n\t\t\tconst containersToApply = this.getContainers(containers);\n\t\t\tif (!isNonEmptyArray(containersToApply)) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Ignore readonly dirty containers because they can't send ops and nothing can be done about them being dirty.\n\t\t\tconst dirtyContainers = containersToApply.filter((c) => {\n\t\t\t\tconst { deltaManager, isDirty } = c;\n\t\t\t\treturn deltaManager.readOnlyInfo.readonly !== true && isDirty;\n\t\t\t});\n\t\t\tif (dirtyContainers.length === 0) {\n\t\t\t\t// Wait for all the leave messages\n\t\t\t\tconst pendingClients = this.getPendingClients(containersToApply);\n\t\t\t\tif (pendingClients.length === 0) {\n\t\t\t\t\tconst needSync = this.needSequenceNumberSynchronize(containersToApply);\n\t\t\t\t\tif (needSync === undefined) {\n\t\t\t\t\t\t// done, we are in sync\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tif (waitingSequenceNumberSynchronized !== needSync.reason) {\n\t\t\t\t\t\t// Don't repeat writing to console if it is the same reason\n\t\t\t\t\t\twaitingSequenceNumberSynchronized = needSync.reason;\n\t\t\t\t\t\tdebugWait(needSync.message);\n\t\t\t\t\t}\n\t\t\t\t\t// Wait for one inbounds ops which might change the state of things\n\t\t\t\t\tawait timeoutAwait(this.waitForAnyInboundOps(containersToApply), {\n\t\t\t\t\t\terrorMsg: `Timeout on ${needSync.message}`,\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\twaitingSequenceNumberSynchronized = undefined;\n\t\t\t\t\tawait timeoutAwait(this.waitForPendingClients(pendingClients), {\n\t\t\t\t\t\terrorMsg: \"Timeout on waiting for pending join or leave op\",\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Wait for all the containers to be saved\n\t\t\t\tdebugWait(\n\t\t\t\t\t`Waiting container to be saved ${this.containerIndexStrings(dirtyContainers)}`,\n\t\t\t\t);\n\t\t\t\twaitingSequenceNumberSynchronized = undefined;\n\t\t\t\tawait Promise.all(\n\t\t\t\t\tdirtyContainers.map(async (c) =>\n\t\t\t\t\t\tPromise.race([\n\t\t\t\t\t\t\ttimeoutPromise((resolve) => c.once(\"saved\", () => resolve()), {\n\t\t\t\t\t\t\t\terrorMsg: \"Timeout on waiting a container to be saved\",\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\tnew Promise((resolve) => c.once(\"closed\", resolve)),\n\t\t\t\t\t\t]),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// Pause all container that was resumed\n\t\t// don't call pause if resumed is empty and pause everything, which is not what we want\n\t\tif (resumed.length !== 0) {\n\t\t\tawait timeoutAwait(this.pauseProcessing(...resumed), {\n\t\t\t\terrorMsg: \"Timeout on waiting for pausing all resumed containers\",\n\t\t\t});\n\t\t}\n\n\t\tdebugWait(\"Synchronized\");\n\t}\n\n\t/**\n\t * Utility to calculate the set of clientId per container in quorum that is NOT associated with\n\t * any container we tracked, indicating there is a pending join or leave op that we need to wait.\n\t *\n\t * @param containersToApply - the set of containers to check\n\t */\n\tprivate getPendingClients(containersToApply: IContainer[]): [IContainer, Set<string>][] {\n\t\t// All the clientId we track should be a superset of the quorum, otherwise, we are missing\n\t\t// leave messages\n\t\tconst openedDocuments = Array.from(this.containers.keys()).filter((c) => !c.closed);\n\t\tconst openedClientId = openedDocuments.map((container) => container.clientId);\n\n\t\tconst pendingClients: [IContainer, Set<string>][] = [];\n\t\tcontainersToApply.forEach((container) => {\n\t\t\tconst pendingClientId = new Set<string>();\n\t\t\tconst quorum = container.getQuorum();\n\t\t\tquorum.getMembers().forEach((client, clientId) => {\n\t\t\t\t// ignore summarizer\n\t\t\t\tif (!client.client.details.capabilities.interactive && !this.syncSummarizerClients) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (!openedClientId.includes(clientId)) {\n\t\t\t\t\tpendingClientId.add(clientId);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tif (pendingClientId.size !== 0) {\n\t\t\t\tpendingClients.push([container, pendingClientId]);\n\t\t\t}\n\t\t});\n\t\treturn pendingClients;\n\t}\n\n\t/**\n\t * Utility to check synchronization based on sequence number\n\t * See ensureSynchronized for more detail\n\t *\n\t * @param containersToApply - the set of containers to check\n\t */\n\tprivate needSequenceNumberSynchronize(\n\t\tcontainersToApply: NonEmptyArray<IContainer>,\n\t): { reason: string; message: string } | undefined {\n\t\t// If there is a pending proposal, wait for it to be accepted\n\t\tconst minSeqNum = containersToApply[0].deltaManager.minimumSequenceNumber;\n\t\tif (minSeqNum < this.lastProposalSeqNum) {\n\t\t\treturn {\n\t\t\t\treason: \"Proposal\",\n\t\t\t\tmessage: `waiting for MSN to advance to proposal at sequence number ${this.lastProposalSeqNum}`,\n\t\t\t};\n\t\t}\n\n\t\t// clientSequenceNumber check detects ops in flight, both on the wire and in the outbound queue\n\t\t// We need both client sequence number and isDirty check because:\n\t\t// - Currently isDirty flag ignores ops for task scheduler, so we need the client sequence number check\n\t\t// - But isDirty flags include ops during forceReadonly and disconnected, because we don't submit\n\t\t// the ops in the first place, clientSequenceNumber is not assigned\n\n\t\tconst containerWithInflightOps = containersToApply.filter((container) => {\n\t\t\tif (container.deltaManager.readOnlyInfo.readonly === true) {\n\t\t\t\t// Ignore readonly container. the clientSeqNum and clientSeqNumObserved might be out of sync\n\t\t\t\t// because we transition to readonly when outbound is not empty or the in transit op got lost\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t// Note that in read only mode, the op won't be submitted\n\t\t\tlet deltaManager = container.deltaManager as any;\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\tconst { trailingNoOps } = this.containers.get(container)!;\n\t\t\t// Back-compat: lastSubmittedClientId/clientSequenceNumber/clientSequenceNumberObserved moved to ConnectionManager in 0.53\n\t\t\tif (!(\"clientSequenceNumber\" in deltaManager)) {\n\t\t\t\tdeltaManager = deltaManager.connectionManager;\n\t\t\t}\n\t\t\tassert(\"clientSequenceNumber\" in deltaManager, \"no clientSequenceNumber\");\n\t\t\tassert(\"clientSequenceNumberObserved\" in deltaManager, \"no clientSequenceNumber\");\n\t\t\t// If last submittedClientId isn't the current clientId, then we haven't send any ops\n\t\t\treturn (\n\t\t\t\tdeltaManager.lastSubmittedClientId === container.clientId &&\n\t\t\t\tdeltaManager.clientSequenceNumber !==\n\t\t\t\t\t(deltaManager.clientSequenceNumberObserved as number) + trailingNoOps\n\t\t\t);\n\t\t});\n\n\t\tif (containerWithInflightOps.length !== 0) {\n\t\t\treturn {\n\t\t\t\treason: \"InflightOps\",\n\t\t\t\tmessage: `waiting for containers with inflight ops: ${this.containerIndexStrings(\n\t\t\t\t\tcontainerWithInflightOps,\n\t\t\t\t)}`,\n\t\t\t};\n\t\t}\n\n\t\t// Check to see if all the container has process the same number of ops.\n\t\tconst maxSeqNum = Math.max(\n\t\t\t...containersToApply.map((c) => c.deltaManager.lastSequenceNumber),\n\t\t);\n\t\tconst containerWithPendingIncoming = containersToApply.filter(\n\t\t\t(c) => c.deltaManager.lastSequenceNumber !== maxSeqNum,\n\t\t);\n\t\tif (containerWithPendingIncoming.length !== 0) {\n\t\t\treturn {\n\t\t\t\treason: \"Pending\",\n\t\t\t\tmessage: `waiting for containers with pending incoming ops up to sequence number ${maxSeqNum}: ${this.containerIndexStrings(\n\t\t\t\t\tcontainerWithPendingIncoming,\n\t\t\t\t)}`,\n\t\t\t};\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tprivate containerIndexStrings(containers: IContainer[]): number[] {\n\t\treturn containers.map(\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t(c) => this.containers.get(c)!.index,\n\t\t);\n\t}\n\n\t/**\n\t * Utility to wait for any clientId in quorum that is NOT associated with any container we\n\t * tracked, indicating there is a pending join or leave op that we need to wait.\n\t *\n\t * Note that this function doesn't account for container that got added after we started waiting\n\t *\n\t * @param containersToApply - the set of containers to wait for any inbound ops for\n\t */\n\tprivate async waitForPendingClients(\n\t\tpendingClients: [IContainer, Set<string>][],\n\t): Promise<void[]> {\n\t\tconst unconnectedClients = Array.from(this.containers.keys()).filter(\n\t\t\t(c) => !c.closed && c.connectionState !== ConnectionState.Connected,\n\t\t);\n\t\treturn Promise.all(\n\t\t\tpendingClients.map(async ([container, pendingClientId]) => {\n\t\t\t\treturn new Promise<void>((resolve) => {\n\t\t\t\t\tconst cleanup = (): void => {\n\t\t\t\t\t\tunconnectedClients.forEach((c) => c.off(\"connected\", handler));\n\t\t\t\t\t\tcontainer.getQuorum().off(\"removeMember\", handler);\n\t\t\t\t\t};\n\t\t\t\t\tconst handler = (clientId: string): void => {\n\t\t\t\t\t\tpendingClientId.delete(clientId);\n\t\t\t\t\t\tif (pendingClientId.size === 0) {\n\t\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\t\tconst index = this.containers.get(container)!.index;\n\t\t\t\t\tdebugWait(\n\t\t\t\t\t\t`${index}: Waiting for pending clients ${Array.from(pendingClientId.keys())}`,\n\t\t\t\t\t);\n\t\t\t\t\tunconnectedClients.forEach((c) => c.on(\"connected\", handler));\n\t\t\t\t\tcontainer.getQuorum().on(\"removeMember\", handler);\n\t\t\t\t\tcontainer.on(\"closed\", () => {\n\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\tresolve();\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t}),\n\t\t);\n\t}\n\n\t/**\n\t * Utility to wait for any inbound ops from a set of containers\n\t * @param containersToApply - the set of containers to wait for any inbound ops for\n\t */\n\tprivate async waitForAnyInboundOps(containersToApply: IContainer[]): Promise<void> {\n\t\treturn new Promise<void>((resolve) => {\n\t\t\tconst handler = (): void => {\n\t\t\t\tcontainersToApply.map((c) => {\n\t\t\t\t\ttoIDeltaManagerFull(c.deltaManager).inbound.off(\"push\", handler);\n\t\t\t\t});\n\t\t\t\tresolve();\n\t\t\t};\n\t\t\tcontainersToApply.map((c) => {\n\t\t\t\ttoIDeltaManagerFull(c.deltaManager).inbound.on(\"push\", handler);\n\t\t\t});\n\t\t});\n\t}\n\n\t/**\n\t * Resume all queue activities on all paused tracked containers and return them\n\t */\n\tpublic resumeProcessing(...containers: IContainer[]): IContainer[] {\n\t\tconst resumed: IContainer[] = [];\n\t\tconst containersToApply = this.getContainers(containers);\n\t\tfor (const container of containersToApply) {\n\t\t\tconst record = this.containers.get(container);\n\t\t\tassert(\n\t\t\t\trecord?.pauseP === undefined,\n\t\t\t\t\"Cannot resume container while pausing is in progress\",\n\t\t\t);\n\t\t\tif (record?.paused === true) {\n\t\t\t\tdebugWait(`${record.index}: container resumed`);\n\t\t\t\tconst deltaManagerFull = toIDeltaManagerFull(container.deltaManager);\n\t\t\t\tdeltaManagerFull.inbound.resume();\n\t\t\t\tdeltaManagerFull.outbound.resume();\n\t\t\t\tresumed.push(container);\n\t\t\t\trecord.paused = false;\n\t\t\t}\n\t\t}\n\t\treturn resumed;\n\t}\n\n\t/**\n\t * Pause all queue activities on the containers given, or all tracked containers\n\t * Any containers given that is not tracked will be ignored.\n\t *\n\t * When a container is paused, it is assumed that we want fine grain control over op\n\t * sequencing. This function will prepare the container and force it into write mode to\n\t * avoid missing join messages or change the sequence of event when switching from read to\n\t * write mode.\n\t */\n\tpublic async pauseProcessing(...containers: IContainer[]): Promise<void> {\n\t\tconst waitP: Promise<void>[] = [];\n\t\tconst containersToApply = this.getContainers(containers);\n\t\tfor (const container of containersToApply) {\n\t\t\tconst record = this.containers.get(container);\n\t\t\tif (record !== undefined && !record.paused) {\n\t\t\t\tif (record.pauseP === undefined) {\n\t\t\t\t\trecord.pauseP = this.pauseContainer(container, record);\n\t\t\t\t}\n\t\t\t\twaitP.push(record.pauseP);\n\t\t\t}\n\t\t}\n\t\tawait Promise.all(waitP);\n\t}\n\n\t/**\n\t * When a container is paused, it is assumed that we want fine grain control over op\n\t * sequencing. This function will prepare the container and force it into write mode to\n\t * avoid missing join messages or change the sequence of event when switching from read to\n\t * write mode.\n\t *\n\t * @param container - the container to pause\n\t * @param record - the record for the container\n\t */\n\tprivate async pauseContainer(container: IContainer, record: ContainerRecord): Promise<void> {\n\t\tdebugWait(`${record.index}: pausing container`);\n\t\tconst deltaManagerFull = toIDeltaManagerFull(container.deltaManager);\n\t\tassert(!deltaManagerFull.outbound.paused, \"Container should not be paused yet\");\n\t\tassert(!deltaManagerFull.inbound.paused, \"Container should not be paused yet\");\n\n\t\t// Pause outbound\n\t\tdebugWait(`${record.index}: pausing container outbound queues`);\n\t\tawait deltaManagerFull.outbound.pause();\n\n\t\t// Ensure the container is connected first.\n\t\tif (container.connectionState !== ConnectionState.Connected) {\n\t\t\tdebugWait(`${record.index}: Wait for container connection`);\n\t\t\tawait waitForContainerConnection(container);\n\t\t}\n\n\t\t// Check if the container is in write mode\n\t\tif (!container.deltaManager.active) {\n\t\t\tlet proposalP: Promise<boolean> | undefined;\n\t\t\tif (deltaManagerFull.outbound.idle) {\n\t\t\t\t// Need to generate an op to force write mode\n\t\t\t\tdebugWait(`${record.index}: container force write connection`);\n\t\t\t\tconst maybeContainer = container as Partial<IContainer>;\n\t\t\t\tconst codeProposal = maybeContainer.getLoadedCodeDetails\n\t\t\t\t\t? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\t\t\tcontainer.getLoadedCodeDetails()!\n\t\t\t\t\t: (container as any).chaincodePackage;\n\n\t\t\t\tproposalP = container.proposeCodeDetails(codeProposal);\n\t\t\t}\n\n\t\t\t// Wait for nack\n\t\t\tdebugWait(`${record.index}: Wait for container disconnect`);\n\t\t\tdeltaManagerFull.outbound.resume();\n\t\t\tawait new Promise<void>((resolve) => container.once(\"disconnected\", resolve));\n\t\t\tconst accepted = proposalP ? await proposalP : false;\n\t\t\tassert(!accepted, \"A proposal in read mode should be rejected\");\n\t\t\tawait deltaManagerFull.outbound.pause();\n\n\t\t\t// Ensure the container is reconnect.\n\t\t\tif (container.connectionState !== ConnectionState.Connected) {\n\t\t\t\tdebugWait(`${record.index}: Wait for container reconnection`);\n\t\t\t\tawait waitForContainerConnection(container);\n\t\t\t}\n\t\t}\n\n\t\tdebugWait(`${record.index}: pausing container inbound queues`);\n\n\t\t// Pause inbound\n\t\tawait deltaManagerFull.inbound.pause();\n\n\t\tdebugWait(`${record.index}: container paused`);\n\n\t\trecord.pauseP = undefined;\n\t\trecord.paused = true;\n\t}\n\n\t/**\n\t * Pause all queue activities on all tracked containers, and resume only\n\t * inbound to process ops until it is idle. All queues are left in the paused state\n\t * after the function.\n\t *\n\t * Pausing will switch the container to write mode. See `pauseProcessing`\n\t */\n\tpublic async processIncoming(...containers: IContainer[]): Promise<void> {\n\t\treturn this.processQueue(\n\t\t\tcontainers,\n\t\t\t(container) => toIDeltaManagerFull(container.deltaManager).inbound,\n\t\t);\n\t}\n\n\t/**\n\t * Pause all queue activities on all tracked containers, and resume only\n\t * outbound to process ops until it is idle. All queues are left in the paused state\n\t * after the function.\n\t *\n\t * Pausing will switch the container to write mode. See `pauseProcessing`\n\t */\n\tpublic async processOutgoing(...containers: IContainer[]): Promise<void> {\n\t\treturn this.processQueue(\n\t\t\tcontainers,\n\t\t\t(container) => toIDeltaManagerFull(container.deltaManager).outbound,\n\t\t);\n\t}\n\n\t/**\n\t * Implementation of processIncoming and processOutgoing\n\t */\n\tprivate async processQueue<U>(\n\t\tcontainers: IContainer[],\n\t\tgetQueue: (container: IContainer) => IDeltaQueue<U>,\n\t): Promise<void> {\n\t\tawait this.pauseProcessing(...containers);\n\t\tconst resumed: IDeltaQueue<U>[] = [];\n\n\t\tconst containersToApply = this.getContainers(containers);\n\n\t\tconst inflightTracker = new Map<IContainer, number>();\n\t\tconst cleanup: (() => void)[] = [];\n\t\tfor (const container of containersToApply) {\n\t\t\tassert(\n\t\t\t\tcontainer.deltaManager.active,\n\t\t\t\t\"Container should be connected in write mode already\",\n\t\t\t);\n\n\t\t\tconst queue = getQueue(container);\n\n\t\t\t// track the outgoing ops (if any) to make sure they make the round trip to at least to the same client\n\t\t\t// to make sure they are sequenced.\n\t\t\tcleanup.push(this.setupInOutTracker(container, inflightTracker));\n\t\t\tqueue.resume();\n\t\t\tresumed.push(queue);\n\t\t}\n\n\t\twhile (resumed.some((queue) => !queue.idle)) {\n\t\t\tdebugWait(\"Wait until queue is idle\");\n\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\tsetTimeout(resolve, 0);\n\t\t\t});\n\t\t}\n\n\t\t// Make sure all the op that we sent out are acked first\n\t\t// This is no op if we are processing incoming\n\t\tif (inflightTracker.size) {\n\t\t\tdebugWait(\"Wait for inflight ops\");\n\t\t\tdo {\n\t\t\t\tawait this.waitForAnyInboundOps(containersToApply);\n\t\t\t} while (inflightTracker.size);\n\t\t}\n\n\t\t// remove the handlers\n\t\tcleanup.forEach((clean) => clean());\n\n\t\tawait Promise.all(resumed.map(async (queue) => queue.pause()));\n\t}\n\n\t/**\n\t * Utility to set up listener to track the outbound ops until it round trip back\n\t * Returns a function to remove the handler after it is done.\n\t *\n\t * @param container - the container to setup\n\t * @param inflightTracker - a map to track the clientSequenceNumber per container it expect to get ops back\n\t */\n\tprivate setupInOutTracker(\n\t\tcontainer: IContainer,\n\t\tinflightTracker: Map<IContainer, number>,\n\t): () => void {\n\t\tconst outHandler = (messages: IDocumentMessage[]): void => {\n\t\t\tfor (const message of messages) {\n\t\t\t\tif (!canBeCoalescedByService(message)) {\n\t\t\t\t\tinflightTracker.set(container, message.clientSequenceNumber);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\tconst inHandler = (message: ISequencedDocumentMessage): void => {\n\t\t\tif (\n\t\t\t\t!canBeCoalescedByService(message) &&\n\t\t\t\tmessage.clientId === container.clientId &&\n\t\t\t\tinflightTracker.get(container) === message.clientSequenceNumber\n\t\t\t) {\n\t\t\t\tinflightTracker.delete(container);\n\t\t\t}\n\t\t};\n\n\t\tconst deltaManagerFull = toIDeltaManagerFull(container.deltaManager);\n\t\tdeltaManagerFull.outbound.on(\"op\", outHandler);\n\t\tdeltaManagerFull.inbound.on(\"push\", inHandler);\n\n\t\treturn (): void => {\n\t\t\tdeltaManagerFull.outbound.off(\"op\", outHandler);\n\t\t\tdeltaManagerFull.inbound.off(\"push\", inHandler);\n\t\t};\n\t}\n\n\t/**\n\t * Setup debug traces for connection and ops\n\t */\n\tprivate setupTrace(container: IContainer, index: number): void {\n\t\tif (debugOp.enabled) {\n\t\t\tconst getContentsString = (type: string, msgContents: any): string => {\n\t\t\t\ttry {\n\t\t\t\t\tif (type !== MessageType.Operation) {\n\t\t\t\t\t\tif (typeof msgContents === \"string\") {\n\t\t\t\t\t\t\treturn msgContents;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn JSON.stringify(msgContents);\n\t\t\t\t\t}\n\t\t\t\t\tlet address = \"\";\n\n\t\t\t\t\t// contents comes in the wire as JSON string (\"push\" event)\n\t\t\t\t\t// But already parsed when apply (\"op\" event)\n\t\t\t\t\tlet contents =\n\t\t\t\t\t\ttypeof msgContents === \"string\" ? JSON.parse(msgContents) : msgContents;\n\t\t\t\t\twhile (contents !== undefined && contents !== null) {\n\t\t\t\t\t\tif (contents.contents?.address !== undefined) {\n\t\t\t\t\t\t\taddress += `/${contents.contents.address}`;\n\t\t\t\t\t\t\tcontents = contents.contents.contents;\n\t\t\t\t\t\t} else if (contents.content?.address !== undefined) {\n\t\t\t\t\t\t\taddress += `/${contents.content.address}`;\n\t\t\t\t\t\t\tcontents = contents.content.contents;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (address) {\n\t\t\t\t\t\treturn `${address} ${JSON.stringify(contents)}`;\n\t\t\t\t\t}\n\t\t\t\t\treturn JSON.stringify(contents);\n\t\t\t\t} catch (e: any) {\n\t\t\t\t\treturn `${e.message}: ${e.stack}`;\n\t\t\t\t}\n\t\t\t};\n\t\t\tdebugOp(`${index}: ADD: clientId: ${container.clientId}`);\n\t\t\tconst deltaManagerFull = toIDeltaManagerFull(container.deltaManager);\n\t\t\tdeltaManagerFull.outbound.on(\"op\", (messages) => {\n\t\t\t\tfor (const msg of messages) {\n\t\t\t\t\tdebugOp(\n\t\t\t\t\t\t`${index}: OUT: ` +\n\t\t\t\t\t\t\t`cli: ${msg.clientSequenceNumber.toString().padStart(3)} ` +\n\t\t\t\t\t\t\t`rsq: ${msg.referenceSequenceNumber.toString().padStart(3)} ` +\n\t\t\t\t\t\t\t`${msg.type} ${getContentsString(msg.type, msg.contents)}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t});\n\t\t\tconst getInboundHandler = (type: string) => {\n\t\t\t\treturn (msg: ISequencedDocumentMessage) => {\n\t\t\t\t\tconst clientSeq =\n\t\t\t\t\t\tmsg.clientId === container.clientId\n\t\t\t\t\t\t\t? `cli: ${msg.clientSequenceNumber.toString().padStart(3)}`\n\t\t\t\t\t\t\t: \" \";\n\t\t\t\t\tdebugOp(\n\t\t\t\t\t\t`${index}: ${type}: seq: ${msg.sequenceNumber.toString().padStart(3)} ` +\n\t\t\t\t\t\t\t`${clientSeq} min: ${msg.minimumSequenceNumber.toString().padStart(3)} ` +\n\t\t\t\t\t\t\t`${msg.type} ${getContentsString(msg.type, msg.contents)}`,\n\t\t\t\t\t);\n\t\t\t\t};\n\t\t\t};\n\t\t\tdeltaManagerFull.inbound.on(\"push\", getInboundHandler(\"IN \"));\n\t\t\tdeltaManagerFull.inbound.on(\"op\", getInboundHandler(\"OP \"));\n\t\t\tcontainer.deltaManager.on(\"connect\", (details) => {\n\t\t\t\tdebugOp(`${index}: CON: clientId: ${details.clientId}`);\n\t\t\t});\n\t\t\tcontainer.deltaManager.on(\"disconnect\", (reason) => {\n\t\t\t\tdebugOp(`${index}: DIS: ${reason}`);\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Filter out the opened containers based on param.\n\t * @param containers - The container to filter to. If the array is empty, it means don't filter and return\n\t * all open containers.\n\t */\n\tprivate getContainers(containers: IContainer[]): IContainer[] {\n\t\tconst containersToApply =\n\t\t\tcontainers.length === 0 ? Array.from(this.containers.keys()) : containers;\n\t\treturn containersToApply.filter((container) => !container.closed);\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"loaderContainerTracker.js","sourceRoot":"","sources":["../src/loaderContainerTracker.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n\tIDeltaQueue,\n\tIContainer,\n\ttype IHostLoader,\n} from \"@fluidframework/container-definitions/internal\";\nimport { ConnectionState } from \"@fluidframework/container-loader\";\nimport {\n\tIContainerCreateProps,\n\tIContainerLoadProps,\n\t// eslint-disable-next-line import-x/no-internal-modules\n} from \"@fluidframework/container-loader/internal/test/container\";\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport {\n\tIDocumentMessage,\n\tMessageType,\n\tISequencedDocumentMessage,\n} from \"@fluidframework/driver-definitions/internal\";\nimport { canBeCoalescedByService } from \"@fluidframework/driver-utils/internal\";\n\nimport { toIDeltaManagerFull, waitForContainerConnection } from \"./containerUtils.js\";\nimport { debug } from \"./debug.js\";\nimport { isNonEmptyArray, type NonEmptyArray } from \"./nonEmptyArrayType.js\";\nimport type { IOpProcessingController } from \"./testObjectProvider.js\";\nimport { timeoutAwait, timeoutPromise } from \"./timeoutUtils.js\";\n\nconst debugOp = debug.extend(\"ops\");\nconst debugWait = debug.extend(\"wait\");\n\ninterface ContainerRecord {\n\t// A short number for debug output\n\tindex: number;\n\n\t// LoaderContainerTracker paused state\n\tpaused: boolean;\n\tpauseP?: Promise<void>; // promise for for the pause that is in progress\n\n\t// Tracking trailing no-op that may or may be acked by the server so we can discount them\n\t// See issue #5629\n\tstartTrailingNoOps: number;\n\ttrailingNoOps: number;\n\n\t// Track last proposal to ensure no unresolved proposal\n\tlastProposal: number;\n}\n\n/**\n * @legacy @beta\n */\nexport class LoaderContainerTracker implements IOpProcessingController {\n\tprivate readonly containers = new Map<IContainer, ContainerRecord>();\n\tprivate lastProposalSeqNum: number = 0;\n\n\tconstructor(private readonly syncSummarizerClients: boolean = false) {}\n\n\t/**\n\t * Add a loader to start to track any container created from them\n\t * @param loader - loader to start tracking any container created.\n\t */\n\tpublic add<LoaderType extends IHostLoader>(loader: LoaderType): void {\n\t\t// TODO: Expose Loader API to able to intercept container creation (See issue #5114)\n\t\tconst patch = <T, C extends IContainer>(fn: (...args) => Promise<C>) => {\n\t\t\tconst boundFn = fn.bind(loader);\n\t\t\treturn async (...args: T[]) => {\n\t\t\t\tconst container = await boundFn(...args);\n\t\t\t\tthis.addContainer(container);\n\t\t\t\treturn container;\n\t\t\t};\n\t\t};\n\t\t/* eslint-disable @typescript-eslint/unbound-method */\n\t\tloader.resolve = patch(loader.resolve);\n\t\tloader.createDetachedContainer = patch(loader.createDetachedContainer);\n\t\tloader.rehydrateDetachedContainerFromSnapshot = patch(\n\t\t\tloader.rehydrateDetachedContainerFromSnapshot,\n\t\t);\n\t\t/* eslint-enable @typescript-eslint/unbound-method */\n\t}\n\n\t/**\n\t * Utility function to add container to be tracked.\n\t *\n\t * @param container - container to add\n\t */\n\tpublic addContainer(container: IContainer): void {\n\t\t// don't add container that is already tracked\n\t\tif (this.containers.has(container)) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Container has a `clone` method that can be used to create another container without going through\n\t\t// the Loader. Such containers won't be added by the `add` method so do it here. For example, summarizer\n\t\t// containers are created via the `clone` method.\n\t\t// Created a type with clone (which is not on IContainer and is readonly) rather than typing to any.\n\t\ttype ContainerWithClone = IContainer & {\n\t\t\tclone: (\n\t\t\t\tloadProps: IContainerLoadProps,\n\t\t\t\tcreateParamOverrides: Partial<IContainerCreateProps>,\n\t\t\t) => Promise<IContainer>;\n\t\t};\n\t\tconst containerWithClone = container as ContainerWithClone;\n\n\t\t// back-compat: Check for undefined because this function was added recently and older containers won't have it.\n\t\tif (containerWithClone.clone !== undefined) {\n\t\t\tconst patch = <T, C extends IContainer>(fn: (...args) => Promise<C>) => {\n\t\t\t\tconst boundFn = fn.bind(containerWithClone);\n\t\t\t\treturn async (...args: T[]) => {\n\t\t\t\t\tconst newContainer = await boundFn(...args);\n\t\t\t\t\tthis.addContainer(newContainer);\n\t\t\t\t\treturn newContainer;\n\t\t\t\t};\n\t\t\t};\n\t\t\tcontainerWithClone.clone = patch(containerWithClone.clone);\n\t\t}\n\n\t\t// ignore summarizer\n\t\tif (\n\t\t\t!container.deltaManager.clientDetails.capabilities.interactive &&\n\t\t\t!this.syncSummarizerClients\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst record = {\n\t\t\tindex: this.containers.size,\n\t\t\tpaused: false,\n\t\t\tstartTrailingNoOps: 0,\n\t\t\ttrailingNoOps: 0,\n\t\t\tlastProposal: 0,\n\t\t};\n\t\tthis.containers.set(container, record);\n\t\tthis.trackTrailingNoOps(container, record);\n\t\tthis.trackLastProposal(container);\n\t\tthis.setupTrace(container, record.index);\n\t}\n\n\t/**\n\t * Keep track of the trailing NoOp that was sent so we can discount them in the clientSequenceNumber tracking.\n\t * The server might coalesce them with other ops, or a single NoOp, or delay it if it don't think it is necessary.\n\t *\n\t * @param container - the container to track\n\t * @param record - the record to update the trailing op information\n\t */\n\tprivate trackTrailingNoOps(container: IContainer, record: ContainerRecord): void {\n\t\tconst deltaManagerFull = toIDeltaManagerFull(container.deltaManager);\n\t\tdeltaManagerFull.outbound.on(\"op\", (messages) => {\n\t\t\tfor (const msg of messages) {\n\t\t\t\tif (canBeCoalescedByService(msg)) {\n\t\t\t\t\t// Track the NoOp that was sent.\n\t\t\t\t\tif (record.trailingNoOps === 0) {\n\t\t\t\t\t\t// record the starting sequence number of the trailing no ops if we haven't been tracking yet.\n\t\t\t\t\t\trecord.startTrailingNoOps = msg.clientSequenceNumber;\n\t\t\t\t\t}\n\t\t\t\t\trecord.trailingNoOps++;\n\t\t\t\t} else {\n\t\t\t\t\t// Other ops has been sent. We would like to see those ack'ed, so no more need to track NoOps\n\t\t\t\t\trecord.trailingNoOps = 0;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tdeltaManagerFull.inbound.on(\"push\", (message) => {\n\t\t\t// Received the no op back, update the record if we are tracking\n\t\t\tif (\n\t\t\t\tcanBeCoalescedByService(message) &&\n\t\t\t\tmessage.clientId === container.clientId &&\n\t\t\t\trecord.trailingNoOps !== 0 &&\n\t\t\t\trecord.startTrailingNoOps <= message.clientSequenceNumber\n\t\t\t) {\n\t\t\t\t// NoOp might have coalesced and skipped ahead some sequence number\n\t\t\t\t// update the record and skip ahead as well\n\t\t\t\tconst oldStartTrailingNoOps = record.startTrailingNoOps;\n\t\t\t\trecord.startTrailingNoOps = message.clientSequenceNumber + 1;\n\t\t\t\trecord.trailingNoOps -= record.startTrailingNoOps - oldStartTrailingNoOps;\n\t\t\t}\n\t\t});\n\n\t\tcontainer.on(\"disconnected\", () => {\n\t\t\t// reset on disconnect.\n\t\t\trecord.trailingNoOps = 0;\n\t\t});\n\t}\n\n\tprivate trackLastProposal(container: IContainer): void {\n\t\tcontainer.on(\"codeDetailsProposed\", (value, proposal) => {\n\t\t\tif (proposal.sequenceNumber > this.lastProposalSeqNum) {\n\t\t\t\tthis.lastProposalSeqNum = proposal.sequenceNumber;\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Reset the tracker, closing all containers and stop tracking them.\n\t */\n\tpublic reset(): void {\n\t\tthis.lastProposalSeqNum = 0;\n\t\tfor (const container of this.containers.keys()) {\n\t\t\tcontainer.close();\n\t\t\t// Optional chaining here is because containers made with LTS loaders don't have a dispose method or process\n\t\t\t// and this package is used with various previous versions of Fluid layers in our compat testing.\n\t\t\tcontainer.dispose?.();\n\t\t}\n\t\tthis.containers.clear();\n\n\t\t// REVIEW: do we need to unpatch the loaders?\n\t}\n\n\t/**\n\t * Make sure all the tracked containers are synchronized.\n\t *\n\t * No isDirty (non-readonly) containers\n\t * No extra clientId in quorum of any container that is not tracked and still opened.\n\t * - i.e. no pending Join/Leave message.\n\t * No unresolved proposal (minSeqNum \\>= lastProposalSeqNum)\n\t * lastSequenceNumber of all container is the same\n\t * clientSequenceNumberObserved is the same as clientSequenceNumber sent\n\t * - this overlaps with !isDirty, but include task scheduler ops.\n\t * - Trailing NoOp is tracked and don't count as pending ops.\n\t *\n\t * Containers that are already pause will resume process and paused again once\n\t * everything is synchronized. Containers that aren't paused will remain unpaused when this\n\t * function returns.\n\t */\n\tpublic async ensureSynchronized(...containers: IContainer[]): Promise<void> {\n\t\tconst resumed = this.resumeProcessing(...containers);\n\n\t\tlet waitingSequenceNumberSynchronized: string | undefined;\n\t\t// eslint-disable-next-line no-constant-condition\n\t\twhile (true) {\n\t\t\t// yield a turn to allow side effect of resuming or the ops we just processed execute before we check\n\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\tsetTimeout(resolve, 0);\n\t\t\t});\n\n\t\t\tconst containersToApply = this.getContainers(containers);\n\t\t\tif (!isNonEmptyArray(containersToApply)) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Ignore readonly dirty containers because they can't send ops and nothing can be done about them being dirty.\n\t\t\tconst dirtyContainers = containersToApply.filter((c) => {\n\t\t\t\tconst { deltaManager, isDirty } = c;\n\t\t\t\treturn deltaManager.readOnlyInfo.readonly !== true && isDirty;\n\t\t\t});\n\t\t\tif (dirtyContainers.length === 0) {\n\t\t\t\t// Wait for all the leave messages\n\t\t\t\tconst pendingClients = this.getPendingClients(containersToApply);\n\t\t\t\tif (pendingClients.length === 0) {\n\t\t\t\t\tconst needSync = this.needSequenceNumberSynchronize(containersToApply);\n\t\t\t\t\tif (needSync === undefined) {\n\t\t\t\t\t\t// done, we are in sync\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tif (waitingSequenceNumberSynchronized !== needSync.reason) {\n\t\t\t\t\t\t// Don't repeat writing to console if it is the same reason\n\t\t\t\t\t\twaitingSequenceNumberSynchronized = needSync.reason;\n\t\t\t\t\t\tdebugWait(needSync.message);\n\t\t\t\t\t}\n\t\t\t\t\t// Wait for one inbounds ops which might change the state of things\n\t\t\t\t\tawait timeoutAwait(this.waitForAnyInboundOps(containersToApply), {\n\t\t\t\t\t\terrorMsg: `Timeout on ${needSync.message}`,\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\twaitingSequenceNumberSynchronized = undefined;\n\t\t\t\t\tawait timeoutAwait(this.waitForPendingClients(pendingClients), {\n\t\t\t\t\t\terrorMsg: \"Timeout on waiting for pending join or leave op\",\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Wait for all the containers to be saved\n\t\t\t\tdebugWait(\n\t\t\t\t\t`Waiting container to be saved ${this.containerIndexStrings(dirtyContainers)}`,\n\t\t\t\t);\n\t\t\t\twaitingSequenceNumberSynchronized = undefined;\n\t\t\t\tawait Promise.all(\n\t\t\t\t\tdirtyContainers.map(async (c) =>\n\t\t\t\t\t\tPromise.race([\n\t\t\t\t\t\t\ttimeoutPromise((resolve) => c.once(\"saved\", () => resolve()), {\n\t\t\t\t\t\t\t\terrorMsg: \"Timeout on waiting a container to be saved\",\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\tnew Promise((resolve) => c.once(\"closed\", resolve)),\n\t\t\t\t\t\t]),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// Pause all container that was resumed\n\t\t// don't call pause if resumed is empty and pause everything, which is not what we want\n\t\tif (resumed.length !== 0) {\n\t\t\tawait timeoutAwait(this.pauseProcessing(...resumed), {\n\t\t\t\terrorMsg: \"Timeout on waiting for pausing all resumed containers\",\n\t\t\t});\n\t\t}\n\n\t\tdebugWait(\"Synchronized\");\n\t}\n\n\t/**\n\t * Utility to calculate the set of clientId per container in quorum that is NOT associated with\n\t * any container we tracked, indicating there is a pending join or leave op that we need to wait.\n\t *\n\t * @param containersToApply - the set of containers to check\n\t */\n\tprivate getPendingClients(containersToApply: IContainer[]): [IContainer, Set<string>][] {\n\t\t// All the clientId we track should be a superset of the quorum, otherwise, we are missing\n\t\t// leave messages\n\t\tconst openedDocuments = Array.from(this.containers.keys()).filter((c) => !c.closed);\n\t\tconst openedClientId = openedDocuments.map((container) => container.clientId);\n\n\t\tconst pendingClients: [IContainer, Set<string>][] = [];\n\t\tcontainersToApply.forEach((container) => {\n\t\t\tconst pendingClientId = new Set<string>();\n\t\t\tconst quorum = container.getQuorum();\n\t\t\tquorum.getMembers().forEach((client, clientId) => {\n\t\t\t\t// ignore summarizer\n\t\t\t\tif (!client.client.details.capabilities.interactive && !this.syncSummarizerClients) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (!openedClientId.includes(clientId)) {\n\t\t\t\t\tpendingClientId.add(clientId);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tif (pendingClientId.size !== 0) {\n\t\t\t\tpendingClients.push([container, pendingClientId]);\n\t\t\t}\n\t\t});\n\t\treturn pendingClients;\n\t}\n\n\t/**\n\t * Utility to check synchronization based on sequence number\n\t * See ensureSynchronized for more detail\n\t *\n\t * @param containersToApply - the set of containers to check\n\t */\n\tprivate needSequenceNumberSynchronize(\n\t\tcontainersToApply: NonEmptyArray<IContainer>,\n\t): { reason: string; message: string } | undefined {\n\t\t// If there is a pending proposal, wait for it to be accepted\n\t\tconst minSeqNum = containersToApply[0].deltaManager.minimumSequenceNumber;\n\t\tif (minSeqNum < this.lastProposalSeqNum) {\n\t\t\treturn {\n\t\t\t\treason: \"Proposal\",\n\t\t\t\tmessage: `waiting for MSN to advance to proposal at sequence number ${this.lastProposalSeqNum}`,\n\t\t\t};\n\t\t}\n\n\t\t// clientSequenceNumber check detects ops in flight, both on the wire and in the outbound queue\n\t\t// We need both client sequence number and isDirty check because:\n\t\t// - Currently isDirty flag ignores ops for task scheduler, so we need the client sequence number check\n\t\t// - But isDirty flags include ops during forceReadonly and disconnected, because we don't submit\n\t\t// the ops in the first place, clientSequenceNumber is not assigned\n\n\t\tconst containerWithInflightOps = containersToApply.filter((container) => {\n\t\t\tif (container.deltaManager.readOnlyInfo.readonly === true) {\n\t\t\t\t// Ignore readonly container. the clientSeqNum and clientSeqNumObserved might be out of sync\n\t\t\t\t// because we transition to readonly when outbound is not empty or the in transit op got lost\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t// Note that in read only mode, the op won't be submitted\n\t\t\tlet deltaManager = container.deltaManager as any;\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\tconst { trailingNoOps } = this.containers.get(container)!;\n\t\t\t// Back-compat: lastSubmittedClientId/clientSequenceNumber/clientSequenceNumberObserved moved to ConnectionManager in 0.53\n\t\t\tif (!(\"clientSequenceNumber\" in deltaManager)) {\n\t\t\t\tdeltaManager = deltaManager.connectionManager;\n\t\t\t}\n\t\t\tassert(\"clientSequenceNumber\" in deltaManager, \"no clientSequenceNumber\");\n\t\t\tassert(\"clientSequenceNumberObserved\" in deltaManager, \"no clientSequenceNumber\");\n\t\t\t// If last submittedClientId isn't the current clientId, then we haven't send any ops\n\t\t\treturn (\n\t\t\t\tdeltaManager.lastSubmittedClientId === container.clientId &&\n\t\t\t\tdeltaManager.clientSequenceNumber !==\n\t\t\t\t\t(deltaManager.clientSequenceNumberObserved as number) + trailingNoOps\n\t\t\t);\n\t\t});\n\n\t\tif (containerWithInflightOps.length !== 0) {\n\t\t\treturn {\n\t\t\t\treason: \"InflightOps\",\n\t\t\t\tmessage: `waiting for containers with inflight ops: ${this.containerIndexStrings(\n\t\t\t\t\tcontainerWithInflightOps,\n\t\t\t\t)}`,\n\t\t\t};\n\t\t}\n\n\t\t// Check to see if all the container has process the same number of ops.\n\t\tconst maxSeqNum = Math.max(\n\t\t\t...containersToApply.map((c) => c.deltaManager.lastSequenceNumber),\n\t\t);\n\t\tconst containerWithPendingIncoming = containersToApply.filter(\n\t\t\t(c) => c.deltaManager.lastSequenceNumber !== maxSeqNum,\n\t\t);\n\t\tif (containerWithPendingIncoming.length !== 0) {\n\t\t\treturn {\n\t\t\t\treason: \"Pending\",\n\t\t\t\tmessage: `waiting for containers with pending incoming ops up to sequence number ${maxSeqNum}: ${this.containerIndexStrings(\n\t\t\t\t\tcontainerWithPendingIncoming,\n\t\t\t\t)}`,\n\t\t\t};\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tprivate containerIndexStrings(containers: IContainer[]): number[] {\n\t\treturn containers.map(\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t(c) => this.containers.get(c)!.index,\n\t\t);\n\t}\n\n\t/**\n\t * Utility to wait for any clientId in quorum that is NOT associated with any container we\n\t * tracked, indicating there is a pending join or leave op that we need to wait.\n\t *\n\t * Note that this function doesn't account for container that got added after we started waiting\n\t *\n\t * @param containersToApply - the set of containers to wait for any inbound ops for\n\t */\n\tprivate async waitForPendingClients(\n\t\tpendingClients: [IContainer, Set<string>][],\n\t): Promise<void[]> {\n\t\tconst unconnectedClients = Array.from(this.containers.keys()).filter(\n\t\t\t(c) => !c.closed && c.connectionState !== ConnectionState.Connected,\n\t\t);\n\t\treturn Promise.all(\n\t\t\tpendingClients.map(async ([container, pendingClientId]) => {\n\t\t\t\treturn new Promise<void>((resolve) => {\n\t\t\t\t\tconst cleanup = (): void => {\n\t\t\t\t\t\tunconnectedClients.forEach((c) => c.off(\"connected\", handler));\n\t\t\t\t\t\tcontainer.getQuorum().off(\"removeMember\", handler);\n\t\t\t\t\t};\n\t\t\t\t\tconst handler = (clientId: string): void => {\n\t\t\t\t\t\tpendingClientId.delete(clientId);\n\t\t\t\t\t\tif (pendingClientId.size === 0) {\n\t\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\t\tconst index = this.containers.get(container)!.index;\n\t\t\t\t\tdebugWait(\n\t\t\t\t\t\t`${index}: Waiting for pending clients ${Array.from(pendingClientId.keys())}`,\n\t\t\t\t\t);\n\t\t\t\t\tunconnectedClients.forEach((c) => c.on(\"connected\", handler));\n\t\t\t\t\tcontainer.getQuorum().on(\"removeMember\", handler);\n\t\t\t\t\tcontainer.on(\"closed\", () => {\n\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\tresolve();\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t}),\n\t\t);\n\t}\n\n\t/**\n\t * Utility to wait for any inbound ops from a set of containers\n\t * @param containersToApply - the set of containers to wait for any inbound ops for\n\t */\n\tprivate async waitForAnyInboundOps(containersToApply: IContainer[]): Promise<void> {\n\t\treturn new Promise<void>((resolve) => {\n\t\t\tconst handler = (): void => {\n\t\t\t\tcontainersToApply.map((c) => {\n\t\t\t\t\ttoIDeltaManagerFull(c.deltaManager).inbound.off(\"push\", handler);\n\t\t\t\t});\n\t\t\t\tresolve();\n\t\t\t};\n\t\t\tcontainersToApply.map((c) => {\n\t\t\t\ttoIDeltaManagerFull(c.deltaManager).inbound.on(\"push\", handler);\n\t\t\t});\n\t\t});\n\t}\n\n\t/**\n\t * Resume all queue activities on all paused tracked containers and return them\n\t */\n\tpublic resumeProcessing(...containers: IContainer[]): IContainer[] {\n\t\tconst resumed: IContainer[] = [];\n\t\tconst containersToApply = this.getContainers(containers);\n\t\tfor (const container of containersToApply) {\n\t\t\tconst record = this.containers.get(container);\n\t\t\tassert(\n\t\t\t\trecord?.pauseP === undefined,\n\t\t\t\t\"Cannot resume container while pausing is in progress\",\n\t\t\t);\n\t\t\tif (record?.paused === true) {\n\t\t\t\tdebugWait(`${record.index}: container resumed`);\n\t\t\t\tconst deltaManagerFull = toIDeltaManagerFull(container.deltaManager);\n\t\t\t\tdeltaManagerFull.inbound.resume();\n\t\t\t\tdeltaManagerFull.outbound.resume();\n\t\t\t\tresumed.push(container);\n\t\t\t\trecord.paused = false;\n\t\t\t}\n\t\t}\n\t\treturn resumed;\n\t}\n\n\t/**\n\t * Pause all queue activities on the containers given, or all tracked containers\n\t * Any containers given that is not tracked will be ignored.\n\t *\n\t * When a container is paused, it is assumed that we want fine grain control over op\n\t * sequencing. This function will prepare the container and force it into write mode to\n\t * avoid missing join messages or change the sequence of event when switching from read to\n\t * write mode.\n\t */\n\tpublic async pauseProcessing(...containers: IContainer[]): Promise<void> {\n\t\tconst waitP: Promise<void>[] = [];\n\t\tconst containersToApply = this.getContainers(containers);\n\t\tfor (const container of containersToApply) {\n\t\t\tconst record = this.containers.get(container);\n\t\t\tif (record !== undefined && !record.paused) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions, @typescript-eslint/prefer-nullish-coalescing -- intentional behavior\n\t\t\t\tif (record.pauseP === undefined) {\n\t\t\t\t\trecord.pauseP = this.pauseContainer(container, record);\n\t\t\t\t}\n\t\t\t\twaitP.push(record.pauseP);\n\t\t\t}\n\t\t}\n\t\tawait Promise.all(waitP);\n\t}\n\n\t/**\n\t * When a container is paused, it is assumed that we want fine grain control over op\n\t * sequencing. This function will prepare the container and force it into write mode to\n\t * avoid missing join messages or change the sequence of event when switching from read to\n\t * write mode.\n\t *\n\t * @param container - the container to pause\n\t * @param record - the record for the container\n\t */\n\tprivate async pauseContainer(container: IContainer, record: ContainerRecord): Promise<void> {\n\t\tdebugWait(`${record.index}: pausing container`);\n\t\tconst deltaManagerFull = toIDeltaManagerFull(container.deltaManager);\n\t\tassert(!deltaManagerFull.outbound.paused, \"Container should not be paused yet\");\n\t\tassert(!deltaManagerFull.inbound.paused, \"Container should not be paused yet\");\n\n\t\t// Pause outbound\n\t\tdebugWait(`${record.index}: pausing container outbound queues`);\n\t\tawait deltaManagerFull.outbound.pause();\n\n\t\t// Ensure the container is connected first.\n\t\tif (container.connectionState !== ConnectionState.Connected) {\n\t\t\tdebugWait(`${record.index}: Wait for container connection`);\n\t\t\tawait waitForContainerConnection(container);\n\t\t}\n\n\t\t// Check if the container is in write mode\n\t\tif (!container.deltaManager.active) {\n\t\t\tlet proposalP: Promise<boolean> | undefined;\n\t\t\tif (deltaManagerFull.outbound.idle) {\n\t\t\t\t// Need to generate an op to force write mode\n\t\t\t\tdebugWait(`${record.index}: container force write connection`);\n\t\t\t\tconst maybeContainer = container as Partial<IContainer>;\n\t\t\t\tconst codeProposal = maybeContainer.getLoadedCodeDetails\n\t\t\t\t\t? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\t\t\tcontainer.getLoadedCodeDetails()!\n\t\t\t\t\t: (container as any).chaincodePackage;\n\n\t\t\t\tproposalP = container.proposeCodeDetails(codeProposal);\n\t\t\t}\n\n\t\t\t// Wait for nack\n\t\t\tdebugWait(`${record.index}: Wait for container disconnect`);\n\t\t\tdeltaManagerFull.outbound.resume();\n\t\t\tawait new Promise<void>((resolve) => container.once(\"disconnected\", resolve));\n\t\t\tconst accepted = proposalP ? await proposalP : false;\n\t\t\tassert(!accepted, \"A proposal in read mode should be rejected\");\n\t\t\tawait deltaManagerFull.outbound.pause();\n\n\t\t\t// Ensure the container is reconnect.\n\t\t\tif (container.connectionState !== ConnectionState.Connected) {\n\t\t\t\tdebugWait(`${record.index}: Wait for container reconnection`);\n\t\t\t\tawait waitForContainerConnection(container);\n\t\t\t}\n\t\t}\n\n\t\tdebugWait(`${record.index}: pausing container inbound queues`);\n\n\t\t// Pause inbound\n\t\tawait deltaManagerFull.inbound.pause();\n\n\t\tdebugWait(`${record.index}: container paused`);\n\n\t\trecord.pauseP = undefined;\n\t\trecord.paused = true;\n\t}\n\n\t/**\n\t * Pause all queue activities on all tracked containers, and resume only\n\t * inbound to process ops until it is idle. All queues are left in the paused state\n\t * after the function.\n\t *\n\t * Pausing will switch the container to write mode. See `pauseProcessing`\n\t */\n\tpublic async processIncoming(...containers: IContainer[]): Promise<void> {\n\t\treturn this.processQueue(\n\t\t\tcontainers,\n\t\t\t(container) => toIDeltaManagerFull(container.deltaManager).inbound,\n\t\t);\n\t}\n\n\t/**\n\t * Pause all queue activities on all tracked containers, and resume only\n\t * outbound to process ops until it is idle. All queues are left in the paused state\n\t * after the function.\n\t *\n\t * Pausing will switch the container to write mode. See `pauseProcessing`\n\t */\n\tpublic async processOutgoing(...containers: IContainer[]): Promise<void> {\n\t\treturn this.processQueue(\n\t\t\tcontainers,\n\t\t\t(container) => toIDeltaManagerFull(container.deltaManager).outbound,\n\t\t);\n\t}\n\n\t/**\n\t * Implementation of processIncoming and processOutgoing\n\t */\n\tprivate async processQueue<U>(\n\t\tcontainers: IContainer[],\n\t\tgetQueue: (container: IContainer) => IDeltaQueue<U>,\n\t): Promise<void> {\n\t\tawait this.pauseProcessing(...containers);\n\t\tconst resumed: IDeltaQueue<U>[] = [];\n\n\t\tconst containersToApply = this.getContainers(containers);\n\n\t\tconst inflightTracker = new Map<IContainer, number>();\n\t\tconst cleanup: (() => void)[] = [];\n\t\tfor (const container of containersToApply) {\n\t\t\tassert(\n\t\t\t\tcontainer.deltaManager.active,\n\t\t\t\t\"Container should be connected in write mode already\",\n\t\t\t);\n\n\t\t\tconst queue = getQueue(container);\n\n\t\t\t// track the outgoing ops (if any) to make sure they make the round trip to at least to the same client\n\t\t\t// to make sure they are sequenced.\n\t\t\tcleanup.push(this.setupInOutTracker(container, inflightTracker));\n\t\t\tqueue.resume();\n\t\t\tresumed.push(queue);\n\t\t}\n\n\t\twhile (resumed.some((queue) => !queue.idle)) {\n\t\t\tdebugWait(\"Wait until queue is idle\");\n\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\tsetTimeout(resolve, 0);\n\t\t\t});\n\t\t}\n\n\t\t// Make sure all the op that we sent out are acked first\n\t\t// This is no op if we are processing incoming\n\t\tif (inflightTracker.size) {\n\t\t\tdebugWait(\"Wait for inflight ops\");\n\t\t\tdo {\n\t\t\t\tawait this.waitForAnyInboundOps(containersToApply);\n\t\t\t} while (inflightTracker.size);\n\t\t}\n\n\t\t// remove the handlers\n\t\tcleanup.forEach((clean) => clean());\n\n\t\tawait Promise.all(resumed.map(async (queue) => queue.pause()));\n\t}\n\n\t/**\n\t * Utility to set up listener to track the outbound ops until it round trip back\n\t * Returns a function to remove the handler after it is done.\n\t *\n\t * @param container - the container to setup\n\t * @param inflightTracker - a map to track the clientSequenceNumber per container it expect to get ops back\n\t */\n\tprivate setupInOutTracker(\n\t\tcontainer: IContainer,\n\t\tinflightTracker: Map<IContainer, number>,\n\t): () => void {\n\t\tconst outHandler = (messages: IDocumentMessage[]): void => {\n\t\t\tfor (const message of messages) {\n\t\t\t\tif (!canBeCoalescedByService(message)) {\n\t\t\t\t\tinflightTracker.set(container, message.clientSequenceNumber);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\tconst inHandler = (message: ISequencedDocumentMessage): void => {\n\t\t\tif (\n\t\t\t\t!canBeCoalescedByService(message) &&\n\t\t\t\tmessage.clientId === container.clientId &&\n\t\t\t\tinflightTracker.get(container) === message.clientSequenceNumber\n\t\t\t) {\n\t\t\t\tinflightTracker.delete(container);\n\t\t\t}\n\t\t};\n\n\t\tconst deltaManagerFull = toIDeltaManagerFull(container.deltaManager);\n\t\tdeltaManagerFull.outbound.on(\"op\", outHandler);\n\t\tdeltaManagerFull.inbound.on(\"push\", inHandler);\n\n\t\treturn (): void => {\n\t\t\tdeltaManagerFull.outbound.off(\"op\", outHandler);\n\t\t\tdeltaManagerFull.inbound.off(\"push\", inHandler);\n\t\t};\n\t}\n\n\t/**\n\t * Setup debug traces for connection and ops\n\t */\n\tprivate setupTrace(container: IContainer, index: number): void {\n\t\tif (debugOp.enabled) {\n\t\t\tconst getContentsString = (type: string, msgContents: any): string => {\n\t\t\t\ttry {\n\t\t\t\t\tif (type !== MessageType.Operation) {\n\t\t\t\t\t\tif (typeof msgContents === \"string\") {\n\t\t\t\t\t\t\treturn msgContents;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn JSON.stringify(msgContents);\n\t\t\t\t\t}\n\t\t\t\t\tlet address = \"\";\n\n\t\t\t\t\t// contents comes in the wire as JSON string (\"push\" event)\n\t\t\t\t\t// But already parsed when apply (\"op\" event)\n\t\t\t\t\tlet contents =\n\t\t\t\t\t\ttypeof msgContents === \"string\" ? JSON.parse(msgContents) : msgContents;\n\t\t\t\t\twhile (contents !== undefined && contents !== null) {\n\t\t\t\t\t\tif (contents.contents?.address !== undefined) {\n\t\t\t\t\t\t\taddress += `/${contents.contents.address}`;\n\t\t\t\t\t\t\tcontents = contents.contents.contents;\n\t\t\t\t\t\t} else if (contents.content?.address !== undefined) {\n\t\t\t\t\t\t\taddress += `/${contents.content.address}`;\n\t\t\t\t\t\t\tcontents = contents.content.contents;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (address) {\n\t\t\t\t\t\treturn `${address} ${JSON.stringify(contents)}`;\n\t\t\t\t\t}\n\t\t\t\t\treturn JSON.stringify(contents);\n\t\t\t\t} catch (e: any) {\n\t\t\t\t\treturn `${e.message}: ${e.stack}`;\n\t\t\t\t}\n\t\t\t};\n\t\t\tdebugOp(`${index}: ADD: clientId: ${container.clientId}`);\n\t\t\tconst deltaManagerFull = toIDeltaManagerFull(container.deltaManager);\n\t\t\tdeltaManagerFull.outbound.on(\"op\", (messages) => {\n\t\t\t\tfor (const msg of messages) {\n\t\t\t\t\tdebugOp(\n\t\t\t\t\t\t`${index}: OUT: ` +\n\t\t\t\t\t\t\t`cli: ${msg.clientSequenceNumber.toString().padStart(3)} ` +\n\t\t\t\t\t\t\t`rsq: ${msg.referenceSequenceNumber.toString().padStart(3)} ` +\n\t\t\t\t\t\t\t`${msg.type} ${getContentsString(msg.type, msg.contents)}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t});\n\t\t\tconst getInboundHandler = (type: string) => {\n\t\t\t\treturn (msg: ISequencedDocumentMessage) => {\n\t\t\t\t\tconst clientSeq =\n\t\t\t\t\t\tmsg.clientId === container.clientId\n\t\t\t\t\t\t\t? `cli: ${msg.clientSequenceNumber.toString().padStart(3)}`\n\t\t\t\t\t\t\t: \" \";\n\t\t\t\t\tdebugOp(\n\t\t\t\t\t\t`${index}: ${type}: seq: ${msg.sequenceNumber.toString().padStart(3)} ` +\n\t\t\t\t\t\t\t`${clientSeq} min: ${msg.minimumSequenceNumber.toString().padStart(3)} ` +\n\t\t\t\t\t\t\t`${msg.type} ${getContentsString(msg.type, msg.contents)}`,\n\t\t\t\t\t);\n\t\t\t\t};\n\t\t\t};\n\t\t\tdeltaManagerFull.inbound.on(\"push\", getInboundHandler(\"IN \"));\n\t\t\tdeltaManagerFull.inbound.on(\"op\", getInboundHandler(\"OP \"));\n\t\t\tcontainer.deltaManager.on(\"connect\", (details) => {\n\t\t\t\tdebugOp(`${index}: CON: clientId: ${details.clientId}`);\n\t\t\t});\n\t\t\tcontainer.deltaManager.on(\"disconnect\", (reason) => {\n\t\t\t\tdebugOp(`${index}: DIS: ${reason}`);\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Filter out the opened containers based on param.\n\t * @param containers - The container to filter to. If the array is empty, it means don't filter and return\n\t * all open containers.\n\t */\n\tprivate getContainers(containers: IContainer[]): IContainer[] {\n\t\tconst containersToApply =\n\t\t\tcontainers.length === 0 ? Array.from(this.containers.keys()) : containers;\n\t\treturn containersToApply.filter((container) => !container.closed);\n\t}\n}\n"]}
|
package/lib/packageVersion.d.ts
CHANGED
|
@@ -5,5 +5,5 @@
|
|
|
5
5
|
* THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
|
|
6
6
|
*/
|
|
7
7
|
export declare const pkgName = "@fluidframework/test-utils";
|
|
8
|
-
export declare const pkgVersion = "2.
|
|
8
|
+
export declare const pkgVersion = "2.81.0-374083";
|
|
9
9
|
//# sourceMappingURL=packageVersion.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,+BAA+B,CAAC;AACpD,eAAO,MAAM,UAAU,
|
|
1
|
+
{"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,+BAA+B,CAAC;AACpD,eAAO,MAAM,UAAU,kBAAkB,CAAC"}
|
package/lib/packageVersion.js
CHANGED