@fluidframework/test-utils 2.0.0-dev.3.1.0.125672 → 2.0.0-dev.4.1.0.148229

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 (39) hide show
  1. package/dist/TestConfigs.d.ts.map +1 -1
  2. package/dist/TestConfigs.js +0 -2
  3. package/dist/TestConfigs.js.map +1 -1
  4. package/dist/TestSummaryUtils.d.ts +14 -3
  5. package/dist/TestSummaryUtils.d.ts.map +1 -1
  6. package/dist/TestSummaryUtils.js +24 -16
  7. package/dist/TestSummaryUtils.js.map +1 -1
  8. package/dist/containerUtils.d.ts +10 -19
  9. package/dist/containerUtils.d.ts.map +1 -1
  10. package/dist/containerUtils.js +12 -25
  11. package/dist/containerUtils.js.map +1 -1
  12. package/dist/index.d.ts +2 -2
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +1 -3
  15. package/dist/index.js.map +1 -1
  16. package/dist/loaderContainerTracker.d.ts +3 -5
  17. package/dist/loaderContainerTracker.d.ts.map +1 -1
  18. package/dist/loaderContainerTracker.js +6 -9
  19. package/dist/loaderContainerTracker.js.map +1 -1
  20. package/dist/packageVersion.d.ts +1 -1
  21. package/dist/packageVersion.js +1 -1
  22. package/dist/packageVersion.js.map +1 -1
  23. package/dist/testObjectProvider.d.ts +4 -1
  24. package/dist/testObjectProvider.d.ts.map +1 -1
  25. package/dist/testObjectProvider.js +39 -11
  26. package/dist/testObjectProvider.js.map +1 -1
  27. package/dist/timeoutUtils.d.ts +0 -2
  28. package/dist/timeoutUtils.d.ts.map +1 -1
  29. package/dist/timeoutUtils.js +1 -7
  30. package/dist/timeoutUtils.js.map +1 -1
  31. package/package.json +62 -63
  32. package/src/TestConfigs.ts +0 -2
  33. package/src/TestSummaryUtils.ts +23 -30
  34. package/src/containerUtils.ts +12 -25
  35. package/src/index.ts +2 -7
  36. package/src/loaderContainerTracker.ts +11 -21
  37. package/src/packageVersion.ts +1 -1
  38. package/src/testObjectProvider.ts +55 -12
  39. package/src/timeoutUtils.ts +0 -7
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/test-utils",
3
- "version": "2.0.0-dev.3.1.0.125672",
3
+ "version": "2.0.0-dev.4.1.0.148229",
4
4
  "description": "Utilities for Fluid tests",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -14,31 +14,6 @@
14
14
  "main": "dist/index.js",
15
15
  "module": "lib/index.js",
16
16
  "types": "dist/index.d.ts",
17
- "scripts": {
18
- "build": "npm run build:genver && concurrently npm:build:compile npm:lint && npm run build:docs",
19
- "build:compile": "npm run tsc && npm run typetests:gen && npm run build:test",
20
- "build:compile:min": "npm run build:compile",
21
- "build:docs": "api-extractor run --local --typescript-compiler-folder ../../../node_modules/typescript && copyfiles -u 1 ./_api-extractor-temp/doc-models/* ../../../_api-extractor-temp/",
22
- "build:full": "npm run build",
23
- "build:full:compile": "npm run build:compile",
24
- "build:genver": "gen-version",
25
- "build:test": "tsc --project ./src/test/tsconfig.json",
26
- "ci:build:docs": "api-extractor run --typescript-compiler-folder ../../../node_modules/typescript && copyfiles -u 1 ./_api-extractor-temp/* ../../../_api-extractor-temp/",
27
- "clean": "rimraf dist lib *.tsbuildinfo *.build.log",
28
- "eslint": "eslint --format stylish src",
29
- "eslint:fix": "eslint --format stylish src --fix --fix-type problem,suggestion,layout",
30
- "format": "npm run prettier:fix",
31
- "lint": "npm run prettier && npm run eslint",
32
- "lint:fix": "npm run prettier:fix && npm run eslint:fix",
33
- "prettier": "prettier --check . --ignore-path ../../../.prettierignore",
34
- "prettier:fix": "prettier --write . --ignore-path ../../../.prettierignore",
35
- "test": "npm run test:mocha",
36
- "test:mocha": "mocha --unhandled-rejections=strict --recursive dist/test/*.spec.js --exit --project src/test/tsconfig.json -r node_modules/@fluidframework/mocha-test-setup",
37
- "test:mocha:verbose": "cross-env FLUID_TEST_VERBOSE=1 npm run test:mocha",
38
- "tsc": "tsc",
39
- "typetests:gen": "flub generate typetests --generate --dir .",
40
- "typetests:prepare": "flub generate typetests --prepare --dir . --pin"
41
- },
42
17
  "nyc": {
43
18
  "all": true,
44
19
  "cache-dir": "nyc/.cache",
@@ -60,64 +35,88 @@
60
35
  "temp-directory": "nyc/.nyc_output"
61
36
  },
62
37
  "dependencies": {
63
- "@fluidframework/aqueduct": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
38
+ "@fluidframework/aqueduct": "2.0.0-dev.4.1.0.148229",
64
39
  "@fluidframework/common-definitions": "^0.20.1",
65
- "@fluidframework/common-utils": "^1.0.0",
66
- "@fluidframework/container-definitions": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
67
- "@fluidframework/container-loader": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
68
- "@fluidframework/container-runtime": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
69
- "@fluidframework/container-runtime-definitions": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
70
- "@fluidframework/core-interfaces": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
71
- "@fluidframework/datastore": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
72
- "@fluidframework/datastore-definitions": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
73
- "@fluidframework/driver-definitions": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
74
- "@fluidframework/driver-utils": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
75
- "@fluidframework/local-driver": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
76
- "@fluidframework/map": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
77
- "@fluidframework/mocha-test-setup": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
40
+ "@fluidframework/common-utils": "^1.1.1",
41
+ "@fluidframework/container-definitions": "2.0.0-dev.4.1.0.148229",
42
+ "@fluidframework/container-loader": "2.0.0-dev.4.1.0.148229",
43
+ "@fluidframework/container-runtime": "2.0.0-dev.4.1.0.148229",
44
+ "@fluidframework/container-runtime-definitions": "2.0.0-dev.4.1.0.148229",
45
+ "@fluidframework/core-interfaces": "2.0.0-dev.4.1.0.148229",
46
+ "@fluidframework/datastore": "2.0.0-dev.4.1.0.148229",
47
+ "@fluidframework/datastore-definitions": "2.0.0-dev.4.1.0.148229",
48
+ "@fluidframework/driver-definitions": "2.0.0-dev.4.1.0.148229",
49
+ "@fluidframework/driver-utils": "2.0.0-dev.4.1.0.148229",
50
+ "@fluidframework/local-driver": "2.0.0-dev.4.1.0.148229",
51
+ "@fluidframework/map": "2.0.0-dev.4.1.0.148229",
78
52
  "@fluidframework/protocol-definitions": "^1.1.0",
79
- "@fluidframework/request-handler": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
80
- "@fluidframework/routerlicious-driver": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
81
- "@fluidframework/runtime-definitions": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
82
- "@fluidframework/runtime-utils": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
83
- "@fluidframework/telemetry-utils": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
84
- "@fluidframework/test-driver-definitions": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
85
- "@fluidframework/test-runtime-utils": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
53
+ "@fluidframework/request-handler": "2.0.0-dev.4.1.0.148229",
54
+ "@fluidframework/routerlicious-driver": "2.0.0-dev.4.1.0.148229",
55
+ "@fluidframework/runtime-definitions": "2.0.0-dev.4.1.0.148229",
56
+ "@fluidframework/runtime-utils": "2.0.0-dev.4.1.0.148229",
57
+ "@fluidframework/telemetry-utils": "2.0.0-dev.4.1.0.148229",
58
+ "@fluidframework/test-driver-definitions": "2.0.0-dev.4.1.0.148229",
59
+ "@fluidframework/test-runtime-utils": "2.0.0-dev.4.1.0.148229",
86
60
  "best-random": "^1.0.0",
87
61
  "debug": "^4.1.1",
88
62
  "uuid": "^8.3.1"
89
63
  },
90
64
  "devDependencies": {
91
- "@fluid-tools/build-cli": "^0.8.0",
65
+ "@fluid-tools/build-cli": "^0.13.1",
92
66
  "@fluidframework/build-common": "^1.1.0",
93
- "@fluidframework/build-tools": "^0.8.0",
67
+ "@fluidframework/build-tools": "^0.13.1",
94
68
  "@fluidframework/eslint-config-fluid": "^2.0.0",
95
- "@fluidframework/test-utils-previous": "npm:@fluidframework/test-utils@2.0.0-internal.3.0.0",
96
- "@microsoft/api-extractor": "^7.22.2",
97
- "@rushstack/eslint-config": "^2.5.1",
69
+ "@fluidframework/mocha-test-setup": "2.0.0-dev.4.1.0.148229",
70
+ "@fluidframework/test-utils-previous": "npm:@fluidframework/test-utils@2.0.0-internal.4.0.0",
71
+ "@microsoft/api-extractor": "^7.34.4",
98
72
  "@types/debug": "^4.1.5",
99
73
  "@types/diff": "^3.5.1",
100
74
  "@types/mocha": "^9.1.1",
101
- "@types/node": "^14.18.36",
75
+ "@types/node": "^14.18.38",
102
76
  "@types/random-js": "^1.0.31",
103
77
  "@types/uuid": "^8.3.0",
104
- "concurrently": "^6.2.0",
78
+ "concurrently": "^7.6.0",
105
79
  "copyfiles": "^2.4.1",
106
- "cross-env": "^7.0.2",
80
+ "cross-env": "^7.0.3",
107
81
  "diff": "^3.5.0",
108
82
  "eslint": "~8.6.0",
109
- "mocha": "^10.0.0",
110
- "nyc": "^15.0.0",
83
+ "mocha": "^10.2.0",
84
+ "mocha-json-output-reporter": "^2.0.1",
85
+ "mocha-multi-reporters": "^1.5.1",
86
+ "moment": "^2.21.0",
87
+ "nyc": "^15.1.0",
111
88
  "prettier": "~2.6.2",
112
89
  "random-js": "^1.0.8",
113
- "rimraf": "^2.6.2",
90
+ "rimraf": "^4.4.0",
114
91
  "typescript": "~4.5.5"
115
92
  },
116
93
  "typeValidation": {
117
- "version": "2.0.0-internal.3.1.0",
118
- "previousVersionStyle": "~previousMinor",
119
- "baselineRange": ">=2.0.0-internal.3.0.0 <2.0.0-internal.3.1.0",
120
- "baselineVersion": "2.0.0-internal.3.0.0",
121
94
  "broken": {}
95
+ },
96
+ "scripts": {
97
+ "build": "npm run build:genver && concurrently npm:build:compile npm:lint && npm run build:docs",
98
+ "build:compile": "npm run tsc && npm run typetests:gen && npm run build:test",
99
+ "build:compile:min": "npm run build:compile",
100
+ "build:docs": "api-extractor run --local --typescript-compiler-folder ../../../node_modules/typescript && copyfiles -u 1 ./_api-extractor-temp/doc-models/* ../../../_api-extractor-temp/",
101
+ "build:full": "npm run build",
102
+ "build:full:compile": "npm run build:compile",
103
+ "build:genver": "gen-version",
104
+ "build:test": "tsc --project ./src/test/tsconfig.json",
105
+ "ci:build:docs": "api-extractor run --typescript-compiler-folder ../../../node_modules/typescript && copyfiles -u 1 ./_api-extractor-temp/* ../../../_api-extractor-temp/",
106
+ "clean": "rimraf dist lib *.tsbuildinfo *.build.log",
107
+ "eslint": "eslint --format stylish src",
108
+ "eslint:fix": "eslint --format stylish src --fix --fix-type problem,suggestion,layout",
109
+ "format": "npm run prettier:fix",
110
+ "lint": "npm run prettier && npm run eslint",
111
+ "lint:fix": "npm run prettier:fix && npm run eslint:fix",
112
+ "prettier": "prettier --check . --ignore-path ../../../.prettierignore",
113
+ "prettier:fix": "prettier --write . --ignore-path ../../../.prettierignore",
114
+ "test": "npm run test:mocha",
115
+ "test:mocha": "mocha --unhandled-rejections=strict --recursive dist/test/*.spec.js --exit --project src/test/tsconfig.json -r node_modules/@fluidframework/mocha-test-setup",
116
+ "test:mocha:multireport": "cross-env FLUID_TEST_MULTIREPORT=1 npm run test:mocha",
117
+ "test:mocha:verbose": "cross-env FLUID_TEST_VERBOSE=1 npm run test:mocha",
118
+ "tsc": "tsc",
119
+ "typetests:gen": "fluid-type-test-generator",
120
+ "typetests:prepare": "flub generate typetests --prepare --dir . --pin"
122
121
  }
123
- }
122
+ }
@@ -8,8 +8,6 @@ import { ConfigTypes, IConfigProviderBase } from "@fluidframework/telemetry-util
8
8
  export const mockConfigProvider = (
9
9
  settings: Record<string, ConfigTypes> = {},
10
10
  ): IConfigProviderBase => {
11
- settings["Fluid.GarbageCollection.TrackGCState"] = "true";
12
- settings["Fluid.GarbageCollection.WriteDataAtRoot"] = "true";
13
11
  return {
14
12
  getRawConfig: (name: string): ConfigTypes => settings[name],
15
13
  };
@@ -29,10 +29,11 @@ import { timeoutAwait } from "./timeoutUtils";
29
29
  const summarizerClientType = "summarizer";
30
30
 
31
31
  async function createSummarizerCore(
32
- absoluteUrl: string | undefined,
32
+ container: IContainer,
33
33
  loader: IHostLoader,
34
34
  summaryVersion?: string,
35
35
  ) {
36
+ const absoluteUrl = await container.getAbsoluteUrl("");
36
37
  if (absoluteUrl === undefined) {
37
38
  throw new Error("URL could not be resolved");
38
39
  }
@@ -52,10 +53,12 @@ async function createSummarizerCore(
52
53
  const summarizerContainer = await loader.resolve(request);
53
54
  await waitForContainerConnection(summarizerContainer);
54
55
 
55
- const fluidObject = await requestFluidObject<FluidObject<ISummarizer>>(summarizerContainer, {
56
- url: "_summarizer",
57
- });
58
- if (fluidObject.ISummarizer === undefined) {
56
+ const fluidObject: FluidObject<ISummarizer> | undefined = summarizerContainer.getEntryPoint
57
+ ? await summarizerContainer.getEntryPoint?.()
58
+ : await requestFluidObject<FluidObject<ISummarizer>>(summarizerContainer, {
59
+ url: "_summarizer",
60
+ });
61
+ if (fluidObject?.ISummarizer === undefined) {
59
62
  throw new Error("Fluid object does not implement ISummarizer");
60
63
  }
61
64
 
@@ -74,6 +77,11 @@ const defaultSummaryOptions: ISummaryRuntimeOptions = {
74
77
  },
75
78
  };
76
79
 
80
+ /**
81
+ * Creates a summarizer client from the given container and data store factory, and returns the summarizer client's
82
+ * IContainer and ISummarizer.
83
+ * The ISummarizer can be used to generate on-demand summaries. The IContainer can be used to fetch data stores, etc.
84
+ */
77
85
  export async function createSummarizerFromFactory(
78
86
  provider: ITestObjectProvider,
79
87
  container: IContainer,
@@ -81,7 +89,8 @@ export async function createSummarizerFromFactory(
81
89
  summaryVersion?: string,
82
90
  containerRuntimeFactoryType = ContainerRuntimeFactoryWithDefaultDataStore,
83
91
  registryEntries?: NamedFluidDataStoreRegistryEntries,
84
- ): Promise<ISummarizer> {
92
+ logger?: ITelemetryBaseLogger,
93
+ ): Promise<{ container: IContainer; summarizer: ISummarizer }> {
85
94
  const innerRequestHandler = async (request: IRequest, runtime: IContainerRuntimeBase) =>
86
95
  runtime.IFluidHandleContext.resolveHandle(request);
87
96
  const runtimeFactory = new containerRuntimeFactoryType(
@@ -94,11 +103,15 @@ export async function createSummarizerFromFactory(
94
103
 
95
104
  const loader = provider.createLoader([[provider.defaultCodeDetails, runtimeFactory]], {
96
105
  configProvider: mockConfigProvider(),
106
+ logger,
97
107
  });
98
- const absoluteUrl = await container.getAbsoluteUrl("");
99
- return (await createSummarizerCore(absoluteUrl, loader, summaryVersion)).summarizer;
108
+ return createSummarizerCore(container, loader, summaryVersion);
100
109
  }
101
110
 
111
+ /**
112
+ * Creates a summarizer client from the given container and returns the summarizer client's IContainer and ISummarizer.
113
+ * The ISummarizer can be used to generate on-demand summaries. The IContainer can be used to fetch data stores, etc.
114
+ */
102
115
  export async function createSummarizer(
103
116
  provider: ITestObjectProvider,
104
117
  container: IContainer,
@@ -106,27 +119,6 @@ export async function createSummarizer(
106
119
  gcOptions?: IGCRuntimeOptions,
107
120
  configProvider: IConfigProviderBase = mockConfigProvider(),
108
121
  logger?: ITelemetryBaseLogger,
109
- ): Promise<ISummarizer> {
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;
121
- }
122
-
123
- export async function createSummarizerWithContainer(
124
- provider: ITestObjectProvider,
125
- absoluteUrl: string | undefined,
126
- summaryVersion?: string,
127
- gcOptions?: IGCRuntimeOptions,
128
- configProvider: IConfigProviderBase = mockConfigProvider(),
129
- logger?: ITelemetryBaseLogger,
130
122
  ): Promise<{ container: IContainer; summarizer: ISummarizer }> {
131
123
  const testContainerConfig: ITestContainerConfig = {
132
124
  runtimeOptions: {
@@ -136,8 +128,9 @@ export async function createSummarizerWithContainer(
136
128
  loaderProps: { configProvider, logger },
137
129
  };
138
130
  const loader = provider.makeTestLoader(testContainerConfig);
139
- return createSummarizerCore(absoluteUrl, loader, summaryVersion);
131
+ return createSummarizerCore(container, loader, summaryVersion);
140
132
  }
133
+
141
134
  /**
142
135
  * Summarizes on demand and returns the summary tree, the version number and the reference sequence number of the
143
136
  * submitted summary.
@@ -4,23 +4,9 @@
4
4
  */
5
5
 
6
6
  import { IContainer } from "@fluidframework/container-definitions";
7
- import { ConnectionState, Container } from "@fluidframework/container-loader";
7
+ import { ConnectionState } from "@fluidframework/container-loader";
8
8
  import { PromiseExecutor, timeoutPromise, TimeoutWithError } from "./timeoutUtils";
9
9
 
10
- /**
11
- * Waits for the specified container to emit a 'connected' event.
12
- *
13
- * @deprecated Use waitForContainerConnection instead.
14
- * Note that an upcoming release will change the default parameters on that function to:
15
- * - failOnContainerClose = true
16
- * - timeoutOptions.durationMs = 1s
17
- */
18
- export async function ensureContainerConnected(container: Container): Promise<void> {
19
- if (!container.connected) {
20
- return timeoutPromise((resolve) => container.once("connected", () => resolve()));
21
- }
22
- }
23
-
24
10
  /**
25
11
  * Utility function to wait for the specified Container to be in Connected state.
26
12
  * If the Container is already connected, the Promise returns immediately; otherwise it resolves when the Container emits
@@ -30,20 +16,21 @@ export async function ensureContainerConnected(container: Container): Promise<vo
30
16
  * @param container - The container to wait for.
31
17
  * @param failOnContainerClose - If true, the returned Promise will be rejected if the container emits a 'closed' event
32
18
  * before a 'connected' event.
33
- * Defaults to false (but this will change in an upcoming version).
19
+ * Defaults to true.
34
20
  * @param timeoutOptions - Options related to the behavior of the timeout.
35
- * If not provided, no timeout will be applied and the promise will wait indefinitely for the Container to emit its
36
- * 'connected' (or 'closed, if failOnContainerClose === true) event.
37
- * @returns A Promise that resolves when the specified container emits a 'connected' event (or immediately if the
38
- * Container is already connected).
39
- * If failOnContainerClose === true and the container emits a 'closed' event before a 'connected' event, the Promise
40
- * is rejected with the error from the 'closed' event, if any.
41
- * If timeoutOptions is provided, the Promise will reject if the container hasn't emmited a relevant event before
42
- * timeoutOptions.durationMs (which defaults to 250ms if left undefined).
21
+ * If provided, the returned Promise will reject if the container hasn't emitted relevant events in timeoutOptions.durationMs.
22
+ * If not provided, the Promise will wait indefinitely for the Container to emit its 'connected' (or 'closed', if
23
+ * failOnContainerClose === true) event.
24
+ *
25
+ * @returns A Promise that either:
26
+ * - Resolves when the specified container emits a 'connected' event (or immediately if the Container is already connected).
27
+ * - Rejects if failOnContainerClose === true and the container emits a 'closed' event before a 'connected' event.
28
+ * - Rejects after timeoutOptions.durationMs if timeoutOptions !== undefined and the container does not emit relevant
29
+ * events, within that timeframe.
43
30
  */
44
31
  export async function waitForContainerConnection(
45
32
  container: IContainer,
46
- failOnContainerClose: boolean = false,
33
+ failOnContainerClose: boolean = true,
47
34
  timeoutOptions?: TimeoutWithError,
48
35
  ): Promise<void> {
49
36
  if (container.connectionState !== ConnectionState.Connected) {
package/src/index.ts CHANGED
@@ -29,12 +29,7 @@ export {
29
29
  ITestObjectProvider,
30
30
  TestObjectProvider,
31
31
  } from "./testObjectProvider";
32
- export {
33
- createSummarizer,
34
- createSummarizerFromFactory,
35
- createSummarizerWithContainer,
36
- summarizeNow,
37
- } from "./TestSummaryUtils";
32
+ export { createSummarizer, createSummarizerFromFactory, summarizeNow } from "./TestSummaryUtils";
38
33
  export {
39
34
  defaultTimeoutDurationMs,
40
35
  timeoutAwait,
@@ -42,4 +37,4 @@ export {
42
37
  TimeoutWithError,
43
38
  TimeoutWithValue,
44
39
  } from "./timeoutUtils";
45
- export { ensureContainerConnected, waitForContainerConnection } from "./containerUtils";
40
+ export { waitForContainerConnection } from "./containerUtils";
@@ -4,7 +4,7 @@
4
4
  */
5
5
  import { assert } from "@fluidframework/common-utils";
6
6
  import { IContainer, IDeltaQueue, IHostLoader } from "@fluidframework/container-definitions";
7
- import { Container } from "@fluidframework/container-loader";
7
+ import { ConnectionState } from "@fluidframework/container-loader";
8
8
  import { canBeCoalescedByService } from "@fluidframework/driver-utils";
9
9
  import {
10
10
  IDocumentMessage,
@@ -123,7 +123,7 @@ export class LoaderContainerTracker implements IOpProcessingController {
123
123
  // Received the no op back, update the record if we are tracking
124
124
  if (
125
125
  canBeCoalescedByService(message) &&
126
- message.clientId === (container as Container).clientId &&
126
+ message.clientId === container.clientId &&
127
127
  record.trailingNoOps !== 0 &&
128
128
  record.startTrailingNoOps <= message.clientSequenceNumber
129
129
  ) {
@@ -162,21 +162,16 @@ export class LoaderContainerTracker implements IOpProcessingController {
162
162
  // REVIEW: do we need to unpatch the loaders?
163
163
  }
164
164
 
165
- /**
166
- * Ensure all tracked containers are synchronized
167
- */
168
- public async ensureSynchronized(...containers: IContainer[]): Promise<void> {
169
- await this.processSynchronized(undefined, ...containers);
170
- }
171
-
172
165
  /**
173
166
  * Ensure all tracked containers are synchronized with a time limit
167
+ *
168
+ * @deprecated - this method is equivalent to @see {@link LoaderContainerTracker.ensureSynchronized}, please configure the test timeout instead
174
169
  */
175
170
  public async ensureSynchronizedWithTimeout?(
176
171
  timeoutDuration: number | undefined,
177
172
  ...containers: IContainer[]
178
173
  ) {
179
- await this.processSynchronized(timeoutDuration, ...containers);
174
+ await this.ensureSynchronized(...containers);
180
175
  }
181
176
 
182
177
  /**
@@ -198,10 +193,7 @@ export class LoaderContainerTracker implements IOpProcessingController {
198
193
  *
199
194
  * - Trailing NoOp is tracked and don't count as pending ops.
200
195
  */
201
- private async processSynchronized(
202
- timeoutDuration: number | undefined,
203
- ...containers: IContainer[]
204
- ) {
196
+ public async ensureSynchronized(...containers: IContainer[]): Promise<void> {
205
197
  const resumed = this.resumeProcessing(...containers);
206
198
 
207
199
  let waitingSequenceNumberSynchronized = false;
@@ -287,9 +279,7 @@ export class LoaderContainerTracker implements IOpProcessingController {
287
279
  // All the clientId we track should be a superset of the quorum, otherwise, we are missing
288
280
  // leave messages
289
281
  const openedDocuments = Array.from(this.containers.keys()).filter((c) => !c.closed);
290
- const openedClientId = openedDocuments.map(
291
- (container) => (container as Container).clientId,
292
- );
282
+ const openedClientId = openedDocuments.map((container) => container.clientId);
293
283
 
294
284
  const pendingClients: [IContainer, Set<string>][] = [];
295
285
  containersToApply.forEach((container) => {
@@ -375,7 +365,7 @@ export class LoaderContainerTracker implements IOpProcessingController {
375
365
  */
376
366
  private async waitForPendingClients(pendingClients: [IContainer, Set<string>][]) {
377
367
  const unconnectedClients = Array.from(this.containers.keys()).filter(
378
- (c) => !c.closed && !(c as Container).connected,
368
+ (c) => !c.closed && c.connectionState !== ConnectionState.Connected,
379
369
  );
380
370
  return Promise.all(
381
371
  pendingClients.map(async ([container, pendingClientId]) => {
@@ -546,7 +536,7 @@ export class LoaderContainerTracker implements IOpProcessingController {
546
536
  const inHandler = (message: ISequencedDocumentMessage) => {
547
537
  if (
548
538
  !canBeCoalescedByService(message) &&
549
- message.clientId === (container as Container).clientId &&
539
+ message.clientId === container.clientId &&
550
540
  inflightTracker.get(container) === message.clientSequenceNumber
551
541
  ) {
552
542
  inflightTracker.delete(container);
@@ -600,7 +590,7 @@ export class LoaderContainerTracker implements IOpProcessingController {
600
590
  return `${e.message}: ${e.stack}`;
601
591
  }
602
592
  };
603
- debugOp(`${index}: ADD: clientId: ${(container as Container).clientId}`);
593
+ debugOp(`${index}: ADD: clientId: ${container.clientId}`);
604
594
  container.deltaManager.outbound.on("op", (messages) => {
605
595
  for (const msg of messages) {
606
596
  debugOp(
@@ -614,7 +604,7 @@ export class LoaderContainerTracker implements IOpProcessingController {
614
604
  const getInboundHandler = (type: string) => {
615
605
  return (msg: ISequencedDocumentMessage) => {
616
606
  const clientSeq =
617
- msg.clientId === (container as Container).clientId
607
+ msg.clientId === container.clientId
618
608
  ? `cli: ${msg.clientSequenceNumber.toString().padStart(3)}`
619
609
  : " ";
620
610
  debugOp(
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/test-utils";
9
- export const pkgVersion = "2.0.0-dev.3.1.0.125672";
9
+ export const pkgVersion = "2.0.0-dev.4.1.0.148229";
@@ -3,7 +3,12 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { IContainer, IHostLoader, IFluidCodeDetails } from "@fluidframework/container-definitions";
6
+ import {
7
+ IContainer,
8
+ IHostLoader,
9
+ IFluidCodeDetails,
10
+ LoaderHeader,
11
+ } from "@fluidframework/container-definitions";
7
12
  import {
8
13
  ITelemetryGenericEvent,
9
14
  ITelemetryBaseLogger,
@@ -154,10 +159,18 @@ function getDocumentIdStrategy(type?: TestDriverTypes): IDocumentIdStrategy {
154
159
  * any expected events that have not occurred.
155
160
  */
156
161
  export class EventAndErrorTrackingLogger extends TelemetryLogger {
157
- /** Even if these error events are logged, tests should still be allowed to pass */
158
- private readonly allowedErrors: string[] = [
162
+ /**
163
+ * Even if these error events are logged, tests should still be allowed to pass
164
+ * Additionally, if downgrade is true, then log as generic (e.g. to avoid polluting the e2e test logs)
165
+ */
166
+ private readonly allowedErrors: { eventName: string; downgrade?: true }[] = [
159
167
  // This log was removed in current version as unnecessary, but it's still present in previous versions
160
- "fluid:telemetry:Container:NoRealStorageInDetachedContainer",
168
+ {
169
+ eventName: "fluid:telemetry:Container:NoRealStorageInDetachedContainer",
170
+ downgrade: true,
171
+ },
172
+ // 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.
173
+ { eventName: "fluid:telemetry:OpPerf:OpRoundtripTime" },
161
174
  ];
162
175
 
163
176
  constructor(private readonly baseLogger: ITelemetryBaseLogger) {
@@ -207,10 +220,15 @@ export class EventAndErrorTrackingLogger extends TelemetryLogger {
207
220
  }
208
221
  }
209
222
  if (event.category === "error") {
210
- if (this.allowedErrors.includes(event.eventName)) {
211
- event.category = "generic";
212
- } else {
223
+ // Check to see if this error is allowed and if its category should be downgraded
224
+ const allowedError = this.allowedErrors.find(
225
+ ({ eventName }) => eventName === event.eventName,
226
+ );
227
+
228
+ if (allowedError === undefined) {
213
229
  this.unexpectedErrors.push(event);
230
+ } else if (allowedError.downgrade) {
231
+ event.category = "generic";
214
232
  }
215
233
  }
216
234
 
@@ -364,10 +382,37 @@ export class TestObjectProvider implements ITestObjectProvider {
364
382
  requestHeader?: IRequestHeader,
365
383
  ): Promise<IContainer> {
366
384
  const loader = this.createLoader([[defaultCodeDetails, entryPoint]], loaderProps);
367
- return loader.resolve({
385
+
386
+ // Once ADO#3889 is done to switch default connection mode to "read" on load, we don't need
387
+ // to load "delayed" across the board. Remove the following code.
388
+ const delayConnection =
389
+ requestHeader === undefined || requestHeader[LoaderHeader.reconnect] !== false;
390
+ const headers: IRequestHeader = delayConnection
391
+ ? {
392
+ [LoaderHeader.loadMode]: { deltaConnection: "delayed" },
393
+ ...requestHeader,
394
+ }
395
+ : requestHeader;
396
+
397
+ const container = await loader.resolve({
368
398
  url: await this.driver.createContainerUrl(this.documentId),
369
- headers: requestHeader,
399
+ headers,
370
400
  });
401
+
402
+ // Once ADO#3889 is done to switch default connection mode to "read" on load, we don't need
403
+ // to load "delayed" across the board. Remove the following code.
404
+ if (delayConnection) {
405
+ // Older version may not have connect, use resume instead.
406
+ const maybeContainer = container as Partial<IContainer>;
407
+ if (maybeContainer.connect !== undefined) {
408
+ container.connect();
409
+ } else {
410
+ // back compat
411
+ (container as any).resume();
412
+ }
413
+ }
414
+
415
+ return container;
371
416
  }
372
417
 
373
418
  /**
@@ -442,9 +487,7 @@ export class TestObjectProvider implements ITestObjectProvider {
442
487
  }
443
488
 
444
489
  public async ensureSynchronized(timeoutDuration?: number): Promise<void> {
445
- return this._loaderContainerTracker.ensureSynchronizedWithTimeout
446
- ? this._loaderContainerTracker.ensureSynchronizedWithTimeout(timeoutDuration)
447
- : this._loaderContainerTracker.ensureSynchronized();
490
+ return this._loaderContainerTracker.ensureSynchronized();
448
491
  }
449
492
 
450
493
  public async waitContainerToCatchUp(container: IContainer) {
@@ -3,7 +3,6 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { Container } from "@fluidframework/container-loader";
7
6
  import { assert, Deferred } from "@fluidframework/common-utils";
8
7
 
9
8
  // @deprecated this value is no longer used
@@ -133,12 +132,6 @@ export async function timeoutAwait<T = void>(
133
132
  return Promise.race([promise, timeoutPromise<T>(() => {}, timeoutOptions)]);
134
133
  }
135
134
 
136
- export async function ensureContainerConnected(container: Container): Promise<void> {
137
- if (!container.connected) {
138
- return timeoutPromise((resolve) => container.once("connected", () => resolve()));
139
- }
140
- }
141
-
142
135
  // Create a promise based on the timeout options
143
136
  async function getTimeoutPromise<T = void>(
144
137
  executor: (