@fluidframework/test-utils 2.0.0-dev-rc.3.0.0.253463 → 2.0.0-dev-rc.3.0.0.254513
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/api-report/test-utils.api.md +33 -13
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/loaderContainerTracker.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/test-utils-alpha.d.ts +3 -0
- package/dist/test-utils-beta.d.ts +5 -0
- package/dist/test-utils-public.d.ts +5 -0
- package/dist/test-utils-untrimmed.d.ts +36 -15
- package/dist/testContainerRuntimeFactory.js +1 -1
- package/dist/testContainerRuntimeFactory.js.map +1 -1
- package/dist/testObjectProvider.d.ts +35 -15
- package/dist/testObjectProvider.d.ts.map +1 -1
- package/dist/testObjectProvider.js +61 -44
- package/dist/testObjectProvider.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/loaderContainerTracker.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/test-utils-alpha.d.ts +3 -0
- package/lib/test-utils-beta.d.ts +5 -0
- package/lib/test-utils-public.d.ts +5 -0
- package/lib/test-utils-untrimmed.d.ts +36 -15
- package/lib/testContainerRuntimeFactory.js +1 -1
- package/lib/testContainerRuntimeFactory.js.map +1 -1
- package/lib/testObjectProvider.d.ts +35 -15
- package/lib/testObjectProvider.d.ts.map +1 -1
- package/lib/testObjectProvider.js +55 -38
- package/lib/testObjectProvider.js.map +1 -1
- package/package.json +27 -24
- package/src/index.ts +1 -0
- package/src/loaderContainerTracker.ts +1 -1
- package/src/packageVersion.ts +1 -1
- package/src/testContainerRuntimeFactory.ts +1 -1
- package/src/testObjectProvider.ts +116 -64
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
import { assert } from "@fluidframework/core-utils/internal";
|
|
6
7
|
import { ITestDriver, TestDriverTypes } from "@fluid-internal/test-driver-definitions";
|
|
7
8
|
import {
|
|
8
9
|
IContainer,
|
|
@@ -27,7 +28,11 @@ import {
|
|
|
27
28
|
IUrlResolver,
|
|
28
29
|
} from "@fluidframework/driver-definitions/internal";
|
|
29
30
|
import { type ITelemetryGenericEventExt } from "@fluidframework/telemetry-utils";
|
|
30
|
-
import {
|
|
31
|
+
import {
|
|
32
|
+
createChildLogger,
|
|
33
|
+
createMultiSinkLogger,
|
|
34
|
+
type ITelemetryLoggerPropertyBags,
|
|
35
|
+
} from "@fluidframework/telemetry-utils/internal";
|
|
31
36
|
import { v4 as uuid } from "uuid";
|
|
32
37
|
|
|
33
38
|
import { LoaderContainerTracker } from "./loaderContainerTracker.js";
|
|
@@ -77,7 +82,12 @@ export interface ITestObjectProvider {
|
|
|
77
82
|
/**
|
|
78
83
|
* Logger used to track expected and unexpected events.
|
|
79
84
|
*/
|
|
80
|
-
logger:
|
|
85
|
+
logger: ITelemetryBaseLogger;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Logger used to track expected and unexpected events.
|
|
89
|
+
*/
|
|
90
|
+
tracker: IEventAndErrorTrackingLogger;
|
|
81
91
|
|
|
82
92
|
/**
|
|
83
93
|
* Used to create a url for the created container with any data store path given in the relative url.
|
|
@@ -175,6 +185,7 @@ export interface ITestObjectProvider {
|
|
|
175
185
|
loadTestContainer(
|
|
176
186
|
testContainerConfig?: ITestContainerConfig,
|
|
177
187
|
requestHeader?: IRequestHeader,
|
|
188
|
+
pendingLocalState?: string,
|
|
178
189
|
): Promise<IContainer>;
|
|
179
190
|
|
|
180
191
|
/**
|
|
@@ -283,6 +294,15 @@ function getDocumentIdStrategy(type?: TestDriverTypes): IDocumentIdStrategy {
|
|
|
283
294
|
}
|
|
284
295
|
}
|
|
285
296
|
|
|
297
|
+
/** @internal */
|
|
298
|
+
export interface IEventAndErrorTrackingLogger {
|
|
299
|
+
registerExpectedEvent: (...orderedExpectedEvents: ITelemetryGenericEventExt[]) => void;
|
|
300
|
+
reportAndClearTrackedEvents: () => {
|
|
301
|
+
expectedNotFound: { index: number; event: ITelemetryGenericEventExt }[];
|
|
302
|
+
unexpectedErrors: ITelemetryBaseEvent[];
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
|
|
286
306
|
/**
|
|
287
307
|
* This class tracks events. It allows specifying expected events, which will be looked for in order.
|
|
288
308
|
* It also tracks all unexpected errors.
|
|
@@ -290,7 +310,9 @@ function getDocumentIdStrategy(type?: TestDriverTypes): IDocumentIdStrategy {
|
|
|
290
310
|
* any expected events that have not occurred.
|
|
291
311
|
* @internal
|
|
292
312
|
*/
|
|
293
|
-
export class EventAndErrorTrackingLogger
|
|
313
|
+
export class EventAndErrorTrackingLogger
|
|
314
|
+
implements ITelemetryBaseLogger, IEventAndErrorTrackingLogger
|
|
315
|
+
{
|
|
294
316
|
/**
|
|
295
317
|
* Even if these error events are logged, tests should still be allowed to pass
|
|
296
318
|
* Additionally, if downgrade is true, then log as generic (e.g. to avoid polluting the e2e test logs)
|
|
@@ -305,12 +327,9 @@ export class EventAndErrorTrackingLogger implements ITelemetryBaseLogger {
|
|
|
305
327
|
{ eventName: "fluid:telemetry:OpPerf:OpRoundtripTime" },
|
|
306
328
|
];
|
|
307
329
|
|
|
308
|
-
constructor(private readonly baseLogger
|
|
330
|
+
constructor(private readonly baseLogger?: ITelemetryBaseLogger) {}
|
|
309
331
|
|
|
310
|
-
private readonly expectedEvents:
|
|
311
|
-
| { index: number; event: ITelemetryGenericEventExt | undefined }
|
|
312
|
-
| undefined
|
|
313
|
-
)[] = [];
|
|
332
|
+
private readonly expectedEvents: { index: number; event: ITelemetryGenericEventExt }[] = [];
|
|
314
333
|
private readonly unexpectedErrors: ITelemetryBaseEvent[] = [];
|
|
315
334
|
|
|
316
335
|
public registerExpectedEvent(...orderedExpectedEvents: ITelemetryGenericEventExt[]) {
|
|
@@ -328,24 +347,26 @@ export class EventAndErrorTrackingLogger implements ITelemetryBaseLogger {
|
|
|
328
347
|
}
|
|
329
348
|
|
|
330
349
|
send(event: ITelemetryBaseEvent): void {
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
350
|
+
if (this.expectedEvents.length > 0) {
|
|
351
|
+
const ee = this.expectedEvents[0].event;
|
|
352
|
+
if (ee.eventName === event.eventName) {
|
|
353
|
+
let matches = true;
|
|
354
|
+
for (const key of Object.keys(ee)) {
|
|
355
|
+
if (ee[key] !== event[key]) {
|
|
356
|
+
matches = false;
|
|
357
|
+
break;
|
|
358
|
+
}
|
|
338
359
|
}
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
360
|
+
if (matches) {
|
|
361
|
+
// we found an expected event
|
|
362
|
+
// so remove it from the list of expected events
|
|
363
|
+
// and if it is an error, change it to generic
|
|
364
|
+
// this helps keep our telemetry clear of
|
|
365
|
+
// expected errors.
|
|
366
|
+
this.expectedEvents.shift();
|
|
367
|
+
if (event.category === "error") {
|
|
368
|
+
event.category = "generic";
|
|
369
|
+
}
|
|
349
370
|
}
|
|
350
371
|
}
|
|
351
372
|
}
|
|
@@ -362,7 +383,7 @@ export class EventAndErrorTrackingLogger implements ITelemetryBaseLogger {
|
|
|
362
383
|
}
|
|
363
384
|
}
|
|
364
385
|
|
|
365
|
-
this.baseLogger
|
|
386
|
+
this.baseLogger?.send(event);
|
|
366
387
|
}
|
|
367
388
|
|
|
368
389
|
public reportAndClearTrackedEvents() {
|
|
@@ -387,7 +408,8 @@ export class TestObjectProvider implements ITestObjectProvider {
|
|
|
387
408
|
private _loaderContainerTracker = new LoaderContainerTracker();
|
|
388
409
|
private _documentServiceFactory: IDocumentServiceFactory | undefined;
|
|
389
410
|
private _urlResolver: IUrlResolver | undefined;
|
|
390
|
-
private _logger:
|
|
411
|
+
private _logger: ITelemetryBaseLogger | undefined;
|
|
412
|
+
private _tracker: EventAndErrorTrackingLogger | undefined;
|
|
391
413
|
private readonly _documentIdStrategy: IDocumentIdStrategy;
|
|
392
414
|
// Since documentId doesn't change we can only create/make one container. Call the load functions instead.
|
|
393
415
|
private _documentCreated = false;
|
|
@@ -416,27 +438,29 @@ export class TestObjectProvider implements ITestObjectProvider {
|
|
|
416
438
|
/**
|
|
417
439
|
* {@inheritDoc ITestObjectProvider.logger}
|
|
418
440
|
*/
|
|
419
|
-
public get logger():
|
|
441
|
+
public get logger(): ITelemetryBaseLogger {
|
|
420
442
|
if (this._logger === undefined) {
|
|
421
|
-
this.
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
443
|
+
this._tracker = new EventAndErrorTrackingLogger(getTestLogger?.());
|
|
444
|
+
this._logger = createChildLogger({
|
|
445
|
+
logger: this._tracker,
|
|
446
|
+
properties: {
|
|
447
|
+
all: {
|
|
448
|
+
testType: this.type,
|
|
449
|
+
driverType: this.driver.type,
|
|
450
|
+
driverEndpointName: this.driver.endpointName,
|
|
451
|
+
driverTenantName: this.driver.tenantName,
|
|
452
|
+
driverUserIndex: this.driver.userIndex,
|
|
431
453
|
},
|
|
432
|
-
}
|
|
433
|
-
);
|
|
454
|
+
},
|
|
455
|
+
});
|
|
434
456
|
}
|
|
435
457
|
return this._logger;
|
|
436
458
|
}
|
|
437
459
|
|
|
438
|
-
|
|
439
|
-
this.
|
|
460
|
+
public get tracker() {
|
|
461
|
+
void this.logger;
|
|
462
|
+
assert(this._tracker !== undefined, "should be initialized");
|
|
463
|
+
return this._tracker;
|
|
440
464
|
}
|
|
441
465
|
|
|
442
466
|
/**
|
|
@@ -567,11 +591,18 @@ export class TestObjectProvider implements ITestObjectProvider {
|
|
|
567
591
|
return this.resolveContainer(loader, requestHeader);
|
|
568
592
|
}
|
|
569
593
|
|
|
570
|
-
private async resolveContainer(
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
594
|
+
private async resolveContainer(
|
|
595
|
+
loader: ILoader,
|
|
596
|
+
headers?: IRequestHeader,
|
|
597
|
+
pendingLocalState?: string,
|
|
598
|
+
) {
|
|
599
|
+
return loader.resolve(
|
|
600
|
+
{
|
|
601
|
+
url: await this.driver.createContainerUrl(this.documentId),
|
|
602
|
+
headers,
|
|
603
|
+
},
|
|
604
|
+
pendingLocalState,
|
|
605
|
+
);
|
|
575
606
|
}
|
|
576
607
|
|
|
577
608
|
/**
|
|
@@ -614,10 +645,11 @@ export class TestObjectProvider implements ITestObjectProvider {
|
|
|
614
645
|
public async loadTestContainer(
|
|
615
646
|
testContainerConfig?: ITestContainerConfig,
|
|
616
647
|
requestHeader?: IRequestHeader,
|
|
648
|
+
pendingLocalState?: string,
|
|
617
649
|
): Promise<IContainer> {
|
|
618
650
|
const loader = this.makeTestLoader(testContainerConfig);
|
|
619
651
|
|
|
620
|
-
const container = await this.resolveContainer(loader, requestHeader);
|
|
652
|
+
const container = await this.resolveContainer(loader, requestHeader, pendingLocalState);
|
|
621
653
|
await this.waitContainerToCatchUp(container);
|
|
622
654
|
|
|
623
655
|
return container;
|
|
@@ -631,11 +663,12 @@ export class TestObjectProvider implements ITestObjectProvider {
|
|
|
631
663
|
this._documentServiceFactory = undefined;
|
|
632
664
|
this._urlResolver = undefined;
|
|
633
665
|
this._documentIdStrategy.reset();
|
|
634
|
-
const logError = getUnexpectedLogErrorException(this.
|
|
666
|
+
const logError = getUnexpectedLogErrorException(this._tracker);
|
|
635
667
|
if (logError) {
|
|
636
668
|
throw logError;
|
|
637
669
|
}
|
|
638
670
|
this._logger = undefined;
|
|
671
|
+
this._tracker = undefined;
|
|
639
672
|
this._documentCreated = false;
|
|
640
673
|
}
|
|
641
674
|
|
|
@@ -685,7 +718,8 @@ export class TestObjectProviderWithVersionedLoad implements ITestObjectProvider
|
|
|
685
718
|
*/
|
|
686
719
|
public readonly type = "TestObjectProviderWithVersionedLoad";
|
|
687
720
|
private _loaderContainerTracker = new LoaderContainerTracker();
|
|
688
|
-
private _logger:
|
|
721
|
+
private _logger: ITelemetryBaseLogger | undefined;
|
|
722
|
+
private _tracker: EventAndErrorTrackingLogger | undefined;
|
|
689
723
|
private readonly _documentIdStrategy: IDocumentIdStrategy;
|
|
690
724
|
private _documentServiceFactory: IDocumentServiceFactory | undefined;
|
|
691
725
|
private _urlResolver: IUrlResolver | undefined;
|
|
@@ -711,6 +745,7 @@ export class TestObjectProviderWithVersionedLoad implements ITestObjectProvider
|
|
|
711
745
|
private readonly createFluidEntryPointForLoading: (
|
|
712
746
|
testContainerConfig?: ITestContainerConfig,
|
|
713
747
|
) => fluidEntryPoint,
|
|
748
|
+
private readonly telemetryProps?: ITelemetryLoggerPropertyBags,
|
|
714
749
|
) {
|
|
715
750
|
this._documentIdStrategy = getDocumentIdStrategy(driverForCreating.type);
|
|
716
751
|
}
|
|
@@ -718,17 +753,23 @@ export class TestObjectProviderWithVersionedLoad implements ITestObjectProvider
|
|
|
718
753
|
/**
|
|
719
754
|
* {@inheritDoc ITestObjectProvider.logger}
|
|
720
755
|
*/
|
|
721
|
-
public get logger()
|
|
756
|
+
public get logger() {
|
|
722
757
|
if (this._logger === undefined) {
|
|
723
|
-
this.
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
);
|
|
758
|
+
this._tracker = new EventAndErrorTrackingLogger(getTestLogger?.());
|
|
759
|
+
this._logger = createChildLogger({
|
|
760
|
+
logger: this._tracker,
|
|
761
|
+
properties: this.telemetryProps,
|
|
762
|
+
});
|
|
728
763
|
}
|
|
729
764
|
return this._logger;
|
|
730
765
|
}
|
|
731
766
|
|
|
767
|
+
public get tracker() {
|
|
768
|
+
void this.logger;
|
|
769
|
+
assert(this._tracker !== undefined, "should be initialized");
|
|
770
|
+
return this._tracker;
|
|
771
|
+
}
|
|
772
|
+
|
|
732
773
|
/**
|
|
733
774
|
* {@inheritDoc ITestObjectProvider.documentServiceFactory}
|
|
734
775
|
*/
|
|
@@ -918,12 +959,16 @@ export class TestObjectProviderWithVersionedLoad implements ITestObjectProvider
|
|
|
918
959
|
loader: ILoader,
|
|
919
960
|
headers?: IRequestHeader,
|
|
920
961
|
driver?: ITestDriver,
|
|
962
|
+
pendingLocalState?: string,
|
|
921
963
|
) {
|
|
922
|
-
return loader.resolve(
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
964
|
+
return loader.resolve(
|
|
965
|
+
{
|
|
966
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
967
|
+
url: await driver!.createContainerUrl(this.documentId),
|
|
968
|
+
headers,
|
|
969
|
+
},
|
|
970
|
+
pendingLocalState,
|
|
971
|
+
);
|
|
927
972
|
}
|
|
928
973
|
|
|
929
974
|
/**
|
|
@@ -970,11 +1015,17 @@ export class TestObjectProviderWithVersionedLoad implements ITestObjectProvider
|
|
|
970
1015
|
public async loadTestContainer(
|
|
971
1016
|
testContainerConfig?: ITestContainerConfig,
|
|
972
1017
|
requestHeader?: IRequestHeader,
|
|
1018
|
+
pendingLocalState?: string,
|
|
973
1019
|
): Promise<IContainer> {
|
|
974
1020
|
// Keep track of which Loader we are about to use so we can pass the correct driver through
|
|
975
1021
|
const driver = this.useCreateApi ? this.driverForCreating : this.driverForLoading;
|
|
976
1022
|
const loader = this.makeTestLoader(testContainerConfig);
|
|
977
|
-
const container = await this.resolveContainer(
|
|
1023
|
+
const container = await this.resolveContainer(
|
|
1024
|
+
loader,
|
|
1025
|
+
requestHeader,
|
|
1026
|
+
driver,
|
|
1027
|
+
pendingLocalState,
|
|
1028
|
+
);
|
|
978
1029
|
await this.waitContainerToCatchUp(container);
|
|
979
1030
|
|
|
980
1031
|
return container;
|
|
@@ -987,10 +1038,11 @@ export class TestObjectProviderWithVersionedLoad implements ITestObjectProvider
|
|
|
987
1038
|
this.useCreateApi = true;
|
|
988
1039
|
this._loaderContainerTracker.reset();
|
|
989
1040
|
this._logger = undefined;
|
|
1041
|
+
this._tracker = undefined;
|
|
990
1042
|
this._documentServiceFactory = undefined;
|
|
991
1043
|
this._urlResolver = undefined;
|
|
992
1044
|
this._documentIdStrategy.reset();
|
|
993
|
-
const logError = getUnexpectedLogErrorException(this.
|
|
1045
|
+
const logError = getUnexpectedLogErrorException(this._tracker);
|
|
994
1046
|
if (logError) {
|
|
995
1047
|
throw logError;
|
|
996
1048
|
}
|
|
@@ -1036,7 +1088,7 @@ export class TestObjectProviderWithVersionedLoad implements ITestObjectProvider
|
|
|
1036
1088
|
* @internal
|
|
1037
1089
|
*/
|
|
1038
1090
|
export function getUnexpectedLogErrorException(
|
|
1039
|
-
logger:
|
|
1091
|
+
logger: IEventAndErrorTrackingLogger | undefined,
|
|
1040
1092
|
prefix?: string,
|
|
1041
1093
|
) {
|
|
1042
1094
|
if (logger === undefined) {
|