@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
@@ -7,16 +7,16 @@ import { ContainerRuntimeFactoryWithDefaultDataStore } from "@fluidframework/aqu
7
7
  import { assert } from "@fluidframework/common-utils";
8
8
  import { IContainer, IHostLoader, LoaderHeader } from "@fluidframework/container-definitions";
9
9
  import {
10
- IGCRuntimeOptions,
11
- ISummarizer,
12
- ISummaryRuntimeOptions,
10
+ IGCRuntimeOptions,
11
+ ISummarizer,
12
+ ISummaryRuntimeOptions,
13
13
  } from "@fluidframework/container-runtime";
14
14
  import { FluidObject, IRequest } from "@fluidframework/core-interfaces";
15
15
  import { DriverHeader } from "@fluidframework/driver-definitions";
16
16
  import {
17
- IContainerRuntimeBase,
18
- IFluidDataStoreFactory,
19
- NamedFluidDataStoreRegistryEntries,
17
+ IContainerRuntimeBase,
18
+ IFluidDataStoreFactory,
19
+ NamedFluidDataStoreRegistryEntries,
20
20
  } from "@fluidframework/runtime-definitions";
21
21
  import { requestFluidObject } from "@fluidframework/runtime-utils";
22
22
  import { IConfigProviderBase } from "@fluidframework/telemetry-utils";
@@ -28,137 +28,142 @@ import { timeoutAwait } from "./timeoutUtils";
28
28
 
29
29
  const summarizerClientType = "summarizer";
30
30
 
31
- async function createSummarizerCore(absoluteUrl: string | undefined, loader: IHostLoader, summaryVersion?: string) {
32
- if (absoluteUrl === undefined) {
33
- throw new Error("URL could not be resolved");
34
- }
35
-
36
- const request: IRequest = {
37
- headers: {
38
- [LoaderHeader.cache]: false,
39
- [LoaderHeader.clientDetails]: {
40
- capabilities: { interactive: false },
41
- type: summarizerClientType,
42
- },
43
- [DriverHeader.summarizingClient]: true,
44
- [LoaderHeader.version]: summaryVersion,
45
- },
46
- url: absoluteUrl,
47
- };
48
- const summarizerContainer = await loader.resolve(request);
49
- await waitForContainerConnection(summarizerContainer);
50
-
51
- const fluidObject =
52
- await requestFluidObject<FluidObject<ISummarizer>>(summarizerContainer, { url: "_summarizer" });
53
- if (fluidObject.ISummarizer === undefined) {
54
- throw new Error("Fluid object does not implement ISummarizer");
55
- }
56
-
57
- return {
58
- container: summarizerContainer,
59
- summarizer: fluidObject.ISummarizer,
60
- };
31
+ async function createSummarizerCore(
32
+ absoluteUrl: string | undefined,
33
+ loader: IHostLoader,
34
+ summaryVersion?: string,
35
+ ) {
36
+ if (absoluteUrl === undefined) {
37
+ throw new Error("URL could not be resolved");
38
+ }
39
+
40
+ const request: IRequest = {
41
+ headers: {
42
+ [LoaderHeader.cache]: false,
43
+ [LoaderHeader.clientDetails]: {
44
+ capabilities: { interactive: false },
45
+ type: summarizerClientType,
46
+ },
47
+ [DriverHeader.summarizingClient]: true,
48
+ [LoaderHeader.version]: summaryVersion,
49
+ },
50
+ url: absoluteUrl,
51
+ };
52
+ const summarizerContainer = await loader.resolve(request);
53
+ await waitForContainerConnection(summarizerContainer);
54
+
55
+ const fluidObject = await requestFluidObject<FluidObject<ISummarizer>>(summarizerContainer, {
56
+ url: "_summarizer",
57
+ });
58
+ if (fluidObject.ISummarizer === undefined) {
59
+ throw new Error("Fluid object does not implement ISummarizer");
60
+ }
61
+
62
+ return {
63
+ container: summarizerContainer,
64
+ summarizer: fluidObject.ISummarizer,
65
+ };
61
66
  }
62
67
 
63
68
  const defaultSummaryOptions: ISummaryRuntimeOptions = {
64
- summaryConfigOverrides: {
65
- state: "disableHeuristics",
66
- maxAckWaitTime: 10000,
67
- maxOpsSinceLastSummary: 7000,
68
- initialSummarizerDelayMs: 0,
69
- },
69
+ summaryConfigOverrides: {
70
+ state: "disableHeuristics",
71
+ maxAckWaitTime: 10000,
72
+ maxOpsSinceLastSummary: 7000,
73
+ initialSummarizerDelayMs: 0,
74
+ },
70
75
  };
71
76
 
72
77
  export async function createSummarizerFromFactory(
73
- provider: ITestObjectProvider,
74
- container: IContainer,
75
- dataStoreFactory: IFluidDataStoreFactory,
76
- summaryVersion?: string,
77
- containerRuntimeFactoryType = ContainerRuntimeFactoryWithDefaultDataStore,
78
- registryEntries?: NamedFluidDataStoreRegistryEntries,
78
+ provider: ITestObjectProvider,
79
+ container: IContainer,
80
+ dataStoreFactory: IFluidDataStoreFactory,
81
+ summaryVersion?: string,
82
+ containerRuntimeFactoryType = ContainerRuntimeFactoryWithDefaultDataStore,
83
+ registryEntries?: NamedFluidDataStoreRegistryEntries,
79
84
  ): Promise<ISummarizer> {
80
- const innerRequestHandler = async (request: IRequest, runtime: IContainerRuntimeBase) =>
81
- runtime.IFluidHandleContext.resolveHandle(request);
82
- const runtimeFactory = new containerRuntimeFactoryType(
83
- dataStoreFactory,
84
- registryEntries ??
85
- [
86
- [dataStoreFactory.type, Promise.resolve(dataStoreFactory)],
87
- ],
88
- undefined,
89
- [innerRequestHandler],
90
- { summaryOptions: defaultSummaryOptions },
91
- );
92
-
93
- const loader = provider.createLoader(
94
- [[provider.defaultCodeDetails, runtimeFactory]],
95
- { configProvider: mockConfigProvider() },
96
- );
97
- const absoluteUrl = await container.getAbsoluteUrl("");
98
- return (await createSummarizerCore(absoluteUrl, loader, summaryVersion)).summarizer;
85
+ const innerRequestHandler = async (request: IRequest, runtime: IContainerRuntimeBase) =>
86
+ runtime.IFluidHandleContext.resolveHandle(request);
87
+ const runtimeFactory = new containerRuntimeFactoryType(
88
+ dataStoreFactory,
89
+ registryEntries ?? [[dataStoreFactory.type, Promise.resolve(dataStoreFactory)]],
90
+ undefined,
91
+ [innerRequestHandler],
92
+ { summaryOptions: defaultSummaryOptions },
93
+ );
94
+
95
+ const loader = provider.createLoader([[provider.defaultCodeDetails, runtimeFactory]], {
96
+ configProvider: mockConfigProvider(),
97
+ });
98
+ const absoluteUrl = await container.getAbsoluteUrl("");
99
+ return (await createSummarizerCore(absoluteUrl, loader, summaryVersion)).summarizer;
99
100
  }
100
101
 
101
102
  export async function createSummarizer(
102
- provider: ITestObjectProvider,
103
- container: IContainer,
104
- summaryVersion?: string,
105
- gcOptions?: IGCRuntimeOptions,
106
- configProvider: IConfigProviderBase = mockConfigProvider(),
107
- logger?: ITelemetryBaseLogger,
103
+ provider: ITestObjectProvider,
104
+ container: IContainer,
105
+ summaryVersion?: string,
106
+ gcOptions?: IGCRuntimeOptions,
107
+ configProvider: IConfigProviderBase = mockConfigProvider(),
108
+ logger?: ITelemetryBaseLogger,
108
109
  ): Promise<ISummarizer> {
109
- const absoluteUrl = await container.getAbsoluteUrl("");
110
- return (await createSummarizerWithContainer(
111
- provider,
112
- absoluteUrl,
113
- summaryVersion,
114
- gcOptions,
115
- configProvider,
116
- logger,
117
- )).summarizer;
110
+ const absoluteUrl = await container.getAbsoluteUrl("");
111
+ return (
112
+ await createSummarizerWithContainer(
113
+ provider,
114
+ absoluteUrl,
115
+ summaryVersion,
116
+ gcOptions,
117
+ configProvider,
118
+ logger,
119
+ )
120
+ ).summarizer;
118
121
  }
119
122
 
120
123
  export async function createSummarizerWithContainer(
121
- provider: ITestObjectProvider,
122
- absoluteUrl: string | undefined,
123
- summaryVersion?: string,
124
- gcOptions?: IGCRuntimeOptions,
125
- configProvider: IConfigProviderBase = mockConfigProvider(),
126
- logger?: ITelemetryBaseLogger,
127
- ): Promise<{ container: IContainer; summarizer: ISummarizer; }> {
128
- const testContainerConfig: ITestContainerConfig = {
129
- runtimeOptions: {
130
- summaryOptions: defaultSummaryOptions,
131
- gcOptions,
132
- },
133
- loaderProps: { configProvider, logger },
134
- };
135
- const loader = provider.makeTestLoader(testContainerConfig);
136
- return createSummarizerCore(absoluteUrl, loader, summaryVersion);
124
+ provider: ITestObjectProvider,
125
+ absoluteUrl: string | undefined,
126
+ summaryVersion?: string,
127
+ gcOptions?: IGCRuntimeOptions,
128
+ configProvider: IConfigProviderBase = mockConfigProvider(),
129
+ logger?: ITelemetryBaseLogger,
130
+ ): Promise<{ container: IContainer; summarizer: ISummarizer }> {
131
+ const testContainerConfig: ITestContainerConfig = {
132
+ runtimeOptions: {
133
+ summaryOptions: defaultSummaryOptions,
134
+ gcOptions,
135
+ },
136
+ loaderProps: { configProvider, logger },
137
+ };
138
+ const loader = provider.makeTestLoader(testContainerConfig);
139
+ return createSummarizerCore(absoluteUrl, loader, summaryVersion);
137
140
  }
138
141
  /**
139
142
  * Summarizes on demand and returns the summary tree, the version number and the reference sequence number of the
140
143
  * submitted summary.
141
- */
144
+ */
142
145
  export async function summarizeNow(summarizer: ISummarizer, reason: string = "end-to-end test") {
143
- const result = summarizer.summarizeOnDemand({ reason });
146
+ const result = summarizer.summarizeOnDemand({ reason });
144
147
 
145
- const submitResult = await timeoutAwait(result.summarySubmitted);
146
- assert(submitResult.success, "on-demand summary should submit");
147
- assert(submitResult.data.stage === "submit",
148
- "on-demand summary submitted data stage should be submit");
149
- assert(submitResult.data.summaryTree !== undefined, "summary tree should exist");
148
+ const submitResult = await timeoutAwait(result.summarySubmitted);
149
+ assert(submitResult.success, "on-demand summary should submit");
150
+ assert(
151
+ submitResult.data.stage === "submit",
152
+ "on-demand summary submitted data stage should be submit",
153
+ );
154
+ assert(submitResult.data.summaryTree !== undefined, "summary tree should exist");
150
155
 
151
- const broadcastResult = await timeoutAwait(result.summaryOpBroadcasted);
152
- assert(broadcastResult.success, "summary op should be broadcast");
156
+ const broadcastResult = await timeoutAwait(result.summaryOpBroadcasted);
157
+ assert(broadcastResult.success, "summary op should be broadcast");
153
158
 
154
- const ackNackResult = await timeoutAwait(result.receivedSummaryAckOrNack);
155
- assert(ackNackResult.success, "summary op should be acked");
159
+ const ackNackResult = await timeoutAwait(result.receivedSummaryAckOrNack);
160
+ assert(ackNackResult.success, "summary op should be acked");
156
161
 
157
- await new Promise((resolve) => process.nextTick(resolve));
162
+ await new Promise((resolve) => process.nextTick(resolve));
158
163
 
159
- return {
160
- summaryTree: submitResult.data.summaryTree,
161
- summaryVersion: ackNackResult.data.summaryAckOp.contents.handle,
162
- summaryRefSeq: submitResult.data.referenceSequenceNumber,
163
- };
164
+ return {
165
+ summaryTree: submitResult.data.summaryTree,
166
+ summaryVersion: ackNackResult.data.summaryAckOp.contents.handle,
167
+ summaryRefSeq: submitResult.data.referenceSequenceNumber,
168
+ };
164
169
  }
@@ -16,9 +16,9 @@ import { PromiseExecutor, timeoutPromise, TimeoutWithError } from "./timeoutUtil
16
16
  * - timeoutOptions.durationMs = 1s
17
17
  */
18
18
  export async function ensureContainerConnected(container: Container): Promise<void> {
19
- if (!container.connected) {
20
- return timeoutPromise((resolve) => container.once("connected", () => resolve()));
21
- }
19
+ if (!container.connected) {
20
+ return timeoutPromise((resolve) => container.once("connected", () => resolve()));
21
+ }
22
22
  }
23
23
 
24
24
  /**
@@ -42,18 +42,20 @@ export async function ensureContainerConnected(container: Container): Promise<vo
42
42
  * timeoutOptions.durationMs (which defaults to 250ms if left undefined).
43
43
  */
44
44
  export async function waitForContainerConnection(
45
- container: IContainer,
46
- failOnContainerClose: boolean = false,
47
- timeoutOptions?: TimeoutWithError): Promise<void> {
48
- if (container.connectionState !== ConnectionState.Connected) {
45
+ container: IContainer,
46
+ failOnContainerClose: boolean = false,
47
+ timeoutOptions?: TimeoutWithError,
48
+ ): Promise<void> {
49
+ if (container.connectionState !== ConnectionState.Connected) {
50
+ const executor: PromiseExecutor = (resolve, reject) => {
51
+ container.once("connected", () => resolve());
52
+ if (failOnContainerClose) {
53
+ container.once("closed", (error) => reject(error));
54
+ }
55
+ };
49
56
 
50
- const executor: PromiseExecutor = (resolve, reject) => {
51
- container.once("connected", () => resolve())
52
- if (failOnContainerClose) {
53
- container.once("closed", (error) => reject(error));
54
- }
55
- };
56
-
57
- return timeoutOptions === undefined ? new Promise(executor) : timeoutPromise(executor, timeoutOptions);
58
- }
57
+ return timeoutOptions === undefined
58
+ ? new Promise(executor)
59
+ : timeoutPromise(executor, timeoutOptions);
60
+ }
59
61
  }
package/src/index.ts CHANGED
@@ -3,39 +3,43 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- export { wrapDocumentService, wrapDocumentServiceFactory, wrapDocumentStorageService } from "./DriverWrappers";
6
+ export {
7
+ wrapDocumentService,
8
+ wrapDocumentServiceFactory,
9
+ wrapDocumentStorageService,
10
+ } from "./DriverWrappers";
7
11
  export { IProvideTestFluidObject, ITestFluidObject } from "./interfaces";
8
12
  export { LoaderContainerTracker } from "./loaderContainerTracker";
9
13
  export { fluidEntryPoint, LocalCodeLoader, SupportedExportInterfaces } from "./localCodeLoader";
10
14
  export { createAndAttachContainer, createLoader } from "./localLoader";
11
15
  export { retryWithEventualValue } from "./retry";
12
16
  export { mockConfigProvider } from "./TestConfigs";
13
- export { createTestContainerRuntimeFactory, TestContainerRuntimeFactory } from "./testContainerRuntimeFactory";
17
+ export {
18
+ createTestContainerRuntimeFactory,
19
+ TestContainerRuntimeFactory,
20
+ } from "./testContainerRuntimeFactory";
14
21
  export { ChannelFactoryRegistry, TestFluidObject, TestFluidObjectFactory } from "./testFluidObject";
15
22
  export {
16
- createDocumentId,
17
- DataObjectFactoryType,
18
- EventAndErrorTrackingLogger,
19
- getUnexpectedLogErrorException,
20
- IOpProcessingController,
21
- ITestContainerConfig,
22
- ITestObjectProvider,
23
- TestObjectProvider,
23
+ createDocumentId,
24
+ DataObjectFactoryType,
25
+ EventAndErrorTrackingLogger,
26
+ getUnexpectedLogErrorException,
27
+ IOpProcessingController,
28
+ ITestContainerConfig,
29
+ ITestObjectProvider,
30
+ TestObjectProvider,
24
31
  } from "./testObjectProvider";
25
32
  export {
26
- createSummarizer,
27
- createSummarizerFromFactory,
28
- createSummarizerWithContainer,
29
- summarizeNow,
33
+ createSummarizer,
34
+ createSummarizerFromFactory,
35
+ createSummarizerWithContainer,
36
+ summarizeNow,
30
37
  } from "./TestSummaryUtils";
31
38
  export {
32
- defaultTimeoutDurationMs,
33
- timeoutAwait,
34
- timeoutPromise,
35
- TimeoutWithError,
36
- TimeoutWithValue,
39
+ defaultTimeoutDurationMs,
40
+ timeoutAwait,
41
+ timeoutPromise,
42
+ TimeoutWithError,
43
+ TimeoutWithValue,
37
44
  } from "./timeoutUtils";
38
- export {
39
- ensureContainerConnected,
40
- waitForContainerConnection,
41
- } from "./containerUtils";
45
+ export { ensureContainerConnected, waitForContainerConnection } from "./containerUtils";
package/src/interfaces.ts CHANGED
@@ -5,17 +5,20 @@
5
5
 
6
6
  import { IFluidDataStoreRuntime } from "@fluidframework/datastore-definitions";
7
7
  import { ISharedMap } from "@fluidframework/map";
8
- import { IFluidDataStoreContext, IFluidDataStoreChannel } from "@fluidframework/runtime-definitions";
8
+ import {
9
+ IFluidDataStoreContext,
10
+ IFluidDataStoreChannel,
11
+ } from "@fluidframework/runtime-definitions";
9
12
  import { IFluidLoadable } from "@fluidframework/core-interfaces";
10
13
 
11
14
  export interface IProvideTestFluidObject {
12
- readonly ITestFluidObject: ITestFluidObject;
15
+ readonly ITestFluidObject: ITestFluidObject;
13
16
  }
14
17
 
15
18
  export interface ITestFluidObject extends IProvideTestFluidObject, IFluidLoadable {
16
- root: ISharedMap;
17
- readonly runtime: IFluidDataStoreRuntime;
18
- readonly channel: IFluidDataStoreChannel;
19
- readonly context: IFluidDataStoreContext;
20
- getSharedObject<T = any>(id: string): Promise<T>;
19
+ root: ISharedMap;
20
+ readonly runtime: IFluidDataStoreRuntime;
21
+ readonly channel: IFluidDataStoreChannel;
22
+ readonly context: IFluidDataStoreContext;
23
+ getSharedObject<T = any>(id: string): Promise<T>;
21
24
  }