@fluidframework/test-utils 2.0.0-internal.3.0.1 → 2.0.0-internal.3.1.0

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.
Files changed (63) hide show
  1. package/.eslintrc.js +8 -10
  2. package/README.md +41 -11
  3. package/api-extractor.json +2 -2
  4. package/dist/DriverWrappers.d.ts.map +1 -1
  5. package/dist/DriverWrappers.js.map +1 -1
  6. package/dist/TestConfigs.d.ts.map +1 -1
  7. package/dist/TestConfigs.js +3 -2
  8. package/dist/TestConfigs.js.map +1 -1
  9. package/dist/TestSummaryUtils.d.ts +1 -1
  10. package/dist/TestSummaryUtils.d.ts.map +1 -1
  11. package/dist/TestSummaryUtils.js +8 -6
  12. package/dist/TestSummaryUtils.js.map +1 -1
  13. package/dist/containerUtils.d.ts.map +1 -1
  14. package/dist/containerUtils.js +3 -1
  15. package/dist/containerUtils.js.map +1 -1
  16. package/dist/index.d.ts +3 -3
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js.map +1 -1
  19. package/dist/interfaces.d.ts.map +1 -1
  20. package/dist/interfaces.js.map +1 -1
  21. package/dist/loaderContainerTracker.d.ts.map +1 -1
  22. package/dist/loaderContainerTracker.js +37 -27
  23. package/dist/loaderContainerTracker.js.map +1 -1
  24. package/dist/localCodeLoader.d.ts.map +1 -1
  25. package/dist/localCodeLoader.js.map +1 -1
  26. package/dist/localLoader.d.ts.map +1 -1
  27. package/dist/localLoader.js.map +1 -1
  28. package/dist/packageVersion.d.ts +1 -1
  29. package/dist/packageVersion.js +1 -1
  30. package/dist/packageVersion.js.map +1 -1
  31. package/dist/retry.d.ts.map +1 -1
  32. package/dist/retry.js.map +1 -1
  33. package/dist/testContainerRuntimeFactory.d.ts.map +1 -1
  34. package/dist/testContainerRuntimeFactory.js +2 -1
  35. package/dist/testContainerRuntimeFactory.js.map +1 -1
  36. package/dist/testFluidObject.d.ts.map +1 -1
  37. package/dist/testFluidObject.js +7 -3
  38. package/dist/testFluidObject.js.map +1 -1
  39. package/dist/testObjectProvider.d.ts +4 -1
  40. package/dist/testObjectProvider.d.ts.map +1 -1
  41. package/dist/testObjectProvider.js +28 -11
  42. package/dist/testObjectProvider.js.map +1 -1
  43. package/dist/timeoutUtils.d.ts.map +1 -1
  44. package/dist/timeoutUtils.js +4 -3
  45. package/dist/timeoutUtils.js.map +1 -1
  46. package/package.json +121 -119
  47. package/prettier.config.cjs +1 -1
  48. package/src/DriverWrappers.ts +40 -37
  49. package/src/TestConfigs.ts +9 -7
  50. package/src/TestSummaryUtils.ts +120 -115
  51. package/src/containerUtils.ts +18 -16
  52. package/src/index.ts +27 -23
  53. package/src/interfaces.ts +10 -7
  54. package/src/loaderContainerTracker.ts +627 -565
  55. package/src/localCodeLoader.ts +85 -77
  56. package/src/localLoader.ts +24 -24
  57. package/src/packageVersion.ts +1 -1
  58. package/src/retry.ts +31 -25
  59. package/src/testContainerRuntimeFactory.ts +59 -56
  60. package/src/testFluidObject.ts +168 -152
  61. package/src/testObjectProvider.ts +445 -384
  62. package/src/timeoutUtils.ts +174 -154
  63. package/tsconfig.json +9 -16
@@ -6,24 +6,28 @@
6
6
  import assert from "assert";
7
7
  import { ContainerRuntimeFactoryWithDefaultDataStore } from "@fluidframework/aqueduct";
8
8
  import {
9
- IProvideRuntimeFactory,
10
- IFluidModule,
11
- IProvideFluidCodeDetailsComparer,
12
- IFluidCodeDetails,
13
- ICodeDetailsLoader,
14
- IFluidModuleWithDetails,
9
+ IProvideRuntimeFactory,
10
+ IFluidModule,
11
+ IProvideFluidCodeDetailsComparer,
12
+ IFluidCodeDetails,
13
+ ICodeDetailsLoader,
14
+ IFluidModuleWithDetails,
15
15
  } from "@fluidframework/container-definitions";
16
16
  import { IRequest } from "@fluidframework/core-interfaces";
17
- import { IContainerRuntimeBase, IProvideFluidDataStoreFactory,
18
- IProvideFluidDataStoreRegistry } from "@fluidframework/runtime-definitions";
17
+ import {
18
+ IContainerRuntimeBase,
19
+ IProvideFluidDataStoreFactory,
20
+ IProvideFluidDataStoreRegistry,
21
+ } from "@fluidframework/runtime-definitions";
19
22
  import { createDataStoreFactory } from "@fluidframework/runtime-utils";
20
23
  import { IContainerRuntimeOptions } from "@fluidframework/container-runtime";
21
24
 
22
25
  export type SupportedExportInterfaces = Partial<
23
- IProvideRuntimeFactory &
24
- IProvideFluidDataStoreFactory &
25
- IProvideFluidDataStoreRegistry &
26
- IProvideFluidCodeDetailsComparer>;
26
+ IProvideRuntimeFactory &
27
+ IProvideFluidDataStoreFactory &
28
+ IProvideFluidDataStoreRegistry &
29
+ IProvideFluidCodeDetailsComparer
30
+ >;
27
31
 
28
32
  // Represents the entry point for a Fluid container.
29
33
  export type fluidEntryPoint = SupportedExportInterfaces | IFluidModule;
@@ -33,75 +37,79 @@ export type fluidEntryPoint = SupportedExportInterfaces | IFluidModule;
33
37
  * On load, it retrieves the entry point matching the package name in the given code details.
34
38
  */
35
39
  export class LocalCodeLoader implements ICodeDetailsLoader {
36
- private readonly fluidPackageCache = new Map<string, IFluidModuleWithDetails>();
40
+ private readonly fluidPackageCache = new Map<string, IFluidModuleWithDetails>();
37
41
 
38
- constructor(
39
- packageEntries: Iterable<[IFluidCodeDetails, fluidEntryPoint]>,
40
- runtimeOptions?: IContainerRuntimeOptions,
41
- ) {
42
- for (const entry of packageEntries) {
43
- // Store the entry point against a unique id in the fluidPackageCache.
44
- // For code details containing a package name, use the package name as the id.
45
- // For code details containing a Fluid package, create a unique id from the package name and version.
46
- const source = entry[0];
47
- const pkgId = typeof source.package === "string"
48
- ? source.package
49
- : `${source.package.name}@${source.package.version}`;
50
- let fluidModule = entry[1] as IFluidModule;
51
- if (fluidModule?.fluidExport === undefined) {
52
- const maybeExport = fluidModule as SupportedExportInterfaces;
42
+ constructor(
43
+ packageEntries: Iterable<[IFluidCodeDetails, fluidEntryPoint]>,
44
+ runtimeOptions?: IContainerRuntimeOptions,
45
+ ) {
46
+ for (const entry of packageEntries) {
47
+ // Store the entry point against a unique id in the fluidPackageCache.
48
+ // For code details containing a package name, use the package name as the id.
49
+ // For code details containing a Fluid package, create a unique id from the package name and version.
50
+ const source = entry[0];
51
+ const pkgId =
52
+ typeof source.package === "string"
53
+ ? source.package
54
+ : `${source.package.name}@${source.package.version}`;
55
+ let fluidModule = entry[1] as IFluidModule;
56
+ if (fluidModule?.fluidExport === undefined) {
57
+ const maybeExport = fluidModule as SupportedExportInterfaces;
53
58
 
54
- if (maybeExport.IRuntimeFactory !== undefined) {
55
- fluidModule = { fluidExport: maybeExport };
56
- } else {
57
- assert(maybeExport.IFluidDataStoreFactory !== undefined);
58
- const defaultFactory = createDataStoreFactory("default", maybeExport.IFluidDataStoreFactory);
59
- const innerRequestHandler = async (request: IRequest, runtime: IContainerRuntimeBase) =>
60
- runtime.IFluidHandleContext.resolveHandle(request);
61
- fluidModule = {
62
- fluidExport: {
63
- ... maybeExport,
64
- IRuntimeFactory:
65
- new ContainerRuntimeFactoryWithDefaultDataStore(
66
- defaultFactory,
67
- [[defaultFactory.type, Promise.resolve(defaultFactory)]],
68
- undefined,
69
- [innerRequestHandler],
70
- runtimeOptions,
71
- ),
72
- },
73
- };
74
- }
75
- }
59
+ if (maybeExport.IRuntimeFactory !== undefined) {
60
+ fluidModule = { fluidExport: maybeExport };
61
+ } else {
62
+ assert(maybeExport.IFluidDataStoreFactory !== undefined);
63
+ const defaultFactory = createDataStoreFactory(
64
+ "default",
65
+ maybeExport.IFluidDataStoreFactory,
66
+ );
67
+ const innerRequestHandler = async (
68
+ request: IRequest,
69
+ runtime: IContainerRuntimeBase,
70
+ ) => runtime.IFluidHandleContext.resolveHandle(request);
71
+ fluidModule = {
72
+ fluidExport: {
73
+ ...maybeExport,
74
+ IRuntimeFactory: new ContainerRuntimeFactoryWithDefaultDataStore(
75
+ defaultFactory,
76
+ [[defaultFactory.type, Promise.resolve(defaultFactory)]],
77
+ undefined,
78
+ [innerRequestHandler],
79
+ runtimeOptions,
80
+ ),
81
+ },
82
+ };
83
+ }
84
+ }
76
85
 
77
- const runtimeFactory = {
78
- module: fluidModule,
79
- details: source,
80
- };
86
+ const runtimeFactory = {
87
+ module: fluidModule,
88
+ details: source,
89
+ };
81
90
 
82
- this.fluidPackageCache.set(pkgId, runtimeFactory);
83
- }
84
- }
91
+ this.fluidPackageCache.set(pkgId, runtimeFactory);
92
+ }
93
+ }
85
94
 
86
- /**
87
- * It finds the entry point for the package name in the given source and return it
88
- * as a Fluid module.
89
- * @param source - Details of where to find chaincode
90
- */
91
- public async load(
92
- source: IFluidCodeDetails,
93
- ): Promise<IFluidModuleWithDetails> {
94
- // Get the entry point for from the fluidPackageCache for the given code details.
95
- // For code details containing a package name, use the package name as the id.
96
- // For code details containing a Fluid package, create a unique id from the package name and version.
97
- const pkdId = typeof source.package === "string"
98
- ? source.package
99
- : `${source.package.name}@${source.package.version}`;
95
+ /**
96
+ * It finds the entry point for the package name in the given source and return it
97
+ * as a Fluid module.
98
+ * @param source - Details of where to find chaincode
99
+ */
100
+ public async load(source: IFluidCodeDetails): Promise<IFluidModuleWithDetails> {
101
+ // Get the entry point for from the fluidPackageCache for the given code details.
102
+ // For code details containing a package name, use the package name as the id.
103
+ // For code details containing a Fluid package, create a unique id from the package name and version.
104
+ const pkdId =
105
+ typeof source.package === "string"
106
+ ? source.package
107
+ : `${source.package.name}@${source.package.version}`;
100
108
 
101
- const entryPoint = this.fluidPackageCache.get(pkdId);
102
- if (entryPoint === undefined) {
103
- throw new Error(`Cannot find package ${pkdId}`);
104
- }
105
- return entryPoint;
106
- }
109
+ const entryPoint = this.fluidPackageCache.get(pkdId);
110
+ if (entryPoint === undefined) {
111
+ throw new Error(`Cannot find package ${pkdId}`);
112
+ }
113
+ return entryPoint;
114
+ }
107
115
  }
@@ -4,11 +4,11 @@
4
4
  */
5
5
 
6
6
  import {
7
- ICodeDetailsLoader,
8
- IContainer,
9
- IHostLoader,
10
- ILoaderOptions,
11
- IFluidCodeDetails,
7
+ ICodeDetailsLoader,
8
+ IContainer,
9
+ IHostLoader,
10
+ ILoaderOptions,
11
+ IFluidCodeDetails,
12
12
  } from "@fluidframework/container-definitions";
13
13
  import { Loader } from "@fluidframework/container-loader";
14
14
  import { IRequest } from "@fluidframework/core-interfaces";
@@ -24,21 +24,21 @@ import { fluidEntryPoint, LocalCodeLoader } from "./localCodeLoader";
24
24
  * @param options - loader options
25
25
  */
26
26
  export function createLoader(
27
- packageEntries: Iterable<[IFluidCodeDetails, fluidEntryPoint]>,
28
- documentServiceFactory: IDocumentServiceFactory,
29
- urlResolver: IUrlResolver,
30
- logger?: ITelemetryBaseLogger,
31
- options?: ILoaderOptions,
27
+ packageEntries: Iterable<[IFluidCodeDetails, fluidEntryPoint]>,
28
+ documentServiceFactory: IDocumentServiceFactory,
29
+ urlResolver: IUrlResolver,
30
+ logger?: ITelemetryBaseLogger,
31
+ options?: ILoaderOptions,
32
32
  ): IHostLoader {
33
- const codeLoader: ICodeDetailsLoader = new LocalCodeLoader(packageEntries);
33
+ const codeLoader: ICodeDetailsLoader = new LocalCodeLoader(packageEntries);
34
34
 
35
- return new Loader({
36
- urlResolver,
37
- documentServiceFactory,
38
- codeLoader,
39
- logger,
40
- options,
41
- });
35
+ return new Loader({
36
+ urlResolver,
37
+ documentServiceFactory,
38
+ codeLoader,
39
+ logger,
40
+ options,
41
+ });
42
42
  }
43
43
 
44
44
  /**
@@ -49,12 +49,12 @@ export function createLoader(
49
49
  */
50
50
 
51
51
  export async function createAndAttachContainer(
52
- source: IFluidCodeDetails,
53
- loader: IHostLoader,
54
- attachRequest: IRequest,
52
+ source: IFluidCodeDetails,
53
+ loader: IHostLoader,
54
+ attachRequest: IRequest,
55
55
  ): Promise<IContainer> {
56
- const container = await loader.createDetachedContainer(source);
57
- await container.attach(attachRequest);
56
+ const container = await loader.createDetachedContainer(source);
57
+ await container.attach(attachRequest);
58
58
 
59
- return container;
59
+ return container;
60
60
  }
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/test-utils";
9
- export const pkgVersion = "2.0.0-internal.3.0.1";
9
+ export const pkgVersion = "2.0.0-internal.3.1.0";
package/src/retry.ts CHANGED
@@ -6,21 +6,21 @@
6
6
  import { delay } from "@fluidframework/common-utils";
7
7
 
8
8
  const retry = async <T>(
9
- callback: () => Promise<T>,
10
- defaultValue: T,
11
- maxTries: number,
12
- backOffMs: number,
9
+ callback: () => Promise<T>,
10
+ defaultValue: T,
11
+ maxTries: number,
12
+ backOffMs: number,
13
13
  ): Promise<T> => {
14
- for (let currentTry = 1; currentTry <= maxTries; currentTry++) {
15
- try {
16
- const result = await callback();
17
- return result;
18
- } catch (error) {
19
- await delay(currentTry * backOffMs);
20
- }
21
- }
14
+ for (let currentTry = 1; currentTry <= maxTries; currentTry++) {
15
+ try {
16
+ const result = await callback();
17
+ return result;
18
+ } catch (error) {
19
+ await delay(currentTry * backOffMs);
20
+ }
21
+ }
22
22
 
23
- return Promise.resolve(defaultValue);
23
+ return Promise.resolve(defaultValue);
24
24
  };
25
25
 
26
26
  /**
@@ -35,16 +35,22 @@ const retry = async <T>(
35
35
  * @returns the actual value from the callback when successful or the default value otherwise
36
36
  */
37
37
  export const retryWithEventualValue = async <T>(
38
- callback: () => Promise<T>,
39
- check: (value: T) => boolean,
40
- defaultValue: T,
41
- maxTries = 20,
42
- backOffMs = 50,
43
- ): Promise<T> => retry(async () => {
44
- const value = await callback();
45
- if (check(value)) {
46
- return value;
47
- }
38
+ callback: () => Promise<T>,
39
+ check: (value: T) => boolean,
40
+ defaultValue: T,
41
+ maxTries = 20,
42
+ backOffMs = 50,
43
+ ): Promise<T> =>
44
+ retry(
45
+ async () => {
46
+ const value = await callback();
47
+ if (check(value)) {
48
+ return value;
49
+ }
48
50
 
49
- throw Error("Not ready");
50
- }, defaultValue, maxTries, backOffMs);
51
+ throw Error("Not ready");
52
+ },
53
+ defaultValue,
54
+ maxTries,
55
+ backOffMs,
56
+ );
@@ -6,74 +6,77 @@
6
6
  import { defaultRouteRequestHandler } from "@fluidframework/aqueduct";
7
7
  import { IContainerContext, IRuntime } from "@fluidframework/container-definitions";
8
8
  import {
9
- ContainerRuntime,
10
- IContainerRuntimeOptions,
11
- DefaultSummaryConfiguration,
9
+ ContainerRuntime,
10
+ IContainerRuntimeOptions,
11
+ DefaultSummaryConfiguration,
12
12
  } from "@fluidframework/container-runtime";
13
13
  import { IContainerRuntime } from "@fluidframework/container-runtime-definitions";
14
- import {
15
- buildRuntimeRequestHandler,
16
- RuntimeRequestHandler } from "@fluidframework/request-handler";
14
+ import { buildRuntimeRequestHandler, RuntimeRequestHandler } from "@fluidframework/request-handler";
17
15
  import { IFluidDataStoreFactory } from "@fluidframework/runtime-definitions";
18
16
  import { RuntimeFactoryHelper } from "@fluidframework/runtime-utils";
19
17
 
20
18
  /**
21
19
  * Create a container runtime factory class that allows you to set runtime options
22
20
  */
23
- export const createTestContainerRuntimeFactory = (containerRuntimeCtor: typeof ContainerRuntime) => {
24
- return class extends RuntimeFactoryHelper {
25
- constructor(
26
- public type: string,
27
- public dataStoreFactory: IFluidDataStoreFactory,
28
- public runtimeOptions: IContainerRuntimeOptions = {
29
- summaryOptions: {
30
- summaryConfigOverrides: {
31
- ...DefaultSummaryConfiguration,
32
- ...{
33
- initialSummarizerDelayMs: 0,
34
- },
35
- },
36
- },
37
- },
38
- public requestHandlers: RuntimeRequestHandler[] = [],
39
- ) {
40
- super();
41
- }
21
+ export const createTestContainerRuntimeFactory = (
22
+ containerRuntimeCtor: typeof ContainerRuntime,
23
+ ) => {
24
+ return class extends RuntimeFactoryHelper {
25
+ constructor(
26
+ public type: string,
27
+ public dataStoreFactory: IFluidDataStoreFactory,
28
+ public runtimeOptions: IContainerRuntimeOptions = {
29
+ summaryOptions: {
30
+ summaryConfigOverrides: {
31
+ ...DefaultSummaryConfiguration,
32
+ ...{
33
+ initialSummarizerDelayMs: 0,
34
+ },
35
+ },
36
+ },
37
+ },
38
+ public requestHandlers: RuntimeRequestHandler[] = [],
39
+ ) {
40
+ super();
41
+ }
42
42
 
43
- public async instantiateFirstTime(runtime: ContainerRuntime): Promise<void> {
44
- const rootContext = runtime.createDetachedRootDataStore([this.type], "default");
45
- const rootRuntime = await this.dataStoreFactory.instantiateDataStore(rootContext, /* existing */ false);
46
- await rootContext.attachRuntime(this.dataStoreFactory, rootRuntime);
47
- }
43
+ public async instantiateFirstTime(runtime: ContainerRuntime): Promise<void> {
44
+ const rootContext = runtime.createDetachedRootDataStore([this.type], "default");
45
+ const rootRuntime = await this.dataStoreFactory.instantiateDataStore(
46
+ rootContext,
47
+ /* existing */ false,
48
+ );
49
+ await rootContext.attachRuntime(this.dataStoreFactory, rootRuntime);
50
+ }
48
51
 
49
- public async instantiateFromExisting(runtime: ContainerRuntime): Promise<void> {
50
- // Validate we can load root data stores.
51
- // We should be able to load any data store that was created in initializeFirstTime!
52
- await runtime.getRootDataStore("default");
53
- }
52
+ public async instantiateFromExisting(runtime: ContainerRuntime): Promise<void> {
53
+ // Validate we can load root data stores.
54
+ // We should be able to load any data store that was created in initializeFirstTime!
55
+ await runtime.getRootDataStore("default");
56
+ }
54
57
 
55
- async preInitialize(
56
- context: IContainerContext,
57
- existing: boolean,
58
- ): Promise<IRuntime & IContainerRuntime> {
59
- const runtime: ContainerRuntime = await containerRuntimeCtor.load(
60
- context,
61
- [
62
- ["default", Promise.resolve(this.dataStoreFactory)],
63
- [this.type, Promise.resolve(this.dataStoreFactory)],
64
- ],
65
- buildRuntimeRequestHandler(
66
- defaultRouteRequestHandler("default"),
67
- ...this.requestHandlers,
68
- ),
69
- this.runtimeOptions,
70
- context.scope,
71
- existing,
72
- );
58
+ async preInitialize(
59
+ context: IContainerContext,
60
+ existing: boolean,
61
+ ): Promise<IRuntime & IContainerRuntime> {
62
+ const runtime: ContainerRuntime = await containerRuntimeCtor.load(
63
+ context,
64
+ [
65
+ ["default", Promise.resolve(this.dataStoreFactory)],
66
+ [this.type, Promise.resolve(this.dataStoreFactory)],
67
+ ],
68
+ buildRuntimeRequestHandler(
69
+ defaultRouteRequestHandler("default"),
70
+ ...this.requestHandlers,
71
+ ),
72
+ this.runtimeOptions,
73
+ context.scope,
74
+ existing,
75
+ );
73
76
 
74
- return runtime;
75
- }
76
- };
77
+ return runtime;
78
+ }
79
+ };
77
80
  };
78
81
 
79
82
  /**