@fluidframework/container-runtime 2.0.0-dev-rc.2.0.0.245554 → 2.0.0-dev-rc.3.0.0.250606
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/container-runtime.api.md +81 -27
- package/dist/batchTracker.d.ts +1 -1
- package/dist/batchTracker.d.ts.map +1 -1
- package/dist/batchTracker.js +2 -2
- package/dist/batchTracker.js.map +1 -1
- package/dist/blobManager.d.ts +3 -3
- package/dist/blobManager.d.ts.map +1 -1
- package/dist/blobManager.js +3 -3
- package/dist/blobManager.js.map +1 -1
- package/dist/channelCollection.d.ts +6 -5
- package/dist/channelCollection.d.ts.map +1 -1
- package/dist/channelCollection.js +57 -19
- package/dist/channelCollection.js.map +1 -1
- package/dist/connectionTelemetry.d.ts +2 -2
- package/dist/connectionTelemetry.d.ts.map +1 -1
- package/dist/connectionTelemetry.js +3 -3
- package/dist/connectionTelemetry.js.map +1 -1
- package/dist/container-runtime-alpha.d.ts +205 -12
- package/dist/container-runtime-beta.d.ts +16 -3
- package/dist/container-runtime-public.d.ts +16 -3
- package/dist/container-runtime-untrimmed.d.ts +207 -26
- package/dist/containerHandleContext.d.ts.map +1 -1
- package/dist/containerHandleContext.js.map +1 -1
- package/dist/containerRuntime.d.ts +32 -26
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +235 -133
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStore.d.ts +1 -1
- package/dist/dataStore.d.ts.map +1 -1
- package/dist/dataStore.js +2 -2
- package/dist/dataStore.js.map +1 -1
- package/dist/dataStoreContext.d.ts +4 -4
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +18 -18
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStoreContexts.d.ts.map +1 -1
- package/dist/dataStoreContexts.js.map +1 -1
- package/dist/dataStoreRegistry.d.ts +4 -0
- package/dist/dataStoreRegistry.d.ts.map +1 -1
- package/dist/dataStoreRegistry.js +2 -2
- package/dist/dataStoreRegistry.js.map +1 -1
- package/dist/deltaScheduler.d.ts +1 -1
- package/dist/deltaScheduler.d.ts.map +1 -1
- package/dist/deltaScheduler.js +1 -1
- package/dist/deltaScheduler.js.map +1 -1
- package/dist/gc/garbageCollection.d.ts +1 -1
- package/dist/gc/garbageCollection.d.ts.map +1 -1
- package/dist/gc/garbageCollection.js +1 -1
- package/dist/gc/garbageCollection.js.map +1 -1
- package/dist/gc/gcConfigs.d.ts +1 -1
- package/dist/gc/gcConfigs.d.ts.map +1 -1
- package/dist/gc/gcConfigs.js.map +1 -1
- package/dist/gc/gcDefinitions.d.ts +1 -1
- package/dist/gc/gcDefinitions.d.ts.map +1 -1
- package/dist/gc/gcDefinitions.js.map +1 -1
- package/dist/gc/gcHelpers.d.ts.map +1 -1
- package/dist/gc/gcHelpers.js.map +1 -1
- package/dist/gc/gcSummaryStateTracker.d.ts +1 -1
- package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -1
- package/dist/gc/gcSummaryStateTracker.js.map +1 -1
- package/dist/gc/gcTelemetry.d.ts +1 -1
- package/dist/gc/gcTelemetry.d.ts.map +1 -1
- package/dist/gc/gcTelemetry.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/messageTypes.d.ts +11 -5
- package/dist/messageTypes.d.ts.map +1 -1
- package/dist/messageTypes.js +4 -0
- package/dist/messageTypes.js.map +1 -1
- package/dist/opLifecycle/definitions.d.ts +1 -19
- package/dist/opLifecycle/definitions.d.ts.map +1 -1
- package/dist/opLifecycle/definitions.js.map +1 -1
- package/dist/opLifecycle/index.d.ts +3 -3
- package/dist/opLifecycle/index.d.ts.map +1 -1
- package/dist/opLifecycle/index.js +3 -1
- package/dist/opLifecycle/index.js.map +1 -1
- package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opCompressor.js +2 -3
- package/dist/opLifecycle/opCompressor.js.map +1 -1
- package/dist/opLifecycle/opDecompressor.d.ts +15 -4
- package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opDecompressor.js +60 -61
- package/dist/opLifecycle/opDecompressor.js.map +1 -1
- package/dist/opLifecycle/opGroupingManager.d.ts +2 -1
- package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/dist/opLifecycle/opGroupingManager.js +9 -11
- package/dist/opLifecycle/opGroupingManager.js.map +1 -1
- package/dist/opLifecycle/opSplitter.d.ts +11 -3
- package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
- package/dist/opLifecycle/opSplitter.js +48 -38
- package/dist/opLifecycle/opSplitter.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.js +18 -17
- package/dist/opLifecycle/outbox.js.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.d.ts +8 -0
- package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.js +36 -32
- package/dist/opLifecycle/remoteMessageProcessor.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/pendingStateManager.d.ts +1 -1
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/scheduleManager.d.ts +1 -1
- package/dist/scheduleManager.d.ts.map +1 -1
- package/dist/scheduleManager.js +6 -2
- package/dist/scheduleManager.js.map +1 -1
- package/dist/summary/documentSchema.d.ts +178 -0
- package/dist/summary/documentSchema.d.ts.map +1 -0
- package/dist/summary/documentSchema.js +345 -0
- package/dist/summary/documentSchema.js.map +1 -0
- package/dist/summary/index.d.ts +2 -1
- package/dist/summary/index.d.ts.map +1 -1
- package/dist/summary/index.js +4 -1
- package/dist/summary/index.js.map +1 -1
- package/dist/summary/orderedClientElection.d.ts +2 -2
- package/dist/summary/orderedClientElection.d.ts.map +1 -1
- package/dist/summary/orderedClientElection.js +7 -2
- package/dist/summary/orderedClientElection.js.map +1 -1
- package/dist/summary/runWhileConnectedCoordinator.d.ts +1 -1
- package/dist/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
- package/dist/summary/runWhileConnectedCoordinator.js.map +1 -1
- package/dist/summary/runningSummarizer.d.ts +2 -2
- package/dist/summary/runningSummarizer.d.ts.map +1 -1
- package/dist/summary/runningSummarizer.js +2 -2
- package/dist/summary/runningSummarizer.js.map +1 -1
- package/dist/summary/summarizer.d.ts +2 -2
- package/dist/summary/summarizer.d.ts.map +1 -1
- package/dist/summary/summarizer.js +2 -2
- package/dist/summary/summarizer.js.map +1 -1
- package/dist/summary/summarizerClientElection.d.ts +2 -2
- package/dist/summary/summarizerClientElection.d.ts.map +1 -1
- package/dist/summary/summarizerClientElection.js.map +1 -1
- package/dist/summary/summarizerHeuristics.d.ts +1 -1
- package/dist/summary/summarizerHeuristics.d.ts.map +1 -1
- package/dist/summary/summarizerHeuristics.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNode.d.ts +2 -2
- package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNode.js +3 -3
- package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts +1 -1
- package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/dist/summary/summarizerTypes.d.ts +3 -3
- package/dist/summary/summarizerTypes.d.ts.map +1 -1
- package/dist/summary/summarizerTypes.js.map +1 -1
- package/dist/summary/summaryCollection.d.ts +2 -2
- package/dist/summary/summaryCollection.d.ts.map +1 -1
- package/dist/summary/summaryCollection.js +1 -1
- package/dist/summary/summaryCollection.js.map +1 -1
- package/dist/summary/summaryFormat.d.ts +5 -16
- package/dist/summary/summaryFormat.d.ts.map +1 -1
- package/dist/summary/summaryFormat.js.map +1 -1
- package/dist/summary/summaryGenerator.d.ts +2 -2
- package/dist/summary/summaryGenerator.d.ts.map +1 -1
- package/dist/summary/summaryGenerator.js +2 -2
- package/dist/summary/summaryGenerator.js.map +1 -1
- package/dist/summary/summaryManager.d.ts +1 -1
- package/dist/summary/summaryManager.d.ts.map +1 -1
- package/dist/summary/summaryManager.js +2 -2
- package/dist/summary/summaryManager.js.map +1 -1
- package/lib/batchTracker.d.ts +1 -1
- package/lib/batchTracker.d.ts.map +1 -1
- package/lib/batchTracker.js +2 -2
- package/lib/batchTracker.js.map +1 -1
- package/lib/blobManager.d.ts +3 -3
- package/lib/blobManager.d.ts.map +1 -1
- package/lib/blobManager.js +5 -5
- package/lib/blobManager.js.map +1 -1
- package/lib/channelCollection.d.ts +6 -5
- package/lib/channelCollection.d.ts.map +1 -1
- package/lib/channelCollection.js +59 -21
- package/lib/channelCollection.js.map +1 -1
- package/lib/connectionTelemetry.d.ts +2 -2
- package/lib/connectionTelemetry.d.ts.map +1 -1
- package/lib/connectionTelemetry.js +3 -3
- package/lib/connectionTelemetry.js.map +1 -1
- package/lib/container-runtime-alpha.d.ts +205 -12
- package/lib/container-runtime-beta.d.ts +16 -3
- package/lib/container-runtime-public.d.ts +16 -3
- package/lib/container-runtime-untrimmed.d.ts +207 -26
- package/lib/containerHandleContext.d.ts.map +1 -1
- package/lib/containerHandleContext.js.map +1 -1
- package/lib/containerRuntime.d.ts +32 -26
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +197 -95
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStore.d.ts +1 -1
- package/lib/dataStore.d.ts.map +1 -1
- package/lib/dataStore.js +2 -2
- package/lib/dataStore.js.map +1 -1
- package/lib/dataStoreContext.d.ts +4 -4
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +3 -3
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStoreContexts.d.ts.map +1 -1
- package/lib/dataStoreContexts.js.map +1 -1
- package/lib/dataStoreRegistry.d.ts +4 -0
- package/lib/dataStoreRegistry.d.ts.map +1 -1
- package/lib/dataStoreRegistry.js.map +1 -1
- package/lib/deltaScheduler.d.ts +1 -1
- package/lib/deltaScheduler.d.ts.map +1 -1
- package/lib/deltaScheduler.js +1 -1
- package/lib/deltaScheduler.js.map +1 -1
- package/lib/gc/garbageCollection.d.ts +1 -1
- package/lib/gc/garbageCollection.d.ts.map +1 -1
- package/lib/gc/garbageCollection.js +3 -3
- package/lib/gc/garbageCollection.js.map +1 -1
- package/lib/gc/gcConfigs.d.ts +1 -1
- package/lib/gc/gcConfigs.d.ts.map +1 -1
- package/lib/gc/gcConfigs.js +1 -1
- package/lib/gc/gcConfigs.js.map +1 -1
- package/lib/gc/gcDefinitions.d.ts +1 -1
- package/lib/gc/gcDefinitions.d.ts.map +1 -1
- package/lib/gc/gcDefinitions.js.map +1 -1
- package/lib/gc/gcHelpers.d.ts.map +1 -1
- package/lib/gc/gcHelpers.js.map +1 -1
- package/lib/gc/gcSummaryStateTracker.d.ts +1 -1
- package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -1
- package/lib/gc/gcSummaryStateTracker.js +1 -1
- package/lib/gc/gcSummaryStateTracker.js.map +1 -1
- package/lib/gc/gcTelemetry.d.ts +1 -1
- package/lib/gc/gcTelemetry.d.ts.map +1 -1
- package/lib/gc/gcTelemetry.js +1 -1
- package/lib/gc/gcTelemetry.js.map +1 -1
- package/lib/index.d.ts +2 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -2
- package/lib/index.js.map +1 -1
- package/lib/messageTypes.d.ts +11 -5
- package/lib/messageTypes.d.ts.map +1 -1
- package/lib/messageTypes.js +4 -0
- package/lib/messageTypes.js.map +1 -1
- package/lib/opLifecycle/definitions.d.ts +1 -19
- package/lib/opLifecycle/definitions.d.ts.map +1 -1
- package/lib/opLifecycle/definitions.js.map +1 -1
- package/lib/opLifecycle/index.d.ts +3 -3
- package/lib/opLifecycle/index.d.ts.map +1 -1
- package/lib/opLifecycle/index.js +2 -2
- package/lib/opLifecycle/index.js.map +1 -1
- package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opCompressor.js +2 -3
- package/lib/opLifecycle/opCompressor.js.map +1 -1
- package/lib/opLifecycle/opDecompressor.d.ts +15 -4
- package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opDecompressor.js +60 -61
- package/lib/opLifecycle/opDecompressor.js.map +1 -1
- package/lib/opLifecycle/opGroupingManager.d.ts +2 -1
- package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/lib/opLifecycle/opGroupingManager.js +7 -10
- package/lib/opLifecycle/opGroupingManager.js.map +1 -1
- package/lib/opLifecycle/opSplitter.d.ts +11 -3
- package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
- package/lib/opLifecycle/opSplitter.js +46 -37
- package/lib/opLifecycle/opSplitter.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js +18 -17
- package/lib/opLifecycle/outbox.js.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.d.ts +8 -0
- package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.js +36 -32
- package/lib/opLifecycle/remoteMessageProcessor.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/pendingStateManager.d.ts +1 -1
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/scheduleManager.d.ts +1 -1
- package/lib/scheduleManager.d.ts.map +1 -1
- package/lib/scheduleManager.js +6 -2
- package/lib/scheduleManager.js.map +1 -1
- package/lib/summary/documentSchema.d.ts +178 -0
- package/lib/summary/documentSchema.d.ts.map +1 -0
- package/lib/summary/documentSchema.js +341 -0
- package/lib/summary/documentSchema.js.map +1 -0
- package/lib/summary/index.d.ts +2 -1
- package/lib/summary/index.d.ts.map +1 -1
- package/lib/summary/index.js +1 -0
- package/lib/summary/index.js.map +1 -1
- package/lib/summary/orderedClientElection.d.ts +2 -2
- package/lib/summary/orderedClientElection.d.ts.map +1 -1
- package/lib/summary/orderedClientElection.js +7 -2
- package/lib/summary/orderedClientElection.js.map +1 -1
- package/lib/summary/runWhileConnectedCoordinator.d.ts +1 -1
- package/lib/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
- package/lib/summary/runWhileConnectedCoordinator.js.map +1 -1
- package/lib/summary/runningSummarizer.d.ts +2 -2
- package/lib/summary/runningSummarizer.d.ts.map +1 -1
- package/lib/summary/runningSummarizer.js +3 -3
- package/lib/summary/runningSummarizer.js.map +1 -1
- package/lib/summary/summarizer.d.ts +2 -2
- package/lib/summary/summarizer.d.ts.map +1 -1
- package/lib/summary/summarizer.js +3 -3
- package/lib/summary/summarizer.js.map +1 -1
- package/lib/summary/summarizerClientElection.d.ts +2 -2
- package/lib/summary/summarizerClientElection.d.ts.map +1 -1
- package/lib/summary/summarizerClientElection.js.map +1 -1
- package/lib/summary/summarizerHeuristics.d.ts +1 -1
- package/lib/summary/summarizerHeuristics.d.ts.map +1 -1
- package/lib/summary/summarizerHeuristics.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.d.ts +2 -2
- package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.js +4 -4
- package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts +1 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/lib/summary/summarizerTypes.d.ts +3 -3
- package/lib/summary/summarizerTypes.d.ts.map +1 -1
- package/lib/summary/summarizerTypes.js.map +1 -1
- package/lib/summary/summaryCollection.d.ts +2 -2
- package/lib/summary/summaryCollection.d.ts.map +1 -1
- package/lib/summary/summaryCollection.js +1 -1
- package/lib/summary/summaryCollection.js.map +1 -1
- package/lib/summary/summaryFormat.d.ts +5 -16
- package/lib/summary/summaryFormat.d.ts.map +1 -1
- package/lib/summary/summaryFormat.js +1 -1
- package/lib/summary/summaryFormat.js.map +1 -1
- package/lib/summary/summaryGenerator.d.ts +2 -2
- package/lib/summary/summaryGenerator.d.ts.map +1 -1
- package/lib/summary/summaryGenerator.js +3 -3
- package/lib/summary/summaryGenerator.js.map +1 -1
- package/lib/summary/summaryManager.d.ts +1 -1
- package/lib/summary/summaryManager.d.ts.map +1 -1
- package/lib/summary/summaryManager.js +2 -2
- package/lib/summary/summaryManager.js.map +1 -1
- package/lib/test/blobManager.spec.js +3 -3
- package/lib/test/blobManager.spec.js.map +1 -1
- package/lib/test/containerRuntime.spec.js +6 -4
- package/lib/test/containerRuntime.spec.js.map +1 -1
- package/lib/test/dataStoreContext.spec.js +4 -4
- package/lib/test/dataStoreContext.spec.js.map +1 -1
- package/lib/test/dataStoreCreation.spec.js +1 -1
- package/lib/test/dataStoreCreation.spec.js.map +1 -1
- package/lib/test/dataStoreRegistry.spec.js.map +1 -1
- package/lib/test/documentSchema.spec.js +282 -0
- package/lib/test/documentSchema.spec.js.map +1 -0
- package/lib/test/fuzz/fuzzUtils.js +11 -7
- package/lib/test/fuzz/fuzzUtils.js.map +1 -1
- package/lib/test/fuzz/summarizer.fuzz.spec.js +9 -7
- package/lib/test/fuzz/summarizer.fuzz.spec.js.map +1 -1
- package/lib/test/fuzz/summarizerFuzzMocks.js +43 -25
- package/lib/test/fuzz/summarizerFuzzMocks.js.map +1 -1
- package/lib/test/fuzz/summarizerFuzzSuite.js +7 -4
- package/lib/test/fuzz/summarizerFuzzSuite.js.map +1 -1
- package/lib/test/gc/garbageCollection.spec.js +5 -5
- package/lib/test/gc/garbageCollection.spec.js.map +1 -1
- package/lib/test/gc/gcConfigs.spec.js +2 -2
- package/lib/test/gc/gcConfigs.spec.js.map +1 -1
- package/lib/test/gc/gcHelpers.spec.js.map +1 -1
- package/lib/test/gc/gcStats.spec.js +2 -2
- package/lib/test/gc/gcStats.spec.js.map +1 -1
- package/lib/test/gc/gcSummaryStateTracker.spec.js +1 -1
- package/lib/test/gc/gcSummaryStateTracker.spec.js.map +1 -1
- package/lib/test/gc/gcTelemetry.spec.js +3 -3
- package/lib/test/gc/gcTelemetry.spec.js.map +1 -1
- package/lib/test/gc/gcUnreferencedStateTracker.spec.js +1 -1
- package/lib/test/gc/gcUnreferencedStateTracker.spec.js.map +1 -1
- package/lib/test/getPendingBlobs.spec.js +1 -1
- package/lib/test/getPendingBlobs.spec.js.map +1 -1
- package/lib/test/hardwareStats.spec.js +1 -1
- package/lib/test/hardwareStats.spec.js.map +1 -1
- package/lib/test/opLifecycle/OpGroupingManager.spec.js +95 -118
- package/lib/test/opLifecycle/OpGroupingManager.spec.js.map +1 -1
- package/lib/test/opLifecycle/batchManager.spec.js +1 -1
- package/lib/test/opLifecycle/batchManager.spec.js.map +1 -1
- package/lib/test/opLifecycle/opCompressor.spec.js +0 -1
- package/lib/test/opLifecycle/opCompressor.spec.js.map +1 -1
- package/lib/test/opLifecycle/opDecompressor.spec.js +60 -55
- package/lib/test/opLifecycle/opDecompressor.spec.js.map +1 -1
- package/lib/test/opLifecycle/opSplitter.spec.js +56 -41
- package/lib/test/opLifecycle/opSplitter.spec.js.map +1 -1
- package/lib/test/opLifecycle/outbox.spec.js +118 -10
- package/lib/test/opLifecycle/outbox.spec.js.map +1 -1
- package/lib/test/opLifecycle/remoteMessageProcessor.spec.js +115 -91
- package/lib/test/opLifecycle/remoteMessageProcessor.spec.js.map +1 -1
- package/lib/test/pendingStateManager.spec.js +1 -1
- package/lib/test/pendingStateManager.spec.js.map +1 -1
- package/lib/test/scheduleManager.spec.js +1 -1
- package/lib/test/scheduleManager.spec.js.map +1 -1
- package/lib/test/summarizerNode.spec.js +1 -1
- package/lib/test/summarizerNode.spec.js.map +1 -1
- package/lib/test/summarizerNodeWithGc.spec.js +1 -1
- package/lib/test/summarizerNodeWithGc.spec.js.map +1 -1
- package/lib/test/summary/runningSummarizer.spec.js +4 -4
- package/lib/test/summary/runningSummarizer.spec.js.map +1 -1
- package/lib/test/summary/summarizer.spec.js.map +1 -1
- package/lib/test/summary/summarizerClientElection.spec.js +2 -2
- package/lib/test/summary/summarizerClientElection.spec.js.map +1 -1
- package/lib/test/summary/summarizerHeuristics.spec.js +1 -1
- package/lib/test/summary/summarizerHeuristics.spec.js.map +1 -1
- package/lib/test/summary/summaryCollection.spec.js +1 -1
- package/lib/test/summary/summaryCollection.spec.js.map +1 -1
- package/lib/test/summary/summaryManager.spec.js +3 -3
- package/lib/test/summary/summaryManager.spec.js.map +1 -1
- package/lib/test/throttler.spec.js +1 -1
- package/lib/test/throttler.spec.js.map +1 -1
- package/lib/test/types/validateContainerRuntimePrevious.generated.js +6 -4
- package/lib/test/types/validateContainerRuntimePrevious.generated.js.map +1 -1
- package/package.json +35 -21
- package/src/batchTracker.ts +3 -3
- package/src/blobManager.ts +15 -15
- package/src/channelCollection.ts +90 -44
- package/src/connectionTelemetry.ts +10 -10
- package/src/containerHandleContext.ts +1 -1
- package/src/containerRuntime.ts +375 -213
- package/src/dataStore.ts +2 -2
- package/src/dataStoreContext.ts +19 -19
- package/src/dataStoreContexts.ts +2 -2
- package/src/dataStoreRegistry.ts +2 -1
- package/src/deltaScheduler.ts +1 -1
- package/src/gc/garbageCollection.ts +12 -12
- package/src/gc/gcConfigs.ts +11 -11
- package/src/gc/gcDefinitions.ts +2 -2
- package/src/gc/gcHelpers.ts +2 -2
- package/src/gc/gcSummaryStateTracker.ts +4 -4
- package/src/gc/gcTelemetry.ts +6 -6
- package/src/index.ts +8 -1
- package/src/messageTypes.ts +18 -5
- package/src/opLifecycle/README.md +89 -0
- package/src/opLifecycle/definitions.ts +1 -20
- package/src/opLifecycle/index.ts +3 -9
- package/src/opLifecycle/opCompressor.ts +4 -5
- package/src/opLifecycle/opDecompressor.ts +83 -100
- package/src/opLifecycle/opGroupingManager.ts +9 -12
- package/src/opLifecycle/opSplitter.ts +73 -47
- package/src/opLifecycle/outbox.ts +26 -37
- package/src/opLifecycle/remoteMessageProcessor.ts +41 -55
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +2 -2
- package/src/scheduleManager.ts +8 -7
- package/src/summary/documentSchema.ts +553 -0
- package/src/summary/index.ts +10 -1
- package/src/summary/orderedClientElection.ts +7 -5
- package/src/summary/runWhileConnectedCoordinator.ts +1 -1
- package/src/summary/runningSummarizer.ts +19 -19
- package/src/summary/summarizer.ts +14 -14
- package/src/summary/summarizerClientElection.ts +2 -2
- package/src/summary/summarizerHeuristics.ts +2 -2
- package/src/summary/summarizerNode/summarizerNode.ts +15 -15
- package/src/summary/summarizerNode/summarizerNodeUtils.ts +1 -1
- package/src/summary/summarizerNode/summarizerNodeWithGc.ts +4 -4
- package/src/summary/summarizerTypes.ts +3 -3
- package/src/summary/summaryCollection.ts +3 -3
- package/src/summary/summaryFormat.ts +8 -19
- package/src/summary/summaryGenerator.ts +10 -10
- package/src/summary/summaryManager.ts +4 -4
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
import { strict as assert } from "assert";
|
|
6
|
+
import { DocumentsSchemaController, } from "../summary/index.js";
|
|
7
|
+
function boolToProp(b) {
|
|
8
|
+
return b ? true : undefined;
|
|
9
|
+
}
|
|
10
|
+
describe("Runtime", () => {
|
|
11
|
+
const validConfig = {
|
|
12
|
+
version: 1,
|
|
13
|
+
refSeq: 0,
|
|
14
|
+
runtime: {
|
|
15
|
+
// explicitSchemaControl: undefined,
|
|
16
|
+
compressionLz4: true,
|
|
17
|
+
idCompressorMode: "delayed",
|
|
18
|
+
// opGroupingEnabled: undefined,
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
const features = {
|
|
22
|
+
explicitSchemaControl: true,
|
|
23
|
+
compressionLz4: true,
|
|
24
|
+
opGroupingEnabled: false,
|
|
25
|
+
idCompressorMode: "delayed",
|
|
26
|
+
};
|
|
27
|
+
function createController(config) {
|
|
28
|
+
return new DocumentsSchemaController(false, // existing,
|
|
29
|
+
config, // old schema,
|
|
30
|
+
features, () => { });
|
|
31
|
+
}
|
|
32
|
+
function testWrongConfig(config) {
|
|
33
|
+
assert.throws(() => {
|
|
34
|
+
createController(config);
|
|
35
|
+
}, "should throw on unknown property");
|
|
36
|
+
const controller = createController(validConfig);
|
|
37
|
+
assert.throws(() => controller.processDocumentSchemaOp(config, false, // local
|
|
38
|
+
100)); // sequenceNumber
|
|
39
|
+
}
|
|
40
|
+
// Validate first that config is indeed valid, such that all further tests are not tripping
|
|
41
|
+
// on something else that they are not modifying.
|
|
42
|
+
it("valid config", () => {
|
|
43
|
+
createController(validConfig);
|
|
44
|
+
});
|
|
45
|
+
// It's hard to say if we will allow additional propeorty trees here like this sample shows.
|
|
46
|
+
// More likely that will require version bump, to ensure that old code does not run with such structure.
|
|
47
|
+
// If if such configs will be backward compatible (similar to runtime options we are listing that were in use for very long time),
|
|
48
|
+
// then maybe ability to add them in such back-compat way is a plus
|
|
49
|
+
it("extra global property ois Ok", () => {
|
|
50
|
+
createController({ ...validConfig, appProperty: { foo: 5 } });
|
|
51
|
+
});
|
|
52
|
+
it("empty object", () => {
|
|
53
|
+
testWrongConfig({});
|
|
54
|
+
});
|
|
55
|
+
it("wrong version", () => {
|
|
56
|
+
testWrongConfig({ ...validConfig, version: 4 });
|
|
57
|
+
testWrongConfig({ ...validConfig, version: "1" });
|
|
58
|
+
testWrongConfig({ ...validConfig, version: "2.0" });
|
|
59
|
+
});
|
|
60
|
+
it("wrong refSeq", () => {
|
|
61
|
+
testWrongConfig({ ...validConfig, refSeq: "aaa" });
|
|
62
|
+
});
|
|
63
|
+
it("no refSeq", () => {
|
|
64
|
+
testWrongConfig({ ...validConfig, refSeq: undefined });
|
|
65
|
+
});
|
|
66
|
+
it("no runtime", () => {
|
|
67
|
+
testWrongConfig({ ...validConfig, runtime: undefined });
|
|
68
|
+
});
|
|
69
|
+
it("unknown runtime property", () => {
|
|
70
|
+
testWrongConfig({ ...validConfig, runtime: { ...validConfig.runtime, foo: 5 } });
|
|
71
|
+
});
|
|
72
|
+
it("wrong values for known properties", () => {
|
|
73
|
+
testWrongConfig({
|
|
74
|
+
...validConfig,
|
|
75
|
+
runtime: { ...validConfig.runtime, idCompressorMode: 5 },
|
|
76
|
+
});
|
|
77
|
+
testWrongConfig({
|
|
78
|
+
...validConfig,
|
|
79
|
+
runtime: { ...validConfig.runtime, idCompressorMode: "foo" },
|
|
80
|
+
});
|
|
81
|
+
testWrongConfig({
|
|
82
|
+
...validConfig,
|
|
83
|
+
runtime: { ...validConfig.runtime, opGroupingEnabled: false },
|
|
84
|
+
});
|
|
85
|
+
testWrongConfig({
|
|
86
|
+
...validConfig,
|
|
87
|
+
runtime: { ...validConfig.runtime, opGroupingEnabled: "aa" },
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
function testSimpleCases(explicitSchemaControl, existing) {
|
|
91
|
+
const controller = new DocumentsSchemaController(existing, // existing,
|
|
92
|
+
undefined, // old schema,
|
|
93
|
+
{ ...features, explicitSchemaControl }, () => assert(false, "no schema changes!"));
|
|
94
|
+
assert(controller.sessionSchema.refSeq === 0, "refSeq");
|
|
95
|
+
assert(controller.sessionSchema.version === 1, "version");
|
|
96
|
+
assert(controller.sessionSchema.runtime.explicitSchemaControl ===
|
|
97
|
+
boolToProp(explicitSchemaControl), "explicitSchemaControl");
|
|
98
|
+
if (existing && explicitSchemaControl) {
|
|
99
|
+
assert(controller.sessionSchema.runtime.compressionLz4 === undefined, "lz4");
|
|
100
|
+
assert(controller.sessionSchema.runtime.idCompressorMode === undefined, "idCompressorMode");
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
assert(controller.sessionSchema.runtime.compressionLz4 === true, "lz4");
|
|
104
|
+
assert(controller.sessionSchema.runtime.idCompressorMode === "delayed", "idCompressorMode");
|
|
105
|
+
}
|
|
106
|
+
assert(controller.sessionSchema.runtime.opGroupingEnabled === undefined, "opGroupingEnabled");
|
|
107
|
+
if (!existing || !explicitSchemaControl) {
|
|
108
|
+
controller.onDisconnect();
|
|
109
|
+
controller.onMessageSent(() => {
|
|
110
|
+
assert(false, "no messages should be sent!");
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
// get rid of all properties with undefined values.
|
|
114
|
+
const summarySchema = JSON.parse(JSON.stringify(controller.summarizeDocumentSchema(100 /* refSeq */)));
|
|
115
|
+
if (!explicitSchemaControl) {
|
|
116
|
+
assert.deepEqual(summarySchema, validConfig, "summarized schema as expected");
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
const expected = {
|
|
120
|
+
version: 1,
|
|
121
|
+
refSeq: 0,
|
|
122
|
+
runtime: {
|
|
123
|
+
// Existing files without any schema are considered to be in legacy mode.
|
|
124
|
+
explicitSchemaControl: boolToProp(!existing),
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
assert.deepEqual(summarySchema, JSON.parse(JSON.stringify(expected)), "summarized schema as expected");
|
|
128
|
+
}
|
|
129
|
+
// No local messages are expected
|
|
130
|
+
assert.throws(() => controller.processDocumentSchemaOp(validConfig, true, // local
|
|
131
|
+
100)); // sequenceNumber
|
|
132
|
+
}
|
|
133
|
+
it("Creation of new document", () => {
|
|
134
|
+
testSimpleCases(true, // explicitSchemaControl
|
|
135
|
+
false);
|
|
136
|
+
testSimpleCases(false, // explicitSchemaControl
|
|
137
|
+
false);
|
|
138
|
+
});
|
|
139
|
+
it("Existing document, no schema", () => {
|
|
140
|
+
testSimpleCases(true, // explicitSchemaControl
|
|
141
|
+
true);
|
|
142
|
+
testSimpleCases(false, // explicitSchemaControl
|
|
143
|
+
true);
|
|
144
|
+
});
|
|
145
|
+
function testExistingDocNoChangesInSchema(schema) {
|
|
146
|
+
const controller = new DocumentsSchemaController(true, // existing,
|
|
147
|
+
schema, // old schema,
|
|
148
|
+
features, () => { });
|
|
149
|
+
controller.onDisconnect();
|
|
150
|
+
controller.onMessageSent(() => {
|
|
151
|
+
assert(false, "no messages should be sent!");
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
it("Existing document with existing schema, no changes", () => {
|
|
155
|
+
testExistingDocNoChangesInSchema(validConfig);
|
|
156
|
+
testExistingDocNoChangesInSchema({
|
|
157
|
+
...validConfig,
|
|
158
|
+
runtime: { ...validConfig.runtime, explicitSchemaControl: true },
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
it("Existing document, changes required; race conditions", () => {
|
|
162
|
+
const controller = new DocumentsSchemaController(true, // existing,
|
|
163
|
+
validConfig, // old schema,
|
|
164
|
+
{ ...features, opGroupingEnabled: true }, () => { });
|
|
165
|
+
let message;
|
|
166
|
+
controller.onMessageSent((msg) => {
|
|
167
|
+
message = msg;
|
|
168
|
+
});
|
|
169
|
+
assert(message !== undefined);
|
|
170
|
+
assert(message.runtime.opGroupingEnabled === true);
|
|
171
|
+
assert(controller.processDocumentSchemaOp(message, true, // local
|
|
172
|
+
200) === true);
|
|
173
|
+
assert(controller.sessionSchema.runtime.opGroupingEnabled === true);
|
|
174
|
+
assert(controller.sessionSchema.refSeq === 200);
|
|
175
|
+
const schema = controller.summarizeDocumentSchema(300);
|
|
176
|
+
assert(schema !== undefined);
|
|
177
|
+
assert(schema.refSeq === 200);
|
|
178
|
+
const controller2 = new DocumentsSchemaController(true, // existing,
|
|
179
|
+
schema, // old schema,
|
|
180
|
+
{ ...features, idCompressorMode: undefined, compressionLz4: false }, () => { });
|
|
181
|
+
assert.deepEqual(controller2.documentSchema, schema);
|
|
182
|
+
// updates with old refSeq should fail silently.
|
|
183
|
+
assert(controller.processDocumentSchemaOp({ ...message, refSeq: 100 }, false, // local
|
|
184
|
+
201) === false);
|
|
185
|
+
// new change with some future sequence number should never happen, thus code should throw.
|
|
186
|
+
assert.throws(() => {
|
|
187
|
+
assert(message !== undefined);
|
|
188
|
+
controller.processDocumentSchemaOp({ ...message, refSeq: 300 }, false, // local
|
|
189
|
+
202);
|
|
190
|
+
});
|
|
191
|
+
// new change in schema with updated ref seq should be allowed
|
|
192
|
+
assert(controller.processDocumentSchemaOp({ ...message, refSeq: 200 }, false, // local
|
|
193
|
+
305) === true);
|
|
194
|
+
// Sequence numbers should move only forward.
|
|
195
|
+
assert.throws(() => {
|
|
196
|
+
assert(message !== undefined);
|
|
197
|
+
controller.processDocumentSchemaOp({ ...message, refSeq: 305 }, false, // local
|
|
198
|
+
300);
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
it("AzureClient modes", () => {
|
|
202
|
+
/**
|
|
203
|
+
* Start with no schema in a document.
|
|
204
|
+
* There should be no ops sent.
|
|
205
|
+
*/
|
|
206
|
+
const controller = new DocumentsSchemaController(true, // existing,
|
|
207
|
+
undefined, // old schema,
|
|
208
|
+
{ ...features, idCompressorMode: undefined, compressionLz4: false }, () => {
|
|
209
|
+
assert(false, "no changes!");
|
|
210
|
+
});
|
|
211
|
+
controller.onMessageSent(() => {
|
|
212
|
+
assert(false, "no messages should be sent!");
|
|
213
|
+
});
|
|
214
|
+
/**
|
|
215
|
+
* validate that we can summarize, load new client from that summary and it also will not send any ops
|
|
216
|
+
*/
|
|
217
|
+
const newSchema = controller.summarizeDocumentSchema(100);
|
|
218
|
+
const controller2 = new DocumentsSchemaController(true, // existing,
|
|
219
|
+
newSchema, // old schema,
|
|
220
|
+
{ ...features, idCompressorMode: undefined, compressionLz4: false }, () => {
|
|
221
|
+
assert(false, "no changes!");
|
|
222
|
+
});
|
|
223
|
+
controller2.onMessageSent(() => {
|
|
224
|
+
assert(false, "no messages should be sent!");
|
|
225
|
+
});
|
|
226
|
+
/**
|
|
227
|
+
* Summarize from that new client and ensure we are getting exactly same summary, thus getting to same state.
|
|
228
|
+
*/
|
|
229
|
+
const newSchema2 = controller.summarizeDocumentSchema(100);
|
|
230
|
+
assert.deepEqual(newSchema, newSchema2, "got into stable state");
|
|
231
|
+
/**
|
|
232
|
+
* Now let's see if we can change schema.
|
|
233
|
+
*/
|
|
234
|
+
let schemaChanged = false;
|
|
235
|
+
const controller3 = new DocumentsSchemaController(true, // existing,
|
|
236
|
+
newSchema, // old schema,
|
|
237
|
+
{ ...features, idCompressorMode: "on", compressionLz4: false }, () => {
|
|
238
|
+
schemaChanged = true;
|
|
239
|
+
});
|
|
240
|
+
// setting is not on yet
|
|
241
|
+
assert(controller3.sessionSchema.runtime.idCompressorMode === undefined);
|
|
242
|
+
let message;
|
|
243
|
+
controller3.onMessageSent((msg) => {
|
|
244
|
+
message = msg;
|
|
245
|
+
assert(message.runtime.idCompressorMode === "on");
|
|
246
|
+
});
|
|
247
|
+
assert(message !== undefined, "message sent");
|
|
248
|
+
controller3.processDocumentSchemaOp(message, true, // local
|
|
249
|
+
100); // sequenceNumber
|
|
250
|
+
assert(schemaChanged, "schema changed");
|
|
251
|
+
assert(controller3.sessionSchema.runtime.idCompressorMode === "on");
|
|
252
|
+
const schema = controller3.summarizeDocumentSchema(200);
|
|
253
|
+
assert(schema.runtime.idCompressorMode === "on", "now on");
|
|
254
|
+
controller3.onMessageSent(() => {
|
|
255
|
+
assert(false, "no more messages to send");
|
|
256
|
+
});
|
|
257
|
+
/**
|
|
258
|
+
* Validate now that another client that was observing schema changes (not initiating them) will arrive to same state
|
|
259
|
+
* This client will want to flip groupedBatching, but it will process someone else op first...
|
|
260
|
+
*/
|
|
261
|
+
schemaChanged = false;
|
|
262
|
+
const controller4 = new DocumentsSchemaController(true, // existing,
|
|
263
|
+
newSchema, // old schema,
|
|
264
|
+
{
|
|
265
|
+
...features,
|
|
266
|
+
idCompressorMode: undefined,
|
|
267
|
+
compressionLz4: false,
|
|
268
|
+
opGroupingEnabled: true,
|
|
269
|
+
}, () => (schemaChanged = true));
|
|
270
|
+
controller4.processDocumentSchemaOp(message, false, // local
|
|
271
|
+
200); // sequenceNumber
|
|
272
|
+
assert(schemaChanged, "schema changed");
|
|
273
|
+
assert(controller4.sessionSchema.runtime.idCompressorMode === "on");
|
|
274
|
+
controller4.onMessageSent(() => {
|
|
275
|
+
assert(false, "no messages should be sent - it lost a race and will not attempt to change file format.");
|
|
276
|
+
});
|
|
277
|
+
// Validate same summaries by two clients.
|
|
278
|
+
const schema2 = controller3.summarizeDocumentSchema(200);
|
|
279
|
+
assert.deepEqual(schema, schema2, "same summaries");
|
|
280
|
+
});
|
|
281
|
+
});
|
|
282
|
+
//# sourceMappingURL=documentSchema.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"documentSchema.spec.js","sourceRoot":"","sources":["../../src/test/documentSchema.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\nimport { strict as assert } from \"assert\";\nimport {\n\tDocumentsSchemaController,\n\ttype IDocumentSchemaCurrent,\n\ttype IDocumentSchemaFeatures,\n} from \"../summary/index.js\";\n\nfunction boolToProp(b: boolean) {\n\treturn b ? true : undefined;\n}\n\ndescribe(\"Runtime\", () => {\n\tconst validConfig: IDocumentSchemaCurrent = {\n\t\tversion: 1,\n\t\trefSeq: 0,\n\t\truntime: {\n\t\t\t// explicitSchemaControl: undefined,\n\t\t\tcompressionLz4: true,\n\t\t\tidCompressorMode: \"delayed\",\n\t\t\t// opGroupingEnabled: undefined,\n\t\t},\n\t};\n\n\tconst features: IDocumentSchemaFeatures = {\n\t\texplicitSchemaControl: true,\n\t\tcompressionLz4: true,\n\t\topGroupingEnabled: false,\n\t\tidCompressorMode: \"delayed\",\n\t};\n\n\tfunction createController(config: unknown) {\n\t\treturn new DocumentsSchemaController(\n\t\t\tfalse, // existing,\n\t\t\tconfig as IDocumentSchemaCurrent, // old schema,\n\t\t\tfeatures,\n\t\t\t() => {}, // onSchemaChange\n\t\t);\n\t}\n\n\tfunction testWrongConfig(config: unknown) {\n\t\tassert.throws(() => {\n\t\t\tcreateController(config);\n\t\t}, \"should throw on unknown property\");\n\n\t\tconst controller = createController(validConfig);\n\t\tassert.throws(() =>\n\t\t\tcontroller.processDocumentSchemaOp(\n\t\t\t\tconfig as IDocumentSchemaCurrent,\n\t\t\t\tfalse, // local\n\t\t\t\t100,\n\t\t\t),\n\t\t); // sequenceNumber\n\t}\n\n\t// Validate first that config is indeed valid, such that all further tests are not tripping\n\t// on something else that they are not modifying.\n\tit(\"valid config\", () => {\n\t\tcreateController(validConfig);\n\t});\n\n\t// It's hard to say if we will allow additional propeorty trees here like this sample shows.\n\t// More likely that will require version bump, to ensure that old code does not run with such structure.\n\t// If if such configs will be backward compatible (similar to runtime options we are listing that were in use for very long time),\n\t// then maybe ability to add them in such back-compat way is a plus\n\tit(\"extra global property ois Ok\", () => {\n\t\tcreateController({ ...validConfig, appProperty: { foo: 5 } });\n\t});\n\n\tit(\"empty object\", () => {\n\t\ttestWrongConfig({});\n\t});\n\n\tit(\"wrong version\", () => {\n\t\ttestWrongConfig({ ...validConfig, version: 4 });\n\t\ttestWrongConfig({ ...validConfig, version: \"1\" });\n\t\ttestWrongConfig({ ...validConfig, version: \"2.0\" });\n\t});\n\n\tit(\"wrong refSeq\", () => {\n\t\ttestWrongConfig({ ...validConfig, refSeq: \"aaa\" });\n\t});\n\n\tit(\"no refSeq\", () => {\n\t\ttestWrongConfig({ ...validConfig, refSeq: undefined });\n\t});\n\n\tit(\"no runtime\", () => {\n\t\ttestWrongConfig({ ...validConfig, runtime: undefined });\n\t});\n\n\tit(\"unknown runtime property\", () => {\n\t\ttestWrongConfig({ ...validConfig, runtime: { ...validConfig.runtime, foo: 5 } });\n\t});\n\n\tit(\"wrong values for known properties\", () => {\n\t\ttestWrongConfig({\n\t\t\t...validConfig,\n\t\t\truntime: { ...validConfig.runtime, idCompressorMode: 5 },\n\t\t});\n\t\ttestWrongConfig({\n\t\t\t...validConfig,\n\t\t\truntime: { ...validConfig.runtime, idCompressorMode: \"foo\" },\n\t\t});\n\t\ttestWrongConfig({\n\t\t\t...validConfig,\n\t\t\truntime: { ...validConfig.runtime, opGroupingEnabled: false },\n\t\t});\n\t\ttestWrongConfig({\n\t\t\t...validConfig,\n\t\t\truntime: { ...validConfig.runtime, opGroupingEnabled: \"aa\" },\n\t\t});\n\t});\n\n\tfunction testSimpleCases(explicitSchemaControl: boolean, existing: boolean) {\n\t\tconst controller = new DocumentsSchemaController(\n\t\t\texisting, // existing,\n\t\t\tundefined, // old schema,\n\t\t\t{ ...features, explicitSchemaControl },\n\t\t\t() => assert(false, \"no schema changes!\"), // onSchemaChange\n\t\t);\n\n\t\tassert(controller.sessionSchema.refSeq === 0, \"refSeq\");\n\t\tassert(controller.sessionSchema.version === 1, \"version\");\n\t\tassert(\n\t\t\tcontroller.sessionSchema.runtime.explicitSchemaControl ===\n\t\t\t\tboolToProp(explicitSchemaControl),\n\t\t\t\"explicitSchemaControl\",\n\t\t);\n\n\t\tif (existing && explicitSchemaControl) {\n\t\t\tassert(controller.sessionSchema.runtime.compressionLz4 === undefined, \"lz4\");\n\t\t\tassert(\n\t\t\t\tcontroller.sessionSchema.runtime.idCompressorMode === undefined,\n\t\t\t\t\"idCompressorMode\",\n\t\t\t);\n\t\t} else {\n\t\t\tassert(controller.sessionSchema.runtime.compressionLz4 === true, \"lz4\");\n\t\t\tassert(\n\t\t\t\tcontroller.sessionSchema.runtime.idCompressorMode === \"delayed\",\n\t\t\t\t\"idCompressorMode\",\n\t\t\t);\n\t\t}\n\t\tassert(\n\t\t\tcontroller.sessionSchema.runtime.opGroupingEnabled === undefined,\n\t\t\t\"opGroupingEnabled\",\n\t\t);\n\n\t\tif (!existing || !explicitSchemaControl) {\n\t\t\tcontroller.onDisconnect();\n\t\t\tcontroller.onMessageSent(() => {\n\t\t\t\tassert(false, \"no messages should be sent!\");\n\t\t\t});\n\t\t}\n\n\t\t// get rid of all properties with undefined values.\n\t\tconst summarySchema = JSON.parse(\n\t\t\tJSON.stringify(controller.summarizeDocumentSchema(100 /* refSeq */)),\n\t\t);\n\t\tif (!explicitSchemaControl) {\n\t\t\tassert.deepEqual(summarySchema, validConfig, \"summarized schema as expected\");\n\t\t} else {\n\t\t\tconst expected = {\n\t\t\t\tversion: 1,\n\t\t\t\trefSeq: 0,\n\t\t\t\truntime: {\n\t\t\t\t\t// Existing files without any schema are considered to be in legacy mode.\n\t\t\t\t\texplicitSchemaControl: boolToProp(!existing),\n\t\t\t\t},\n\t\t\t};\n\t\t\tassert.deepEqual(\n\t\t\t\tsummarySchema,\n\t\t\t\tJSON.parse(JSON.stringify(expected)),\n\t\t\t\t\"summarized schema as expected\",\n\t\t\t);\n\t\t}\n\n\t\t// No local messages are expected\n\t\tassert.throws(() =>\n\t\t\tcontroller.processDocumentSchemaOp(\n\t\t\t\tvalidConfig,\n\t\t\t\ttrue, // local\n\t\t\t\t100,\n\t\t\t),\n\t\t); // sequenceNumber\n\t}\n\n\tit(\"Creation of new document\", () => {\n\t\ttestSimpleCases(\n\t\t\ttrue, // explicitSchemaControl\n\t\t\tfalse, // existing\n\t\t);\n\t\ttestSimpleCases(\n\t\t\tfalse, // explicitSchemaControl\n\t\t\tfalse, // existing\n\t\t);\n\t});\n\n\tit(\"Existing document, no schema\", () => {\n\t\ttestSimpleCases(\n\t\t\ttrue, // explicitSchemaControl\n\t\t\ttrue, // existing\n\t\t);\n\t\ttestSimpleCases(\n\t\t\tfalse, // explicitSchemaControl\n\t\t\ttrue, // existing\n\t\t);\n\t});\n\n\tfunction testExistingDocNoChangesInSchema(schema: IDocumentSchemaCurrent) {\n\t\tconst controller = new DocumentsSchemaController(\n\t\t\ttrue, // existing,\n\t\t\tschema, // old schema,\n\t\t\tfeatures,\n\t\t\t() => {}, // onSchemaChange\n\t\t);\n\n\t\tcontroller.onDisconnect();\n\t\tcontroller.onMessageSent(() => {\n\t\t\tassert(false, \"no messages should be sent!\");\n\t\t});\n\t}\n\n\tit(\"Existing document with existing schema, no changes\", () => {\n\t\ttestExistingDocNoChangesInSchema(validConfig);\n\t\ttestExistingDocNoChangesInSchema({\n\t\t\t...validConfig,\n\t\t\truntime: { ...validConfig.runtime, explicitSchemaControl: true },\n\t\t});\n\t});\n\n\tit(\"Existing document, changes required; race conditions\", () => {\n\t\tconst controller = new DocumentsSchemaController(\n\t\t\ttrue, // existing,\n\t\t\tvalidConfig, // old schema,\n\t\t\t{ ...features, opGroupingEnabled: true },\n\t\t\t() => {}, // onSchemaChange\n\t\t);\n\n\t\tlet message: IDocumentSchemaCurrent | undefined;\n\t\tcontroller.onMessageSent((msg) => {\n\t\t\tmessage = msg as IDocumentSchemaCurrent;\n\t\t});\n\n\t\tassert(message !== undefined);\n\t\tassert(message.runtime.opGroupingEnabled === true);\n\n\t\tassert(\n\t\t\tcontroller.processDocumentSchemaOp(\n\t\t\t\tmessage,\n\t\t\t\ttrue, // local\n\t\t\t\t200,\n\t\t\t) === true,\n\t\t);\n\n\t\tassert(controller.sessionSchema.runtime.opGroupingEnabled === true);\n\t\tassert(controller.sessionSchema.refSeq === 200);\n\n\t\tconst schema = controller.summarizeDocumentSchema(300);\n\t\tassert(schema !== undefined);\n\t\tassert(schema.refSeq === 200);\n\n\t\tconst controller2 = new DocumentsSchemaController(\n\t\t\ttrue, // existing,\n\t\t\tschema, // old schema,\n\t\t\t{ ...features, idCompressorMode: undefined, compressionLz4: false },\n\t\t\t() => {}, // onSchemaChange\n\t\t);\n\n\t\tassert.deepEqual((controller2 as any).documentSchema, schema);\n\n\t\t// updates with old refSeq should fail silently.\n\t\tassert(\n\t\t\tcontroller.processDocumentSchemaOp(\n\t\t\t\t{ ...message, refSeq: 100 },\n\t\t\t\tfalse, // local\n\t\t\t\t201,\n\t\t\t) === false,\n\t\t);\n\n\t\t// new change with some future sequence number should never happen, thus code should throw.\n\t\tassert.throws(() => {\n\t\t\tassert(message !== undefined);\n\t\t\tcontroller.processDocumentSchemaOp(\n\t\t\t\t{ ...message, refSeq: 300 },\n\t\t\t\tfalse, // local\n\t\t\t\t202,\n\t\t\t);\n\t\t});\n\n\t\t// new change in schema with updated ref seq should be allowed\n\t\tassert(\n\t\t\tcontroller.processDocumentSchemaOp(\n\t\t\t\t{ ...message, refSeq: 200 },\n\t\t\t\tfalse, // local\n\t\t\t\t305,\n\t\t\t) === true,\n\t\t);\n\n\t\t// Sequence numbers should move only forward.\n\t\tassert.throws(() => {\n\t\t\tassert(message !== undefined);\n\t\t\tcontroller.processDocumentSchemaOp(\n\t\t\t\t{ ...message, refSeq: 305 },\n\t\t\t\tfalse, // local\n\t\t\t\t300,\n\t\t\t);\n\t\t});\n\t});\n\n\tit(\"AzureClient modes\", () => {\n\t\t/**\n\t\t * Start with no schema in a document.\n\t\t * There should be no ops sent.\n\t\t */\n\t\tconst controller = new DocumentsSchemaController(\n\t\t\ttrue, // existing,\n\t\t\tundefined, // old schema,\n\t\t\t{ ...features, idCompressorMode: undefined, compressionLz4: false },\n\t\t\t() => {\n\t\t\t\tassert(false, \"no changes!\");\n\t\t\t}, // onSchemaChange\n\t\t);\n\n\t\tcontroller.onMessageSent(() => {\n\t\t\tassert(false, \"no messages should be sent!\");\n\t\t});\n\n\t\t/**\n\t\t * validate that we can summarize, load new client from that summary and it also will not send any ops\n\t\t */\n\t\tconst newSchema = controller.summarizeDocumentSchema(100);\n\t\tconst controller2 = new DocumentsSchemaController(\n\t\t\ttrue, // existing,\n\t\t\tnewSchema, // old schema,\n\t\t\t{ ...features, idCompressorMode: undefined, compressionLz4: false },\n\t\t\t() => {\n\t\t\t\tassert(false, \"no changes!\");\n\t\t\t}, // onSchemaChange\n\t\t);\n\n\t\tcontroller2.onMessageSent(() => {\n\t\t\tassert(false, \"no messages should be sent!\");\n\t\t});\n\n\t\t/**\n\t\t * Summarize from that new client and ensure we are getting exactly same summary, thus getting to same state.\n\t\t */\n\t\tconst newSchema2 = controller.summarizeDocumentSchema(100);\n\t\tassert.deepEqual(newSchema, newSchema2, \"got into stable state\");\n\n\t\t/**\n\t\t * Now let's see if we can change schema.\n\t\t */\n\t\tlet schemaChanged = false;\n\t\tconst controller3 = new DocumentsSchemaController(\n\t\t\ttrue, // existing,\n\t\t\tnewSchema, // old schema,\n\t\t\t{ ...features, idCompressorMode: \"on\", compressionLz4: false },\n\t\t\t() => {\n\t\t\t\tschemaChanged = true;\n\t\t\t}, // onSchemaChange\n\t\t);\n\n\t\t// setting is not on yet\n\t\tassert(controller3.sessionSchema.runtime.idCompressorMode === undefined);\n\n\t\tlet message: IDocumentSchemaCurrent | undefined;\n\t\tcontroller3.onMessageSent((msg) => {\n\t\t\tmessage = msg as IDocumentSchemaCurrent;\n\t\t\tassert(message.runtime.idCompressorMode === \"on\");\n\t\t});\n\t\tassert(message !== undefined, \"message sent\");\n\n\t\tcontroller3.processDocumentSchemaOp(\n\t\t\tmessage,\n\t\t\ttrue, // local\n\t\t\t100,\n\t\t); // sequenceNumber\n\t\tassert(schemaChanged, \"schema changed\");\n\t\tassert(controller3.sessionSchema.runtime.idCompressorMode === \"on\");\n\t\tconst schema = controller3.summarizeDocumentSchema(200) as IDocumentSchemaCurrent;\n\t\tassert(schema.runtime.idCompressorMode === \"on\", \"now on\");\n\n\t\tcontroller3.onMessageSent(() => {\n\t\t\tassert(false, \"no more messages to send\");\n\t\t});\n\n\t\t/**\n\t\t * Validate now that another client that was observing schema changes (not initiating them) will arrive to same state\n\t\t * This client will want to flip groupedBatching, but it will process someone else op first...\n\t\t */\n\t\tschemaChanged = false;\n\t\tconst controller4 = new DocumentsSchemaController(\n\t\t\ttrue, // existing,\n\t\t\tnewSchema, // old schema,\n\t\t\t{\n\t\t\t\t...features,\n\t\t\t\tidCompressorMode: undefined,\n\t\t\t\tcompressionLz4: false,\n\t\t\t\topGroupingEnabled: true,\n\t\t\t},\n\t\t\t() => (schemaChanged = true), // onSchemaChange\n\t\t);\n\t\tcontroller4.processDocumentSchemaOp(\n\t\t\tmessage,\n\t\t\tfalse, // local\n\t\t\t200,\n\t\t); // sequenceNumber\n\t\tassert(schemaChanged, \"schema changed\");\n\t\tassert(controller4.sessionSchema.runtime.idCompressorMode === \"on\");\n\t\tcontroller4.onMessageSent(() => {\n\t\t\tassert(\n\t\t\t\tfalse,\n\t\t\t\t\"no messages should be sent - it lost a race and will not attempt to change file format.\",\n\t\t\t);\n\t\t});\n\n\t\t// Validate same summaries by two clients.\n\t\tconst schema2 = controller3.summarizeDocumentSchema(200) as IDocumentSchemaCurrent;\n\t\tassert.deepEqual(schema, schema2, \"same summaries\");\n\t});\n});\n"]}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
-
import {
|
|
5
|
+
import { combineReducersAsync, createWeightedAsyncGenerator, } from "@fluid-private/stochastic-test-utils";
|
|
6
6
|
import { MockFluidDataStoreRuntime } from "@fluidframework/test-runtime-utils";
|
|
7
7
|
const defaultConfig = {
|
|
8
8
|
weights: {
|
|
@@ -41,24 +41,28 @@ function makeReducer() {
|
|
|
41
41
|
await baseReducer(state, operation);
|
|
42
42
|
state.containerRuntimeFactory.processAllMessages();
|
|
43
43
|
};
|
|
44
|
+
const createNewSummarizer = async (state) => {
|
|
45
|
+
const oldRuntime = state.containerRuntime;
|
|
46
|
+
oldRuntime.disposeFn();
|
|
47
|
+
state.containerRuntime = state.containerRuntimeFactory.createContainerRuntime(new MockFluidDataStoreRuntime());
|
|
48
|
+
await state.containerRuntime.initializeWithStashedOps(oldRuntime);
|
|
49
|
+
};
|
|
44
50
|
const reducer = combineReducersAsync({
|
|
45
51
|
reconnect: async (state, _op) => {
|
|
46
|
-
// TODO AB#6954
|
|
47
52
|
state.containerRuntime.connected = false;
|
|
48
53
|
state.containerRuntime.connected = true;
|
|
54
|
+
await createNewSummarizer(state);
|
|
49
55
|
},
|
|
50
56
|
newSummarizer: async (state, _op) => {
|
|
51
|
-
|
|
52
|
-
state.containerRuntime.disposeFn();
|
|
53
|
-
state.containerRuntime = state.containerRuntimeFactory.createContainerRuntime(new MockFluidDataStoreRuntime());
|
|
57
|
+
await createNewSummarizer(state);
|
|
54
58
|
},
|
|
55
59
|
summaryNack: async (state, _op) => {
|
|
56
|
-
// TODO AB#6954: not sure if it deadlocks between needing to process the SummaryNack and waiting for it
|
|
57
60
|
state.containerRuntime.prepareSummaryNack();
|
|
58
61
|
await state.containerRuntime.summarize();
|
|
59
62
|
},
|
|
60
63
|
submitOp: async (state, _op) => {
|
|
61
|
-
//
|
|
64
|
+
// Send arbitrary runtime op
|
|
65
|
+
state.containerRuntime.submit({}, {});
|
|
62
66
|
},
|
|
63
67
|
});
|
|
64
68
|
return wrapper(reducer);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fuzzUtils.js","sourceRoot":"","sources":["../../../src/test/fuzz/fuzzUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"fuzzUtils.js","sourceRoot":"","sources":["../../../src/test/fuzz/fuzzUtils.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n\tAsyncGenerator,\n\tAsyncReducer,\n\tcombineReducersAsync,\n\tcreateWeightedAsyncGenerator,\n} from \"@fluid-private/stochastic-test-utils\";\nimport { MockFluidDataStoreRuntime } from \"@fluidframework/test-runtime-utils\";\nimport type { SummarizerFuzzModel, SummarizerFuzzTestState } from \"./summarizerFuzzSuite.js\";\n\ninterface Reconnect {\n\ttype: \"reconnect\";\n}\n\ninterface NewSummarizer {\n\ttype: \"newSummarizer\";\n}\n\ninterface SummaryNack {\n\ttype: \"summaryNack\";\n}\n\ninterface SubmitOp {\n\ttype: \"submitOp\";\n}\n\nexport type SummarizerOperation = Reconnect | NewSummarizer | SummaryNack | SubmitOp;\n\nexport interface ISummarizerOperationGenerationConfig {\n\tweights?: {\n\t\treconnect: number;\n\t\tnewSummarizer: number;\n\t\tsummaryNack: number;\n\t\tsubmitOp: number;\n\t};\n}\n\nconst defaultConfig: Required<ISummarizerOperationGenerationConfig> = {\n\tweights: {\n\t\treconnect: 1,\n\t\tnewSummarizer: 1,\n\t\tsummaryNack: 1,\n\t\tsubmitOp: 1,\n\t},\n};\n\nexport function summarizerOperationGenerator(\n\toptions: ISummarizerOperationGenerationConfig,\n): AsyncGenerator<SummarizerOperation, SummarizerFuzzTestState> {\n\tconst reconnect = async (_state: SummarizerFuzzTestState): Promise<Reconnect> => ({\n\t\ttype: \"reconnect\",\n\t});\n\n\tconst newSummarizer = async (_state: SummarizerFuzzTestState): Promise<NewSummarizer> => ({\n\t\ttype: \"newSummarizer\",\n\t});\n\n\tconst summaryNack = async (_state: SummarizerFuzzTestState): Promise<SummaryNack> => ({\n\t\ttype: \"summaryNack\",\n\t});\n\n\tconst submitOp = async (_state: SummarizerFuzzTestState): Promise<SubmitOp> => ({\n\t\ttype: \"submitOp\",\n\t});\n\n\tconst usableWeights = options.weights ?? defaultConfig.weights;\n\n\treturn createWeightedAsyncGenerator<SummarizerOperation, SummarizerFuzzTestState>([\n\t\t[reconnect, usableWeights.reconnect],\n\t\t[newSummarizer, usableWeights.newSummarizer],\n\t\t[summaryNack, usableWeights.summaryNack],\n\t\t[submitOp, usableWeights.submitOp],\n\t]);\n}\n\nexport const baseModel: Omit<SummarizerFuzzModel, \"workloadName\" | \"generatorFactory\"> = {\n\treducer: makeReducer(),\n};\n\nfunction makeReducer(): AsyncReducer<SummarizerOperation, SummarizerFuzzTestState> {\n\tconst wrapper =\n\t\t<T>(\n\t\t\tbaseReducer: AsyncReducer<T, SummarizerFuzzTestState>,\n\t\t): AsyncReducer<T, SummarizerFuzzTestState> =>\n\t\tasync (state, operation) => {\n\t\t\tawait baseReducer(state, operation);\n\t\t\tstate.containerRuntimeFactory.processAllMessages();\n\t\t};\n\n\tconst createNewSummarizer = async (state: SummarizerFuzzTestState) => {\n\t\tconst oldRuntime = state.containerRuntime;\n\t\toldRuntime.disposeFn();\n\t\tstate.containerRuntime = state.containerRuntimeFactory.createContainerRuntime(\n\t\t\tnew MockFluidDataStoreRuntime(),\n\t\t);\n\t\tawait state.containerRuntime.initializeWithStashedOps(oldRuntime);\n\t};\n\n\tconst reducer = combineReducersAsync<SummarizerOperation, SummarizerFuzzTestState>({\n\t\treconnect: async (state: SummarizerFuzzTestState, _op: Reconnect) => {\n\t\t\tstate.containerRuntime.connected = false;\n\t\t\tstate.containerRuntime.connected = true;\n\t\t\tawait createNewSummarizer(state);\n\t\t},\n\t\tnewSummarizer: async (state: SummarizerFuzzTestState, _op: NewSummarizer) => {\n\t\t\tawait createNewSummarizer(state);\n\t\t},\n\t\tsummaryNack: async (state: SummarizerFuzzTestState, _op: SummaryNack) => {\n\t\t\tstate.containerRuntime.prepareSummaryNack();\n\t\t\tawait state.containerRuntime.summarize();\n\t\t},\n\t\tsubmitOp: async (state: SummarizerFuzzTestState, _op: SubmitOp) => {\n\t\t\t// Send arbitrary runtime op\n\t\t\tstate.containerRuntime.submit({}, {});\n\t\t},\n\t});\n\n\treturn wrapper(reducer);\n}\n"]}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
import { takeAsync } from "@fluid-private/stochastic-test-utils";
|
|
6
|
-
import {
|
|
6
|
+
import { baseModel, summarizerOperationGenerator } from "./fuzzUtils.js";
|
|
7
7
|
import { createSummarizerFuzzSuite } from "./summarizerFuzzSuite.js";
|
|
8
8
|
/**
|
|
9
9
|
* Summarizer fuzz test should test that we eventually recover and send a summary successfully.
|
|
@@ -17,15 +17,17 @@ describe("Summarizer fuzz testing", () => {
|
|
|
17
17
|
const model = {
|
|
18
18
|
...baseModel,
|
|
19
19
|
workloadName: "summarizer",
|
|
20
|
-
generatorFactory: () => takeAsync(
|
|
20
|
+
generatorFactory: () => takeAsync(1000, summarizerOperationGenerator({
|
|
21
21
|
weights: {
|
|
22
|
-
reconnect:
|
|
23
|
-
newSummarizer:
|
|
24
|
-
summaryNack:
|
|
25
|
-
submitOp:
|
|
22
|
+
reconnect: 1,
|
|
23
|
+
newSummarizer: 1,
|
|
24
|
+
summaryNack: 1,
|
|
25
|
+
submitOp: 1,
|
|
26
26
|
},
|
|
27
27
|
})),
|
|
28
28
|
};
|
|
29
|
-
createSummarizerFuzzSuite(model
|
|
29
|
+
createSummarizerFuzzSuite(model, {
|
|
30
|
+
defaultTestCount: 25,
|
|
31
|
+
});
|
|
30
32
|
});
|
|
31
33
|
//# sourceMappingURL=summarizer.fuzz.spec.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"summarizer.fuzz.spec.js","sourceRoot":"","sources":["../../../src/test/fuzz/summarizer.fuzz.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,sCAAsC,CAAC;AACjE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"summarizer.fuzz.spec.js","sourceRoot":"","sources":["../../../src/test/fuzz/summarizer.fuzz.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,sCAAsC,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,4BAA4B,EAAE,MAAM,gBAAgB,CAAC;AACzE,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AAErE;;;;;;;GAOG;AAEH,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;IACxC,MAAM,KAAK,GAAG;QACb,GAAG,SAAS;QACZ,YAAY,EAAE,YAAY;QAC1B,gBAAgB,EAAE,GAAG,EAAE,CACtB,SAAS,CACR,IAAI,EACJ,4BAA4B,CAAC;YAC5B,OAAO,EAAE;gBACR,SAAS,EAAE,CAAC;gBACZ,aAAa,EAAE,CAAC;gBAChB,WAAW,EAAE,CAAC;gBACd,QAAQ,EAAE,CAAC;aACX;SACD,CAAC,CACF;KACF,CAAC;IAEF,yBAAyB,CAAC,KAAK,EAAE;QAChC,gBAAgB,EAAE,EAAE;KACpB,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { takeAsync } from \"@fluid-private/stochastic-test-utils\";\nimport { baseModel, summarizerOperationGenerator } from \"./fuzzUtils.js\";\nimport { createSummarizerFuzzSuite } from \"./summarizerFuzzSuite.js\";\n\n/**\n * Summarizer fuzz test should test that we eventually recover and send a summary successfully.\n * For DDS, we test for eventual consistency. For summarizer, we could test for eventual recovery.\n * After performing operations (i.e. disconnects, summaryNacks, ops from other clients, etc.) we should:\n * - start a fresh summarizer\n * - attempt a summary\n * If the system doesn't recover properly, then we have a bug to fix.\n */\n\ndescribe(\"Summarizer fuzz testing\", () => {\n\tconst model = {\n\t\t...baseModel,\n\t\tworkloadName: \"summarizer\",\n\t\tgeneratorFactory: () =>\n\t\t\ttakeAsync(\n\t\t\t\t1000,\n\t\t\t\tsummarizerOperationGenerator({\n\t\t\t\t\tweights: {\n\t\t\t\t\t\treconnect: 1,\n\t\t\t\t\t\tnewSummarizer: 1,\n\t\t\t\t\t\tsummaryNack: 1,\n\t\t\t\t\t\tsubmitOp: 1,\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t),\n\t};\n\n\tcreateSummarizerFuzzSuite(model, {\n\t\tdefaultTestCount: 25,\n\t});\n});\n"]}
|
|
@@ -2,15 +2,16 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
-
import { MockContainerRuntimeFactoryForReconnection, MockContainerRuntimeForReconnection, } from "@fluidframework/test-runtime-utils";
|
|
6
5
|
import { TypedEventEmitter } from "@fluid-internal/client-utils";
|
|
7
|
-
import { createChildLogger, raiseConnectedEvent, } from "@fluidframework/telemetry-utils";
|
|
8
6
|
import { MessageType, SummaryType, } from "@fluidframework/protocol-definitions";
|
|
9
7
|
import { mergeStats } from "@fluidframework/runtime-utils";
|
|
10
|
-
import {
|
|
8
|
+
import { createChildLogger, raiseConnectedEvent, } from "@fluidframework/telemetry-utils";
|
|
9
|
+
import { MockContainerRuntimeFactoryForReconnection, MockContainerRuntimeForReconnection, } from "@fluidframework/test-runtime-utils";
|
|
10
|
+
import { v4 as uuid } from "uuid";
|
|
11
|
+
import { RunWhileConnectedCoordinator, Summarizer, SummaryCollection, SummaryManager, } from "../../summary/index.js";
|
|
11
12
|
export class MockContainerRuntimeFactoryForSummarizer extends MockContainerRuntimeFactoryForReconnection {
|
|
12
|
-
createContainerRuntime(dataStoreRuntime,
|
|
13
|
-
const containerRuntime = new MockContainerRuntimeForSummarizer(dataStoreRuntime, this, this.runtimeOptions
|
|
13
|
+
createContainerRuntime(dataStoreRuntime, _) {
|
|
14
|
+
const containerRuntime = new MockContainerRuntimeForSummarizer(dataStoreRuntime, this, this.runtimeOptions);
|
|
14
15
|
this.runtimes.add(containerRuntime);
|
|
15
16
|
return containerRuntime;
|
|
16
17
|
}
|
|
@@ -22,9 +23,11 @@ const DefaultSummaryConfiguration = {
|
|
|
22
23
|
initialSummarizerDelayMs: 5 * 1000, // 5 secs.
|
|
23
24
|
};
|
|
24
25
|
export class MockContainerRuntimeForSummarizer extends MockContainerRuntimeForReconnection {
|
|
25
|
-
constructor(dataStoreRuntime, factory, runtimeOptions = {}
|
|
26
|
-
|
|
26
|
+
constructor(dataStoreRuntime, factory, runtimeOptions = {}) {
|
|
27
|
+
// trackRemoteOps is needed for replaying all ops on creating new ContainerRuntime
|
|
28
|
+
super(dataStoreRuntime, factory, runtimeOptions, { trackRemoteOps: true });
|
|
27
29
|
this.logger = createChildLogger();
|
|
30
|
+
this.nackScheduled = false;
|
|
28
31
|
this.disposed = false;
|
|
29
32
|
this.deltaManager.on("op", (message) => {
|
|
30
33
|
this.emit("op", message);
|
|
@@ -42,12 +45,7 @@ export class MockContainerRuntimeForSummarizer extends MockContainerRuntimeForRe
|
|
|
42
45
|
}
|
|
43
46
|
/** Prepare a SummaryNack to be sent by the server */
|
|
44
47
|
prepareSummaryNack() {
|
|
45
|
-
|
|
46
|
-
summaryProposal: {
|
|
47
|
-
summarySequenceNumber: this.deltaManager.lastSequenceNumber,
|
|
48
|
-
},
|
|
49
|
-
};
|
|
50
|
-
this.deltaManager.prepareInboundResponse(MessageType.SummaryNack, contents);
|
|
48
|
+
this.nackScheduled = true;
|
|
51
49
|
}
|
|
52
50
|
/** Call on the Summarizer object to summarize */
|
|
53
51
|
async summarize() {
|
|
@@ -62,27 +60,27 @@ export class MockContainerRuntimeForSummarizer extends MockContainerRuntimeForRe
|
|
|
62
60
|
]);
|
|
63
61
|
}
|
|
64
62
|
async submitSummary(options) {
|
|
63
|
+
const handle = uuid();
|
|
65
64
|
const summaryMessage = {
|
|
66
|
-
handle
|
|
65
|
+
handle,
|
|
67
66
|
head: "",
|
|
68
67
|
message: "",
|
|
69
68
|
parents: [],
|
|
70
69
|
};
|
|
70
|
+
const clientSequenceNumber = ++this.deltaManager.clientSequenceNumber;
|
|
71
71
|
const referenceSequenceNumber = this.deltaManager.lastSequenceNumber;
|
|
72
|
+
const minimumSequenceNumber = this.factory.getMinSeq();
|
|
72
73
|
const summarizeMessage = {
|
|
73
74
|
type: MessageType.Summarize,
|
|
74
|
-
clientSequenceNumber
|
|
75
|
+
clientSequenceNumber,
|
|
75
76
|
referenceSequenceNumber,
|
|
76
77
|
contents: summaryMessage,
|
|
77
78
|
};
|
|
78
|
-
this.deltaManager.inbound.push({
|
|
79
|
-
...summarizeMessage,
|
|
80
|
-
clientId: this.clientId,
|
|
81
|
-
sequenceNumber: 0,
|
|
82
|
-
minimumSequenceNumber: 0,
|
|
83
|
-
timestamp: 0,
|
|
84
|
-
});
|
|
85
79
|
this.deltaManager.outbound.push([summarizeMessage]);
|
|
80
|
+
this.addPendingMessage(summarizeMessage.contents, summarizeMessage.metadata, summarizeMessage.clientSequenceNumber);
|
|
81
|
+
this.factory.processAllMessages();
|
|
82
|
+
this.scheduleAckNack(this.nackScheduled /* isNack */, handle, this.deltaManager.lastSequenceNumber);
|
|
83
|
+
this.nackScheduled = false;
|
|
86
84
|
const summaryStats = {
|
|
87
85
|
...mergeStats(),
|
|
88
86
|
dataStoreCount: 1,
|
|
@@ -91,10 +89,10 @@ export class MockContainerRuntimeForSummarizer extends MockContainerRuntimeForRe
|
|
|
91
89
|
};
|
|
92
90
|
return {
|
|
93
91
|
stage: "submit",
|
|
94
|
-
handle
|
|
95
|
-
clientSequenceNumber
|
|
92
|
+
handle,
|
|
93
|
+
clientSequenceNumber,
|
|
96
94
|
referenceSequenceNumber,
|
|
97
|
-
minimumSequenceNumber
|
|
95
|
+
minimumSequenceNumber,
|
|
98
96
|
submitOpDuration: 0,
|
|
99
97
|
uploadDuration: 0,
|
|
100
98
|
generateDuration: 0,
|
|
@@ -106,6 +104,26 @@ export class MockContainerRuntimeForSummarizer extends MockContainerRuntimeForRe
|
|
|
106
104
|
summaryStats,
|
|
107
105
|
};
|
|
108
106
|
}
|
|
107
|
+
scheduleAckNack(isNack, handle, summarySequenceNumber) {
|
|
108
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
109
|
+
Promise.resolve().then(() => {
|
|
110
|
+
const contents = {
|
|
111
|
+
handle,
|
|
112
|
+
summaryProposal: {
|
|
113
|
+
summarySequenceNumber,
|
|
114
|
+
},
|
|
115
|
+
};
|
|
116
|
+
const summaryAckMessage = {
|
|
117
|
+
type: isNack ? MessageType.SummaryNack : MessageType.SummaryAck,
|
|
118
|
+
clientSequenceNumber: ++this.deltaManager.clientSequenceNumber,
|
|
119
|
+
referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
|
|
120
|
+
contents,
|
|
121
|
+
};
|
|
122
|
+
this.deltaManager.outbound.push([summaryAckMessage]);
|
|
123
|
+
this.addPendingMessage(summaryAckMessage.contents, undefined, summaryAckMessage.clientSequenceNumber);
|
|
124
|
+
this.factory.processAllMessages();
|
|
125
|
+
});
|
|
126
|
+
}
|
|
109
127
|
async refreshLatestSummaryAck(options) {
|
|
110
128
|
// Do nothing
|
|
111
129
|
}
|