@fluidframework/test-utils 2.0.0-internal.3.0.5 → 2.0.0-internal.3.1.1
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/.eslintrc.js +8 -10
- package/README.md +41 -11
- package/api-extractor.json +2 -2
- package/dist/DriverWrappers.d.ts.map +1 -1
- package/dist/DriverWrappers.js.map +1 -1
- package/dist/TestConfigs.d.ts.map +1 -1
- package/dist/TestConfigs.js +3 -2
- package/dist/TestConfigs.js.map +1 -1
- package/dist/TestSummaryUtils.d.ts +1 -1
- package/dist/TestSummaryUtils.d.ts.map +1 -1
- package/dist/TestSummaryUtils.js +8 -6
- package/dist/TestSummaryUtils.js.map +1 -1
- package/dist/containerUtils.d.ts.map +1 -1
- package/dist/containerUtils.js +3 -1
- package/dist/containerUtils.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/interfaces.d.ts.map +1 -1
- package/dist/interfaces.js.map +1 -1
- package/dist/loaderContainerTracker.d.ts.map +1 -1
- package/dist/loaderContainerTracker.js +37 -27
- package/dist/loaderContainerTracker.js.map +1 -1
- package/dist/localCodeLoader.d.ts.map +1 -1
- package/dist/localCodeLoader.js.map +1 -1
- package/dist/localLoader.d.ts.map +1 -1
- package/dist/localLoader.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/retry.d.ts.map +1 -1
- package/dist/retry.js.map +1 -1
- package/dist/testContainerRuntimeFactory.d.ts.map +1 -1
- package/dist/testContainerRuntimeFactory.js +2 -1
- package/dist/testContainerRuntimeFactory.js.map +1 -1
- package/dist/testFluidObject.d.ts.map +1 -1
- package/dist/testFluidObject.js +7 -3
- package/dist/testFluidObject.js.map +1 -1
- package/dist/testObjectProvider.d.ts +4 -1
- package/dist/testObjectProvider.d.ts.map +1 -1
- package/dist/testObjectProvider.js +28 -11
- package/dist/testObjectProvider.js.map +1 -1
- package/dist/timeoutUtils.d.ts.map +1 -1
- package/dist/timeoutUtils.js +4 -3
- package/dist/timeoutUtils.js.map +1 -1
- package/package.json +121 -119
- package/prettier.config.cjs +1 -1
- package/src/DriverWrappers.ts +40 -37
- package/src/TestConfigs.ts +9 -7
- package/src/TestSummaryUtils.ts +120 -115
- package/src/containerUtils.ts +18 -16
- package/src/index.ts +27 -23
- package/src/interfaces.ts +10 -7
- package/src/loaderContainerTracker.ts +627 -565
- package/src/localCodeLoader.ts +85 -77
- package/src/localLoader.ts +24 -24
- package/src/packageVersion.ts +1 -1
- package/src/retry.ts +31 -25
- package/src/testContainerRuntimeFactory.ts +59 -56
- package/src/testFluidObject.ts +168 -152
- package/src/testObjectProvider.ts +445 -384
- package/src/timeoutUtils.ts +174 -154
- package/tsconfig.json +9 -16
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testFluidObject.js","sourceRoot":"","sources":["../src/testFluidObject.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 { defaultFluidObjectRequestHandler } from \"@fluidframework/aqueduct\";\nimport {\n IRequest,\n IResponse,\n IFluidHandle,\n IFluidRouter,\n FluidObject,\n IProvideFluidRouter,\n} from \"@fluidframework/core-interfaces\";\nimport { FluidObjectHandle, FluidDataStoreRuntime, mixinRequestHandler } from \"@fluidframework/datastore\";\nimport { SharedMap, ISharedMap } from \"@fluidframework/map\";\nimport {\n IFluidDataStoreContext,\n IFluidDataStoreFactory,\n IFluidDataStoreChannel,\n} from \"@fluidframework/runtime-definitions\";\nimport { IFluidDataStoreRuntime, IChannelFactory } from \"@fluidframework/datastore-definitions\";\nimport { assert } from \"@fluidframework/common-utils\";\nimport { ITestFluidObject } from \"./interfaces\";\n\n/**\n * A test Fluid object that will create a shared object for each key-value pair in the factoryEntries passed to load.\n * The shared objects can be retrieved by passing the key of the entry to getSharedObject.\n * It exposes the IFluidDataStoreContext and IFluidDataStoreRuntime.\n */\nexport class TestFluidObject implements ITestFluidObject, IFluidRouter {\n public static async load(\n runtime: IFluidDataStoreRuntime,\n channel: IFluidDataStoreChannel,\n context: IFluidDataStoreContext,\n factoryEntries: Map<string, IChannelFactory>,\n existing: boolean,\n ) {\n const fluidObject = new TestFluidObject(runtime, channel, context, factoryEntries);\n await fluidObject.initialize(existing);\n\n return fluidObject;\n }\n\n public get ITestFluidObject() {\n return this;\n }\n\n public get IFluidLoadable() {\n return this;\n }\n\n public get IFluidRouter() {\n return this;\n }\n\n public get handle(): IFluidHandle<this> { return this.innerHandle; }\n\n public root!: ISharedMap;\n private readonly innerHandle: IFluidHandle<this>;\n\n /**\n * Creates a new TestFluidObject.\n * @param runtime - The data store runtime.\n * @param context - The data store context.\n * @param factoryEntries - A list of id to IChannelFactory mapping. For each item in the list,\n * a shared object is created which can be retrieved by calling getSharedObject() with the id;\n */\n constructor(\n public readonly runtime: IFluidDataStoreRuntime,\n public readonly channel: IFluidDataStoreChannel,\n public readonly context: IFluidDataStoreContext,\n private readonly factoryEntriesMap: Map<string, IChannelFactory>,\n ) {\n this.innerHandle = new FluidObjectHandle(this, \"\", runtime.objectsRoutingContext);\n }\n\n /**\n * Retrieves a shared object with the given id.\n * @param id - The id of the shared object to retrieve.\n */\n public async getSharedObject<T = any>(id: string): Promise<T> {\n if (this.factoryEntriesMap === undefined) {\n throw new Error(\"Shared objects were not provided during creation.\");\n }\n\n for (const key of this.factoryEntriesMap.keys()) {\n if (key === id) {\n const handle = this.root.get<IFluidHandle>(id);\n return handle?.get() as unknown as T;\n }\n }\n\n throw new Error(`Shared object with id ${id} not found.`);\n }\n\n public async request(request: IRequest): Promise<IResponse> {\n return defaultFluidObjectRequestHandler(this, request);\n }\n\n private async initialize(existing: boolean) {\n if (!existing) {\n this.root = SharedMap.create(this.runtime, \"root\");\n\n this.factoryEntriesMap.forEach((sharedObjectFactory: IChannelFactory, key: string) => {\n const sharedObject = this.runtime.createChannel(key, sharedObjectFactory.type);\n this.root.set(key, sharedObject.handle);\n });\n\n this.root.bindToContext();\n }\n\n this.root = await this.runtime.getChannel(\"root\") as ISharedMap;\n }\n}\n\nexport type ChannelFactoryRegistry = Iterable<[string | undefined, IChannelFactory]>;\n\n/**\n * Creates a factory for a TestFluidObject with the given object factory entries. It creates a data store runtime\n * with the object factories in the entry list. All the entries with an id other than undefined are passed to the\n * Fluid object so that it can create a shared object for each.\n *\n * @example\n * The following will create a Fluid object that creates and loads a SharedString and SharedDirectory.\n * It will add SparseMatrix to the data store's factory so that it can be created later.\n *\n * ```typescript\n * new TestFluidObjectFactory([\n * [ \"sharedString\", SharedString.getFactory() ],\n * [ \"sharedDirectory\", SharedDirectory.getFactory() ],\n * [ undefined, SparseMatrix.getFactory() ],\n * ]);\n * ```\n *\n * The SharedString and SharedDirectory can be retrieved via getSharedObject() on the TestFluidObject as follows:\n *\n * ```typescript\n * sharedString = testFluidObject.getSharedObject<SharedString>(\"sharedString\");\n * sharedDir = testFluidObject.getSharedObject<SharedDirectory>(\"sharedDirectory\");\n * ```\n */\nexport class TestFluidObjectFactory implements IFluidDataStoreFactory {\n public get IFluidDataStoreFactory() { return this; }\n\n /**\n * Creates a new TestFluidObjectFactory.\n * @param factoryEntries - A list of id to IChannelFactory mapping. It creates a data store runtime with each\n * IChannelFactory. Entries with string ids are passed to the Fluid object so that it can create a shared object\n * for it.\n */\n constructor(private readonly factoryEntries: ChannelFactoryRegistry,\n public readonly type = \"TestFluidObjectFactory\") { }\n\n public async instantiateDataStore(\n context: IFluidDataStoreContext,\n existing: boolean,\n ): Promise<FluidDataStoreRuntime> {\n const dataTypes = new Map<string, IChannelFactory>();\n\n // Add SharedMap's factory which will be used to create the root map.\n const sharedMapFactory = SharedMap.getFactory();\n dataTypes.set(sharedMapFactory.type, sharedMapFactory);\n\n // Add the object factories to the list to be sent to data store runtime.\n for (const entry of this.factoryEntries) {\n const factory = entry[1];\n dataTypes.set(factory.type, factory);\n }\n\n // Create a map from the factory entries with entries that don't have the id as undefined. This will be\n // passed to the Fluid object.\n const factoryEntriesMapForObject = new Map<string, IChannelFactory>();\n for (const entry of this.factoryEntries) {\n const id = entry[0];\n if (id !== undefined) {\n factoryEntriesMapForObject.set(id, entry[1]);\n }\n }\n\n const runtimeClass = mixinRequestHandler(\n async (request: IRequest, rt: FluidDataStoreRuntime) => {\n const maybeRouter: FluidObject<IProvideFluidRouter> | undefined\n = await rt.entryPoint?.get();\n assert(maybeRouter?.IFluidRouter !== undefined, \"entryPoint should have been initialized by now\");\n return maybeRouter.IFluidRouter.request(request);\n });\n\n return new runtimeClass(\n context,\n dataTypes,\n existing,\n async (dataStoreRuntime: IFluidDataStoreRuntime) => TestFluidObject.load(\n dataStoreRuntime,\n // This works because 'runtime' is an instance of runtimeClass (which is a FluidDataStoreRuntime and\n // thus implements IFluidDataStoreChannel) which passes itself as the parameter to this function.\n dataStoreRuntime as FluidDataStoreRuntime,\n context,\n factoryEntriesMapForObject,\n existing,\n ));\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"testFluidObject.js","sourceRoot":"","sources":["../src/testFluidObject.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 { defaultFluidObjectRequestHandler } from \"@fluidframework/aqueduct\";\nimport {\n\tIRequest,\n\tIResponse,\n\tIFluidHandle,\n\tIFluidRouter,\n\tFluidObject,\n\tIProvideFluidRouter,\n} from \"@fluidframework/core-interfaces\";\nimport {\n\tFluidObjectHandle,\n\tFluidDataStoreRuntime,\n\tmixinRequestHandler,\n} from \"@fluidframework/datastore\";\nimport { SharedMap, ISharedMap } from \"@fluidframework/map\";\nimport {\n\tIFluidDataStoreContext,\n\tIFluidDataStoreFactory,\n\tIFluidDataStoreChannel,\n} from \"@fluidframework/runtime-definitions\";\nimport { IFluidDataStoreRuntime, IChannelFactory } from \"@fluidframework/datastore-definitions\";\nimport { assert } from \"@fluidframework/common-utils\";\nimport { ITestFluidObject } from \"./interfaces\";\n\n/**\n * A test Fluid object that will create a shared object for each key-value pair in the factoryEntries passed to load.\n * The shared objects can be retrieved by passing the key of the entry to getSharedObject.\n * It exposes the IFluidDataStoreContext and IFluidDataStoreRuntime.\n */\nexport class TestFluidObject implements ITestFluidObject, IFluidRouter {\n\tpublic static async load(\n\t\truntime: IFluidDataStoreRuntime,\n\t\tchannel: IFluidDataStoreChannel,\n\t\tcontext: IFluidDataStoreContext,\n\t\tfactoryEntries: Map<string, IChannelFactory>,\n\t\texisting: boolean,\n\t) {\n\t\tconst fluidObject = new TestFluidObject(runtime, channel, context, factoryEntries);\n\t\tawait fluidObject.initialize(existing);\n\n\t\treturn fluidObject;\n\t}\n\n\tpublic get ITestFluidObject() {\n\t\treturn this;\n\t}\n\n\tpublic get IFluidLoadable() {\n\t\treturn this;\n\t}\n\n\tpublic get IFluidRouter() {\n\t\treturn this;\n\t}\n\n\tpublic get handle(): IFluidHandle<this> {\n\t\treturn this.innerHandle;\n\t}\n\n\tpublic root!: ISharedMap;\n\tprivate readonly innerHandle: IFluidHandle<this>;\n\n\t/**\n\t * Creates a new TestFluidObject.\n\t * @param runtime - The data store runtime.\n\t * @param context - The data store context.\n\t * @param factoryEntries - A list of id to IChannelFactory mapping. For each item in the list,\n\t * a shared object is created which can be retrieved by calling getSharedObject() with the id;\n\t */\n\tconstructor(\n\t\tpublic readonly runtime: IFluidDataStoreRuntime,\n\t\tpublic readonly channel: IFluidDataStoreChannel,\n\t\tpublic readonly context: IFluidDataStoreContext,\n\t\tprivate readonly factoryEntriesMap: Map<string, IChannelFactory>,\n\t) {\n\t\tthis.innerHandle = new FluidObjectHandle(this, \"\", runtime.objectsRoutingContext);\n\t}\n\n\t/**\n\t * Retrieves a shared object with the given id.\n\t * @param id - The id of the shared object to retrieve.\n\t */\n\tpublic async getSharedObject<T = any>(id: string): Promise<T> {\n\t\tif (this.factoryEntriesMap === undefined) {\n\t\t\tthrow new Error(\"Shared objects were not provided during creation.\");\n\t\t}\n\n\t\tfor (const key of this.factoryEntriesMap.keys()) {\n\t\t\tif (key === id) {\n\t\t\t\tconst handle = this.root.get<IFluidHandle>(id);\n\t\t\t\treturn handle?.get() as unknown as T;\n\t\t\t}\n\t\t}\n\n\t\tthrow new Error(`Shared object with id ${id} not found.`);\n\t}\n\n\tpublic async request(request: IRequest): Promise<IResponse> {\n\t\treturn defaultFluidObjectRequestHandler(this, request);\n\t}\n\n\tprivate async initialize(existing: boolean) {\n\t\tif (!existing) {\n\t\t\tthis.root = SharedMap.create(this.runtime, \"root\");\n\n\t\t\tthis.factoryEntriesMap.forEach((sharedObjectFactory: IChannelFactory, key: string) => {\n\t\t\t\tconst sharedObject = this.runtime.createChannel(key, sharedObjectFactory.type);\n\t\t\t\tthis.root.set(key, sharedObject.handle);\n\t\t\t});\n\n\t\t\tthis.root.bindToContext();\n\t\t}\n\n\t\tthis.root = (await this.runtime.getChannel(\"root\")) as ISharedMap;\n\t}\n}\n\nexport type ChannelFactoryRegistry = Iterable<[string | undefined, IChannelFactory]>;\n\n/**\n * Creates a factory for a TestFluidObject with the given object factory entries. It creates a data store runtime\n * with the object factories in the entry list. All the entries with an id other than undefined are passed to the\n * Fluid object so that it can create a shared object for each.\n *\n * @example\n * The following will create a Fluid object that creates and loads a SharedString and SharedDirectory.\n * It will add SparseMatrix to the data store's factory so that it can be created later.\n *\n * ```typescript\n * new TestFluidObjectFactory([\n * [ \"sharedString\", SharedString.getFactory() ],\n * [ \"sharedDirectory\", SharedDirectory.getFactory() ],\n * [ undefined, SparseMatrix.getFactory() ],\n * ]);\n * ```\n *\n * The SharedString and SharedDirectory can be retrieved via getSharedObject() on the TestFluidObject as follows:\n *\n * ```typescript\n * sharedString = testFluidObject.getSharedObject<SharedString>(\"sharedString\");\n * sharedDir = testFluidObject.getSharedObject<SharedDirectory>(\"sharedDirectory\");\n * ```\n */\nexport class TestFluidObjectFactory implements IFluidDataStoreFactory {\n\tpublic get IFluidDataStoreFactory() {\n\t\treturn this;\n\t}\n\n\t/**\n\t * Creates a new TestFluidObjectFactory.\n\t * @param factoryEntries - A list of id to IChannelFactory mapping. It creates a data store runtime with each\n\t * IChannelFactory. Entries with string ids are passed to the Fluid object so that it can create a shared object\n\t * for it.\n\t */\n\tconstructor(\n\t\tprivate readonly factoryEntries: ChannelFactoryRegistry,\n\t\tpublic readonly type = \"TestFluidObjectFactory\",\n\t) {}\n\n\tpublic async instantiateDataStore(\n\t\tcontext: IFluidDataStoreContext,\n\t\texisting: boolean,\n\t): Promise<FluidDataStoreRuntime> {\n\t\tconst dataTypes = new Map<string, IChannelFactory>();\n\n\t\t// Add SharedMap's factory which will be used to create the root map.\n\t\tconst sharedMapFactory = SharedMap.getFactory();\n\t\tdataTypes.set(sharedMapFactory.type, sharedMapFactory);\n\n\t\t// Add the object factories to the list to be sent to data store runtime.\n\t\tfor (const entry of this.factoryEntries) {\n\t\t\tconst factory = entry[1];\n\t\t\tdataTypes.set(factory.type, factory);\n\t\t}\n\n\t\t// Create a map from the factory entries with entries that don't have the id as undefined. This will be\n\t\t// passed to the Fluid object.\n\t\tconst factoryEntriesMapForObject = new Map<string, IChannelFactory>();\n\t\tfor (const entry of this.factoryEntries) {\n\t\t\tconst id = entry[0];\n\t\t\tif (id !== undefined) {\n\t\t\t\tfactoryEntriesMapForObject.set(id, entry[1]);\n\t\t\t}\n\t\t}\n\n\t\tconst runtimeClass = mixinRequestHandler(\n\t\t\tasync (request: IRequest, rt: FluidDataStoreRuntime) => {\n\t\t\t\tconst maybeRouter: FluidObject<IProvideFluidRouter> | undefined =\n\t\t\t\t\tawait rt.entryPoint?.get();\n\t\t\t\tassert(\n\t\t\t\t\tmaybeRouter?.IFluidRouter !== undefined,\n\t\t\t\t\t\"entryPoint should have been initialized by now\",\n\t\t\t\t);\n\t\t\t\treturn maybeRouter.IFluidRouter.request(request);\n\t\t\t},\n\t\t);\n\n\t\treturn new runtimeClass(\n\t\t\tcontext,\n\t\t\tdataTypes,\n\t\t\texisting,\n\t\t\tasync (dataStoreRuntime: IFluidDataStoreRuntime) =>\n\t\t\t\tTestFluidObject.load(\n\t\t\t\t\tdataStoreRuntime,\n\t\t\t\t\t// This works because 'runtime' is an instance of runtimeClass (which is a FluidDataStoreRuntime and\n\t\t\t\t\t// thus implements IFluidDataStoreChannel) which passes itself as the parameter to this function.\n\t\t\t\t\tdataStoreRuntime as FluidDataStoreRuntime,\n\t\t\t\t\tcontext,\n\t\t\t\t\tfactoryEntriesMapForObject,\n\t\t\t\t\texisting,\n\t\t\t\t),\n\t\t);\n\t}\n}\n"]}
|
|
@@ -70,7 +70,10 @@ export declare const createDocumentId: () => string;
|
|
|
70
70
|
*/
|
|
71
71
|
export declare class EventAndErrorTrackingLogger extends TelemetryLogger {
|
|
72
72
|
private readonly baseLogger;
|
|
73
|
-
/**
|
|
73
|
+
/**
|
|
74
|
+
* Even if these error events are logged, tests should still be allowed to pass
|
|
75
|
+
* Additionally, if downgrade is true, then log as generic (e.g. to avoid polluting the e2e test logs)
|
|
76
|
+
*/
|
|
74
77
|
private readonly allowedErrors;
|
|
75
78
|
constructor(baseLogger: ITelemetryBaseLogger);
|
|
76
79
|
private readonly expectedEvents;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testObjectProvider.d.ts","sourceRoot":"","sources":["../src/testObjectProvider.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AACnG,OAAO,
|
|
1
|
+
{"version":3,"file":"testObjectProvider.d.ts","sourceRoot":"","sources":["../src/testObjectProvider.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AACnG,OAAO,EACN,sBAAsB,EACtB,oBAAoB,EACpB,mBAAmB,EACnB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACN,YAAY,EACZ,MAAM,EAEN,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,wBAAwB,EAAE,MAAM,mCAAmC,CAAC;AAC7E,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EACN,uBAAuB,EACvB,YAAY,EACZ,YAAY,EACZ,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EAAE,WAAW,EAAmB,MAAM,yCAAyC,CAAC;AAEvF,OAAO,EAAgC,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAEhG,OAAO,EAAE,eAAe,EAAmB,MAAM,mBAAmB,CAAC;AAErE,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAO3D,MAAM,WAAW,uBAAuB;IACvC,eAAe,CAAC,GAAG,UAAU,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D,eAAe,CAAC,GAAG,UAAU,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D,eAAe,CAAC,GAAG,UAAU,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D,gBAAgB,CAAC,GAAG,UAAU,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;CACpD;AAED,MAAM,WAAW,mBAAmB;IACnC,qBAAqB,EAAE,CAAC,mBAAmB,CAAC,EAAE,oBAAoB,KAAK,eAAe,CAAC;IACvF,YAAY,CACX,cAAc,EAAE,QAAQ,CAAC,CAAC,iBAAiB,EAAE,eAAe,CAAC,CAAC,EAC9D,WAAW,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GACjC,WAAW,CAAC;IACf,eAAe,CACd,UAAU,EAAE,eAAe,EAC3B,WAAW,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GACjC,OAAO,CAAC,UAAU,CAAC,CAAC;IACvB,aAAa,CACZ,UAAU,EAAE,eAAe,EAC3B,WAAW,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,EACnC,aAAa,CAAC,EAAE,cAAc,GAC5B,OAAO,CAAC,UAAU,CAAC,CAAC;IAEvB;;;OAGG;IACH,cAAc,CAAC,mBAAmB,CAAC,EAAE,oBAAoB,GAAG,WAAW,CAAC;IACxE,iBAAiB,CAAC,mBAAmB,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACnF,iBAAiB,CAChB,mBAAmB,CAAC,EAAE,oBAAoB,EAC1C,aAAa,CAAC,EAAE,cAAc,GAC5B,OAAO,CAAC,UAAU,CAAC,CAAC;IACvB;;;OAGG;IACH,gBAAgB,CAAC,GAAG,EAAE,YAAY,GAAG,SAAS,GAAG,IAAI,CAAC;IAEtD,MAAM,EAAE,oBAAoB,CAAC;IAC7B,sBAAsB,EAAE,uBAAuB,CAAC;IAChD,WAAW,EAAE,YAAY,CAAC;IAC1B,kBAAkB,EAAE,iBAAiB,CAAC;IACtC,sBAAsB,EAAE,uBAAuB,CAAC;IAEhD,kBAAkB,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D,KAAK,IAAI,IAAI,CAAC;IAEd,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,WAAW,CAAC;CACpB;AAED,oBAAY,qBAAqB;IAChC,MAAM,IAAA;IACN,IAAI,IAAA;CACJ;AAED,MAAM,WAAW,oBAAoB;IACpC,qDAAqD;IACrD,mBAAmB,CAAC,EAAE,qBAAqB,CAAC;IAE5C,yFAAyF;IACzF,QAAQ,CAAC,EAAE,sBAAsB,CAAC;IAElC,2DAA2D;IAC3D,cAAc,CAAC,EAAE,wBAAwB,CAAC;IAE1C,oFAAoF;IACpF,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B,8DAA8D;IAC9D,WAAW,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;CACpC;AAED,eAAO,MAAM,gBAAgB,QAAO,MAAgB,CAAC;AAsCrD;;;;;GAKG;AACH,qBAAa,2BAA4B,SAAQ,eAAe;IAenD,OAAO,CAAC,QAAQ,CAAC,UAAU;IAdvC;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,aAAa,CAQ5B;gBAE2B,UAAU,EAAE,oBAAoB;IAI7D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAGtB;IACT,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA6B;IAEvD,qBAAqB,CAAC,GAAG,qBAAqB,EAAE,sBAAsB,EAAE;IAc/E,IAAI,CAAC,KAAK,EAAE,mBAAmB,GAAG,IAAI;IAsC/B,2BAA2B;;;;;;;CAQlC;AAED;;GAEG;AACH,qBAAa,kBAAmB,YAAW,mBAAmB;aAe5C,iBAAiB,EAAE,OAAO,MAAM;aAChC,MAAM,EAAE,WAAW;aACnB,qBAAqB,EAAE,CACtC,mBAAmB,CAAC,EAAE,oBAAoB,KACtC,eAAe;IAlBrB,OAAO,CAAC,uBAAuB,CAAgC;IAC/D,OAAO,CAAC,uBAAuB,CAAsC;IACrE,OAAO,CAAC,YAAY,CAA2B;IAC/C,OAAO,CAAC,OAAO,CAA0C;IACzD,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAsB;IAE1D,OAAO,CAAC,gBAAgB,CAAS;IAEjC;;;;OAIG;gBAEc,iBAAiB,EAAE,OAAO,MAAM,EAChC,MAAM,EAAE,WAAW,EACnB,qBAAqB,EAAE,CACtC,mBAAmB,CAAC,EAAE,oBAAoB,KACtC,eAAe;IAKrB,IAAI,MAAM,IAAI,2BAA2B,CAcxC;IAED,IAAI,MAAM,CAAC,MAAM,EAAE,2BAA2B,EAE7C;IAED,IAAI,sBAAsB,4BAKzB;IAED,IAAI,WAAW,iBAKd;IAED,IAAI,UAAU,WAEb;IAED,IAAI,kBAAkB,sBAErB;IAED,IAAI,sBAAsB,IAAI,uBAAuB,CAEpD;IAED;;;;;;;OAOG;IACI,YAAY,CAClB,cAAc,EAAE,QAAQ,CAAC,CAAC,iBAAiB,EAAE,eAAe,CAAC,CAAC,EAC9D,WAAW,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC;IAoBpC;;;;;;;;OAQG;IACU,eAAe,CAAC,UAAU,EAAE,eAAe,EAAE,WAAW,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC;IAmBhF,aAAa,CACzB,UAAU,EAAE,eAAe,EAC3B,WAAW,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,EACnC,aAAa,CAAC,EAAE,cAAc,GAC5B,OAAO,CAAC,UAAU,CAAC;IAQtB;;;;OAIG;IACI,cAAc,CAAC,mBAAmB,CAAC,EAAE,oBAAoB;IAOhE;;;;OAIG;IACU,iBAAiB,CAC7B,mBAAmB,CAAC,EAAE,oBAAoB,GACxC,OAAO,CAAC,UAAU,CAAC;IAmBtB;;;;;OAKG;IACU,iBAAiB,CAC7B,mBAAmB,CAAC,EAAE,oBAAoB,EAC1C,aAAa,CAAC,EAAE,cAAc,GAC5B,OAAO,CAAC,UAAU,CAAC;IAWf,KAAK;IAaC,kBAAkB,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM3D,sBAAsB,CAAC,SAAS,EAAE,UAAU;IAYzD,gBAAgB,CAAC,WAAW,EAAE,YAAY,GAAG,SAAS;IAI/C,2BAA2B,CAAC,qBAAqB,GAAE,OAAe;CAIzE;AAED,wBAAgB,8BAA8B,CAC7C,MAAM,EAAE,2BAA2B,GAAG,SAAS,EAC/C,MAAM,CAAC,EAAE,MAAM,qBAwBf"}
|
|
@@ -34,7 +34,9 @@ function getDocumentIdStrategy(type) {
|
|
|
34
34
|
return {
|
|
35
35
|
get: () => documentId,
|
|
36
36
|
update: () => { },
|
|
37
|
-
reset: () => {
|
|
37
|
+
reset: () => {
|
|
38
|
+
documentId = (0, exports.createDocumentId)();
|
|
39
|
+
},
|
|
38
40
|
};
|
|
39
41
|
default:
|
|
40
42
|
return {
|
|
@@ -45,7 +47,9 @@ function getDocumentIdStrategy(type) {
|
|
|
45
47
|
(0, driver_utils_1.ensureFluidResolvedUrl)(resolvedUrl);
|
|
46
48
|
documentId = (_a = resolvedUrl.id) !== null && _a !== void 0 ? _a : documentId;
|
|
47
49
|
},
|
|
48
|
-
reset: () => {
|
|
50
|
+
reset: () => {
|
|
51
|
+
documentId = (0, exports.createDocumentId)();
|
|
52
|
+
},
|
|
49
53
|
};
|
|
50
54
|
}
|
|
51
55
|
}
|
|
@@ -59,10 +63,18 @@ class EventAndErrorTrackingLogger extends telemetry_utils_1.TelemetryLogger {
|
|
|
59
63
|
constructor(baseLogger) {
|
|
60
64
|
super();
|
|
61
65
|
this.baseLogger = baseLogger;
|
|
62
|
-
/**
|
|
66
|
+
/**
|
|
67
|
+
* Even if these error events are logged, tests should still be allowed to pass
|
|
68
|
+
* Additionally, if downgrade is true, then log as generic (e.g. to avoid polluting the e2e test logs)
|
|
69
|
+
*/
|
|
63
70
|
this.allowedErrors = [
|
|
64
71
|
// This log was removed in current version as unnecessary, but it's still present in previous versions
|
|
65
|
-
|
|
72
|
+
{
|
|
73
|
+
eventName: "fluid:telemetry:Container:NoRealStorageInDetachedContainer",
|
|
74
|
+
downgrade: true,
|
|
75
|
+
},
|
|
76
|
+
// 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.
|
|
77
|
+
{ eventName: "fluid:telemetry:OpPerf:OpRoundtripTime" },
|
|
66
78
|
];
|
|
67
79
|
this.expectedEvents = [];
|
|
68
80
|
this.unexpectedErrors = [];
|
|
@@ -71,8 +83,8 @@ class EventAndErrorTrackingLogger extends telemetry_utils_1.TelemetryLogger {
|
|
|
71
83
|
if (this.expectedEvents.length !== 0) {
|
|
72
84
|
// we don't have to error here. just no reason not to. given the events must be
|
|
73
85
|
// ordered it could be tricky to figure out problems around multiple registrations.
|
|
74
|
-
throw new Error("Expected events already registered.\n"
|
|
75
|
-
|
|
86
|
+
throw new Error("Expected events already registered.\n" +
|
|
87
|
+
"Call reportAndClearTrackedEvents to clear them before registering more");
|
|
76
88
|
}
|
|
77
89
|
this.expectedEvents.push(...orderedExpectedEvents.map((event, index) => ({ index, event })));
|
|
78
90
|
}
|
|
@@ -100,12 +112,14 @@ class EventAndErrorTrackingLogger extends telemetry_utils_1.TelemetryLogger {
|
|
|
100
112
|
}
|
|
101
113
|
}
|
|
102
114
|
if (event.category === "error") {
|
|
103
|
-
if
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
else {
|
|
115
|
+
// Check to see if this error is allowed and if its category should be downgraded
|
|
116
|
+
const allowedError = this.allowedErrors.find(({ eventName }) => eventName === event.eventName);
|
|
117
|
+
if (allowedError === undefined) {
|
|
107
118
|
this.unexpectedErrors.push(event);
|
|
108
119
|
}
|
|
120
|
+
else if (allowedError.downgrade) {
|
|
121
|
+
event.category = "generic";
|
|
122
|
+
}
|
|
109
123
|
}
|
|
110
124
|
this.baseLogger.send(event);
|
|
111
125
|
}
|
|
@@ -216,7 +230,10 @@ class TestObjectProvider {
|
|
|
216
230
|
}
|
|
217
231
|
async loadContainer(entryPoint, loaderProps, requestHeader) {
|
|
218
232
|
const loader = this.createLoader([[defaultCodeDetails, entryPoint]], loaderProps);
|
|
219
|
-
return loader.resolve({
|
|
233
|
+
return loader.resolve({
|
|
234
|
+
url: await this.driver.createContainerUrl(this.documentId),
|
|
235
|
+
headers: requestHeader,
|
|
236
|
+
});
|
|
220
237
|
}
|
|
221
238
|
/**
|
|
222
239
|
* Make a test loader. Containers created/loaded through this loader will be added to the OpProcessingController.
|
|
@@ -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 { IContainer, IHostLoader, IFluidCodeDetails } from \"@fluidframework/container-definitions\";\nimport { ITelemetryGenericEvent, ITelemetryBaseLogger, ITelemetryBaseEvent } from \"@fluidframework/common-definitions\";\nimport {\n ILoaderProps,\n Loader,\n waitContainerToCatchUp as waitContainerToCatchUp_original,\n} from \"@fluidframework/container-loader\";\nimport { IContainerRuntimeOptions } from \"@fluidframework/container-runtime\";\nimport { IRequestHeader } from \"@fluidframework/core-interfaces\";\nimport { IDocumentServiceFactory, IResolvedUrl, IUrlResolver } from \"@fluidframework/driver-definitions\";\nimport { ensureFluidResolvedUrl } from \"@fluidframework/driver-utils\";\nimport { ITestDriver, TestDriverTypes } from \"@fluidframework/test-driver-definitions\";\nimport { v4 as uuid } from \"uuid\";\nimport { ChildLogger, MultiSinkLogger, TelemetryLogger } from \"@fluidframework/telemetry-utils\";\nimport { LoaderContainerTracker } from \"./loaderContainerTracker\";\nimport { fluidEntryPoint, LocalCodeLoader } from \"./localCodeLoader\";\nimport { createAndAttachContainer } from \"./localLoader\";\nimport { ChannelFactoryRegistry } from \"./testFluidObject\";\n\nconst defaultCodeDetails: IFluidCodeDetails = {\n package: \"defaultTestPackage\",\n config: {},\n};\n\nexport interface IOpProcessingController {\n processIncoming(...containers: IContainer[]): Promise<void>;\n processOutgoing(...containers: IContainer[]): Promise<void>;\n pauseProcessing(...containers: IContainer[]): Promise<void>;\n resumeProcessing(...containers: IContainer[]): void;\n}\n\nexport interface ITestObjectProvider {\n createFluidEntryPoint: (testContainerConfig?: ITestContainerConfig) => fluidEntryPoint;\n createLoader(\n packageEntries: Iterable<[IFluidCodeDetails, fluidEntryPoint]>,\n loaderProps?: Partial<ILoaderProps>,\n ): IHostLoader;\n createContainer(entryPoint: fluidEntryPoint, loaderProps?: Partial<ILoaderProps>): Promise<IContainer>;\n loadContainer(\n entryPoint: fluidEntryPoint,\n loaderProps?: Partial<ILoaderProps>,\n requestHeader?: IRequestHeader,\n ): Promise<IContainer>;\n\n /**\n * Used to create a test Container. The Loader/ContainerRuntime/DataRuntime might be different versioned.\n * In generateLocalCompatTest(), this Container and its runtime will be arbitrarily-versioned.\n */\n makeTestLoader(testContainerConfig?: ITestContainerConfig): IHostLoader;\n makeTestContainer(testContainerConfig?: ITestContainerConfig): Promise<IContainer>;\n loadTestContainer(testContainerConfig?: ITestContainerConfig, requestHeader?: IRequestHeader): Promise<IContainer>;\n /**\n *\n * @param url - Resolved container URL\n */\n updateDocumentId(url: IResolvedUrl | undefined): void;\n\n logger: ITelemetryBaseLogger;\n documentServiceFactory: IDocumentServiceFactory;\n urlResolver: IUrlResolver;\n defaultCodeDetails: IFluidCodeDetails;\n opProcessingController: IOpProcessingController;\n\n ensureSynchronized(timeoutDuration?: number): Promise<void>;\n reset(): void;\n\n documentId: string;\n driver: ITestDriver;\n}\n\nexport enum DataObjectFactoryType {\n Primed, // default\n Test,\n}\n\nexport interface ITestContainerConfig {\n /** TestFluidDataObject instead of PrimedDataStore */\n fluidDataObjectType?: DataObjectFactoryType;\n\n /** An array of channel name and DDS factory pair to create on container creation time */\n registry?: ChannelFactoryRegistry;\n\n /** Container runtime options for the container instance */\n runtimeOptions?: IContainerRuntimeOptions;\n\n /** Whether this runtime should be instantiated using a mixed-in attributor class */\n enableAttribution?: boolean;\n\n /** Loader options for the loader used to create containers */\n loaderProps?: Partial<ILoaderProps>;\n}\n\nexport const createDocumentId = (): string => uuid();\n\ninterface IDocumentIdStrategy {\n get(): string;\n update(resolvedUrl?: IResolvedUrl): void;\n reset(): 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 let documentId = createDocumentId();\n switch (type) {\n case \"odsp\":\n return {\n get: () => documentId,\n update: () => { }, // do not update the document ID in odsp test cases\n reset: () => { documentId = createDocumentId(); },\n };\n default:\n return {\n get: () => documentId,\n update: (resolvedUrl?: IResolvedUrl) => {\n // Extract the document ID from the resolved container's URL and reset the ID property\n ensureFluidResolvedUrl(resolvedUrl);\n documentId = resolvedUrl.id ?? documentId;\n },\n reset: () => { documentId = createDocumentId(); },\n };\n }\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 */\nexport class EventAndErrorTrackingLogger extends TelemetryLogger {\n /** Even if these error events are logged, tests should still be allowed to pass */\n private readonly allowedErrors: string[] = [\n // This log was removed in current version as unnecessary, but it's still present in previous versions\n \"fluid:telemetry:Container:NoRealStorageInDetachedContainer\",\n ];\n\n constructor(private readonly baseLogger: ITelemetryBaseLogger) {\n super();\n }\n\n private readonly expectedEvents: ({ index: number; event: ITelemetryGenericEvent | undefined; } | undefined)[] = [];\n private readonly unexpectedErrors: ITelemetryBaseEvent[] = [];\n\n public registerExpectedEvent(...orderedExpectedEvents: ITelemetryGenericEvent[]) {\n if (this.expectedEvents.length !== 0) {\n // we don't have to error here. just no reason not to. given the events must be\n // ordered it could be tricky to figure out problems around multiple registrations.\n throw new Error(\n \"Expected events already registered.\\n\"\n + \"Call reportAndClearTrackedEvents to clear them before registering more\");\n }\n this.expectedEvents.push(...orderedExpectedEvents.map((event, index) => ({ index, event })));\n }\n\n send(event: ITelemetryBaseEvent): void {\n const ee = this.expectedEvents[0]?.event;\n if (ee?.eventName === event.eventName) {\n let matches = true;\n for (const key of Object.keys(ee)) {\n if (ee[key] !== event[key]) {\n matches = false;\n break;\n }\n }\n if (matches) {\n // we found an expected event\n // so remove it from the list of expected events\n // and if it is an error, change it to generic\n // this helps keep our telemetry clear of\n // expected errors.\n this.expectedEvents.shift();\n if (event.category === \"error\") {\n event.category = \"generic\";\n }\n }\n }\n if (event.category === \"error\") {\n if (this.allowedErrors.includes(event.eventName)) {\n event.category = \"generic\";\n } else {\n this.unexpectedErrors.push(event);\n }\n }\n\n this.baseLogger.send(event);\n }\n\n public reportAndClearTrackedEvents() {\n const expectedNotFound = this.expectedEvents.splice(0, this.expectedEvents.length);\n const unexpectedErrors = this.unexpectedErrors.splice(0, this.unexpectedErrors.length);\n return {\n expectedNotFound,\n unexpectedErrors,\n };\n }\n}\n\n/**\n * Shared base class for test object provider. Contain code for loader and container creation and loading\n */\nexport class TestObjectProvider implements ITestObjectProvider {\n private _loaderContainerTracker = new LoaderContainerTracker();\n private _documentServiceFactory: IDocumentServiceFactory | undefined;\n private _urlResolver: IUrlResolver | undefined;\n private _logger: EventAndErrorTrackingLogger | undefined;\n private readonly _documentIdStrategy: IDocumentIdStrategy;\n // Since documentId doesn't change we can only create/make one container. Call the load functions instead.\n private _documentCreated = false;\n\n /**\n * Manage objects for loading and creating container, including the driver, loader, and OpProcessingController\n * @param createFluidEntryPoint - callback to create a fluidEntryPoint, with an optional set of channel name\n * and factory for TestFluidObject\n */\n constructor(\n public readonly LoaderConstructor: typeof Loader,\n public readonly driver: ITestDriver,\n public readonly createFluidEntryPoint: (testContainerConfig?: ITestContainerConfig) => fluidEntryPoint,\n ) {\n this._documentIdStrategy = getDocumentIdStrategy(driver.type);\n }\n\n get logger(): EventAndErrorTrackingLogger {\n if (this._logger === undefined) {\n this._logger = new EventAndErrorTrackingLogger(\n ChildLogger.create(getTestLogger?.(), undefined,\n {\n all: {\n driverType: this.driver.type,\n driverEndpointName: this.driver.endpointName,\n driverTenantName: this.driver.tenantName,\n driverUserIndex: this.driver.userIndex,\n },\n }));\n }\n return this._logger;\n }\n\n set logger(logger: EventAndErrorTrackingLogger) {\n this._logger = logger;\n }\n\n get documentServiceFactory() {\n if (!this._documentServiceFactory) {\n this._documentServiceFactory = this.driver.createDocumentServiceFactory();\n }\n return this._documentServiceFactory;\n }\n\n get urlResolver() {\n if (!this._urlResolver) {\n this._urlResolver = this.driver.createUrlResolver();\n }\n return this._urlResolver;\n }\n\n get documentId() {\n return this._documentIdStrategy.get();\n }\n\n get defaultCodeDetails() {\n return defaultCodeDetails;\n }\n\n get opProcessingController(): IOpProcessingController {\n return this._loaderContainerTracker;\n }\n\n /**\n * Create a loader. Containers created/loaded through this loader will be added to the OpProcessingController.\n *\n * Only the version of the loader will vary based on compat config. The version of\n * containerRuntime/dataRuntime used in fluidEntryPoint will be used as is from what is passed in.\n *\n * @param packageEntries - list of code details and fluidEntryPoint pairs.\n */\n public createLoader(\n packageEntries: Iterable<[IFluidCodeDetails, fluidEntryPoint]>,\n loaderProps?: Partial<ILoaderProps>,\n ) {\n const multiSinkLogger = new MultiSinkLogger();\n multiSinkLogger.addLogger(this.logger);\n if (loaderProps?.logger !== undefined) {\n multiSinkLogger.addLogger(loaderProps.logger);\n }\n\n const loader = new this.LoaderConstructor({\n ...loaderProps,\n logger: multiSinkLogger,\n codeLoader: loaderProps?.codeLoader ?? new LocalCodeLoader(packageEntries),\n urlResolver: loaderProps?.urlResolver ?? this.urlResolver,\n documentServiceFactory: loaderProps?.documentServiceFactory ?? this.documentServiceFactory,\n });\n this._loaderContainerTracker.add(loader);\n return loader;\n }\n\n /**\n * Create a container using a default document id and code details.\n * Container created is automatically added to the OpProcessingController to manage op flow\n *\n * Only the version of the loader will vary based on compat config. The version of\n * containerRuntime/dataRuntime used in fluidEntryPoint will be used as is from what is passed in.\n *\n * @param packageEntries - list of code details and fluidEntryPoint pairs.\n */\n public async createContainer(entryPoint: fluidEntryPoint, loaderProps?: Partial<ILoaderProps>) {\n if (this._documentCreated) {\n throw new Error(\n \"Only one container/document can be created. To load the container/document use loadContainer\");\n }\n const loader = this.createLoader([[defaultCodeDetails, entryPoint]], loaderProps);\n const container = await createAndAttachContainer(\n defaultCodeDetails,\n loader,\n this.driver.createCreateNewRequest(this.documentId),\n );\n this._documentCreated = true;\n // r11s driver will generate a new ID for the new container.\n // update the document ID with the actual ID of the attached container.\n this._documentIdStrategy.update(container.resolvedUrl);\n return container;\n }\n\n public async loadContainer(\n entryPoint: fluidEntryPoint,\n loaderProps?: Partial<ILoaderProps>,\n requestHeader?: IRequestHeader): Promise<IContainer> {\n const loader = this.createLoader([[defaultCodeDetails, entryPoint]], loaderProps);\n return loader.resolve({ url: await this.driver.createContainerUrl(this.documentId), headers: requestHeader });\n }\n\n /**\n * Make a test loader. Containers created/loaded through this loader will be added to the OpProcessingController.\n * The version of the loader/containerRuntime/dataRuntime may vary based on compat config of the current run\n * @param testContainerConfig - optional configuring the test Container\n */\n public makeTestLoader(testContainerConfig?: ITestContainerConfig) {\n return this.createLoader(\n [[defaultCodeDetails, this.createFluidEntryPoint(testContainerConfig)]],\n testContainerConfig?.loaderProps,\n );\n }\n\n /**\n * Make a container using a default document id and code details\n * Container loaded is automatically added to the OpProcessingController to manage op flow\n * @param testContainerConfig - optional configuring the test Container\n */\n public async makeTestContainer(testContainerConfig?: ITestContainerConfig): Promise<IContainer> {\n if (this._documentCreated) {\n throw new Error(\n \"Only one container/document can be created. To load the container/document use loadTestContainer\");\n }\n const loader = this.makeTestLoader(testContainerConfig);\n const container =\n await createAndAttachContainer(\n defaultCodeDetails,\n loader,\n this.driver.createCreateNewRequest(this.documentId));\n this._documentCreated = true;\n // r11s driver will generate a new ID for the new container.\n // update the document ID with the actual ID of the attached container.\n this._documentIdStrategy.update(container.resolvedUrl);\n return container;\n }\n\n /**\n * Load a container using a default document id and code details.\n * IContainer loaded is automatically added to the OpProcessingController to manage op flow\n * @param testContainerConfig - optional configuring the test Container\n * @param requestHeader - optional headers to be supplied to the loader\n */\n public async loadTestContainer(\n testContainerConfig?: ITestContainerConfig,\n requestHeader?: IRequestHeader,\n ): Promise<IContainer> {\n const loader = this.makeTestLoader(testContainerConfig);\n const container = await loader.resolve({\n url: await this.driver.createContainerUrl(this.documentId),\n headers: requestHeader,\n });\n await this.waitContainerToCatchUp(container);\n\n return container;\n }\n\n public reset() {\n this._loaderContainerTracker.reset();\n this._documentServiceFactory = undefined;\n this._urlResolver = undefined;\n this._documentIdStrategy.reset();\n const logError = getUnexpectedLogErrorException(this._logger);\n if (logError) {\n throw logError;\n }\n this._logger = undefined;\n this._documentCreated = false;\n }\n\n public async ensureSynchronized(timeoutDuration?: number): Promise<void> {\n return this._loaderContainerTracker.ensureSynchronizedWithTimeout\n ? this._loaderContainerTracker.ensureSynchronizedWithTimeout(timeoutDuration)\n : this._loaderContainerTracker.ensureSynchronized();\n }\n\n public async waitContainerToCatchUp(container: IContainer) {\n // The original waitContainerToCatchUp() from container loader uses either Container.resume()\n // or Container.connect() as part of its implementation. However, resume() was deprecated\n // and eventually replaced with connect(). To avoid issues during LTS compatibility testing\n // with older container versions issues, we use resume() when connect() is unavailable.\n if ((container as any).connect === undefined) {\n (container as any).connect = (container as any).resume;\n }\n\n return waitContainerToCatchUp_original(container);\n }\n\n updateDocumentId(resolvedUrl: IResolvedUrl | undefined) {\n this._documentIdStrategy.update(resolvedUrl);\n }\n\n public resetLoaderContainerTracker(syncSummarizerClients: boolean = false) {\n this._loaderContainerTracker.reset();\n this._loaderContainerTracker = new LoaderContainerTracker(syncSummarizerClients);\n }\n}\n\nexport function getUnexpectedLogErrorException(logger: EventAndErrorTrackingLogger | undefined, prefix?: string) {\n if (logger === undefined) {\n return;\n }\n const results = logger.reportAndClearTrackedEvents();\n if (results.unexpectedErrors.length > 0) {\n return new Error(\n `${prefix ?? \"\"}Unexpected Errors in Logs:\\n${JSON.stringify(results.unexpectedErrors, undefined, 2)}`);\n }\n if (results.expectedNotFound.length > 0) {\n return new Error(\n `${prefix ?? \"\"}Expected Events not found:\\n${JSON.stringify(results.expectedNotFound, undefined, 2)}`);\n }\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 { IContainer, IHostLoader, IFluidCodeDetails } from \"@fluidframework/container-definitions\";\nimport {\n\tITelemetryGenericEvent,\n\tITelemetryBaseLogger,\n\tITelemetryBaseEvent,\n} from \"@fluidframework/common-definitions\";\nimport {\n\tILoaderProps,\n\tLoader,\n\twaitContainerToCatchUp as waitContainerToCatchUp_original,\n} from \"@fluidframework/container-loader\";\nimport { IContainerRuntimeOptions } from \"@fluidframework/container-runtime\";\nimport { IRequestHeader } from \"@fluidframework/core-interfaces\";\nimport {\n\tIDocumentServiceFactory,\n\tIResolvedUrl,\n\tIUrlResolver,\n} from \"@fluidframework/driver-definitions\";\nimport { ensureFluidResolvedUrl } from \"@fluidframework/driver-utils\";\nimport { ITestDriver, TestDriverTypes } from \"@fluidframework/test-driver-definitions\";\nimport { v4 as uuid } from \"uuid\";\nimport { ChildLogger, MultiSinkLogger, TelemetryLogger } from \"@fluidframework/telemetry-utils\";\nimport { LoaderContainerTracker } from \"./loaderContainerTracker\";\nimport { fluidEntryPoint, LocalCodeLoader } from \"./localCodeLoader\";\nimport { createAndAttachContainer } from \"./localLoader\";\nimport { ChannelFactoryRegistry } from \"./testFluidObject\";\n\nconst defaultCodeDetails: IFluidCodeDetails = {\n\tpackage: \"defaultTestPackage\",\n\tconfig: {},\n};\n\nexport interface IOpProcessingController {\n\tprocessIncoming(...containers: IContainer[]): Promise<void>;\n\tprocessOutgoing(...containers: IContainer[]): Promise<void>;\n\tpauseProcessing(...containers: IContainer[]): Promise<void>;\n\tresumeProcessing(...containers: IContainer[]): void;\n}\n\nexport interface ITestObjectProvider {\n\tcreateFluidEntryPoint: (testContainerConfig?: ITestContainerConfig) => fluidEntryPoint;\n\tcreateLoader(\n\t\tpackageEntries: Iterable<[IFluidCodeDetails, fluidEntryPoint]>,\n\t\tloaderProps?: Partial<ILoaderProps>,\n\t): IHostLoader;\n\tcreateContainer(\n\t\tentryPoint: fluidEntryPoint,\n\t\tloaderProps?: Partial<ILoaderProps>,\n\t): Promise<IContainer>;\n\tloadContainer(\n\t\tentryPoint: fluidEntryPoint,\n\t\tloaderProps?: Partial<ILoaderProps>,\n\t\trequestHeader?: IRequestHeader,\n\t): Promise<IContainer>;\n\n\t/**\n\t * Used to create a test Container. The Loader/ContainerRuntime/DataRuntime might be different versioned.\n\t * In generateLocalCompatTest(), this Container and its runtime will be arbitrarily-versioned.\n\t */\n\tmakeTestLoader(testContainerConfig?: ITestContainerConfig): IHostLoader;\n\tmakeTestContainer(testContainerConfig?: ITestContainerConfig): Promise<IContainer>;\n\tloadTestContainer(\n\t\ttestContainerConfig?: ITestContainerConfig,\n\t\trequestHeader?: IRequestHeader,\n\t): Promise<IContainer>;\n\t/**\n\t *\n\t * @param url - Resolved container URL\n\t */\n\tupdateDocumentId(url: IResolvedUrl | undefined): void;\n\n\tlogger: ITelemetryBaseLogger;\n\tdocumentServiceFactory: IDocumentServiceFactory;\n\turlResolver: IUrlResolver;\n\tdefaultCodeDetails: IFluidCodeDetails;\n\topProcessingController: IOpProcessingController;\n\n\tensureSynchronized(timeoutDuration?: number): Promise<void>;\n\treset(): void;\n\n\tdocumentId: string;\n\tdriver: ITestDriver;\n}\n\nexport enum DataObjectFactoryType {\n\tPrimed, // default\n\tTest,\n}\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?: IContainerRuntimeOptions;\n\n\t/** Whether this runtime should be instantiated using a mixed-in attributor class */\n\tenableAttribution?: boolean;\n\n\t/** Loader options for the loader used to create containers */\n\tloaderProps?: Partial<ILoaderProps>;\n}\n\nexport const createDocumentId = (): string => uuid();\n\ninterface IDocumentIdStrategy {\n\tget(): string;\n\tupdate(resolvedUrl?: IResolvedUrl): void;\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\tensureFluidResolvedUrl(resolvedUrl);\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/**\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 */\nexport class EventAndErrorTrackingLogger extends TelemetryLogger {\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:OpPerf:OpRoundtripTime\" },\n\t];\n\n\tconstructor(private readonly baseLogger: ITelemetryBaseLogger) {\n\t\tsuper();\n\t}\n\n\tprivate readonly expectedEvents: (\n\t\t| { index: number; event: ITelemetryGenericEvent | undefined }\n\t\t| undefined\n\t)[] = [];\n\tprivate readonly unexpectedErrors: ITelemetryBaseEvent[] = [];\n\n\tpublic registerExpectedEvent(...orderedExpectedEvents: ITelemetryGenericEvent[]) {\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\tconst ee = this.expectedEvents[0]?.event;\n\t\tif (ee?.eventName === event.eventName) {\n\t\t\tlet matches = true;\n\t\t\tfor (const key of Object.keys(ee)) {\n\t\t\t\tif (ee[key] !== event[key]) {\n\t\t\t\t\tmatches = false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (matches) {\n\t\t\t\t// we found an expected event\n\t\t\t\t// so remove it from the list of expected events\n\t\t\t\t// and if it is an error, change it to generic\n\t\t\t\t// this helps keep our telemetry clear of\n\t\t\t\t// expected errors.\n\t\t\t\tthis.expectedEvents.shift();\n\t\t\t\tif (event.category === \"error\") {\n\t\t\t\t\tevent.category = \"generic\";\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\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 */\nexport class TestObjectProvider implements ITestObjectProvider {\n\tprivate _loaderContainerTracker = new LoaderContainerTracker();\n\tprivate _documentServiceFactory: IDocumentServiceFactory | undefined;\n\tprivate _urlResolver: IUrlResolver | undefined;\n\tprivate _logger: 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\tpublic readonly LoaderConstructor: typeof Loader,\n\t\tpublic readonly driver: ITestDriver,\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\tget logger(): EventAndErrorTrackingLogger {\n\t\tif (this._logger === undefined) {\n\t\t\tthis._logger = new EventAndErrorTrackingLogger(\n\t\t\t\tChildLogger.create(getTestLogger?.(), undefined, {\n\t\t\t\t\tall: {\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\tset logger(logger: EventAndErrorTrackingLogger) {\n\t\tthis._logger = logger;\n\t}\n\n\tget documentServiceFactory() {\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\tget urlResolver() {\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\tget documentId() {\n\t\treturn this._documentIdStrategy.get();\n\t}\n\n\tget defaultCodeDetails() {\n\t\treturn defaultCodeDetails;\n\t}\n\n\tget opProcessingController(): IOpProcessingController {\n\t\treturn this._loaderContainerTracker;\n\t}\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 */\n\tpublic createLoader(\n\t\tpackageEntries: Iterable<[IFluidCodeDetails, fluidEntryPoint]>,\n\t\tloaderProps?: Partial<ILoaderProps>,\n\t) {\n\t\tconst multiSinkLogger = new MultiSinkLogger();\n\t\tmultiSinkLogger.addLogger(this.logger);\n\t\tif (loaderProps?.logger !== undefined) {\n\t\t\tmultiSinkLogger.addLogger(loaderProps.logger);\n\t\t}\n\n\t\tconst loader = new this.LoaderConstructor({\n\t\t\t...loaderProps,\n\t\t\tlogger: multiSinkLogger,\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 * 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\tpublic async createContainer(entryPoint: fluidEntryPoint, loaderProps?: Partial<ILoaderProps>) {\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._documentIdStrategy.update(container.resolvedUrl);\n\t\treturn container;\n\t}\n\n\tpublic async loadContainer(\n\t\tentryPoint: fluidEntryPoint,\n\t\tloaderProps?: Partial<ILoaderProps>,\n\t\trequestHeader?: IRequestHeader,\n\t): Promise<IContainer> {\n\t\tconst loader = this.createLoader([[defaultCodeDetails, entryPoint]], loaderProps);\n\t\treturn loader.resolve({\n\t\t\turl: await this.driver.createContainerUrl(this.documentId),\n\t\t\theaders: requestHeader,\n\t\t});\n\t}\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\tpublic makeTestLoader(testContainerConfig?: ITestContainerConfig) {\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 * 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\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._documentIdStrategy.update(container.resolvedUrl);\n\t\treturn container;\n\t}\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\tpublic async loadTestContainer(\n\t\ttestContainerConfig?: ITestContainerConfig,\n\t\trequestHeader?: IRequestHeader,\n\t): Promise<IContainer> {\n\t\tconst loader = this.makeTestLoader(testContainerConfig);\n\t\tconst container = await loader.resolve({\n\t\t\turl: await this.driver.createContainerUrl(this.documentId),\n\t\t\theaders: requestHeader,\n\t\t});\n\t\tawait this.waitContainerToCatchUp(container);\n\n\t\treturn container;\n\t}\n\n\tpublic reset() {\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._logger);\n\t\tif (logError) {\n\t\t\tthrow logError;\n\t\t}\n\t\tthis._logger = undefined;\n\t\tthis._documentCreated = false;\n\t}\n\n\tpublic async ensureSynchronized(timeoutDuration?: number): Promise<void> {\n\t\treturn this._loaderContainerTracker.ensureSynchronizedWithTimeout\n\t\t\t? this._loaderContainerTracker.ensureSynchronizedWithTimeout(timeoutDuration)\n\t\t\t: this._loaderContainerTracker.ensureSynchronized();\n\t}\n\n\tpublic async waitContainerToCatchUp(container: IContainer) {\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\tupdateDocumentId(resolvedUrl: IResolvedUrl | undefined) {\n\t\tthis._documentIdStrategy.update(resolvedUrl);\n\t}\n\n\tpublic resetLoaderContainerTracker(syncSummarizerClients: boolean = false) {\n\t\tthis._loaderContainerTracker.reset();\n\t\tthis._loaderContainerTracker = new LoaderContainerTracker(syncSummarizerClients);\n\t}\n}\n\nexport function getUnexpectedLogErrorException(\n\tlogger: EventAndErrorTrackingLogger | undefined,\n\tprefix?: string,\n) {\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,\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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timeoutUtils.d.ts","sourceRoot":"","sources":["../src/timeoutUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAI7D,eAAO,MAAM,wBAAwB,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"timeoutUtils.d.ts","sourceRoot":"","sources":["../src/timeoutUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAI7D,eAAO,MAAM,wBAAwB,MAAM,CAAC;AA6F5C,MAAM,WAAW,gBAAgB;IAChC;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,IAAI,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AACD,MAAM,WAAW,gBAAgB,CAAC,CAAC,GAAG,IAAI;IACzC;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,KAAK,CAAC;IACd,KAAK,EAAE,CAAC,CAAC;CACT;AAED,oBAAY,eAAe,CAAC,CAAC,GAAG,IAAI,IAAI,CACvC,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,IAAI,EAC5C,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,GAAG,KAAK,IAAI,KAC1B,IAAI,CAAC;AAEV,wBAAsB,YAAY,CAAC,CAAC,GAAG,IAAI,EAC1C,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,EACvB,cAAc,GAAE,gBAAgB,GAAG,gBAAgB,CAAC,CAAC,CAAM,cAG3D;AAED,wBAAsB,wBAAwB,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAIlF;AA6CD,wBAAsB,cAAc,CAAC,CAAC,GAAG,IAAI,EAC5C,QAAQ,EAAE,CACT,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,IAAI,EAC5C,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,GAAG,KAAK,IAAI,KAC1B,IAAI,EACT,cAAc,GAAE,gBAAgB,GAAG,gBAAgB,CAAC,CAAC,CAAM,GACzD,OAAO,CAAC,CAAC,CAAC,CA6BZ"}
|
package/dist/timeoutUtils.js
CHANGED
|
@@ -108,7 +108,9 @@ async function getTimeoutPromise(executor, timeoutOptions, err) {
|
|
|
108
108
|
errorObject.message = `${errorObject.message} (${timeout}ms)`;
|
|
109
109
|
reject(err);
|
|
110
110
|
};
|
|
111
|
-
const timer = setTimeout(() => timeoutOptions.reject === false
|
|
111
|
+
const timer = setTimeout(() => timeoutOptions.reject === false
|
|
112
|
+
? resolve(timeoutOptions.value)
|
|
113
|
+
: timeoutRejections(), timeout);
|
|
112
114
|
executor((value) => {
|
|
113
115
|
clearTimeout(timer);
|
|
114
116
|
resolve(value);
|
|
@@ -138,8 +140,7 @@ async function timeoutPromise(executor, timeoutOptions = {}) {
|
|
|
138
140
|
// If the rejection is because of the timeout then
|
|
139
141
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
140
142
|
const errorObject = err;
|
|
141
|
-
errorObject.message =
|
|
142
|
-
`${(_a = timeoutOptions.errorMsg) !== null && _a !== void 0 ? _a : "Test timed out"} (${currentTestTimeout.getTimeout()}ms)`;
|
|
143
|
+
errorObject.message = `${(_a = timeoutOptions.errorMsg) !== null && _a !== void 0 ? _a : "Test timed out"} (${currentTestTimeout.getTimeout()}ms)`;
|
|
143
144
|
throw errorObject;
|
|
144
145
|
}
|
|
145
146
|
return timeoutOptions.value;
|
package/dist/timeoutUtils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timeoutUtils.js","sourceRoot":"","sources":["../src/timeoutUtils.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 { Container } from \"@fluidframework/container-loader\";\nimport { assert, Deferred } from \"@fluidframework/common-utils\";\n\n// @deprecated this value is no longer used\nexport const defaultTimeoutDurationMs = 250;\n\n// TestTimeout class manage tracking of test timeout. It create a timer when timeout is in effect,\n// and provide a promise that will be reject before the test timeout happen with a `timeBuffer` of 15 ms.\n// Once rejected, a new TestTimeout object will be create for the timeout.\n\nconst timeBuffer = 15; // leave 15 ms leeway for finish processing\n\nclass TestTimeout {\n private timeout: number = 0;\n private timer: NodeJS.Timeout | undefined;\n private readonly deferred: Deferred<void>;\n private rejected = false;\n\n private static instance: TestTimeout = new TestTimeout();\n public static reset(runnable: Mocha.Runnable) {\n TestTimeout.clear();\n TestTimeout.instance.resetTimer(runnable);\n }\n\n public static clear() {\n if (TestTimeout.instance.rejected) {\n TestTimeout.instance = new TestTimeout();\n } else {\n TestTimeout.instance.clearTimer();\n }\n }\n\n public static getInstance() {\n return TestTimeout.instance;\n }\n\n public async getPromise() {\n return this.deferred.promise;\n }\n\n public getTimeout() {\n return this.timeout;\n }\n\n private constructor() {\n this.deferred = new Deferred();\n // Ignore rejection for timeout promise if no one is waiting for it.\n this.deferred.promise.catch(() => { });\n }\n\n private resetTimer(runnable: Mocha.Runnable) {\n assert(!this.timer, \"clearTimer should have been called before reset\");\n assert(!this.deferred.isCompleted, \"can't reset a completed TestTimeout\");\n\n // Check the test timeout setting\n const timeout = runnable.timeout();\n if (!(Number.isFinite(timeout) && timeout > 0)) { return; }\n\n // subtract a buffer\n this.timeout = Math.max(timeout - timeBuffer, 1);\n\n // Set up timer to reject near the test timeout.\n this.timer = setTimeout(() => {\n this.deferred.reject(this);\n this.rejected = true;\n }, this.timeout);\n }\n private clearTimer() {\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = undefined;\n }\n }\n}\n\n// only register if we are running with mocha-test-setup loaded\nif (globalThis.getMochaModule !== undefined) {\n // patching resetTimeout and clearTimeout on the runnable object\n // so we can track when test timeout are enforced\n const mochaModule = globalThis.getMochaModule() as typeof Mocha;\n const runnablePrototype = mochaModule.Runnable.prototype;\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const oldResetTimeoutFunc = runnablePrototype.resetTimeout;\n runnablePrototype.resetTimeout = function(this: Mocha.Runnable) {\n oldResetTimeoutFunc.call(this);\n TestTimeout.reset(this);\n };\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const oldClearTimeoutFunc = runnablePrototype.clearTimeout;\n runnablePrototype.clearTimeout = function(this: Mocha.Runnable) {\n TestTimeout.clear();\n oldClearTimeoutFunc.call(this);\n };\n}\n\nexport interface TimeoutWithError {\n /**\n * Timeout duration in milliseconds, if it is great than 0 and not Infinity\n * If it is undefined, then it will use test timeout if we are in side the test function\n * Otherwise, there is no timeout\n */\n durationMs?: number;\n reject?: true;\n errorMsg?: string;\n}\nexport interface TimeoutWithValue<T = void> {\n /**\n * Timeout duration in milliseconds, if it is great than 0 and not Infinity\n * If it is undefined, then it will use test timeout if we are in side the test function\n * Otherwise, there is no timeout\n */\n durationMs?: number;\n reject: false;\n value: T;\n}\n\nexport type PromiseExecutor<T = void> = (resolve: (value: T | PromiseLike<T>) => void, reject: (reason?: any) => void) => void;\n\nexport async function timeoutAwait<T = void>(\n promise: PromiseLike<T>,\n timeoutOptions: TimeoutWithError | TimeoutWithValue<T> = {},\n) {\n return Promise.race([promise, timeoutPromise<T>(() => { }, timeoutOptions)]);\n}\n\nexport async function ensureContainerConnected(container: Container): Promise<void> {\n if (!container.connected) {\n return timeoutPromise((resolve) => container.once(\"connected\", () => resolve()));\n }\n}\n\n// Create a promise based on the timeout options\nasync function getTimeoutPromise<T = void>(\n executor: (resolve: (value: T | PromiseLike<T>) => void, reject: (reason?: any) => void) => void,\n timeoutOptions: TimeoutWithError | TimeoutWithValue<T>,\n err: Error | undefined,\n) {\n const timeout = timeoutOptions.durationMs ?? 0;\n if (timeout <= 0 || !Number.isFinite(timeout)) {\n return new Promise(executor);\n }\n\n return new Promise<T>((resolve, reject) => {\n const timeoutRejections = () => {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const errorObject = err!;\n errorObject.message = `${errorObject.message} (${timeout}ms)`;\n reject(err);\n };\n const timer = setTimeout(\n () => timeoutOptions.reject === false ? resolve(timeoutOptions.value) : timeoutRejections(),\n timeout);\n\n executor(\n (value) => {\n clearTimeout(timer);\n resolve(value);\n },\n (reason) => {\n clearTimeout(timer);\n reject(reason);\n });\n });\n}\n\n// Create a promise based on test timeout and the timeout options\nexport async function timeoutPromise<T = void>(\n executor: (resolve: (value: T | PromiseLike<T>) => void, reject: (reason?: any) => void) => void,\n timeoutOptions: TimeoutWithError | TimeoutWithValue<T> = {},\n): Promise<T> {\n // create the timeout error outside the async task, so its callstack includes\n // the original call site, this makes it easier to debug\n const err = timeoutOptions.reject === false\n ? undefined\n : new Error(timeoutOptions.errorMsg ?? \"Timed out\");\n const executorPromise = getTimeoutPromise(executor, timeoutOptions, err);\n\n const currentTestTimeout = TestTimeout.getInstance();\n if (currentTestTimeout === undefined) { return executorPromise; }\n\n return Promise.race([executorPromise, currentTestTimeout.getPromise()]).catch((e) => {\n if (e === currentTestTimeout) {\n if (timeoutOptions.reject !== false) {\n // If the rejection is because of the timeout then\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const errorObject = err!;\n errorObject.message =\n `${timeoutOptions.errorMsg ?? \"Test timed out\"} (${currentTestTimeout.getTimeout()}ms)`;\n throw errorObject;\n }\n return timeoutOptions.value;\n }\n throw e;\n }) as Promise<T>;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"timeoutUtils.js","sourceRoot":"","sources":["../src/timeoutUtils.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 { Container } from \"@fluidframework/container-loader\";\nimport { assert, Deferred } from \"@fluidframework/common-utils\";\n\n// @deprecated this value is no longer used\nexport const defaultTimeoutDurationMs = 250;\n\n// TestTimeout class manage tracking of test timeout. It create a timer when timeout is in effect,\n// and provide a promise that will be reject before the test timeout happen with a `timeBuffer` of 15 ms.\n// Once rejected, a new TestTimeout object will be create for the timeout.\n\nconst timeBuffer = 15; // leave 15 ms leeway for finish processing\n\nclass TestTimeout {\n\tprivate timeout: number = 0;\n\tprivate timer: NodeJS.Timeout | undefined;\n\tprivate readonly deferred: Deferred<void>;\n\tprivate rejected = false;\n\n\tprivate static instance: TestTimeout = new TestTimeout();\n\tpublic static reset(runnable: Mocha.Runnable) {\n\t\tTestTimeout.clear();\n\t\tTestTimeout.instance.resetTimer(runnable);\n\t}\n\n\tpublic static clear() {\n\t\tif (TestTimeout.instance.rejected) {\n\t\t\tTestTimeout.instance = new TestTimeout();\n\t\t} else {\n\t\t\tTestTimeout.instance.clearTimer();\n\t\t}\n\t}\n\n\tpublic static getInstance() {\n\t\treturn TestTimeout.instance;\n\t}\n\n\tpublic async getPromise() {\n\t\treturn this.deferred.promise;\n\t}\n\n\tpublic getTimeout() {\n\t\treturn this.timeout;\n\t}\n\n\tprivate constructor() {\n\t\tthis.deferred = new Deferred();\n\t\t// Ignore rejection for timeout promise if no one is waiting for it.\n\t\tthis.deferred.promise.catch(() => {});\n\t}\n\n\tprivate resetTimer(runnable: Mocha.Runnable) {\n\t\tassert(!this.timer, \"clearTimer should have been called before reset\");\n\t\tassert(!this.deferred.isCompleted, \"can't reset a completed TestTimeout\");\n\n\t\t// Check the test timeout setting\n\t\tconst timeout = runnable.timeout();\n\t\tif (!(Number.isFinite(timeout) && timeout > 0)) {\n\t\t\treturn;\n\t\t}\n\n\t\t// subtract a buffer\n\t\tthis.timeout = Math.max(timeout - timeBuffer, 1);\n\n\t\t// Set up timer to reject near the test timeout.\n\t\tthis.timer = setTimeout(() => {\n\t\t\tthis.deferred.reject(this);\n\t\t\tthis.rejected = true;\n\t\t}, this.timeout);\n\t}\n\tprivate clearTimer() {\n\t\tif (this.timer) {\n\t\t\tclearTimeout(this.timer);\n\t\t\tthis.timer = undefined;\n\t\t}\n\t}\n}\n\n// only register if we are running with mocha-test-setup loaded\nif (globalThis.getMochaModule !== undefined) {\n\t// patching resetTimeout and clearTimeout on the runnable object\n\t// so we can track when test timeout are enforced\n\tconst mochaModule = globalThis.getMochaModule() as typeof Mocha;\n\tconst runnablePrototype = mochaModule.Runnable.prototype;\n\t// eslint-disable-next-line @typescript-eslint/unbound-method\n\tconst oldResetTimeoutFunc = runnablePrototype.resetTimeout;\n\trunnablePrototype.resetTimeout = function (this: Mocha.Runnable) {\n\t\toldResetTimeoutFunc.call(this);\n\t\tTestTimeout.reset(this);\n\t};\n\t// eslint-disable-next-line @typescript-eslint/unbound-method\n\tconst oldClearTimeoutFunc = runnablePrototype.clearTimeout;\n\trunnablePrototype.clearTimeout = function (this: Mocha.Runnable) {\n\t\tTestTimeout.clear();\n\t\toldClearTimeoutFunc.call(this);\n\t};\n}\n\nexport interface TimeoutWithError {\n\t/**\n\t * Timeout duration in milliseconds, if it is great than 0 and not Infinity\n\t * If it is undefined, then it will use test timeout if we are in side the test function\n\t * Otherwise, there is no timeout\n\t */\n\tdurationMs?: number;\n\treject?: true;\n\terrorMsg?: string;\n}\nexport interface TimeoutWithValue<T = void> {\n\t/**\n\t * Timeout duration in milliseconds, if it is great than 0 and not Infinity\n\t * If it is undefined, then it will use test timeout if we are in side the test function\n\t * Otherwise, there is no timeout\n\t */\n\tdurationMs?: number;\n\treject: false;\n\tvalue: T;\n}\n\nexport type PromiseExecutor<T = void> = (\n\tresolve: (value: T | PromiseLike<T>) => void,\n\treject: (reason?: any) => void,\n) => void;\n\nexport async function timeoutAwait<T = void>(\n\tpromise: PromiseLike<T>,\n\ttimeoutOptions: TimeoutWithError | TimeoutWithValue<T> = {},\n) {\n\treturn Promise.race([promise, timeoutPromise<T>(() => {}, timeoutOptions)]);\n}\n\nexport async function ensureContainerConnected(container: Container): Promise<void> {\n\tif (!container.connected) {\n\t\treturn timeoutPromise((resolve) => container.once(\"connected\", () => resolve()));\n\t}\n}\n\n// Create a promise based on the timeout options\nasync function getTimeoutPromise<T = void>(\n\texecutor: (\n\t\tresolve: (value: T | PromiseLike<T>) => void,\n\t\treject: (reason?: any) => void,\n\t) => void,\n\ttimeoutOptions: TimeoutWithError | TimeoutWithValue<T>,\n\terr: Error | undefined,\n) {\n\tconst timeout = timeoutOptions.durationMs ?? 0;\n\tif (timeout <= 0 || !Number.isFinite(timeout)) {\n\t\treturn new Promise(executor);\n\t}\n\n\treturn new Promise<T>((resolve, reject) => {\n\t\tconst timeoutRejections = () => {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\tconst errorObject = err!;\n\t\t\terrorObject.message = `${errorObject.message} (${timeout}ms)`;\n\t\t\treject(err);\n\t\t};\n\t\tconst timer = setTimeout(\n\t\t\t() =>\n\t\t\t\ttimeoutOptions.reject === false\n\t\t\t\t\t? resolve(timeoutOptions.value)\n\t\t\t\t\t: timeoutRejections(),\n\t\t\ttimeout,\n\t\t);\n\n\t\texecutor(\n\t\t\t(value) => {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\tresolve(value);\n\t\t\t},\n\t\t\t(reason) => {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\treject(reason);\n\t\t\t},\n\t\t);\n\t});\n}\n\n// Create a promise based on test timeout and the timeout options\nexport async function timeoutPromise<T = void>(\n\texecutor: (\n\t\tresolve: (value: T | PromiseLike<T>) => void,\n\t\treject: (reason?: any) => void,\n\t) => void,\n\ttimeoutOptions: TimeoutWithError | TimeoutWithValue<T> = {},\n): Promise<T> {\n\t// create the timeout error outside the async task, so its callstack includes\n\t// the original call site, this makes it easier to debug\n\tconst err =\n\t\ttimeoutOptions.reject === false\n\t\t\t? undefined\n\t\t\t: new Error(timeoutOptions.errorMsg ?? \"Timed out\");\n\tconst executorPromise = getTimeoutPromise(executor, timeoutOptions, err);\n\n\tconst currentTestTimeout = TestTimeout.getInstance();\n\tif (currentTestTimeout === undefined) {\n\t\treturn executorPromise;\n\t}\n\n\treturn Promise.race([executorPromise, currentTestTimeout.getPromise()]).catch((e) => {\n\t\tif (e === currentTestTimeout) {\n\t\t\tif (timeoutOptions.reject !== false) {\n\t\t\t\t// If the rejection is because of the timeout then\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tconst errorObject = err!;\n\t\t\t\terrorObject.message = `${\n\t\t\t\t\ttimeoutOptions.errorMsg ?? \"Test timed out\"\n\t\t\t\t} (${currentTestTimeout.getTimeout()}ms)`;\n\t\t\t\tthrow errorObject;\n\t\t\t}\n\t\t\treturn timeoutOptions.value;\n\t\t}\n\t\tthrow e;\n\t}) as Promise<T>;\n}\n"]}
|