@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.
Files changed (41) hide show
  1. package/api-report/test-utils.api.md +33 -13
  2. package/dist/index.d.ts +1 -1
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/loaderContainerTracker.js.map +1 -1
  6. package/dist/packageVersion.d.ts +1 -1
  7. package/dist/packageVersion.js +1 -1
  8. package/dist/packageVersion.js.map +1 -1
  9. package/dist/test-utils-alpha.d.ts +3 -0
  10. package/dist/test-utils-beta.d.ts +5 -0
  11. package/dist/test-utils-public.d.ts +5 -0
  12. package/dist/test-utils-untrimmed.d.ts +36 -15
  13. package/dist/testContainerRuntimeFactory.js +1 -1
  14. package/dist/testContainerRuntimeFactory.js.map +1 -1
  15. package/dist/testObjectProvider.d.ts +35 -15
  16. package/dist/testObjectProvider.d.ts.map +1 -1
  17. package/dist/testObjectProvider.js +61 -44
  18. package/dist/testObjectProvider.js.map +1 -1
  19. package/lib/index.d.ts +1 -1
  20. package/lib/index.d.ts.map +1 -1
  21. package/lib/index.js.map +1 -1
  22. package/lib/loaderContainerTracker.js.map +1 -1
  23. package/lib/packageVersion.d.ts +1 -1
  24. package/lib/packageVersion.js +1 -1
  25. package/lib/packageVersion.js.map +1 -1
  26. package/lib/test-utils-alpha.d.ts +3 -0
  27. package/lib/test-utils-beta.d.ts +5 -0
  28. package/lib/test-utils-public.d.ts +5 -0
  29. package/lib/test-utils-untrimmed.d.ts +36 -15
  30. package/lib/testContainerRuntimeFactory.js +1 -1
  31. package/lib/testContainerRuntimeFactory.js.map +1 -1
  32. package/lib/testObjectProvider.d.ts +35 -15
  33. package/lib/testObjectProvider.d.ts.map +1 -1
  34. package/lib/testObjectProvider.js +55 -38
  35. package/lib/testObjectProvider.js.map +1 -1
  36. package/package.json +27 -24
  37. package/src/index.ts +1 -0
  38. package/src/loaderContainerTracker.ts +1 -1
  39. package/src/packageVersion.ts +1 -1
  40. package/src/testContainerRuntimeFactory.ts +1 -1
  41. 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 { createChildLogger, createMultiSinkLogger } from "@fluidframework/telemetry-utils/internal";
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: EventAndErrorTrackingLogger | undefined;
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 implements ITelemetryBaseLogger {
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: ITelemetryBaseLogger) {}
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
- const ee = this.expectedEvents[0]?.event;
332
- if (ee?.eventName === event.eventName) {
333
- let matches = true;
334
- for (const key of Object.keys(ee)) {
335
- if (ee[key] !== event[key]) {
336
- matches = false;
337
- break;
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
- if (matches) {
341
- // we found an expected event
342
- // so remove it from the list of expected events
343
- // and if it is an error, change it to generic
344
- // this helps keep our telemetry clear of
345
- // expected errors.
346
- this.expectedEvents.shift();
347
- if (event.category === "error") {
348
- event.category = "generic";
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.send(event);
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: EventAndErrorTrackingLogger | undefined;
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(): EventAndErrorTrackingLogger {
441
+ public get logger(): ITelemetryBaseLogger {
420
442
  if (this._logger === undefined) {
421
- this._logger = new EventAndErrorTrackingLogger(
422
- createChildLogger({
423
- logger: getTestLogger?.(),
424
- properties: {
425
- all: {
426
- driverType: this.driver.type,
427
- driverEndpointName: this.driver.endpointName,
428
- driverTenantName: this.driver.tenantName,
429
- driverUserIndex: this.driver.userIndex,
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
- private set logger(logger: EventAndErrorTrackingLogger) {
439
- this._logger = logger;
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(loader: ILoader, headers?: IRequestHeader) {
571
- return loader.resolve({
572
- url: await this.driver.createContainerUrl(this.documentId),
573
- headers,
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._logger);
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: EventAndErrorTrackingLogger | undefined;
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(): EventAndErrorTrackingLogger {
756
+ public get logger() {
722
757
  if (this._logger === undefined) {
723
- this._logger = new EventAndErrorTrackingLogger(
724
- createChildLogger({
725
- logger: getTestLogger?.(),
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
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
924
- url: await driver!.createContainerUrl(this.documentId),
925
- headers,
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(loader, requestHeader, driver);
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._logger);
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: EventAndErrorTrackingLogger | undefined,
1091
+ logger: IEventAndErrorTrackingLogger | undefined,
1040
1092
  prefix?: string,
1041
1093
  ) {
1042
1094
  if (logger === undefined) {