@fluidframework/test-utils 2.90.0-378676 → 2.91.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.
- package/CHANGELOG.md +8 -0
- package/README.md +2 -0
- package/dist/TestSummaryUtils.d.ts.map +1 -1
- package/dist/TestSummaryUtils.js +0 -1
- package/dist/TestSummaryUtils.js.map +1 -1
- package/dist/eventAndErrorLogger.d.ts +51 -0
- package/dist/eventAndErrorLogger.d.ts.map +1 -0
- package/dist/eventAndErrorLogger.js +116 -0
- package/dist/eventAndErrorLogger.js.map +1 -0
- package/dist/index.d.ts +7 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -5
- package/dist/index.js.map +1 -1
- package/dist/loaderContainerTracker.d.ts.map +1 -1
- package/dist/loaderContainerTracker.js +1 -2
- package/dist/loaderContainerTracker.js.map +1 -1
- package/dist/localCodeLoader.d.ts.map +1 -1
- package/dist/localCodeLoader.js +0 -1
- package/dist/localCodeLoader.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/testObjectProvider.d.ts +4 -46
- package/dist/testObjectProvider.d.ts.map +1 -1
- package/dist/testObjectProvider.js +10 -117
- package/dist/testObjectProvider.js.map +1 -1
- package/dist/timeoutUtils.d.ts.map +1 -1
- package/dist/timeoutUtils.js +2 -0
- package/dist/timeoutUtils.js.map +1 -1
- package/lib/TestSummaryUtils.d.ts.map +1 -1
- package/lib/TestSummaryUtils.js +0 -1
- package/lib/TestSummaryUtils.js.map +1 -1
- package/lib/eventAndErrorLogger.d.ts +51 -0
- package/lib/eventAndErrorLogger.d.ts.map +1 -0
- package/lib/eventAndErrorLogger.js +111 -0
- package/lib/eventAndErrorLogger.js.map +1 -0
- package/lib/index.d.ts +7 -3
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +11 -2
- package/lib/index.js.map +1 -1
- package/lib/loaderContainerTracker.d.ts.map +1 -1
- package/lib/loaderContainerTracker.js +1 -2
- package/lib/loaderContainerTracker.js.map +1 -1
- package/lib/localCodeLoader.d.ts.map +1 -1
- package/lib/localCodeLoader.js +0 -1
- package/lib/localCodeLoader.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.d.ts.map +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/testObjectProvider.d.ts +4 -46
- package/lib/testObjectProvider.d.ts.map +1 -1
- package/lib/testObjectProvider.js +5 -110
- package/lib/testObjectProvider.js.map +1 -1
- package/lib/timeoutUtils.d.ts.map +1 -1
- package/lib/timeoutUtils.js +2 -0
- package/lib/timeoutUtils.js.map +1 -1
- package/package.json +27 -27
- package/src/TestSummaryUtils.ts +0 -2
- package/src/eventAndErrorLogger.ts +164 -0
- package/src/index.ts +22 -8
- package/src/loaderContainerTracker.ts +2 -3
- package/src/localCodeLoader.ts +0 -1
- package/src/packageVersion.ts +1 -1
- package/src/testObjectProvider.ts +9 -159
- package/src/timeoutUtils.ts +8 -0
package/src/index.ts
CHANGED
|
@@ -3,8 +3,12 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
export type { IEventAndErrorTrackingLogger } from "./eventAndErrorLogger.js";
|
|
7
|
+
export {
|
|
8
|
+
EventAndErrorTrackingLogger,
|
|
9
|
+
getUnexpectedLogErrorException,
|
|
10
|
+
} from "./eventAndErrorLogger.js";
|
|
6
11
|
export { IProvideTestFluidObject, ITestFluidObject } from "./interfaces.js";
|
|
7
|
-
export { LoaderContainerTracker } from "./loaderContainerTracker.js";
|
|
8
12
|
export {
|
|
9
13
|
fluidEntryPoint,
|
|
10
14
|
LocalCodeLoader,
|
|
@@ -30,25 +34,33 @@ export {
|
|
|
30
34
|
TestFluidObjectFactory,
|
|
31
35
|
TestDataObjectKind,
|
|
32
36
|
} from "./testFluidObject.js";
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
|
|
38
|
+
// #region Exports with load side-effect
|
|
39
|
+
// The below runtime (not "type") exports transitively or directly import
|
|
40
|
+
// timeoutUtils.ts, which always executes on import and may patch Mocha's timeout
|
|
41
|
+
// handling. That patching only takes effect when consumers use
|
|
42
|
+
// @fluid-internal/mocha-test-setup that sets globalThis.getMochaModule.
|
|
43
|
+
// @fluid-internal/mocha-test-setup is pervasive in our tests and thus patch
|
|
44
|
+
// is usually in effect (when this package is used).
|
|
45
|
+
export { LoaderContainerTracker } from "./loaderContainerTracker.js";
|
|
46
|
+
export type {
|
|
39
47
|
IDocumentIdStrategy,
|
|
40
48
|
IOpProcessingController,
|
|
41
49
|
ITestContainerConfig,
|
|
42
50
|
ITestObjectProvider,
|
|
51
|
+
} from "./testObjectProvider.js";
|
|
52
|
+
export {
|
|
53
|
+
createDocumentId,
|
|
54
|
+
DataObjectFactoryType,
|
|
43
55
|
TestObjectProvider,
|
|
44
56
|
TestObjectProviderWithVersionedLoad,
|
|
45
57
|
} from "./testObjectProvider.js";
|
|
58
|
+
export type { SummaryInfo } from "./TestSummaryUtils.js";
|
|
46
59
|
export {
|
|
47
60
|
createSummarizer,
|
|
48
61
|
createSummarizerCore,
|
|
49
62
|
createSummarizerFromFactory,
|
|
50
63
|
summarizeNow,
|
|
51
|
-
SummaryInfo,
|
|
52
64
|
} from "./TestSummaryUtils.js";
|
|
53
65
|
export {
|
|
54
66
|
timeoutAwait,
|
|
@@ -63,6 +75,8 @@ export {
|
|
|
63
75
|
getContainerEntryPointBackCompat,
|
|
64
76
|
getDataStoreEntryPointBackCompat,
|
|
65
77
|
} from "./containerUtils.js";
|
|
78
|
+
// #endregion
|
|
79
|
+
|
|
66
80
|
export {
|
|
67
81
|
type ContainerRuntimeFactoryWithDefaultDataStoreConstructor,
|
|
68
82
|
type ContainerRuntimeFactoryWithDefaultDataStoreProps,
|
|
@@ -12,7 +12,6 @@ import { ConnectionState } from "@fluidframework/container-loader";
|
|
|
12
12
|
import {
|
|
13
13
|
IContainerCreateProps,
|
|
14
14
|
IContainerLoadProps,
|
|
15
|
-
// eslint-disable-next-line import-x/no-internal-modules
|
|
16
15
|
} from "@fluidframework/container-loader/internal/test/container";
|
|
17
16
|
import { assert } from "@fluidframework/core-utils/internal";
|
|
18
17
|
import {
|
|
@@ -228,7 +227,7 @@ export class LoaderContainerTracker implements IOpProcessingController {
|
|
|
228
227
|
const resumed = this.resumeProcessing(...containers);
|
|
229
228
|
|
|
230
229
|
let waitingSequenceNumberSynchronized: string | undefined;
|
|
231
|
-
|
|
230
|
+
|
|
232
231
|
while (true) {
|
|
233
232
|
// yield a turn to allow side effect of resuming or the ops we just processed execute before we check
|
|
234
233
|
await new Promise<void>((resolve) => {
|
|
@@ -515,7 +514,7 @@ export class LoaderContainerTracker implements IOpProcessingController {
|
|
|
515
514
|
for (const container of containersToApply) {
|
|
516
515
|
const record = this.containers.get(container);
|
|
517
516
|
if (record !== undefined && !record.paused) {
|
|
518
|
-
// eslint-disable-next-line @typescript-eslint/
|
|
517
|
+
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- intentional behavior
|
|
519
518
|
if (record.pauseP === undefined) {
|
|
520
519
|
record.pauseP = this.pauseContainer(container, record);
|
|
521
520
|
}
|
package/src/localCodeLoader.ts
CHANGED
|
@@ -45,7 +45,6 @@ export type fluidEntryPoint = SupportedExportInterfaces | IFluidModule;
|
|
|
45
45
|
*/
|
|
46
46
|
export type Factory = IFluidDataStoreFactory & Partial<IProvideFluidDataStoreRegistry>;
|
|
47
47
|
|
|
48
|
-
// eslint-disable-next-line jsdoc/require-description -- TODO: add documentation
|
|
49
48
|
/**
|
|
50
49
|
* @internal
|
|
51
50
|
*/
|
package/src/packageVersion.ts
CHANGED
|
@@ -18,7 +18,6 @@ import {
|
|
|
18
18
|
import type { IContainerRuntimeOptionsInternal } from "@fluidframework/container-runtime/internal";
|
|
19
19
|
import {
|
|
20
20
|
IRequestHeader,
|
|
21
|
-
ITelemetryBaseEvent,
|
|
22
21
|
ITelemetryBaseLogger,
|
|
23
22
|
ITelemetryBaseProperties,
|
|
24
23
|
TelemetryBaseEventPropertyType,
|
|
@@ -32,7 +31,6 @@ import {
|
|
|
32
31
|
import { isOdspResolvedUrl } from "@fluidframework/odsp-driver/internal";
|
|
33
32
|
import type { MinimumVersionForCollab } from "@fluidframework/runtime-definitions/internal";
|
|
34
33
|
import {
|
|
35
|
-
type ITelemetryGenericEventExt,
|
|
36
34
|
createChildLogger,
|
|
37
35
|
createMultiSinkLogger,
|
|
38
36
|
type ITelemetryLoggerPropertyBags,
|
|
@@ -41,10 +39,14 @@ import {
|
|
|
41
39
|
} from "@fluidframework/telemetry-utils/internal";
|
|
42
40
|
import { v4 as uuid } from "uuid";
|
|
43
41
|
|
|
42
|
+
import type { IEventAndErrorTrackingLogger } from "./eventAndErrorLogger.js";
|
|
43
|
+
import {
|
|
44
|
+
EventAndErrorTrackingLogger,
|
|
45
|
+
getUnexpectedLogErrorException,
|
|
46
|
+
} from "./eventAndErrorLogger.js";
|
|
44
47
|
import { LoaderContainerTracker } from "./loaderContainerTracker.js";
|
|
45
48
|
import { LocalCodeLoader, fluidEntryPoint } from "./localCodeLoader.js";
|
|
46
49
|
import { createAndAttachContainer } from "./localLoader.js";
|
|
47
|
-
import { isNonEmptyArray } from "./nonEmptyArrayType.js";
|
|
48
50
|
import { ChannelFactoryRegistry } from "./testFluidObject.js";
|
|
49
51
|
|
|
50
52
|
const defaultCodeDetails: IFluidCodeDetails = {
|
|
@@ -329,111 +331,6 @@ function getDocumentIdStrategy(type?: TestDriverTypes): IDocumentIdStrategy {
|
|
|
329
331
|
}
|
|
330
332
|
}
|
|
331
333
|
|
|
332
|
-
/** @internal */
|
|
333
|
-
export interface IEventAndErrorTrackingLogger {
|
|
334
|
-
registerExpectedEvent: (...orderedExpectedEvents: ITelemetryGenericEventExt[]) => void;
|
|
335
|
-
reportAndClearTrackedEvents: () => {
|
|
336
|
-
expectedNotFound: { index: number; event: ITelemetryGenericEventExt }[];
|
|
337
|
-
unexpectedErrors: ITelemetryBaseEvent[];
|
|
338
|
-
};
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
/**
|
|
342
|
-
* This class tracks events. It allows specifying expected events, which will be looked for in order.
|
|
343
|
-
* It also tracks all unexpected errors.
|
|
344
|
-
* At any point you call reportAndClearTrackedEvents which will provide all unexpected errors, and
|
|
345
|
-
* any expected events that have not occurred.
|
|
346
|
-
* @internal
|
|
347
|
-
*/
|
|
348
|
-
export class EventAndErrorTrackingLogger
|
|
349
|
-
implements ITelemetryBaseLogger, IEventAndErrorTrackingLogger
|
|
350
|
-
{
|
|
351
|
-
/**
|
|
352
|
-
* Even if these error events are logged, tests should still be allowed to pass
|
|
353
|
-
* Additionally, if downgrade is true, then log as generic (e.g. to avoid polluting the e2e test logs)
|
|
354
|
-
*/
|
|
355
|
-
private readonly allowedErrors: { eventName: string; downgrade?: true }[] = [
|
|
356
|
-
// This log was removed in current version as unnecessary, but it's still present in previous versions
|
|
357
|
-
{
|
|
358
|
-
eventName: "fluid:telemetry:Container:NoRealStorageInDetachedContainer",
|
|
359
|
-
downgrade: true,
|
|
360
|
-
},
|
|
361
|
-
// 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.
|
|
362
|
-
{ eventName: "fluid:telemetry:OpRoundtripTime" },
|
|
363
|
-
];
|
|
364
|
-
|
|
365
|
-
constructor(private readonly baseLogger?: ITelemetryBaseLogger) {}
|
|
366
|
-
|
|
367
|
-
private readonly expectedEvents: { index: number; event: ITelemetryGenericEventExt }[] = [];
|
|
368
|
-
private readonly unexpectedErrors: ITelemetryBaseEvent[] = [];
|
|
369
|
-
|
|
370
|
-
public registerExpectedEvent(...orderedExpectedEvents: ITelemetryGenericEventExt[]): void {
|
|
371
|
-
if (this.expectedEvents.length !== 0) {
|
|
372
|
-
// we don't have to error here. just no reason not to. given the events must be
|
|
373
|
-
// ordered it could be tricky to figure out problems around multiple registrations.
|
|
374
|
-
throw new Error(
|
|
375
|
-
"Expected events already registered.\n" +
|
|
376
|
-
"Call reportAndClearTrackedEvents to clear them before registering more",
|
|
377
|
-
);
|
|
378
|
-
}
|
|
379
|
-
this.expectedEvents.push(
|
|
380
|
-
...orderedExpectedEvents.map((event, index) => ({ index, event })),
|
|
381
|
-
);
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
send(event: ITelemetryBaseEvent): void {
|
|
385
|
-
if (isNonEmptyArray(this.expectedEvents)) {
|
|
386
|
-
const ee = this.expectedEvents[0].event;
|
|
387
|
-
if (ee.eventName === event.eventName) {
|
|
388
|
-
let matches = true;
|
|
389
|
-
for (const key of Object.keys(ee)) {
|
|
390
|
-
if (ee[key] !== event[key]) {
|
|
391
|
-
matches = false;
|
|
392
|
-
break;
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
if (matches) {
|
|
396
|
-
// we found an expected event
|
|
397
|
-
// so remove it from the list of expected events
|
|
398
|
-
// and if it is an error, change it to generic
|
|
399
|
-
// this helps keep our telemetry clear of
|
|
400
|
-
// expected errors.
|
|
401
|
-
this.expectedEvents.shift();
|
|
402
|
-
if (event.category === "error") {
|
|
403
|
-
event.category = "generic";
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
if (event.category === "error") {
|
|
409
|
-
// Check to see if this error is allowed and if its category should be downgraded
|
|
410
|
-
const allowedError = this.allowedErrors.find(
|
|
411
|
-
({ eventName }) => eventName === event.eventName,
|
|
412
|
-
);
|
|
413
|
-
|
|
414
|
-
if (allowedError === undefined) {
|
|
415
|
-
this.unexpectedErrors.push(event);
|
|
416
|
-
} else if (allowedError.downgrade) {
|
|
417
|
-
event.category = "generic";
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
this.baseLogger?.send(event);
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
public reportAndClearTrackedEvents(): {
|
|
425
|
-
expectedNotFound: { index: number; event: ITelemetryGenericEventExt }[];
|
|
426
|
-
unexpectedErrors: ITelemetryBaseEvent[];
|
|
427
|
-
} {
|
|
428
|
-
const expectedNotFound = this.expectedEvents.splice(0, this.expectedEvents.length);
|
|
429
|
-
const unexpectedErrors = this.unexpectedErrors.splice(0, this.unexpectedErrors.length);
|
|
430
|
-
return {
|
|
431
|
-
expectedNotFound,
|
|
432
|
-
unexpectedErrors,
|
|
433
|
-
};
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
|
|
437
334
|
/**
|
|
438
335
|
* Shared base class for test object provider. Contain code for loader and container creation and loading
|
|
439
336
|
* @internal
|
|
@@ -505,7 +402,7 @@ export class TestObjectProvider implements ITestObjectProvider {
|
|
|
505
402
|
* {@inheritDoc ITestObjectProvider.documentServiceFactory}
|
|
506
403
|
*/
|
|
507
404
|
public get documentServiceFactory(): IDocumentServiceFactory {
|
|
508
|
-
// eslint-disable-next-line @typescript-eslint/
|
|
405
|
+
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- intentional behavior
|
|
509
406
|
if (!this._documentServiceFactory) {
|
|
510
407
|
this._documentServiceFactory = this.driver.createDocumentServiceFactory();
|
|
511
408
|
}
|
|
@@ -516,7 +413,7 @@ export class TestObjectProvider implements ITestObjectProvider {
|
|
|
516
413
|
* {@inheritDoc ITestObjectProvider.urlResolver}
|
|
517
414
|
*/
|
|
518
415
|
public get urlResolver(): IUrlResolver {
|
|
519
|
-
// eslint-disable-next-line @typescript-eslint/
|
|
416
|
+
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- intentional behavior
|
|
520
417
|
if (!this._urlResolver) {
|
|
521
418
|
this._urlResolver = this.driver.createUrlResolver();
|
|
522
419
|
}
|
|
@@ -823,7 +720,7 @@ export class TestObjectProviderWithVersionedLoad implements ITestObjectProvider
|
|
|
823
720
|
* {@inheritDoc ITestObjectProvider.documentServiceFactory}
|
|
824
721
|
*/
|
|
825
722
|
public get documentServiceFactory(): IDocumentServiceFactory {
|
|
826
|
-
// eslint-disable-next-line @typescript-eslint/
|
|
723
|
+
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- intentional behavior
|
|
827
724
|
if (!this._documentServiceFactory) {
|
|
828
725
|
this._documentServiceFactory = this.driverForCreating.createDocumentServiceFactory();
|
|
829
726
|
}
|
|
@@ -834,7 +731,7 @@ export class TestObjectProviderWithVersionedLoad implements ITestObjectProvider
|
|
|
834
731
|
* {@inheritDoc ITestObjectProvider.urlResolver}
|
|
835
732
|
*/
|
|
836
733
|
public get urlResolver(): IUrlResolver {
|
|
837
|
-
// eslint-disable-next-line @typescript-eslint/
|
|
734
|
+
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- intentional behavior
|
|
838
735
|
if (!this._urlResolver) {
|
|
839
736
|
this._urlResolver = this.driverForCreating.createUrlResolver();
|
|
840
737
|
}
|
|
@@ -1171,50 +1068,3 @@ function getUrlTelemetryProps(
|
|
|
1171
1068
|
|
|
1172
1069
|
return tagData(TelemetryDataTag.UserData, props);
|
|
1173
1070
|
}
|
|
1174
|
-
|
|
1175
|
-
/** Summarize the event with just the primary properties, for succinct output in case of test failure */
|
|
1176
|
-
const primaryEventProps = ({
|
|
1177
|
-
category,
|
|
1178
|
-
eventName,
|
|
1179
|
-
error,
|
|
1180
|
-
errorType,
|
|
1181
|
-
}: ITelemetryBaseEvent): Partial<ITelemetryBaseEvent> => ({
|
|
1182
|
-
category,
|
|
1183
|
-
eventName,
|
|
1184
|
-
error,
|
|
1185
|
-
errorType,
|
|
1186
|
-
["..."]: "*** Additional properties not shown, see full log for details ***",
|
|
1187
|
-
});
|
|
1188
|
-
|
|
1189
|
-
/**
|
|
1190
|
-
* Retrieves unexpected errors from a logger and returns them as an exception.
|
|
1191
|
-
*
|
|
1192
|
-
* @internal
|
|
1193
|
-
*/
|
|
1194
|
-
export function getUnexpectedLogErrorException(
|
|
1195
|
-
logger: IEventAndErrorTrackingLogger | undefined,
|
|
1196
|
-
prefix?: string,
|
|
1197
|
-
): Error | undefined {
|
|
1198
|
-
if (logger === undefined) {
|
|
1199
|
-
return;
|
|
1200
|
-
}
|
|
1201
|
-
const results = logger.reportAndClearTrackedEvents();
|
|
1202
|
-
if (results.unexpectedErrors.length > 0) {
|
|
1203
|
-
return new Error(
|
|
1204
|
-
`${prefix ?? ""}Unexpected Errors in Logs:\n${JSON.stringify(
|
|
1205
|
-
results.unexpectedErrors.map(primaryEventProps),
|
|
1206
|
-
undefined,
|
|
1207
|
-
2,
|
|
1208
|
-
)}`,
|
|
1209
|
-
);
|
|
1210
|
-
}
|
|
1211
|
-
if (results.expectedNotFound.length > 0) {
|
|
1212
|
-
return new Error(
|
|
1213
|
-
`${prefix ?? ""}Expected Events not found:\n${JSON.stringify(
|
|
1214
|
-
results.expectedNotFound,
|
|
1215
|
-
undefined,
|
|
1216
|
-
2,
|
|
1217
|
-
)}`,
|
|
1218
|
-
);
|
|
1219
|
-
}
|
|
1220
|
-
}
|
package/src/timeoutUtils.ts
CHANGED
|
@@ -3,7 +3,15 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
// Warning: this module has load side effect of patching Mocha's timeout handling.
|
|
7
|
+
// See globalThis.getMochaModule use below.
|
|
8
|
+
|
|
6
9
|
import { assert, Deferred } from "@fluidframework/core-utils/internal";
|
|
10
|
+
// Note that "@types/mocha" is only a devDependency of this package.
|
|
11
|
+
// None of the mocha types are exposed through exports and thus it's reasonable
|
|
12
|
+
// to leave mocha as a devDependency only. Further, the underlying code is only
|
|
13
|
+
// used when @fluid-internal/mocha-test-setup is used and that package dictates
|
|
14
|
+
// a mocha version.
|
|
7
15
|
import type * as Mocha from "mocha";
|
|
8
16
|
|
|
9
17
|
const timeBuffer = 15; // leave 15 ms leeway for finish processing
|