@fluidframework/container-runtime 2.0.0-rc.2.0.1 → 2.0.0-rc.3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -0
- package/api-report/container-runtime.api.md +471 -52
- package/dist/batchTracker.d.ts +1 -1
- package/dist/batchTracker.d.ts.map +1 -1
- package/dist/batchTracker.js +4 -4
- package/dist/batchTracker.js.map +1 -1
- package/dist/blobManager.d.ts +33 -30
- package/dist/blobManager.d.ts.map +1 -1
- package/dist/blobManager.js +82 -107
- package/dist/blobManager.js.map +1 -1
- package/dist/channelCollection.d.ts +27 -22
- package/dist/channelCollection.d.ts.map +1 -1
- package/dist/channelCollection.js +189 -165
- package/dist/channelCollection.js.map +1 -1
- package/dist/connectionTelemetry.d.ts +3 -3
- package/dist/connectionTelemetry.d.ts.map +1 -1
- package/dist/connectionTelemetry.js +17 -17
- package/dist/connectionTelemetry.js.map +1 -1
- package/dist/containerHandleContext.d.ts.map +1 -1
- package/dist/containerHandleContext.js +2 -2
- package/dist/containerHandleContext.js.map +1 -1
- package/dist/containerRuntime.d.ts +42 -39
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +425 -292
- 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 +8 -8
- package/dist/dataStore.js.map +1 -1
- package/dist/dataStoreContext.d.ts +58 -19
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +171 -114
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStoreContexts.d.ts +1 -0
- package/dist/dataStoreContexts.d.ts.map +1 -1
- package/dist/dataStoreContexts.js +12 -11
- package/dist/dataStoreContexts.js.map +1 -1
- package/dist/dataStoreRegistry.d.ts +5 -1
- package/dist/dataStoreRegistry.d.ts.map +1 -1
- package/dist/dataStoreRegistry.js +4 -4
- package/dist/dataStoreRegistry.js.map +1 -1
- package/dist/deltaManagerSummarizerProxy.d.ts +1 -1
- package/dist/deltaManagerSummarizerProxy.d.ts.map +1 -1
- package/dist/deltaManagerSummarizerProxy.js.map +1 -1
- package/dist/deltaScheduler.d.ts +1 -1
- package/dist/deltaScheduler.d.ts.map +1 -1
- package/dist/deltaScheduler.js +6 -6
- package/dist/deltaScheduler.js.map +1 -1
- package/dist/error.d.ts +1 -1
- package/dist/error.d.ts.map +1 -1
- package/dist/error.js +4 -4
- package/dist/error.js.map +1 -1
- package/dist/gc/garbageCollection.d.ts +3 -2
- package/dist/gc/garbageCollection.d.ts.map +1 -1
- package/dist/gc/garbageCollection.js +23 -23
- package/dist/gc/garbageCollection.js.map +1 -1
- package/dist/gc/gcConfigs.d.ts +2 -2
- package/dist/gc/gcConfigs.d.ts.map +1 -1
- package/dist/gc/gcConfigs.js +4 -5
- package/dist/gc/gcConfigs.js.map +1 -1
- package/dist/gc/gcDefinitions.d.ts +4 -5
- package/dist/gc/gcDefinitions.d.ts.map +1 -1
- package/dist/gc/gcDefinitions.js.map +1 -1
- package/dist/gc/gcHelpers.d.ts +5 -1
- package/dist/gc/gcHelpers.d.ts.map +1 -1
- package/dist/gc/gcHelpers.js +21 -12
- package/dist/gc/gcHelpers.js.map +1 -1
- package/dist/gc/gcSummaryStateTracker.d.ts +2 -2
- package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -1
- package/dist/gc/gcSummaryStateTracker.js +11 -11
- package/dist/gc/gcSummaryStateTracker.js.map +1 -1
- package/dist/gc/gcTelemetry.d.ts +2 -1
- package/dist/gc/gcTelemetry.d.ts.map +1 -1
- package/dist/gc/gcTelemetry.js +11 -9
- package/dist/gc/gcTelemetry.js.map +1 -1
- package/dist/gc/gcUnreferencedStateTracker.d.ts.map +1 -1
- package/dist/gc/gcUnreferencedStateTracker.js +6 -6
- package/dist/gc/gcUnreferencedStateTracker.js.map +1 -1
- package/dist/gc/index.d.ts +1 -1
- package/dist/gc/index.d.ts.map +1 -1
- package/dist/gc/index.js +2 -1
- package/dist/gc/index.js.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -2
- package/dist/index.js.map +1 -1
- package/dist/legacy.d.ts +91 -0
- 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/batchManager.d.ts.map +1 -1
- package/dist/opLifecycle/batchManager.js.map +1 -1
- package/dist/opLifecycle/definitions.d.ts +2 -20
- 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 +5 -6
- 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 +62 -63
- 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 +14 -16
- package/dist/opLifecycle/opGroupingManager.js.map +1 -1
- package/dist/opLifecycle/opSplitter.d.ts +12 -4
- package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
- package/dist/opLifecycle/opSplitter.js +63 -53
- package/dist/opLifecycle/opSplitter.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts +2 -1
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.js +30 -29
- 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 +18 -18
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/public.d.ts +12 -0
- package/dist/scheduleManager.d.ts +1 -1
- package/dist/scheduleManager.d.ts.map +1 -1
- package/dist/scheduleManager.js +28 -24
- package/dist/scheduleManager.js.map +1 -1
- package/dist/storageServiceWithAttachBlobs.d.ts +2 -2
- package/dist/storageServiceWithAttachBlobs.d.ts.map +1 -1
- package/dist/storageServiceWithAttachBlobs.js +2 -2
- package/dist/storageServiceWithAttachBlobs.js.map +1 -1
- package/dist/summary/documentSchema.d.ts +209 -0
- package/dist/summary/documentSchema.d.ts.map +1 -0
- package/dist/summary/documentSchema.js +390 -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 +12 -7
- 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 +3 -3
- package/dist/summary/runWhileConnectedCoordinator.js.map +1 -1
- package/dist/summary/runningSummarizer.d.ts +3 -3
- package/dist/summary/runningSummarizer.d.ts.map +1 -1
- package/dist/summary/runningSummarizer.js +16 -16
- package/dist/summary/runningSummarizer.js.map +1 -1
- package/dist/summary/summarizer.d.ts +3 -2
- package/dist/summary/summarizer.d.ts.map +1 -1
- package/dist/summary/summarizer.js +13 -13
- 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 +2 -2
- package/dist/summary/summarizerHeuristics.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNode.d.ts +3 -2
- package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNode.js +28 -28
- package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts +2 -1
- package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeUtils.js +3 -3
- package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +2 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js +14 -14
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/dist/summary/summarizerTypes.d.ts +5 -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 +7 -7
- package/dist/summary/summaryCollection.js.map +1 -1
- package/dist/summary/summaryFormat.d.ts +6 -17
- package/dist/summary/summaryFormat.d.ts.map +1 -1
- package/dist/summary/summaryFormat.js +8 -8
- package/dist/summary/summaryFormat.js.map +1 -1
- package/dist/summary/summaryGenerator.d.ts +4 -3
- package/dist/summary/summaryGenerator.d.ts.map +1 -1
- package/dist/summary/summaryGenerator.js +17 -17
- 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 +15 -14
- package/dist/summary/summaryManager.js.map +1 -1
- package/internal.d.ts +11 -0
- package/legacy.d.ts +11 -0
- 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 +33 -30
- package/lib/blobManager.d.ts.map +1 -1
- package/lib/blobManager.js +48 -73
- package/lib/blobManager.js.map +1 -1
- package/lib/channelCollection.d.ts +27 -22
- package/lib/channelCollection.d.ts.map +1 -1
- package/lib/channelCollection.js +132 -108
- package/lib/channelCollection.js.map +1 -1
- package/lib/connectionTelemetry.d.ts +3 -3
- package/lib/connectionTelemetry.d.ts.map +1 -1
- package/lib/connectionTelemetry.js +3 -3
- package/lib/connectionTelemetry.js.map +1 -1
- package/lib/containerHandleContext.d.ts.map +1 -1
- package/lib/containerHandleContext.js +1 -1
- package/lib/containerHandleContext.js.map +1 -1
- package/lib/containerRuntime.d.ts +42 -39
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +276 -141
- 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 +3 -3
- package/lib/dataStore.js.map +1 -1
- package/lib/dataStoreContext.d.ts +58 -19
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +110 -53
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStoreContexts.d.ts +1 -0
- package/lib/dataStoreContexts.d.ts.map +1 -1
- package/lib/dataStoreContexts.js +3 -2
- package/lib/dataStoreContexts.js.map +1 -1
- package/lib/dataStoreRegistry.d.ts +5 -1
- package/lib/dataStoreRegistry.d.ts.map +1 -1
- package/lib/dataStoreRegistry.js +1 -1
- package/lib/dataStoreRegistry.js.map +1 -1
- package/lib/deltaManagerSummarizerProxy.d.ts +1 -1
- package/lib/deltaManagerSummarizerProxy.d.ts.map +1 -1
- package/lib/deltaManagerSummarizerProxy.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/error.d.ts +1 -1
- package/lib/error.d.ts.map +1 -1
- package/lib/error.js +2 -2
- package/lib/error.js.map +1 -1
- package/lib/gc/garbageCollection.d.ts +3 -2
- package/lib/gc/garbageCollection.d.ts.map +1 -1
- package/lib/gc/garbageCollection.js +8 -8
- package/lib/gc/garbageCollection.js.map +1 -1
- package/lib/gc/gcConfigs.d.ts +2 -2
- package/lib/gc/gcConfigs.d.ts.map +1 -1
- package/lib/gc/gcConfigs.js +4 -5
- package/lib/gc/gcConfigs.js.map +1 -1
- package/lib/gc/gcDefinitions.d.ts +4 -5
- package/lib/gc/gcDefinitions.d.ts.map +1 -1
- package/lib/gc/gcDefinitions.js.map +1 -1
- package/lib/gc/gcHelpers.d.ts +5 -1
- package/lib/gc/gcHelpers.d.ts.map +1 -1
- package/lib/gc/gcHelpers.js +10 -2
- package/lib/gc/gcHelpers.js.map +1 -1
- package/lib/gc/gcSummaryStateTracker.d.ts +2 -2
- package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -1
- package/lib/gc/gcSummaryStateTracker.js +2 -2
- package/lib/gc/gcSummaryStateTracker.js.map +1 -1
- package/lib/gc/gcTelemetry.d.ts +2 -1
- package/lib/gc/gcTelemetry.d.ts.map +1 -1
- package/lib/gc/gcTelemetry.js +4 -2
- package/lib/gc/gcTelemetry.js.map +1 -1
- package/lib/gc/gcUnreferencedStateTracker.d.ts.map +1 -1
- package/lib/gc/gcUnreferencedStateTracker.js +2 -2
- package/lib/gc/gcUnreferencedStateTracker.js.map +1 -1
- package/lib/gc/index.d.ts +1 -1
- package/lib/gc/index.d.ts.map +1 -1
- package/lib/gc/index.js +1 -1
- package/lib/gc/index.js.map +1 -1
- package/lib/index.d.ts +5 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +5 -2
- package/lib/index.js.map +1 -1
- package/lib/legacy.d.ts +91 -0
- 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/batchManager.d.ts.map +1 -1
- package/lib/opLifecycle/batchManager.js.map +1 -1
- package/lib/opLifecycle/definitions.d.ts +2 -20
- 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 +61 -62
- 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 +9 -12
- package/lib/opLifecycle/opGroupingManager.js.map +1 -1
- package/lib/opLifecycle/opSplitter.d.ts +12 -4
- package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
- package/lib/opLifecycle/opSplitter.js +47 -38
- package/lib/opLifecycle/opSplitter.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts +2 -1
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js +19 -18
- 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 +2 -2
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/public.d.ts +12 -0
- package/lib/scheduleManager.d.ts +1 -1
- package/lib/scheduleManager.d.ts.map +1 -1
- package/lib/scheduleManager.js +7 -3
- package/lib/scheduleManager.js.map +1 -1
- package/lib/storageServiceWithAttachBlobs.d.ts +2 -2
- package/lib/storageServiceWithAttachBlobs.d.ts.map +1 -1
- package/lib/storageServiceWithAttachBlobs.js +1 -1
- package/lib/storageServiceWithAttachBlobs.js.map +1 -1
- package/lib/summary/documentSchema.d.ts +209 -0
- package/lib/summary/documentSchema.d.ts.map +1 -0
- package/lib/summary/documentSchema.js +386 -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 +1 -1
- package/lib/summary/runWhileConnectedCoordinator.js.map +1 -1
- package/lib/summary/runningSummarizer.d.ts +3 -3
- 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 +3 -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 +1 -1
- package/lib/summary/summarizerHeuristics.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.d.ts +3 -2
- package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.js +5 -5
- package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts +2 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.js +1 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts +2 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js +3 -3
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/lib/summary/summarizerTypes.d.ts +5 -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 +6 -17
- package/lib/summary/summaryFormat.d.ts.map +1 -1
- package/lib/summary/summaryFormat.js +3 -3
- package/lib/summary/summaryFormat.js.map +1 -1
- package/lib/summary/summaryGenerator.d.ts +4 -3
- package/lib/summary/summaryGenerator.d.ts.map +1 -1
- package/lib/summary/summaryGenerator.js +4 -4
- 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 +9 -8
- package/lib/summary/summaryManager.js.map +1 -1
- package/package.json +57 -65
- package/src/batchTracker.ts +4 -3
- package/src/blobManager.ts +100 -77
- package/src/channelCollection.ts +223 -167
- package/src/connectionTelemetry.ts +12 -12
- package/src/containerHandleContext.ts +3 -2
- package/src/containerRuntime.ts +481 -277
- package/src/dataStore.ts +9 -4
- package/src/dataStoreContext.ts +201 -97
- package/src/dataStoreContexts.ts +5 -2
- package/src/dataStoreRegistry.ts +3 -2
- package/src/deltaManagerSummarizerProxy.ts +1 -1
- package/src/deltaScheduler.ts +2 -1
- package/src/error.ts +2 -2
- package/src/gc/garbageCollection.ts +21 -20
- package/src/gc/gcConfigs.ts +15 -18
- package/src/gc/gcDefinitions.ts +6 -8
- package/src/gc/gcHelpers.ts +22 -5
- package/src/gc/gcSummaryStateTracker.ts +7 -5
- package/src/gc/gcTelemetry.ts +13 -7
- package/src/gc/gcUnreferencedStateTracker.ts +3 -2
- package/src/gc/index.ts +1 -0
- package/src/index.ts +22 -1
- package/src/messageTypes.ts +20 -6
- package/src/opLifecycle/README.md +89 -0
- package/src/opLifecycle/batchManager.ts +1 -0
- package/src/opLifecycle/definitions.ts +3 -21
- package/src/opLifecycle/index.ts +3 -9
- package/src/opLifecycle/opCompressor.ts +6 -5
- package/src/opLifecycle/opDecompressor.ts +90 -100
- package/src/opLifecycle/opGroupingManager.ts +12 -14
- package/src/opLifecycle/opSplitter.ts +76 -48
- package/src/opLifecycle/outbox.ts +30 -38
- package/src/opLifecycle/remoteMessageProcessor.ts +43 -55
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +6 -6
- package/src/scheduleManager.ts +10 -8
- package/src/storageServiceWithAttachBlobs.ts +2 -2
- package/src/summary/documentSchema.ts +631 -0
- package/src/summary/index.ts +10 -1
- package/src/summary/orderedClientElection.ts +7 -7
- package/src/summary/runWhileConnectedCoordinator.ts +3 -2
- package/src/summary/runningSummarizer.ts +22 -20
- package/src/summary/summarizer.ts +17 -15
- package/src/summary/summarizerClientElection.ts +3 -2
- package/src/summary/summarizerHeuristics.ts +4 -2
- package/src/summary/summarizerNode/summarizerNode.ts +20 -18
- package/src/summary/summarizerNode/summarizerNodeUtils.ts +3 -2
- package/src/summary/summarizerNode/summarizerNodeWithGc.ts +16 -8
- package/src/summary/summarizerTypes.ts +7 -3
- package/src/summary/summaryCollection.ts +3 -3
- package/src/summary/summaryFormat.ts +14 -26
- package/src/summary/summaryGenerator.ts +12 -15
- package/src/summary/summaryManager.ts +16 -13
- package/api-extractor-cjs.json +0 -8
- package/dist/container-runtime-alpha.d.ts +0 -1753
- package/dist/container-runtime-beta.d.ts +0 -268
- package/dist/container-runtime-public.d.ts +0 -268
- package/dist/container-runtime-untrimmed.d.ts +0 -1893
- package/lib/container-runtime-alpha.d.ts +0 -1753
- package/lib/container-runtime-beta.d.ts +0 -268
- package/lib/container-runtime-public.d.ts +0 -268
- package/lib/container-runtime-untrimmed.d.ts +0 -1893
- package/lib/test/batchTracker.spec.js +0 -88
- package/lib/test/batchTracker.spec.js.map +0 -1
- package/lib/test/blobManager.spec.js +0 -835
- package/lib/test/blobManager.spec.js.map +0 -1
- package/lib/test/channelCollection.spec.js +0 -141
- package/lib/test/channelCollection.spec.js.map +0 -1
- package/lib/test/containerRuntime.spec.js +0 -1748
- package/lib/test/containerRuntime.spec.js.map +0 -1
- package/lib/test/dataStoreContext.spec.js +0 -801
- package/lib/test/dataStoreContext.spec.js.map +0 -1
- package/lib/test/dataStoreCreation.spec.js +0 -312
- package/lib/test/dataStoreCreation.spec.js.map +0 -1
- package/lib/test/dataStoreRegistry.spec.js +0 -26
- package/lib/test/dataStoreRegistry.spec.js.map +0 -1
- package/lib/test/fuzz/fuzzUtils.js +0 -66
- package/lib/test/fuzz/fuzzUtils.js.map +0 -1
- package/lib/test/fuzz/summarizer.fuzz.spec.js +0 -31
- package/lib/test/fuzz/summarizer.fuzz.spec.js.map +0 -1
- package/lib/test/fuzz/summarizerFuzzMocks.js +0 -162
- package/lib/test/fuzz/summarizerFuzzMocks.js.map +0 -1
- package/lib/test/fuzz/summarizerFuzzSuite.js +0 -106
- package/lib/test/fuzz/summarizerFuzzSuite.js.map +0 -1
- package/lib/test/gc/garbageCollection.spec.js +0 -1465
- package/lib/test/gc/garbageCollection.spec.js.map +0 -1
- package/lib/test/gc/gcConfigs.spec.js +0 -690
- package/lib/test/gc/gcConfigs.spec.js.map +0 -1
- package/lib/test/gc/gcHelpers.spec.js +0 -110
- package/lib/test/gc/gcHelpers.spec.js.map +0 -1
- package/lib/test/gc/gcReferenceGraphAlgorithm.spec.js +0 -68
- package/lib/test/gc/gcReferenceGraphAlgorithm.spec.js.map +0 -1
- package/lib/test/gc/gcStats.spec.js +0 -391
- package/lib/test/gc/gcStats.spec.js.map +0 -1
- package/lib/test/gc/gcSummaryStateTracker.spec.js +0 -228
- package/lib/test/gc/gcSummaryStateTracker.spec.js.map +0 -1
- package/lib/test/gc/gcTelemetry.spec.js +0 -530
- package/lib/test/gc/gcTelemetry.spec.js.map +0 -1
- package/lib/test/gc/gcUnitTestHelpers.js +0 -29
- package/lib/test/gc/gcUnitTestHelpers.js.map +0 -1
- package/lib/test/gc/gcUnreferencedStateTracker.spec.js +0 -192
- package/lib/test/gc/gcUnreferencedStateTracker.spec.js.map +0 -1
- package/lib/test/getPendingBlobs.spec.js +0 -193
- package/lib/test/getPendingBlobs.spec.js.map +0 -1
- package/lib/test/hardwareStats.spec.js +0 -93
- package/lib/test/hardwareStats.spec.js.map +0 -1
- package/lib/test/index.js +0 -6
- package/lib/test/index.js.map +0 -1
- package/lib/test/opLifecycle/OpGroupingManager.spec.js +0 -225
- package/lib/test/opLifecycle/OpGroupingManager.spec.js.map +0 -1
- package/lib/test/opLifecycle/batchManager.spec.js +0 -189
- package/lib/test/opLifecycle/batchManager.spec.js.map +0 -1
- package/lib/test/opLifecycle/opCompressor.spec.js +0 -74
- package/lib/test/opLifecycle/opCompressor.spec.js.map +0 -1
- package/lib/test/opLifecycle/opDecompressor.spec.js +0 -218
- package/lib/test/opLifecycle/opDecompressor.spec.js.map +0 -1
- package/lib/test/opLifecycle/opSplitter.spec.js +0 -272
- package/lib/test/opLifecycle/opSplitter.spec.js.map +0 -1
- package/lib/test/opLifecycle/outbox.spec.js +0 -675
- package/lib/test/opLifecycle/outbox.spec.js.map +0 -1
- package/lib/test/opLifecycle/remoteMessageProcessor.spec.js +0 -196
- package/lib/test/opLifecycle/remoteMessageProcessor.spec.js.map +0 -1
- package/lib/test/pendingStateManager.spec.js +0 -329
- package/lib/test/pendingStateManager.spec.js.map +0 -1
- package/lib/test/scheduleManager.spec.js +0 -270
- package/lib/test/scheduleManager.spec.js.map +0 -1
- package/lib/test/summarizerNode.spec.js +0 -326
- package/lib/test/summarizerNode.spec.js.map +0 -1
- package/lib/test/summarizerNodeWithGc.spec.js +0 -318
- package/lib/test/summarizerNodeWithGc.spec.js.map +0 -1
- package/lib/test/summary/orderedClientElection.spec.js +0 -535
- package/lib/test/summary/orderedClientElection.spec.js.map +0 -1
- package/lib/test/summary/runningSummarizer.spec.js +0 -1349
- package/lib/test/summary/runningSummarizer.spec.js.map +0 -1
- package/lib/test/summary/summarizer.spec.js +0 -29
- package/lib/test/summary/summarizer.spec.js.map +0 -1
- package/lib/test/summary/summarizerClientElection.spec.js +0 -436
- package/lib/test/summary/summarizerClientElection.spec.js.map +0 -1
- package/lib/test/summary/summarizerHeuristics.spec.js +0 -289
- package/lib/test/summary/summarizerHeuristics.spec.js.map +0 -1
- package/lib/test/summary/summaryCollection.spec.js +0 -200
- package/lib/test/summary/summaryCollection.spec.js.map +0 -1
- package/lib/test/summary/summaryManager.spec.js +0 -430
- package/lib/test/summary/summaryManager.spec.js.map +0 -1
- package/lib/test/summary/testQuorumClients.js +0 -34
- package/lib/test/summary/testQuorumClients.js.map +0 -1
- package/lib/test/throttler.spec.js +0 -175
- package/lib/test/throttler.spec.js.map +0 -1
- package/lib/test/types/validateContainerRuntimePrevious.generated.js +0 -180
- package/lib/test/types/validateContainerRuntimePrevious.generated.js.map +0 -1
- /package/{dist → lib}/tsdoc-metadata.json +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"garbageCollection.spec.js","sourceRoot":"","sources":["../../../src/test/gc/garbageCollection.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 */\n\nimport { strict as assert } from \"assert\";\nimport { SinonFakeTimers, useFakeTimers, spy } from \"sinon\";\nimport {\n\tContainerErrorTypes,\n\tICriticalContainerError,\n} from \"@fluidframework/container-definitions\";\nimport { IErrorBase, ITelemetryBaseEvent } from \"@fluidframework/core-interfaces\";\nimport { ISnapshotTree, SummaryType } from \"@fluidframework/protocol-definitions\";\nimport {\n\tgcBlobPrefix,\n\tgcTreeKey,\n\tIGarbageCollectionData,\n\tIGarbageCollectionDetailsBase,\n\tISummarizeResult,\n\tgcDeletedBlobKey,\n\tchannelsTreeName,\n\tgcTombstoneBlobKey,\n} from \"@fluidframework/runtime-definitions\";\nimport {\n\tMockLogger,\n\tmixinMonitoringContext,\n\tMonitoringContext,\n\ttagCodeArtifacts,\n\tcreateChildLogger,\n} from \"@fluidframework/telemetry-utils\";\nimport { Timer } from \"@fluidframework/core-utils\";\nimport {\n\tconcatGarbageCollectionStates,\n\tGarbageCollector,\n\tGCNodeType,\n\tGCSummaryStateTracker,\n\tIGarbageCollectionNodeData,\n\tIGarbageCollectionState,\n\tIGarbageCollectionSummaryDetailsLegacy,\n\tIGarbageCollectionRuntime,\n\tIGarbageCollector,\n\tIGarbageCollectorConfigs,\n\tIGarbageCollectorCreateParams,\n\tIGCMetadata,\n\tIGCSummaryTrackingData,\n\tdefaultSessionExpiryDurationMs,\n\toneDayMs,\n\tGCVersion,\n\tstableGCVersion,\n\tIGarbageCollectionSnapshotData,\n\tUnreferencedStateTracker,\n\tUnreferencedState,\n\tdefaultSweepGracePeriodMs,\n\tGarbageCollectionMessage,\n\tGarbageCollectionMessageType,\n\tGCTelemetryTracker,\n\tIGCStats,\n} from \"../../gc/index.js\";\nimport { ContainerMessageType, ContainerRuntimeGCMessage } from \"../../messageTypes.js\";\nimport {\n\tdataStoreAttributesBlobName,\n\tIContainerRuntimeMetadata,\n\tmetadataBlobName,\n} from \"../../summary/index.js\";\nimport { pkgVersion } from \"../../packageVersion.js\";\nimport { createTestConfigProvider } from \"./gcUnitTestHelpers.js\";\n\ntype WithPrivates<T, TPrivates> = Omit<T, keyof TPrivates> & TPrivates;\n\ntype GcWithPrivates = IGarbageCollector & {\n\treadonly runtime: IGarbageCollectionRuntime;\n\treadonly configs: IGarbageCollectorConfigs;\n\treadonly summaryStateTracker: WithPrivates<\n\t\tGCSummaryStateTracker,\n\t\t{\n\t\t\tlatestSummaryGCVersion: GCVersion;\n\t\t\tlatestSummaryData: IGCSummaryTrackingData | undefined;\n\t\t\tfullGCModeForAutoRecovery: boolean;\n\t\t}\n\t>;\n\treadonly telemetryTracker: GCTelemetryTracker;\n\treadonly mc: MonitoringContext;\n\treadonly sessionExpiryTimer: Omit<Timer, \"defaultTimeout\"> & { defaultTimeout: number };\n\treadonly baseSnapshotDataP: Promise<IGarbageCollectionSnapshotData | undefined>;\n\treadonly tombstones: string[];\n\treadonly deletedNodes: Set<string>;\n\treadonly unreferencedNodesState: Map<string, UnreferencedStateTracker>;\n\treadonly submitMessage: (message: ContainerRuntimeGCMessage) => void;\n\trunGC: (fullGC: boolean) => Promise<IGCStats>;\n};\n\ndescribe(\"Garbage Collection Tests\", () => {\n\tconst defaultSnapshotCacheExpiryMs = 5 * 24 * 60 * 60 * 1000;\n\tconst defaultTombstoneTimeoutMs =\n\t\tdefaultSessionExpiryDurationMs + defaultSnapshotCacheExpiryMs + oneDayMs;\n\t// Nodes in the reference graph.\n\tconst nodes: string[] = [\"/node1\", \"/node2\", \"/node3\", \"/node4\", \"/node5\", \"/node6\"];\n\tconst testPkgPath = [\"testPkg\"];\n\tconst configProvider = createTestConfigProvider();\n\n\tlet mockLogger: MockLogger;\n\tlet mc: MonitoringContext<MockLogger>;\n\tlet clock: SinonFakeTimers;\n\n\t// The default GC data returned by `getGCData` on which GC is run. Update this to update the referenced graph.\n\tlet defaultGCData: IGarbageCollectionData = { gcNodes: {} };\n\n\t// Returns a dummy snapshot tree to be built upon.\n\tconst getDummySnapshotTree = (): ISnapshotTree => {\n\t\treturn {\n\t\t\tblobs: {},\n\t\t\ttrees: {},\n\t\t};\n\t};\n\n\t/**\n\t * Called when sweep runs. It deleted the nodes from defaultGCData.\n\t */\n\tfunction deleteSweepReadyNodes(sweepReadyRoutes: string[]): string[] {\n\t\tfor (const nodeId of sweepReadyRoutes) {\n\t\t\tassert(\n\t\t\t\tdefaultGCData.gcNodes[nodeId] !== undefined,\n\t\t\t\t`Deleted node ${nodeId} doesn't exist`,\n\t\t\t);\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n\t\t\tdelete defaultGCData.gcNodes[nodeId];\n\t\t}\n\t\treturn sweepReadyRoutes;\n\t}\n\n\tfunction createGarbageCollector(\n\t\tparams: {\n\t\t\tcreateParams?: Partial<IGarbageCollectorCreateParams>;\n\t\t\tgcBlobsMap?: Map<string, any>;\n\t\t\tgcMetadata?: IGCMetadata;\n\t\t\tcloseFn?: (error?: ICriticalContainerError) => void;\n\t\t\tisSummarizerClient?: boolean;\n\t\t\tgetGCData?: (fullGC?: boolean) => Promise<IGarbageCollectionData>;\n\t\t} = {},\n\t): GcWithPrivates {\n\t\tconst {\n\t\t\tcreateParams = {},\n\t\t\tgcBlobsMap = new Map(),\n\t\t\tgcMetadata = {},\n\t\t\tcloseFn = () => {},\n\t\t\tisSummarizerClient = true,\n\t\t\tgetGCData = async () => defaultGCData,\n\t\t} = params;\n\n\t\tconst getNodeType = (nodePath: string) => {\n\t\t\tif (nodePath.split(\"/\").length !== 2) {\n\t\t\t\treturn GCNodeType.Other;\n\t\t\t}\n\t\t\treturn GCNodeType.DataStore;\n\t\t};\n\n\t\t// The runtime to be passed to the garbage collector.\n\t\tconst gcRuntime: IGarbageCollectionRuntime = {\n\t\t\tupdateStateBeforeGC: async () => {},\n\t\t\tgetGCData,\n\t\t\tupdateUsedRoutes: (usedRoutes: string[]) => {\n\t\t\t\treturn { totalNodeCount: 0, unusedNodeCount: 0 };\n\t\t\t},\n\t\t\tupdateUnusedRoutes: (unusedRoutes: string[]) => {},\n\t\t\tdeleteSweepReadyNodes,\n\t\t\tupdateTombstonedRoutes: (tombstoneRoutes: string[]) => {},\n\t\t\tgetNodeType,\n\t\t\tgetCurrentReferenceTimestampMs: () => Date.now(),\n\t\t\tcloseFn,\n\t\t};\n\n\t\tlet metadata = createParams.metadata;\n\t\tconst existing = createParams.baseSnapshot !== undefined;\n\t\t// For existing, add container runtime metadata which is required for GC to be enabled.\n\t\tif (existing) {\n\t\t\tmetadata = {\n\t\t\t\t...metadata,\n\t\t\t\t...gcMetadata,\n\t\t\t\tgcFeature: gcMetadata.gcFeature ?? stableGCVersion,\n\t\t\t\tsummaryFormatVersion: 1,\n\t\t\t\tmessage: undefined,\n\t\t\t};\n\t\t}\n\n\t\treturn GarbageCollector.create({\n\t\t\t...createParams,\n\t\t\truntime: gcRuntime,\n\t\t\tgcOptions: createParams.gcOptions ?? {},\n\t\t\tbaseSnapshot: createParams.baseSnapshot,\n\t\t\tbaseLogger: createChildLogger({ logger: mc.logger }),\n\t\t\texisting,\n\t\t\tmetadata,\n\t\t\tcreateContainerMetadata: {\n\t\t\t\tcreateContainerRuntimeVersion: pkgVersion,\n\t\t\t\tcreateContainerTimestamp: Date.now(),\n\t\t\t},\n\t\t\tisSummarizerClient,\n\t\t\treadAndParseBlob: async <T>(id: string) => gcBlobsMap.get(id) as T,\n\t\t\tgetNodePackagePath: async (nodeId: string) => testPkgPath,\n\t\t\tgetLastSummaryTimestampMs: () => Date.now(),\n\t\t\tsubmitMessage: (message: ContainerRuntimeGCMessage) => {},\n\t\t\tsessionExpiryTimerStarted: createParams.sessionExpiryTimerStarted,\n\t\t}) as GcWithPrivates;\n\t}\n\tlet gc: GcWithPrivates | undefined;\n\n\tbefore(() => {\n\t\tclock = useFakeTimers();\n\t});\n\n\tbeforeEach(() => {\n\t\tgc = undefined;\n\t\tmockLogger = new MockLogger();\n\t\tmc = mixinMonitoringContext(mockLogger, configProvider);\n\t});\n\n\tafterEach(() => {\n\t\tclock.reset();\n\t\tmockLogger.clear();\n\t\tconfigProvider.clear();\n\t\tdefaultGCData = { gcNodes: {} };\n\t\tgc?.dispose();\n\t});\n\n\tafter(() => {\n\t\tclock.restore();\n\t});\n\n\tdescribe(\"Session expiry\", () => {\n\t\tit(\"Session expiry closes container\", () => {\n\t\t\tlet closeCalled = false;\n\t\t\tfunction closeCalledAfterExactTicks(ticks: number) {\n\t\t\t\tclock.tick(ticks - 1);\n\t\t\t\tif (closeCalled) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tclock.tick(1);\n\t\t\t\treturn closeCalled;\n\t\t\t}\n\n\t\t\tgc = createGarbageCollector({\n\t\t\t\tcloseFn: () => {\n\t\t\t\t\tcloseCalled = true;\n\t\t\t\t},\n\t\t\t});\n\t\t\tassert(\n\t\t\t\tcloseCalledAfterExactTicks(defaultSessionExpiryDurationMs),\n\t\t\t\t\"Close should have been called at exactly defaultSessionExpiryDurationMs\",\n\t\t\t);\n\t\t});\n\n\t\tit(\"Session expiry is adjusted by sessionExpiryTimerStarted\", () => {\n\t\t\tlet closeCalled = false;\n\t\t\tconst sessionExpiryTimerStarted = defaultSessionExpiryDurationMs - 1; // arbitrary number\n\t\t\tclock.tick(sessionExpiryTimerStarted + defaultSessionExpiryDurationMs - 1);\n\t\t\tgc = createGarbageCollector({\n\t\t\t\tcreateParams: { sessionExpiryTimerStarted },\n\t\t\t\tcloseFn: () => {\n\t\t\t\t\tcloseCalled = true;\n\t\t\t\t},\n\t\t\t});\n\t\t\tassert(closeCalled === false, \"Close should not have been called\");\n\t\t\tclock.tick(1);\n\t\t\tassert(closeCalled, \"Close should have been called\");\n\t\t});\n\n\t\tit(\"it throws when already expired\", () => {\n\t\t\tclock.tick(defaultSessionExpiryDurationMs + 1);\n\t\t\tassert.throws(() =>\n\t\t\t\tcreateGarbageCollector({\n\t\t\t\t\tcreateParams: { sessionExpiryTimerStarted: 1 },\n\t\t\t\t\tcloseFn: () => {\n\t\t\t\t\t\tthrow new Error(\"Session expired\");\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t);\n\t\t});\n\t});\n\n\tdescribe(\"addedOutboundReference\", () => {\n\t\tit(\"ignores target relative URLs\", () => {\n\t\t\tconst garbageCollector = createGarbageCollector();\n\t\t\tconst spies = {\n\t\t\t\ttelemetryTracker: { nodeUsed: spy(garbageCollector.telemetryTracker, \"nodeUsed\") },\n\t\t\t};\n\t\t\tgarbageCollector.addedOutboundReference(\"/from\", \"to/relative/url\");\n\t\t\tmockLogger.assertMatch(\n\t\t\t\t[{ eventName: \"GarbageCollector:InvalidRelativeOutboundRoute\", category: \"error\" }],\n\t\t\t\t\"Expected error log\",\n\t\t\t);\n\t\t\tassert.equal(\n\t\t\t\tspies.telemetryTracker.nodeUsed.callCount,\n\t\t\t\t0,\n\t\t\t\t\"nodeUsed should not be called\",\n\t\t\t);\n\t\t});\n\t\tit(\"tracks target absolute URLs\", () => {\n\t\t\tconst garbageCollector = createGarbageCollector();\n\t\t\tconst spies = {\n\t\t\t\ttelemetryTracker: { nodeUsed: spy(garbageCollector.telemetryTracker, \"nodeUsed\") },\n\t\t\t};\n\t\t\tgarbageCollector.addedOutboundReference(\"/from\", \"/to/absolute/url\");\n\t\t\tmockLogger.assertMatchNone(\n\t\t\t\t[{ eventName: \"GarbageCollector:InvalidRelativeOutboundRoute\" }],\n\t\t\t\t\"unexpected events logged\",\n\t\t\t);\n\t\t\tassert.equal(\n\t\t\t\tspies.telemetryTracker.nodeUsed.callCount,\n\t\t\t\t1,\n\t\t\t\t\"nodeUsed should have been called\",\n\t\t\t);\n\t\t});\n\t});\n\n\tdescribe(\"Tombstone and Sweep\", () => {\n\t\tit(\"Tombstone then Delete\", async () => {\n\t\t\t// Simple starting reference graph - root and two nodes\n\t\t\tdefaultGCData.gcNodes[\"/\"] = [nodes[0], nodes[1]];\n\t\t\tdefaultGCData.gcNodes[nodes[0]] = [];\n\t\t\tdefaultGCData.gcNodes[nodes[1]] = [];\n\n\t\t\t// Sweep enabled\n\t\t\tgc = createGarbageCollector({ createParams: { gcOptions: { enableGCSweep: true } } });\n\t\t\t// These spies will let us monitor how each of these functions are called (or not) during runSweepPhase.\n\t\t\t// The original behavior of the function is preserved, but we can check how it was called.\n\t\t\tconst spies = {\n\t\t\t\tupdateTombstonedRoutes: spy(gc.runtime, \"updateTombstonedRoutes\"),\n\t\t\t\tsubmitMessage: spy(gc, \"submitMessage\"),\n\t\t\t};\n\n\t\t\t// Nodes 0 and 1 are referenced\n\t\t\tawait gc.collectGarbage({});\n\n\t\t\t// Unreference 0\n\t\t\tdefaultGCData.gcNodes[\"/\"] = [nodes[1]];\n\t\t\tclock.tick(10);\n\t\t\tawait gc.collectGarbage({});\n\n\t\t\t// Erase the spy's tracking of calls up to this point - I just want to observe what happens next.\n\t\t\tspies.updateTombstonedRoutes.resetHistory();\n\n\t\t\t// Skip to TombstoneReady state\n\t\t\tclock.tick(defaultTombstoneTimeoutMs);\n\t\t\tawait gc.collectGarbage({});\n\n\t\t\tassert(\n\t\t\t\tspies.updateTombstonedRoutes.calledWith([nodes[0]]),\n\t\t\t\t\"updateTombstonedRoutes should be called with node 0\",\n\t\t\t);\n\t\t\tassert.equal(\n\t\t\t\tspies.submitMessage.callCount,\n\t\t\t\t0,\n\t\t\t\t\"submitMessage should not be called yet, didn't pass Grace Period yet\",\n\t\t\t);\n\t\t\tspies.updateTombstonedRoutes.resetHistory();\n\n\t\t\t// Skip past Sweep Grace Period. GC Sweep op should be submitted\n\t\t\tclock.tick(defaultSweepGracePeriodMs);\n\t\t\tawait gc.collectGarbage({});\n\n\t\t\tassert.equal(\n\t\t\t\tspies.submitMessage.callCount,\n\t\t\t\t1,\n\t\t\t\t\"submitMessage should be called since Sweep is enabled\",\n\t\t\t);\n\t\t\tassert(\n\t\t\t\tspies.updateTombstonedRoutes.alwaysCalledWith([]),\n\t\t\t\t\"No additional nodes should be Tombstoned\",\n\t\t\t);\n\t\t});\n\n\t\tit(\"Sweep Disabled - Should Tombstone SweepReady nodes\", async () => {\n\t\t\tdefaultGCData.gcNodes[\"/\"] = [nodes[0], nodes[1]];\n\t\t\tdefaultGCData.gcNodes[nodes[0]] = [];\n\t\t\tdefaultGCData.gcNodes[nodes[1]] = [];\n\n\t\t\tgc = createGarbageCollector();\n\t\t\tconst spies = {\n\t\t\t\tupdateTombstonedRoutes: spy(gc.runtime, \"updateTombstonedRoutes\"),\n\t\t\t\tsubmitMessage: spy(gc, \"submitMessage\"),\n\t\t\t};\n\n\t\t\t// Nodes 0 and 1 are referenced\n\t\t\tawait gc.collectGarbage({});\n\n\t\t\t// Unreference 0\n\t\t\tdefaultGCData.gcNodes[\"/\"] = [nodes[1]];\n\t\t\tclock.tick(10);\n\t\t\tawait gc.collectGarbage({});\n\n\t\t\t// Skip all the way past Sweep Grace Period. But Sweep is disabled, so Tombstone should happen\n\t\t\tclock.tick(defaultTombstoneTimeoutMs + defaultSweepGracePeriodMs);\n\t\t\tassert.equal(\n\t\t\t\tgc.unreferencedNodesState.get(nodes[0])?.state,\n\t\t\t\t\"SweepReady\",\n\t\t\t\t\"Node 0 should be SweepReady (not TombstoneReady)\",\n\t\t\t);\n\n\t\t\tspies.updateTombstonedRoutes.resetHistory();\n\t\t\tawait gc.collectGarbage({});\n\n\t\t\tassert(\n\t\t\t\tspies.updateTombstonedRoutes.calledWith([nodes[0]]),\n\t\t\t\t\"updateTombstonedRoutes should be called with node 0\",\n\t\t\t);\n\t\t\tassert.equal(\n\t\t\t\tspies.submitMessage.callCount,\n\t\t\t\t0,\n\t\t\t\t\"submitMessage should not be called since Sweep is disabled\",\n\t\t\t);\n\t\t});\n\n\t\tit(\"Autorecovery upon loading a Tombstoned node\", async () => {\n\t\t\t// Simple starting reference graph - root and two nodes\n\t\t\tdefaultGCData.gcNodes[\"/\"] = [nodes[0], nodes[1]];\n\t\t\tdefaultGCData.gcNodes[nodes[0]] = [];\n\t\t\tdefaultGCData.gcNodes[nodes[1]] = [];\n\n\t\t\t// Simulate GC Data with a route missing (nodes[0] is referenced but missing here)\n\t\t\t// We'll return this from getGCData unless fullGC is passed in.\n\t\t\tconst corruptedGCData: IGarbageCollectionData = JSON.parse(\n\t\t\t\tJSON.stringify(defaultGCData),\n\t\t\t);\n\t\t\tcorruptedGCData.gcNodes[\"/\"] = [nodes[1]];\n\n\t\t\t// getGCData set up to sometimes return the corrupted data\n\t\t\tgc = createGarbageCollector({\n\t\t\t\tgetGCData: async (fullGC?: boolean) => {\n\t\t\t\t\treturn fullGC ? defaultGCData : corruptedGCData;\n\t\t\t\t},\n\t\t\t});\n\t\t\t// These spies will let us monitor how each of these functions are called (or not) during runSweepPhase.\n\t\t\t// The original behavior of the function is preserved, but we can check how it was called.\n\t\t\tconst spies = {\n\t\t\t\tgc: {\n\t\t\t\t\tsubmitMessage: spy(gc, \"submitMessage\"),\n\t\t\t\t\taddedOutboundReference: spy(gc, \"addedOutboundReference\"),\n\t\t\t\t\trunGC: spy(gc, \"runGC\"),\n\t\t\t\t},\n\t\t\t};\n\n\t\t\t// Nodes 0 and 1 are referenced (use correct gcData via fullGC true)\n\t\t\t// Simulate successful summary ack to clear doesGCStateNeedReset flag so it doesn't interfere (it leads to fullGC too)\n\t\t\tawait gc.collectGarbage({ fullGC: true });\n\t\t\tawait gc.summaryStateTracker.refreshLatestSummary({\n\t\t\t\tisSummaryTracked: true,\n\t\t\t\tisSummaryNewer: false,\n\t\t\t});\n\t\t\tassert(\n\t\t\t\t!gc.unreferencedNodesState.has(nodes[0]),\n\t\t\t\t\"node 0 should not be unreferenced to start\",\n\t\t\t);\n\n\t\t\t// Now run GC again - this time with the corrupted data (via fullGC false)\n\t\t\tclock.tick(10);\n\t\t\tawait gc.collectGarbage({ fullGC: false });\n\t\t\tassert.equal(\n\t\t\t\tgc.unreferencedNodesState.get(nodes[0])?.state,\n\t\t\t\tUnreferencedState.Active, // This means recently unreferenced\n\t\t\t\t\"node 0 should appear unreferenced after running GC with corrupted GC Data\",\n\t\t\t);\n\n\t\t\t// Let node 0 become Tombstoned and verify it\n\t\t\tclock.tick(defaultTombstoneTimeoutMs);\n\t\t\tawait gc.collectGarbage({});\n\t\t\tassert.equal(\n\t\t\t\tgc.unreferencedNodesState.get(nodes[0])?.state,\n\t\t\t\tUnreferencedState.TombstoneReady,\n\t\t\t\t\"node 0 should be TombstoneReady\",\n\t\t\t);\n\t\t\tassert.deepEqual(gc.tombstones, [nodes[0]], \"node 0 should be in the Tombstones list\");\n\n\t\t\t// Simulate usage to trigger TombstoneLoaded op.\n\t\t\tgc.nodeUpdated(nodes[0], \"Loaded\");\n\t\t\tconst [gcTombstoneLoadedMessage] = spies.gc.submitMessage.args[0];\n\t\t\tassert.deepEqual(\n\t\t\t\tgcTombstoneLoadedMessage,\n\t\t\t\t{\n\t\t\t\t\ttype: ContainerMessageType.GC,\n\t\t\t\t\tcontents: {\n\t\t\t\t\t\ttype: GarbageCollectionMessageType.TombstoneLoaded,\n\t\t\t\t\t\tnodePath: nodes[0],\n\t\t\t\t\t},\n\t\t\t\t\tcompatDetails: { behavior: \"Ignore\" },\n\t\t\t\t} satisfies ContainerRuntimeGCMessage,\n\t\t\t\t\"submitted message not as expected\",\n\t\t\t);\n\n\t\t\t// Plumb the message to processMessage fn to trigger autorecovery\n\t\t\t// Autorecovery: addedOutboundReference should be called with the tombstoned node, which should transition to \"Active\" state\n\t\t\tgc.processMessage(gcTombstoneLoadedMessage, true /* local */);\n\t\t\tassert.deepEqual(\n\t\t\t\tspies.gc.addedOutboundReference.args[0],\n\t\t\t\t[\"/\", nodes[0], /* autorecovery: */ true],\n\t\t\t\t\"addedOutboundReference should be called with node 0\",\n\t\t\t);\n\t\t\tassert.equal(\n\t\t\t\tgc.unreferencedNodesState.get(nodes[0])?.state,\n\t\t\t\tUnreferencedState.Active,\n\t\t\t\t\"node 0 should be unreferenced but 'Active' after initial Autorecovery moment (it was TombstoneReady)\",\n\t\t\t);\n\n\t\t\t// Simulate a successful GC/Summary.\n\t\t\t// GC Data corruption should be fixed (nodes[0] should be referenced again) and autorecovery fullGC state should be reset\n\t\t\tspies.gc.runGC.resetHistory();\n\t\t\tawait gc.collectGarbage({});\n\t\t\tassert(\n\t\t\t\tspies.gc.runGC.calledWith(/* fullGC: */ true),\n\t\t\t\t\"runGC should be called with fullGC true\",\n\t\t\t);\n\t\t\tassert(\n\t\t\t\tgc.summaryStateTracker.fullGCModeForAutoRecovery,\n\t\t\t\t\"fullGCModeForAutoRecovery should NOT have been reset to false yet\",\n\t\t\t);\n\t\t\tawait gc.summaryStateTracker.refreshLatestSummary({\n\t\t\t\tisSummaryTracked: true,\n\t\t\t\tisSummaryNewer: false,\n\t\t\t});\n\t\t\tassert(\n\t\t\t\t!gc.summaryStateTracker.fullGCModeForAutoRecovery,\n\t\t\t\t\"fullGCModeForAutoRecovery should have been reset to false now\",\n\t\t\t);\n\n\t\t\t// Lastly, confirm that the node was successfully restored\n\t\t\t// (not actually that interesting since we're hardcoding the GC Data, but still)\n\t\t\tassert(\n\t\t\t\t!gc.unreferencedNodesState.has(nodes[0]),\n\t\t\t\t\"node 0 should not be unreferenced after repairing GC Data\",\n\t\t\t);\n\t\t});\n\t});\n\n\tdescribe(\"errors when unreferenced objects are used after they are inactive / deleted\", () => {\n\t\t// Mock node loaded and changed activity for all the nodes in the graph.\n\t\tasync function mockNodeChangesAndRunGC(garbageCollector: IGarbageCollector) {\n\t\t\tnodes.forEach((nodeId) => {\n\t\t\t\tgarbageCollector.nodeUpdated(nodeId, \"Loaded\", Date.now(), testPkgPath);\n\t\t\t\tgarbageCollector.nodeUpdated(nodeId, \"Changed\", Date.now(), testPkgPath);\n\t\t\t});\n\t\t\tawait garbageCollector.collectGarbage({});\n\t\t}\n\n\t\tbeforeEach(async () => {\n\t\t\t// Set up the reference graph such that all nodes are referenced. Add in a couple of cycles in the graph.\n\t\t\t// Here's a diagram showing the references:\n\t\t\t// 0 - 1 - 2 - 3\n\t\t\t// | / /\n\t\t\t// |-/-------/\n\t\t\tdefaultGCData.gcNodes[\"/\"] = [nodes[0]];\n\t\t\tdefaultGCData.gcNodes[nodes[0]] = [nodes[1]];\n\t\t\tdefaultGCData.gcNodes[nodes[1]] = [nodes[0], nodes[2]];\n\t\t\tdefaultGCData.gcNodes[nodes[2]] = [nodes[3]];\n\t\t\tdefaultGCData.gcNodes[nodes[3]] = [nodes[0]];\n\t\t});\n\n\t\tconst summarizerContainerTests = (\n\t\t\ttimeout: number,\n\t\t\tmode: \"inactive\" | \"tombstone\" | \"sweep\",\n\t\t\trevivedEventName: string,\n\t\t\tchangedEventName: string,\n\t\t\tloadedEventName: string,\n\t\t\tsweepGracePeriodMsOverride?: number,\n\t\t) => {\n\t\t\t// Validates that no unexpected event has been fired.\n\t\t\tfunction validateNoEvents() {\n\t\t\t\tmockLogger.assertMatchNone(\n\t\t\t\t\t[\n\t\t\t\t\t\t{ eventName: revivedEventName },\n\t\t\t\t\t\t{ eventName: changedEventName },\n\t\t\t\t\t\t{ eventName: loadedEventName },\n\t\t\t\t\t],\n\t\t\t\t\t\"unexpected events logged\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst sweepGracePeriodMs = sweepGracePeriodMsOverride ?? defaultSweepGracePeriodMs;\n\n\t\t\tconst createGCOverride = (\n\t\t\t\tbaseSnapshot?: ISnapshotTree,\n\t\t\t\tgcBlobsMap?: Map<string, IGarbageCollectionState | IGarbageCollectionDetailsBase>,\n\t\t\t) => {\n\t\t\t\tconst tombstoneTimeoutMs =\n\t\t\t\t\tmode === \"tombstone\"\n\t\t\t\t\t\t? timeout\n\t\t\t\t\t\t: mode === \"sweep\"\n\t\t\t\t\t\t? timeout - sweepGracePeriodMs\n\t\t\t\t\t\t: undefined;\n\t\t\t\tconst gcOptions = { sweepGracePeriodMs };\n\t\t\t\treturn createGarbageCollector({\n\t\t\t\t\tcreateParams: { baseSnapshot, gcOptions },\n\t\t\t\t\tgcBlobsMap,\n\t\t\t\t\tgcMetadata: {\n\t\t\t\t\t\ttombstoneTimeoutMs,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t};\n\n\t\t\tit(\"doesn't generate events for referenced nodes\", async () => {\n\t\t\t\tconst garbageCollector = createGCOverride();\n\n\t\t\t\t// Run garbage collection on the default GC data where everything is referenced.\n\t\t\t\tawait garbageCollector.collectGarbage({});\n\n\t\t\t\t// Advance the clock just before the timeout and validate no events are generated.\n\t\t\t\tclock.tick(timeout - 1);\n\t\t\t\tawait mockNodeChangesAndRunGC(garbageCollector);\n\t\t\t\tvalidateNoEvents();\n\n\t\t\t\t// Advance the clock to expire the timeout.\n\t\t\t\tclock.tick(1);\n\n\t\t\t\t// Update all nodes again. Validate that no unexpected events are generated since everything is referenced.\n\t\t\t\tawait mockNodeChangesAndRunGC(garbageCollector);\n\t\t\t\tvalidateNoEvents();\n\t\t\t});\n\n\t\t\tit(\"generates events for nodes that are used after time out\", async () => {\n\t\t\t\tconst garbageCollector = createGCOverride();\n\n\t\t\t\t// Remove node 2's reference from node 1. This should make node 2 and node 3 unreferenced.\n\t\t\t\tdefaultGCData.gcNodes[nodes[1]] = [];\n\n\t\t\t\tawait garbageCollector.collectGarbage({});\n\n\t\t\t\t// Advance the clock just before the timeout and validate no unexpected events are logged.\n\t\t\t\tclock.tick(timeout - 1);\n\t\t\t\tawait mockNodeChangesAndRunGC(garbageCollector);\n\t\t\t\tvalidateNoEvents();\n\n\t\t\t\t// Expire the timeout and validate that all events for node 2 and node 3 are logged.\n\t\t\t\tclock.tick(1);\n\t\t\t\tawait mockNodeChangesAndRunGC(garbageCollector);\n\t\t\t\tconst expectedEvents: Omit<ITelemetryBaseEvent, \"category\">[] = [];\n\t\t\t\texpectedEvents.push(\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: loadedEventName,\n\t\t\t\t\t\ttimeout,\n\t\t\t\t\t\t...tagCodeArtifacts({ id: nodes[2], pkg: testPkgPath.join(\"/\") }),\n\t\t\t\t\t\tcreateContainerRuntimeVersion: pkgVersion,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: changedEventName,\n\t\t\t\t\t\ttimeout,\n\t\t\t\t\t\t...tagCodeArtifacts({ id: nodes[2], pkg: testPkgPath.join(\"/\") }),\n\t\t\t\t\t\tcreateContainerRuntimeVersion: pkgVersion,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: loadedEventName,\n\t\t\t\t\t\ttimeout,\n\t\t\t\t\t\t...tagCodeArtifacts({ id: nodes[3], pkg: testPkgPath.join(\"/\") }),\n\t\t\t\t\t\tcreateContainerRuntimeVersion: pkgVersion,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: changedEventName,\n\t\t\t\t\t\ttimeout,\n\t\t\t\t\t\t...tagCodeArtifacts({ id: nodes[3], pkg: testPkgPath.join(\"/\") }),\n\t\t\t\t\t\tcreateContainerRuntimeVersion: pkgVersion,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tmockLogger.assertMatch(\n\t\t\t\t\texpectedEvents,\n\t\t\t\t\t\"all events not generated as expected\",\n\t\t\t\t\ttrue /* inlineDetailsProp */,\n\t\t\t\t);\n\n\t\t\t\t// Add reference from node 1 to node 3 and validate that we get a revived event.\n\t\t\t\tgarbageCollector.addedOutboundReference(nodes[1], nodes[3]);\n\t\t\t\tawait garbageCollector.collectGarbage({});\n\t\t\t\tmockLogger.assertMatch(\n\t\t\t\t\t[\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\teventName: revivedEventName,\n\t\t\t\t\t\t\ttimeout,\n\t\t\t\t\t\t\t...tagCodeArtifacts({\n\t\t\t\t\t\t\t\tid: nodes[3],\n\t\t\t\t\t\t\t\tfromId: nodes[1],\n\t\t\t\t\t\t\t\tpkg: testPkgPath.join(\"/\"),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\t\"revived event not generated as expected\",\n\t\t\t\t\ttrue /* inlineDetailsProp */,\n\t\t\t\t);\n\t\t\t});\n\n\t\t\tit(\"generates only revived event when an inactive node is changed and revived\", async () => {\n\t\t\t\tconst garbageCollector = createGCOverride();\n\n\t\t\t\t// Remove node 2's reference from node 1. This should make node 2 and node 3 unreferenced.\n\t\t\t\tdefaultGCData.gcNodes[nodes[1]] = [];\n\n\t\t\t\tawait garbageCollector.collectGarbage({});\n\n\t\t\t\t// Advance the clock just before the timeout and validate no unexpected events are logged.\n\t\t\t\tclock.tick(timeout - 1);\n\t\t\t\tawait mockNodeChangesAndRunGC(garbageCollector);\n\t\t\t\tvalidateNoEvents();\n\n\t\t\t\t// Expire the timeout and validate that only revived event is generated for node 2.\n\t\t\t\tclock.tick(1);\n\t\t\t\tgarbageCollector.nodeUpdated(nodes[2], \"Changed\", Date.now(), testPkgPath);\n\t\t\t\tgarbageCollector.nodeUpdated(nodes[2], \"Loaded\", Date.now(), testPkgPath);\n\t\t\t\tgarbageCollector.addedOutboundReference(nodes[1], nodes[2]);\n\t\t\t\tawait garbageCollector.collectGarbage({});\n\n\t\t\t\tfor (const event of mockLogger.events) {\n\t\t\t\t\tassert.notStrictEqual(\n\t\t\t\t\t\tevent.eventName,\n\t\t\t\t\t\tloadedEventName,\n\t\t\t\t\t\t\"Unexpected loaded event logged\",\n\t\t\t\t\t);\n\t\t\t\t\tassert.notStrictEqual(\n\t\t\t\t\t\tevent.eventName,\n\t\t\t\t\t\tchangedEventName,\n\t\t\t\t\t\t\"Unexpected changed event logged\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tmockLogger.assertMatch(\n\t\t\t\t\t[\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\teventName: revivedEventName,\n\t\t\t\t\t\t\ttimeout,\n\t\t\t\t\t\t\t...tagCodeArtifacts({\n\t\t\t\t\t\t\t\tid: nodes[2],\n\t\t\t\t\t\t\t\tfromId: nodes[1],\n\t\t\t\t\t\t\t\tpkg: testPkgPath.join(\"/\"),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\t\"revived event not logged as expected\",\n\t\t\t\t\ttrue /* inlineDetailsProp */,\n\t\t\t\t);\n\t\t\t});\n\n\t\t\tit(\"generates events once per node\", async () => {\n\t\t\t\tconst garbageCollector = createGCOverride();\n\n\t\t\t\t// Remove node 3's reference from node 2.\n\t\t\t\tdefaultGCData.gcNodes[nodes[2]] = [];\n\n\t\t\t\tawait garbageCollector.collectGarbage({});\n\n\t\t\t\t// Advance the clock just before the timeout and validate no unexpected events are logged.\n\t\t\t\tclock.tick(timeout - 1);\n\t\t\t\tawait mockNodeChangesAndRunGC(garbageCollector);\n\t\t\t\tvalidateNoEvents();\n\n\t\t\t\t// Expire the timeout and validate that all events for node 2 and node 3 are logged.\n\t\t\t\tclock.tick(1);\n\t\t\t\tawait mockNodeChangesAndRunGC(garbageCollector);\n\t\t\t\tconst expectedEvents: Omit<ITelemetryBaseEvent, \"category\">[] = [];\n\t\t\t\texpectedEvents.push(\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: loadedEventName,\n\t\t\t\t\t\ttimeout,\n\t\t\t\t\t\t...tagCodeArtifacts({ id: nodes[3], pkg: testPkgPath.join(\"/\") }),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: changedEventName,\n\t\t\t\t\t\ttimeout,\n\t\t\t\t\t\t...tagCodeArtifacts({ id: nodes[3], pkg: testPkgPath.join(\"/\") }),\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tmockLogger.assertMatch(\n\t\t\t\t\texpectedEvents,\n\t\t\t\t\t\"all events not generated as expected\",\n\t\t\t\t\ttrue /* inlineDetailsProp */,\n\t\t\t\t);\n\n\t\t\t\t// Update all nodes again. There shouldn't be any more events since for each node the event is only once.\n\t\t\t\tawait mockNodeChangesAndRunGC(garbageCollector);\n\t\t\t\tvalidateNoEvents();\n\t\t\t});\n\n\t\t\t/**\n\t\t\t * Here, the base snapshot contains nodes that have timed out. The test validates that we generate errors\n\t\t\t * when these nodes are used.\n\t\t\t */\n\t\t\tit(\"generates events for nodes that time out on load\", async () => {\n\t\t\t\t// Create GC state where node 3's unreferenced time was > timeout ms ago.\n\t\t\t\t// This means this node should time out as soon as its data is loaded.\n\n\t\t\t\t// Create a snapshot tree to be used as the GC snapshot tree.\n\t\t\t\tconst gcSnapshotTree = getDummySnapshotTree();\n\t\t\t\tconst gcBlobId = \"root\";\n\t\t\t\t// Add a GC blob with key that start with `gcBlobPrefix` to the GC snapshot tree. The blob Id for this\n\t\t\t\t// is generated by server in real scenarios but we use a static id here for testing.\n\t\t\t\tgcSnapshotTree.blobs[`${gcBlobPrefix}_${gcBlobId}`] = gcBlobId;\n\n\t\t\t\t// Create a base snapshot that contains the GC snapshot tree.\n\t\t\t\tconst baseSnapshot = getDummySnapshotTree();\n\t\t\t\tbaseSnapshot.trees[gcTreeKey] = gcSnapshotTree;\n\n\t\t\t\t// Create GC state with node 3 expired. This will be returned when the garbage collector asks\n\t\t\t\t// for the GC blob with `gcBlobId`.\n\t\t\t\tconst gcState: IGarbageCollectionState = { gcNodes: {} };\n\t\t\t\tconst node3Data: IGarbageCollectionNodeData = {\n\t\t\t\t\toutboundRoutes: [],\n\t\t\t\t\tunreferencedTimestampMs: Date.now() - (timeout + 100),\n\t\t\t\t};\n\t\t\t\tgcState.gcNodes[nodes[3]] = node3Data;\n\n\t\t\t\tconst gcBlobMap: Map<string, IGarbageCollectionState> = new Map([\n\t\t\t\t\t[gcBlobId, gcState],\n\t\t\t\t]);\n\t\t\t\tconst garbageCollector = createGCOverride(baseSnapshot, gcBlobMap);\n\n\t\t\t\t// Remove node 3's reference from node 2 so that it is still unreferenced.\n\t\t\t\tdefaultGCData.gcNodes[nodes[2]] = [];\n\n\t\t\t\t// Run GC to trigger loading the GC details from the base summary. Will also generate Delete logs\n\t\t\t\tawait garbageCollector.collectGarbage({});\n\t\t\t\t// Validate that all events are logged as expected.\n\t\t\t\tgarbageCollector.nodeUpdated(nodes[3], \"Loaded\", Date.now(), testPkgPath);\n\t\t\t\tgarbageCollector.nodeUpdated(nodes[3], \"Changed\", Date.now(), testPkgPath);\n\t\t\t\tawait garbageCollector.collectGarbage({});\n\t\t\t\tmockLogger.assertMatch(\n\t\t\t\t\t[\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\teventName: loadedEventName,\n\t\t\t\t\t\t\ttimeout,\n\t\t\t\t\t\t\t...tagCodeArtifacts({ id: nodes[3], pkg: testPkgPath.join(\"/\") }),\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\teventName: changedEventName,\n\t\t\t\t\t\t\ttimeout,\n\t\t\t\t\t\t\t...tagCodeArtifacts({ id: nodes[3], pkg: testPkgPath.join(\"/\") }),\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\t\"all events not generated as expected\",\n\t\t\t\t\ttrue /* inlineDetailsProp */,\n\t\t\t\t);\n\n\t\t\t\t// Add reference from node 2 to node 3 and validate that revived event is logged.\n\t\t\t\tdefaultGCData.gcNodes[nodes[2]] = [nodes[3]];\n\t\t\t\tgarbageCollector.addedOutboundReference(nodes[2], nodes[3]);\n\t\t\t\tawait garbageCollector.collectGarbage({});\n\t\t\t\tmockLogger.assertMatch(\n\t\t\t\t\t[\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\teventName: revivedEventName,\n\t\t\t\t\t\t\ttimeout,\n\t\t\t\t\t\t\t...tagCodeArtifacts({\n\t\t\t\t\t\t\t\tid: nodes[3],\n\t\t\t\t\t\t\t\tfromId: nodes[2],\n\t\t\t\t\t\t\t\tpkg: testPkgPath.join(\"/\"),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\t\"revived event not generated as expected\",\n\t\t\t\t\ttrue /* inlineDetailsProp */,\n\t\t\t\t);\n\t\t\t});\n\n\t\t\t/**\n\t\t\t * Here, the base snapshot contains nodes that have timed out. The test validates that we generate errors\n\t\t\t * when these nodes are used via trailing ops. It simulates trailing ops by calling `nodeUsed` (called when\n\t\t\t * ops are processed) before initializing garbage collector.\n\t\t\t */\n\t\t\tit(\"generates events for nodes that time out on load - nodes are used via trailing ops\", async () => {\n\t\t\t\t// Create GC state where node 3's unreferenced time was > timeout ms ago.\n\t\t\t\t// This means this node should time out as soon as its data is loaded.\n\n\t\t\t\t// Create a snapshot tree to be used as the GC snapshot tree.\n\t\t\t\tconst gcSnapshotTree = getDummySnapshotTree();\n\t\t\t\tconst gcBlobId = \"root\";\n\t\t\t\t// Add a GC blob with key that start with `gcBlobPrefix` to the GC snapshot tree. The blob Id for this\n\t\t\t\t// is generated by server in real scenarios but we use a static id here for testing.\n\t\t\t\tgcSnapshotTree.blobs[`${gcBlobPrefix}_${gcBlobId}`] = gcBlobId;\n\n\t\t\t\t// Create a base snapshot that contains the GC snapshot tree.\n\t\t\t\tconst baseSnapshot = getDummySnapshotTree();\n\t\t\t\tbaseSnapshot.trees[gcTreeKey] = gcSnapshotTree;\n\n\t\t\t\t// Create GC state with node 3 expired. This will be returned when the garbage collector asks\n\t\t\t\t// for the GC blob with `gcBlobId`.\n\t\t\t\tconst gcState: IGarbageCollectionState = { gcNodes: {} };\n\t\t\t\tconst node3Data: IGarbageCollectionNodeData = {\n\t\t\t\t\toutboundRoutes: [],\n\t\t\t\t\tunreferencedTimestampMs: Date.now() - (timeout + 100),\n\t\t\t\t};\n\t\t\t\tgcState.gcNodes[nodes[3]] = node3Data;\n\n\t\t\t\tconst gcBlobMap: Map<string, IGarbageCollectionState> = new Map([\n\t\t\t\t\t[gcBlobId, gcState],\n\t\t\t\t]);\n\t\t\t\tconst garbageCollector = createGCOverride(baseSnapshot, gcBlobMap);\n\n\t\t\t\t// Initialize the base state which happens during runtime initialization.\n\t\t\t\tawait garbageCollector.initializeBaseState();\n\n\t\t\t\t// Simulate sending op and loading the node in unreferenced state.\n\t\t\t\tgarbageCollector.nodeUpdated(nodes[3], \"Loaded\", Date.now(), testPkgPath);\n\t\t\t\tgarbageCollector.nodeUpdated(nodes[3], \"Changed\", Date.now(), testPkgPath);\n\n\t\t\t\t// Log pending events explicitly. This is needed because summarizer clients don't log these events\n\t\t\t\t// until the next GC run which calls this function.\n\t\t\t\tawait garbageCollector.telemetryTracker.logPendingEvents(\n\t\t\t\t\tgarbageCollector.mc.logger,\n\t\t\t\t);\n\t\t\t\tmockLogger.assertMatch(\n\t\t\t\t\t[\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\teventName: loadedEventName,\n\t\t\t\t\t\t\ttimeout,\n\t\t\t\t\t\t\t...tagCodeArtifacts({ id: nodes[3], pkg: testPkgPath.join(\"/\") }),\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\teventName: changedEventName,\n\t\t\t\t\t\t\ttimeout,\n\t\t\t\t\t\t\t...tagCodeArtifacts({ id: nodes[3], pkg: testPkgPath.join(\"/\") }),\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\t\"all events not generated as expected\",\n\t\t\t\t\ttrue /* inlineDetailsProp */,\n\t\t\t\t);\n\n\t\t\t\t// Add reference from node 2 to node 3 and validate that revived event is logged. Node 3 needs to be\n\t\t\t\t// deleted from unreferencedNodesState otherwise revived events are not logged.\n\t\t\t\tgarbageCollector.addedOutboundReference(nodes[2], nodes[3]);\n\t\t\t\tgarbageCollector.unreferencedNodesState.delete(nodes[3]);\n\t\t\t\tawait garbageCollector.telemetryTracker.logPendingEvents(\n\t\t\t\t\tgarbageCollector.mc.logger,\n\t\t\t\t);\n\t\t\t\tmockLogger.assertMatch(\n\t\t\t\t\t[\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\teventName: revivedEventName,\n\t\t\t\t\t\t\ttimeout,\n\t\t\t\t\t\t\t...tagCodeArtifacts({\n\t\t\t\t\t\t\t\tid: nodes[3],\n\t\t\t\t\t\t\t\tfromId: nodes[2],\n\t\t\t\t\t\t\t\tpkg: testPkgPath.join(\"/\"),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\t\"revived event not generated as expected\",\n\t\t\t\t\ttrue /* inlineDetailsProp */,\n\t\t\t\t);\n\t\t\t});\n\n\t\t\t/**\n\t\t\t * Here, the base snapshot contains nodes that have timed out and the GC blob in snapshot is in old format. The\n\t\t\t * test validates that we generate errors when these nodes are used.\n\t\t\t */\n\t\t\tit(\"generates events for nodes that time out on load - old snapshot format\", async () => {\n\t\t\t\t// Create GC details for node 3's GC blob whose unreferenced time was > timeout ms ago.\n\t\t\t\t// This means this node should time out as soon as its data is loaded.\n\t\t\t\tconst node3GCDetails: IGarbageCollectionSummaryDetailsLegacy = {\n\t\t\t\t\tgcData: { gcNodes: { \"/\": [] } },\n\t\t\t\t\tunrefTimestamp: Date.now() - (timeout + 100),\n\t\t\t\t};\n\t\t\t\tconst node3Snapshot = getDummySnapshotTree();\n\t\t\t\tconst gcBlobId = \"node3GCDetails\";\n\t\t\t\tconst attributesBlobId = \"attributesBlob\";\n\t\t\t\tnode3Snapshot.blobs[gcTreeKey] = gcBlobId;\n\t\t\t\tnode3Snapshot.blobs[dataStoreAttributesBlobName] = attributesBlobId;\n\n\t\t\t\t// Create a base snapshot that contains snapshot tree of node 3.\n\t\t\t\tconst channelsTree = getDummySnapshotTree();\n\t\t\t\tchannelsTree.trees[nodes[3].slice(1)] = node3Snapshot;\n\t\t\t\tconst baseSnapshot = getDummySnapshotTree();\n\t\t\t\tbaseSnapshot.trees[channelsTreeName] = channelsTree;\n\n\t\t\t\t// Set up the getNodeGCDetails function to return the GC details for node 3 when asked by garbage collector.\n\t\t\t\tconst gcBlobMap = new Map([\n\t\t\t\t\t[gcBlobId, node3GCDetails],\n\t\t\t\t\t[attributesBlobId, {}],\n\t\t\t\t]);\n\t\t\t\tconst garbageCollector = createGCOverride(baseSnapshot, gcBlobMap);\n\n\t\t\t\t// Remove node 3's reference from node 2 so that it is still unreferenced. The GC details from the base\n\t\t\t\t// summary is not loaded until the first time GC is run, so do that immediately.\n\t\t\t\tdefaultGCData.gcNodes[nodes[2]] = [];\n\t\t\t\tawait garbageCollector.collectGarbage({});\n\n\t\t\t\t// Validate that no events are generated since none of the timeouts have passed\n\t\t\t\tgarbageCollector.nodeUpdated(nodes[3], \"Loaded\", Date.now(), testPkgPath);\n\t\t\t\tgarbageCollector.nodeUpdated(nodes[3], \"Changed\", Date.now(), testPkgPath);\n\t\t\t\tawait garbageCollector.collectGarbage({});\n\t\t\t\tmockLogger.assertMatchNone(\n\t\t\t\t\t[\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\teventName: loadedEventName,\n\t\t\t\t\t\t\ttimeout,\n\t\t\t\t\t\t\t...tagCodeArtifacts({ id: nodes[3], pkg: testPkgPath.join(\"/\") }),\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\teventName: changedEventName,\n\t\t\t\t\t\t\ttimeout,\n\t\t\t\t\t\t\t...tagCodeArtifacts({ id: nodes[3], pkg: testPkgPath.join(\"/\") }),\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\t\"all events not generated as expected\",\n\t\t\t\t\ttrue /* inlineDetailsProp */,\n\t\t\t\t);\n\n\t\t\t\t// No revived events should be logged as no timeouts should have occurred\n\t\t\t\tgarbageCollector.addedOutboundReference(nodes[2], nodes[3]);\n\t\t\t\tawait garbageCollector.collectGarbage({});\n\t\t\t\tmockLogger.assertMatchNone(\n\t\t\t\t\t[\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\teventName: revivedEventName,\n\t\t\t\t\t\t\ttimeout,\n\t\t\t\t\t\t\t...tagCodeArtifacts({\n\t\t\t\t\t\t\t\tid: nodes[3],\n\t\t\t\t\t\t\t\tfromId: nodes[2],\n\t\t\t\t\t\t\t\tpkg: testPkgPath.join(\"/\"),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\t\"revived event not generated as expected\",\n\t\t\t\t\ttrue /* inlineDetailsProp */,\n\t\t\t\t);\n\t\t\t});\n\n\t\t\t/**\n\t\t\t * Here, the base snapshot contains nodes that have timed out and the GC data in snapshot is present in multiple\n\t\t\t * blobs. The test validates that we generate errors when these nodes are used.\n\t\t\t */\n\t\t\tit(`generates events for nodes that time out on load - multi blob GC data`, async () => {\n\t\t\t\tconst gcBlobMap: Map<string, IGarbageCollectionState> = new Map();\n\t\t\t\tconst expiredTimestampMs = Date.now() - (timeout + 100);\n\n\t\t\t\t// Create three GC states to be added into separate GC blobs. Each GC state has a node whose unreferenced\n\t\t\t\t// time was > timeout ms ago. These three GC blobs are the added to the GC tree in summary.\n\t\t\t\tconst blob1Id = \"blob1\";\n\t\t\t\tconst blob1GCState: IGarbageCollectionState = { gcNodes: {} };\n\t\t\t\tblob1GCState.gcNodes[nodes[1]] = {\n\t\t\t\t\toutboundRoutes: [],\n\t\t\t\t\tunreferencedTimestampMs: expiredTimestampMs,\n\t\t\t\t};\n\t\t\t\tgcBlobMap.set(blob1Id, blob1GCState);\n\n\t\t\t\tconst blob2Id = \"blob2\";\n\t\t\t\tconst blob2GCState: IGarbageCollectionState = { gcNodes: {} };\n\t\t\t\tblob2GCState.gcNodes[nodes[2]] = {\n\t\t\t\t\toutboundRoutes: [],\n\t\t\t\t\tunreferencedTimestampMs: expiredTimestampMs,\n\t\t\t\t};\n\t\t\t\tgcBlobMap.set(blob2Id, blob2GCState);\n\n\t\t\t\tconst blob3Id = \"blob3\";\n\t\t\t\tconst blob3GCState: IGarbageCollectionState = { gcNodes: {} };\n\t\t\t\tblob3GCState.gcNodes[nodes[3]] = {\n\t\t\t\t\toutboundRoutes: [],\n\t\t\t\t\tunreferencedTimestampMs: expiredTimestampMs,\n\t\t\t\t};\n\t\t\t\tgcBlobMap.set(blob3Id, blob3GCState);\n\n\t\t\t\t// Create a GC snapshot tree and add the above three GC blob ids to it.\n\t\t\t\tconst gcSnapshotTree = getDummySnapshotTree();\n\t\t\t\tgcSnapshotTree.blobs[`${gcBlobPrefix}_${blob1Id}`] = blob1Id;\n\t\t\t\tgcSnapshotTree.blobs[`${gcBlobPrefix}_${blob2Id}`] = blob2Id;\n\t\t\t\tgcSnapshotTree.blobs[`${gcBlobPrefix}_${blob3Id}`] = blob3Id;\n\n\t\t\t\t// Create a base snapshot that contains the above GC snapshot tree.\n\t\t\t\tconst baseSnapshot = getDummySnapshotTree();\n\t\t\t\tbaseSnapshot.trees[gcTreeKey] = gcSnapshotTree;\n\n\t\t\t\tconst garbageCollector = createGCOverride(baseSnapshot, gcBlobMap);\n\n\t\t\t\t// For the nodes in the GC snapshot blobs, remove their references from the default GC data.\n\t\t\t\tdefaultGCData.gcNodes[nodes[0]] = [];\n\t\t\t\tdefaultGCData.gcNodes[nodes[1]] = [];\n\t\t\t\tdefaultGCData.gcNodes[nodes[2]] = [];\n\n\t\t\t\tawait garbageCollector.collectGarbage({});\n\n\t\t\t\t// Validate that all events are logged as expected.\n\t\t\t\tgarbageCollector.nodeUpdated(nodes[3], \"Loaded\", Date.now(), testPkgPath);\n\t\t\t\tgarbageCollector.nodeUpdated(nodes[1], \"Changed\", Date.now(), testPkgPath);\n\t\t\t\tgarbageCollector.nodeUpdated(nodes[2], \"Changed\", Date.now(), testPkgPath);\n\t\t\t\tawait garbageCollector.collectGarbage({});\n\t\t\t\tmockLogger.assertMatch(\n\t\t\t\t\t[\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\teventName: loadedEventName,\n\t\t\t\t\t\t\ttimeout,\n\t\t\t\t\t\t\t...tagCodeArtifacts({ id: nodes[3], pkg: testPkgPath.join(\"/\") }),\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\teventName: changedEventName,\n\t\t\t\t\t\t\ttimeout,\n\t\t\t\t\t\t\t...tagCodeArtifacts({ id: nodes[1], pkg: testPkgPath.join(\"/\") }),\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\teventName: changedEventName,\n\t\t\t\t\t\t\ttimeout,\n\t\t\t\t\t\t\t...tagCodeArtifacts({ id: nodes[2], pkg: testPkgPath.join(\"/\") }),\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\t\"all events not generated as expected\",\n\t\t\t\t\ttrue /* inlineDetailsProp */,\n\t\t\t\t);\n\t\t\t});\n\t\t};\n\n\t\tdescribe(\"Inactive events (summarizer container)\", () => {\n\t\t\tconst inactiveTimeoutMs = 500;\n\n\t\t\tbeforeEach(() => {\n\t\t\t\tconfigProvider.set(\n\t\t\t\t\t\"Fluid.GarbageCollection.TestOverride.InactiveTimeoutMs\",\n\t\t\t\t\tinactiveTimeoutMs,\n\t\t\t\t);\n\t\t\t});\n\n\t\t\tsummarizerContainerTests(\n\t\t\t\tinactiveTimeoutMs,\n\t\t\t\t\"inactive\",\n\t\t\t\t\"GarbageCollector:InactiveObject_Revived\",\n\t\t\t\t\"GarbageCollector:InactiveObject_Changed\",\n\t\t\t\t\"GarbageCollector:InactiveObject_Loaded\",\n\t\t\t);\n\t\t});\n\n\t\tdescribe(\"TombstoneReady events (summarizer container)\", () => {\n\t\t\tsummarizerContainerTests(\n\t\t\t\tdefaultTombstoneTimeoutMs,\n\t\t\t\t\"tombstone\",\n\t\t\t\t\"GarbageCollector:TombstoneReadyObject_Revived\",\n\t\t\t\t\"GarbageCollector:TombstoneReadyObject_Changed\",\n\t\t\t\t\"GarbageCollector:TombstoneReadyObject_Loaded\",\n\t\t\t);\n\t\t});\n\n\t\tdescribe(\"SweepReady events - No sweepGracePeriodMs (summarizer container)\", () => {\n\t\t\tsummarizerContainerTests(\n\t\t\t\tdefaultTombstoneTimeoutMs,\n\t\t\t\t\"sweep\", // Jump straight to SweepReady given 0 delay\n\t\t\t\t\"GarbageCollector:SweepReadyObject_Revived\",\n\t\t\t\t\"GarbageCollector:SweepReadyObject_Changed\",\n\t\t\t\t\"GarbageCollector:SweepReadyObject_Loaded\",\n\t\t\t\t0 /* sweepGracePeriodMsOverride */,\n\t\t\t);\n\t\t});\n\n\t\tdescribe(\"SweepReady events - with sweepGracePeriodMs delay (summarizer container)\", () => {\n\t\t\tsummarizerContainerTests(\n\t\t\t\tdefaultTombstoneTimeoutMs + defaultSweepGracePeriodMs,\n\t\t\t\t\"sweep\",\n\t\t\t\t\"GarbageCollector:SweepReadyObject_Revived\",\n\t\t\t\t\"GarbageCollector:SweepReadyObject_Changed\",\n\t\t\t\t\"GarbageCollector:SweepReadyObject_Loaded\",\n\t\t\t);\n\t\t});\n\n\t\tdescribe(\"GC version changes\", () => {\n\t\t\tfunction getSnapshotWithGCVersion(gcVersion: GCVersion) {\n\t\t\t\t// Create a snapshot tree to be used as the GC snapshot tree.\n\t\t\t\tconst gcSnapshotTree = getDummySnapshotTree();\n\t\t\t\tconst gcBlobId = \"root\";\n\t\t\t\t// Add a GC blob with key that start with `blob` to the GC snapshot tree. The blob Id for this\n\t\t\t\t// is generated by server in real scenarios but we use a static id here for testing.\n\t\t\t\tgcSnapshotTree.blobs[`${gcBlobPrefix}_${gcBlobId}`] = gcBlobId;\n\n\t\t\t\t// Create GC state with a node. This will be returned when the garbage collector asks for the GC blob\n\t\t\t\t// with `gcBlobId`.\n\t\t\t\tconst gcState: IGarbageCollectionState = { gcNodes: {} };\n\t\t\t\tconst nodeData: IGarbageCollectionNodeData = {\n\t\t\t\t\toutboundRoutes: [],\n\t\t\t\t\tunreferencedTimestampMs: 123,\n\t\t\t\t};\n\t\t\t\tgcState.gcNodes[nodes[0]] = nodeData;\n\n\t\t\t\t// Create a tombstone blob. This will be returned when the garbage collector asks for tombstone blob.\n\t\t\t\tconst gcTombstoneBlobId = \"tombstone\";\n\t\t\t\tgcSnapshotTree.blobs[gcTombstoneBlobKey] = gcTombstoneBlobId;\n\t\t\t\tconst tombstones = [nodes[0]];\n\n\t\t\t\t// Create a deleted nodes blob. This will be returned when the garbage collector asks for deleted\n\t\t\t\t// nodes blob.\n\t\t\t\tconst gcDeletedBlobId = \"deletedNodes\";\n\t\t\t\tgcSnapshotTree.blobs[gcDeletedBlobKey] = gcDeletedBlobId;\n\t\t\t\tconst deletedBlobs = [nodes[0]];\n\n\t\t\t\t// Create a snapshot that contains the GC snapshot tree.\n\t\t\t\tconst snapshotTree = getDummySnapshotTree();\n\t\t\t\tsnapshotTree.trees[gcTreeKey] = gcSnapshotTree;\n\n\t\t\t\tconst metadataBlobId = \"metadata\";\n\t\t\t\tconst metadata: IContainerRuntimeMetadata = {\n\t\t\t\t\tgcFeature: gcVersion,\n\t\t\t\t\tsummaryFormatVersion: 1,\n\t\t\t\t\tmessage: undefined,\n\t\t\t\t};\n\t\t\t\tsnapshotTree.blobs[metadataBlobName] = metadataBlobId;\n\n\t\t\t\tconst gcBlobsMap: Map<string, any> = new Map();\n\t\t\t\tgcBlobsMap.set(gcBlobId, gcState);\n\t\t\t\tgcBlobsMap.set(gcTombstoneBlobId, tombstones);\n\t\t\t\tgcBlobsMap.set(gcDeletedBlobId, deletedBlobs);\n\t\t\t\tgcBlobsMap.set(metadataBlobId, metadata);\n\n\t\t\t\treturn { snapshotTree, gcBlobsMap };\n\t\t\t}\n\n\t\t\tfunction createGCOverride(gcFeature: GCVersion) {\n\t\t\t\tconst gcMetadata: IGCMetadata = {\n\t\t\t\t\tgcFeature,\n\t\t\t\t};\n\t\t\t\tconst { snapshotTree, gcBlobsMap } = getSnapshotWithGCVersion(gcFeature);\n\t\t\t\treturn createGarbageCollector({\n\t\t\t\t\tcreateParams: { baseSnapshot: snapshotTree },\n\t\t\t\t\tgcBlobsMap,\n\t\t\t\t\tgcMetadata,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tit(\"reads all GC data from base snapshot when GC version does not change\", async () => {\n\t\t\t\tconst garbageCollector = createGCOverride(stableGCVersion);\n\n\t\t\t\t// GC state, tombstone state and deleted nodes should all be read from base snapshot.\n\t\t\t\tconst baseSnapshotData = await garbageCollector.baseSnapshotDataP;\n\t\t\t\tassert(\n\t\t\t\t\tbaseSnapshotData !== undefined,\n\t\t\t\t\t\"base snapshot was not initialized correctly\",\n\t\t\t\t);\n\t\t\t\tassert(\n\t\t\t\t\tbaseSnapshotData.gcState !== undefined,\n\t\t\t\t\t\"GC state in base snapshot should not be available\",\n\t\t\t\t);\n\t\t\t\tassert(\n\t\t\t\t\tbaseSnapshotData.tombstones !== undefined,\n\t\t\t\t\t\"Tombstone state in base snapshot should be available\",\n\t\t\t\t);\n\t\t\t\tassert(\n\t\t\t\t\tbaseSnapshotData.deletedNodes !== undefined,\n\t\t\t\t\t\"Deleted nodes in base snapshot should be available\",\n\t\t\t\t);\n\n\t\t\t\t// Initialize from the base state and validate that tombstones and deleted state both have one entry\n\t\t\t\t// as per the base snapshot.\n\t\t\t\tawait garbageCollector.initializeBaseState();\n\t\t\t\tassert.strictEqual(\n\t\t\t\t\tgarbageCollector.tombstones.length,\n\t\t\t\t\t1,\n\t\t\t\t\t\"Expecting 1 tombstone node\",\n\t\t\t\t);\n\t\t\t\tassert.strictEqual(\n\t\t\t\t\tgarbageCollector.deletedNodes.size,\n\t\t\t\t\t1,\n\t\t\t\t\t\"Expecting 1 deleted node\",\n\t\t\t\t);\n\t\t\t});\n\n\t\t\tit(\"discards GC state and tombstone state in base snapshot when GC version changes\", async () => {\n\t\t\t\tconst garbageCollector = createGCOverride(stableGCVersion + 1);\n\n\t\t\t\t// GC state and tombstone state should be discarded but deleted nodes should be read from base snapshot.\n\t\t\t\tconst baseSnapshotData = await garbageCollector.baseSnapshotDataP;\n\t\t\t\tassert(\n\t\t\t\t\tbaseSnapshotData !== undefined,\n\t\t\t\t\t\"base snapshot was not initialized correctly\",\n\t\t\t\t);\n\t\t\t\tassert(\n\t\t\t\t\tbaseSnapshotData.gcState === undefined,\n\t\t\t\t\t\"GC state in base snapshot should be undefined when GC version changes\",\n\t\t\t\t);\n\t\t\t\tassert(\n\t\t\t\t\tbaseSnapshotData.tombstones === undefined,\n\t\t\t\t\t\"Tombstone state in base snapshot should be undefined when GC version changes\",\n\t\t\t\t);\n\t\t\t\tassert(\n\t\t\t\t\tbaseSnapshotData.deletedNodes !== undefined,\n\t\t\t\t\t\"Deleted nodes in base snapshot should be available\",\n\t\t\t\t);\n\n\t\t\t\t// Initialize from the base state and validate that tombstones has 0 entry because it was discarded.\n\t\t\t\t// Deleted nodes should have one entry because it is still used.\n\t\t\t\tawait garbageCollector.initializeBaseState();\n\t\t\t\tassert.strictEqual(\n\t\t\t\t\tgarbageCollector.tombstones.length,\n\t\t\t\t\t0,\n\t\t\t\t\t\"Expecting no tombstone nodes\",\n\t\t\t\t);\n\t\t\t\tassert.strictEqual(\n\t\t\t\t\tgarbageCollector.deletedNodes.size,\n\t\t\t\t\t1,\n\t\t\t\t\t\"Expecting 1 deleted node\",\n\t\t\t\t);\n\t\t\t});\n\t\t});\n\n\t\tit(\"Unreferenced nodes transition through Inactive, TombstoneReady and SweepReady states\", async () => {\n\t\t\tconst inactiveTimeoutMs = 500;\n\t\t\tconfigProvider.set(\n\t\t\t\t\"Fluid.GarbageCollection.TestOverride.InactiveTimeoutMs\",\n\t\t\t\tinactiveTimeoutMs,\n\t\t\t);\n\n\t\t\tconst garbageCollector = createGarbageCollector({});\n\n\t\t\tfunction validateUnreferencedStates(\n\t\t\t\texpectedUnreferencedStates: Record<number, UnreferencedState>,\n\t\t\t) {\n\t\t\t\t// Base assumption is that all 6 nodes are still referenced (no state tracker aka 'undefined')\n\t\t\t\t// Then update this with the given expected unreferenced states\n\t\t\t\tconst expectedStates = Object.assign(\n\t\t\t\t\t[undefined, undefined, undefined, undefined, undefined, undefined],\n\t\t\t\t\texpectedUnreferencedStates,\n\t\t\t\t);\n\t\t\t\tfor (const [id, state] of expectedStates.entries()) {\n\t\t\t\t\tassert.equal(\n\t\t\t\t\t\tgarbageCollector.unreferencedNodesState.get(nodes[id])?.state,\n\t\t\t\t\t\tstate,\n\t\t\t\t\t\t`node ${id} should be ${state ?? \"referenced\"}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove node 2's reference from node 1. This should make node 2 and node 3 unreferenced.\n\t\t\tdefaultGCData.gcNodes[nodes[1]] = [];\n\t\t\tawait garbageCollector.collectGarbage({});\n\n\t\t\t// Advance the clock to trigger inactive timeout and validate that we get inactive events.\n\t\t\tclock.tick(inactiveTimeoutMs + 1);\n\t\t\tawait garbageCollector.collectGarbage({});\n\t\t\tvalidateUnreferencedStates({ 2: \"Inactive\", 3: \"Inactive\" });\n\n\t\t\t// Advance the clock to trigger tombstoneTimeoutMs and validate that we get tombstone ready events.\n\t\t\tclock.tick(defaultTombstoneTimeoutMs - inactiveTimeoutMs);\n\t\t\tawait garbageCollector.collectGarbage({});\n\t\t\tvalidateUnreferencedStates({ 2: \"TombstoneReady\", 3: \"TombstoneReady\" });\n\n\t\t\t// Advance the clock the sweep delay and validate that we get sweep ready events.\n\t\t\tclock.tick(defaultSweepGracePeriodMs);\n\t\t\tawait garbageCollector.collectGarbage({});\n\t\t\tvalidateUnreferencedStates({ 2: \"SweepReady\", 3: \"SweepReady\" });\n\t\t});\n\t});\n\n\tdescribe(\"Deleted blobs in GC summary tree\", () => {\n\t\tit(\"correctly reads and write deleted blobs in summary\", async () => {\n\t\t\t// Set up the GC reference graph to have something to work with.\n\t\t\tdefaultGCData.gcNodes[\"/\"] = [nodes[0]];\n\n\t\t\t// Create a snapshot tree to be used as the GC snapshot tree.\n\t\t\tconst gcSnapshotTree = getDummySnapshotTree();\n\t\t\t// Add a blob to the tree for deleted nodes.\n\t\t\tconst deletedNodesBlobId = \"deletedNodes\";\n\t\t\tgcSnapshotTree.blobs[gcDeletedBlobKey] = deletedNodesBlobId;\n\t\t\tconst deletedNodeIds = [...nodes];\n\t\t\t// Add deleted nodes list the blobs map that will service read and parse blob calls from GC.\n\t\t\tconst gcBlobsMap: Map<string, string[]> = new Map([\n\t\t\t\t[deletedNodesBlobId, deletedNodeIds],\n\t\t\t]);\n\t\t\t// Create a base snapshot that contains the GC snapshot tree.\n\t\t\tconst baseSnapshot = getDummySnapshotTree();\n\t\t\tbaseSnapshot.trees[gcTreeKey] = gcSnapshotTree;\n\n\t\t\t// Create and initialize garbage collector.\n\t\t\tconst garbageCollector = createGarbageCollector({\n\t\t\t\tcreateParams: { baseSnapshot },\n\t\t\t\tgcBlobsMap,\n\t\t\t});\n\t\t\tawait garbageCollector.initializeBaseState();\n\n\t\t\t// The nodes in deletedNodeIds should be marked as deleted.\n\t\t\tfor (const nodeId of deletedNodeIds) {\n\t\t\t\tassert(\n\t\t\t\t\tgarbageCollector.isNodeDeleted(nodeId) === true,\n\t\t\t\t\t`${nodeId} should be marked deleted`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tawait garbageCollector.collectGarbage({});\n\t\t\t// Summarize with fullTree as true so that the deleted nodes are written as a blob and can be validated.\n\t\t\tconst summaryTree = garbageCollector.summarize(\n\t\t\t\ttrue /* fullTree */,\n\t\t\t\ttrue /* trackState */,\n\t\t\t);\n\t\t\tassert(summaryTree?.summary.type === SummaryType.Tree, \"The summary should be a tree\");\n\n\t\t\t// Get the deleted node ids from summary and validate that its the same as the one GC loaded from.\n\t\t\tconst deletedNodesBlob = summaryTree.summary.tree[gcDeletedBlobKey];\n\t\t\tassert(\n\t\t\t\tdeletedNodesBlob.type === SummaryType.Blob,\n\t\t\t\t\"Deleted blob not present in summary\",\n\t\t\t);\n\t\t\tconst deletedNodeIdsInSummary = JSON.parse(\n\t\t\t\tdeletedNodesBlob.content as string,\n\t\t\t) as string[];\n\t\t\tassert.deepStrictEqual(\n\t\t\t\tdeletedNodeIdsInSummary,\n\t\t\t\tdeletedNodeIds,\n\t\t\t\t\"Unexpected deleted nodes in summary\",\n\t\t\t);\n\t\t});\n\n\t\tit(\"writes handle for deleted blobs when its unchanged\", async () => {\n\t\t\t// Set up the GC reference graph to have something to work with.\n\t\t\tdefaultGCData.gcNodes[\"/\"] = [nodes[0]];\n\n\t\t\t// Create a snapshot tree to be used as the GC snapshot tree.\n\t\t\tconst gcSnapshotTree = getDummySnapshotTree();\n\t\t\t// Add a blob to the tree for deleted nodes.\n\t\t\tconst deletedNodesBlobId = \"deletedNodes\";\n\t\t\tgcSnapshotTree.blobs[gcDeletedBlobKey] = deletedNodesBlobId;\n\t\t\tconst deletedNodeIds = [...nodes];\n\t\t\t// Add deleted nodes list the blobs map that will service read and parse blob calls from GC.\n\t\t\tconst gcBlobsMap: Map<string, string[]> = new Map([\n\t\t\t\t[deletedNodesBlobId, deletedNodeIds],\n\t\t\t]);\n\t\t\t// Create a base snapshot that contains the GC snapshot tree.\n\t\t\tconst baseSnapshot = getDummySnapshotTree();\n\t\t\tbaseSnapshot.trees[gcTreeKey] = gcSnapshotTree;\n\n\t\t\t// Create and initialize garbage collector.\n\t\t\tconst garbageCollector = createGarbageCollector({\n\t\t\t\tcreateParams: { baseSnapshot },\n\t\t\t\tgcBlobsMap,\n\t\t\t});\n\t\t\tawait garbageCollector.initializeBaseState();\n\n\t\t\t// Run GC and summarize. The summary should contain the deleted nodes.\n\t\t\tawait garbageCollector.collectGarbage({});\n\t\t\tconst gcSummary = garbageCollector.summarize(\n\t\t\t\tfalse /* fullTree */,\n\t\t\t\ttrue /* trackState */,\n\t\t\t);\n\t\t\tassert(gcSummary?.summary.type === SummaryType.Tree, \"The summary should be a tree\");\n\n\t\t\t// Get the deleted node ids from summary and validate that its the same as the one GC loaded from.\n\t\t\tconst deletedNodesBlob = gcSummary.summary.tree[gcDeletedBlobKey];\n\t\t\tassert(\n\t\t\t\tdeletedNodesBlob.type === SummaryType.Handle,\n\t\t\t\t\"Deleted nodes state should be a handle\",\n\t\t\t);\n\n\t\t\tawait garbageCollector.refreshLatestSummary({\n\t\t\t\tisSummaryTracked: true,\n\t\t\t\tisSummaryNewer: true,\n\t\t\t});\n\n\t\t\t// Run GC and summarize again. The whole GC summary should now be a summary handle.\n\t\t\tawait garbageCollector.collectGarbage({});\n\t\t\tconst gcSummary2 = garbageCollector.summarize(\n\t\t\t\tfalse /* fullTree */,\n\t\t\t\ttrue /* trackState */,\n\t\t\t);\n\t\t\tassert(\n\t\t\t\tgcSummary2?.summary.type === SummaryType.Handle,\n\t\t\t\t\"The summary should be a handle\",\n\t\t\t);\n\t\t});\n\t});\n\n\tdescribe(\"GC completed runs\", () => {\n\t\tconst gcEndEvent = \"GarbageCollector:GarbageCollection_end\";\n\n\t\tit(\"increments GC completed runs in logged events correctly\", async () => {\n\t\t\tconst garbageCollector = createGarbageCollector();\n\n\t\t\tawait garbageCollector.collectGarbage({});\n\t\t\tmockLogger.assertMatch(\n\t\t\t\t[{ eventName: gcEndEvent, completedGCRuns: 0 }],\n\t\t\t\t\"completedGCRuns should be 0 since this event was logged before first GC run completed\",\n\t\t\t);\n\n\t\t\tawait garbageCollector.collectGarbage({});\n\t\t\tmockLogger.assertMatch(\n\t\t\t\t[{ eventName: gcEndEvent, completedGCRuns: 1 }],\n\t\t\t\t\"completedGCRuns should be 1 since this event was logged after first GC run completed\",\n\t\t\t);\n\n\t\t\tawait garbageCollector.collectGarbage({});\n\t\t\tmockLogger.assertMatch(\n\t\t\t\t[{ eventName: gcEndEvent, completedGCRuns: 2 }],\n\t\t\t\t\"completedGCRuns should be 2 since this event was logged after second GC run completed\",\n\t\t\t);\n\n\t\t\t// The GC run count should reset for new garbage collector.\n\t\t\tconst garbageCollector2 = createGarbageCollector();\n\t\t\tawait garbageCollector2.collectGarbage({});\n\t\t\tmockLogger.assertMatch(\n\t\t\t\t[{ eventName: gcEndEvent, completedGCRuns: 0 }],\n\t\t\t\t\"completedGCRuns should be 0 since this event was logged before first GC run in new garbage collector\",\n\t\t\t);\n\t\t});\n\t});\n\n\t/*\n\t * These tests validate scenarios where nodes that are referenced between summaries have their unreferenced\n\t * timestamp updated. These scenarios fall into the following categories:\n\t * 1. Nodes transition from unreferenced -> referenced -> unreferenced between 2 summaries - In these scenarios\n\t * when GC runs, it should detect that the node was referenced and update its unreferenced timestamp.\n\t * 2. Unreferenced nodes are referenced from other unreferenced nodes - In this case, even though the node remains\n\t * unreferenced, its unreferenced timestamp should be updated.\n\t *\n\t * In these tests, V = nodes and E = edges between nodes. Root nodes that are always referenced are marked as *.\n\t */\n\tdescribe(\"References between summaries\", () => {\n\t\tlet garbageCollector: IGarbageCollector;\n\t\tconst nodeA = \"/A\";\n\t\tconst nodeB = \"/B\";\n\t\tconst nodeC = \"/C\";\n\t\tconst nodeD = \"/D\";\n\t\tconst nodeE = \"/A/E\";\n\n\t\t// Runs GC and returns the unreferenced timestamps of all nodes in the GC summary.\n\t\tasync function getUnreferencedTimestamps() {\n\t\t\t// Advance the clock by 1 tick so that the unreferenced timestamp is updated in between runs.\n\t\t\tclock.tick(1);\n\n\t\t\tawait garbageCollector.collectGarbage({});\n\n\t\t\tconst summaryTree = garbageCollector.summarize(true, false)?.summary;\n\t\t\tassert(summaryTree !== undefined, \"Nothing to summarize after running GC\");\n\t\t\tassert(summaryTree.type === SummaryType.Tree, \"Expecting a summary tree!\");\n\n\t\t\tlet rootGCState: IGarbageCollectionState = { gcNodes: {} };\n\t\t\tfor (const key of Object.keys(summaryTree.tree)) {\n\t\t\t\t// Skip blobs that do not start with the GC prefix.\n\t\t\t\tif (!key.startsWith(gcBlobPrefix)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst gcBlob = summaryTree.tree[key];\n\t\t\t\tassert(gcBlob?.type === SummaryType.Blob, `GC blob not available`);\n\t\t\t\tconst gcState = JSON.parse(gcBlob.content as string) as IGarbageCollectionState;\n\t\t\t\t// Merge the GC state of this blob into the root GC state.\n\t\t\t\trootGCState = concatGarbageCollectionStates(rootGCState, gcState);\n\t\t\t}\n\t\t\tconst nodeTimestamps: Map<string, number | undefined> = new Map();\n\t\t\tfor (const [nodeId, nodeData] of Object.entries(rootGCState.gcNodes)) {\n\t\t\t\tnodeTimestamps.set(nodeId, nodeData.unreferencedTimestampMs);\n\t\t\t}\n\t\t\treturn nodeTimestamps;\n\t\t}\n\n\t\tbeforeEach(() => {\n\t\t\tdefaultGCData.gcNodes = {};\n\t\t\tgarbageCollector = createGarbageCollector();\n\t\t});\n\n\t\tdescribe(\"Nodes transitioning from unreferenced -> referenced -> unreferenced\", () => {\n\t\t\t/**\n\t\t\t * Validates that we can detect references that were added and then removed.\n\t\t\t * 1. Summary 1 at t1. V = [A*, B]. E = []. B has unreferenced time t1.\n\t\t\t * 2. Reference from A to B added. E = [A -\\> B].\n\t\t\t * 3. Reference from A to B removed. E = [].\n\t\t\t * 4. Summary 2 at t2. V = [A*, B]. E = []. B has unreferenced time t2.\n\t\t\t * Validates that the unreferenced time for B is t2 which is \\> t1.\n\t\t\t */\n\t\t\tit(`Scenario 1 - Reference added and then removed`, async () => {\n\t\t\t\t// Initialize nodes A and B.\n\t\t\t\tdefaultGCData.gcNodes[\"/\"] = [nodeA];\n\t\t\t\tdefaultGCData.gcNodes[nodeA] = [];\n\t\t\t\tdefaultGCData.gcNodes[nodeB] = [];\n\n\t\t\t\t// 1. Run GC and generate summary 1. E = [].\n\t\t\t\tconst timestamps1 = await getUnreferencedTimestamps();\n\t\t\t\tassert(timestamps1.get(nodeA) === undefined, \"A should be referenced\");\n\n\t\t\t\tconst nodeBTime1 = timestamps1.get(nodeB);\n\t\t\t\tassert(nodeBTime1 !== undefined, \"B should have unreferenced timestamp\");\n\n\t\t\t\t// 2. Add reference from A to B. E = [A -\\> B].\n\t\t\t\tgarbageCollector.addedOutboundReference(nodeA, nodeB);\n\t\t\t\tdefaultGCData.gcNodes[nodeA] = [nodeB];\n\n\t\t\t\t// 3. Remove reference from A to B. E = [].\n\t\t\t\tdefaultGCData.gcNodes[nodeA] = [];\n\n\t\t\t\t// 4. Run GC and generate summary 2. E = [].\n\t\t\t\tconst timestamps2 = await getUnreferencedTimestamps();\n\t\t\t\tassert(timestamps2.get(nodeA) === undefined, \"A should be referenced\");\n\n\t\t\t\tconst nodeBTime2 = timestamps2.get(nodeB);\n\n\t\t\t\tassert(\n\t\t\t\t\tnodeBTime2 !== undefined && nodeBTime2 > nodeBTime1,\n\t\t\t\t\t\"B's timestamp should have updated\",\n\t\t\t\t);\n\t\t\t});\n\n\t\t\t/**\n\t\t\t * Validates that we can detect references that were added transitively and then removed.\n\t\t\t * 1. Summary 1 at t1. V = [A*, B, C]. E = [B -\\> C]. B and C have unreferenced time t2.\n\t\t\t * 2. Reference from A to B added. E = [A -\\> B, B -\\> C].\n\t\t\t * 3. Reference from B to C removed. E = [A -\\> B].\n\t\t\t * 4. Reference from A to B removed. E = [].\n\t\t\t * 5. Summary 2 at t2. V = [A*, B, C]. E = []. B and C have unreferenced time t2.\n\t\t\t * Validates that the unreferenced time for B and C is t2 which is \\> t1.\n\t\t\t */\n\t\t\tit(`Scenario 2 - Reference transitively added and removed`, async () => {\n\t\t\t\t// Initialize nodes A, B and C.\n\t\t\t\tdefaultGCData.gcNodes[\"/\"] = [nodeA];\n\t\t\t\tdefaultGCData.gcNodes[nodeA] = [];\n\t\t\t\tdefaultGCData.gcNodes[nodeB] = [nodeC];\n\t\t\t\tdefaultGCData.gcNodes[nodeC] = [];\n\n\t\t\t\t// 1. Run GC and generate summary 1. E = [B -\\> C].\n\t\t\t\tconst timestamps1 = await getUnreferencedTimestamps();\n\t\t\t\tassert(timestamps1.get(nodeA) === undefined, \"A should be referenced\");\n\n\t\t\t\tconst nodeBTime1 = timestamps1.get(nodeB);\n\t\t\t\tconst nodeCTime1 = timestamps1.get(nodeC);\n\t\t\t\tassert(nodeBTime1 !== undefined, \"B should have unreferenced timestamp\");\n\t\t\t\tassert(nodeCTime1 !== undefined, \"C should have unreferenced timestamp\");\n\n\t\t\t\t// 2. Add reference from A to B. E = [A -\\> B, B -\\> C].\n\t\t\t\tgarbageCollector.addedOutboundReference(nodeA, nodeB);\n\t\t\t\tdefaultGCData.gcNodes[nodeA] = [nodeB];\n\n\t\t\t\t// 3. Remove reference from B to C. E = [A -\\> B].\n\t\t\t\tdefaultGCData.gcNodes[nodeB] = [];\n\n\t\t\t\t// 4. Remove reference from A to B. E = [].\n\t\t\t\tdefaultGCData.gcNodes[nodeA] = [];\n\n\t\t\t\t// 5. Run GC and generate summary 2. E = [].\n\t\t\t\tconst timestamps2 = await getUnreferencedTimestamps();\n\t\t\t\tassert(timestamps2.get(nodeA) === undefined, \"A should be referenced\");\n\n\t\t\t\tconst nodeBTime2 = timestamps2.get(nodeB);\n\t\t\t\tconst nodeCTime2 = timestamps2.get(nodeC);\n\t\t\t\tassert(\n\t\t\t\t\tnodeBTime2 !== undefined && nodeBTime2 > nodeBTime1,\n\t\t\t\t\t\"B's timestamp should have updated\",\n\t\t\t\t);\n\t\t\t\tassert(\n\t\t\t\t\tnodeCTime2 !== undefined && nodeCTime2 > nodeCTime1,\n\t\t\t\t\t\"C's timestamp should have updated\",\n\t\t\t\t);\n\t\t\t});\n\n\t\t\t/**\n\t\t\t * Validates that we can detect chain of references in which the first reference was added and then removed.\n\t\t\t * 1. Summary 1 at t1. V = [A*, B, C, D]. E = [B -\\> C, C -\\> D]. B, C and D have unreferenced time t2.\n\t\t\t * 2. Reference from A to B added. E = [A -\\> B, B -\\> C, C -\\> D].\n\t\t\t * 3. Reference from A to B removed. E = [B -\\> C, C -\\> D].\n\t\t\t * 4. Summary 2 at t2. V = [A*, B, C, D]. E = [B -\\> C, C -\\> D]. B, C and D have unreferenced time t2.\n\t\t\t * Validates that the unreferenced time for B, C and D is t2 which is \\> t1.\n\t\t\t */\n\t\t\tit(`Scenario 3 - Reference added through chain of references and removed`, async () => {\n\t\t\t\t// Initialize nodes A, B, C and D.\n\t\t\t\tdefaultGCData.gcNodes[\"/\"] = [nodeA];\n\t\t\t\tdefaultGCData.gcNodes[nodeA] = [];\n\t\t\t\tdefaultGCData.gcNodes[nodeB] = [nodeC];\n\t\t\t\tdefaultGCData.gcNodes[nodeC] = [nodeD];\n\t\t\t\tdefaultGCData.gcNodes[nodeD] = [];\n\n\t\t\t\t// 1. Run GC and generate summary 1. E = [B -\\> C, C -\\> D].\n\t\t\t\tconst timestamps1 = await getUnreferencedTimestamps();\n\t\t\t\tassert(timestamps1.get(nodeA) === undefined, \"A should be referenced\");\n\n\t\t\t\tconst nodeBTime1 = timestamps1.get(nodeB);\n\t\t\t\tconst nodeCTime1 = timestamps1.get(nodeC);\n\t\t\t\tconst nodeDTime1 = timestamps1.get(nodeD);\n\t\t\t\tassert(nodeBTime1 !== undefined, \"B should have unreferenced timestamp\");\n\t\t\t\tassert(nodeCTime1 !== undefined, \"C should have unreferenced timestamp\");\n\t\t\t\tassert(nodeDTime1 !== undefined, \"D should have unreferenced timestamp\");\n\n\t\t\t\t// 2. Add reference from A to B. E = [A -\\> B, B -\\> C, C -\\> D].\n\t\t\t\tgarbageCollector.addedOutboundReference(nodeA, nodeB);\n\t\t\t\tdefaultGCData.gcNodes[nodeA] = [nodeB];\n\n\t\t\t\t// 3. Remove reference from A to B. E = [B -\\> C, C -\\> D].\n\t\t\t\tdefaultGCData.gcNodes[nodeA] = [];\n\n\t\t\t\t// 4. Run GC and generate summary 2. E = [B -\\> C, C -\\> D].\n\t\t\t\tconst timestamps2 = await getUnreferencedTimestamps();\n\t\t\t\tassert(timestamps2.get(nodeA) === undefined, \"A should be referenced\");\n\n\t\t\t\tconst nodeBTime2 = timestamps2.get(nodeB);\n\t\t\t\tconst nodeCTime2 = timestamps2.get(nodeC);\n\t\t\t\tconst nodeDTime2 = timestamps2.get(nodeD);\n\t\t\t\tassert(\n\t\t\t\t\tnodeBTime2 !== undefined && nodeBTime2 > nodeBTime1,\n\t\t\t\t\t\"B's timestamp should have updated\",\n\t\t\t\t);\n\t\t\t\tassert(\n\t\t\t\t\tnodeCTime2 !== undefined && nodeCTime2 > nodeCTime1,\n\t\t\t\t\t\"C's timestamp should have updated\",\n\t\t\t\t);\n\t\t\t\tassert(\n\t\t\t\t\tnodeDTime2 !== undefined && nodeDTime2 > nodeDTime1,\n\t\t\t\t\t\"D's timestamp should have updated\",\n\t\t\t\t);\n\t\t\t});\n\n\t\t\t/**\n\t\t\t * Validates that we can detect references that were added and removed via new nodes.\n\t\t\t * 1. Summary 1 at t1. V = [A*, C]. E = []. C has unreferenced time t1.\n\t\t\t * 2. Node B is created. E = [].\n\t\t\t * 3. Reference from A to B added. E = [A -\\> B].\n\t\t\t * 4. Reference from B to C added. E = [A -\\> B, B -\\> C].\n\t\t\t * 5. Reference from B to C removed. E = [A -\\> B].\n\t\t\t * 6. Summary 2 at t2. V = [A*, B, C]. E = [A -\\> B]. C has unreferenced time t2.\n\t\t\t * Validates that the unreferenced time for C is t2 which is \\> t1.\n\t\t\t */\n\t\t\tit(`Scenario 4 - Reference added via new nodes and removed`, async () => {\n\t\t\t\t// Initialize nodes A, B and C.\n\t\t\t\tdefaultGCData.gcNodes[\"/\"] = [nodeA];\n\t\t\t\tdefaultGCData.gcNodes[nodeA] = [];\n\t\t\t\tdefaultGCData.gcNodes[nodeC] = [];\n\n\t\t\t\t// 1. Run GC and generate summary 1. E = [].\n\t\t\t\tconst timestamps1 = await getUnreferencedTimestamps();\n\t\t\t\tassert(timestamps1.get(nodeA) === undefined, \"A should be referenced\");\n\n\t\t\t\tconst nodeCTime1 = timestamps1.get(nodeC);\n\t\t\t\tassert(nodeCTime1 !== undefined, \"C should have unreferenced timestamp\");\n\n\t\t\t\t// 2. Create node B, i.e., add B to GC data. E = [].\n\t\t\t\tdefaultGCData.gcNodes[nodeB] = [];\n\n\t\t\t\t// 3. Add reference from A to B. E = [A -\\> B].\n\t\t\t\tgarbageCollector.addedOutboundReference(nodeA, nodeB);\n\t\t\t\tdefaultGCData.gcNodes[nodeA] = [nodeB];\n\n\t\t\t\t// 4. Add reference from B to C. E = [A -\\> B, B -\\> C].\n\t\t\t\tgarbageCollector.addedOutboundReference(nodeB, nodeC);\n\t\t\t\tdefaultGCData.gcNodes[nodeB] = [nodeC];\n\n\t\t\t\t// 5. Remove reference from B to C. E = [A -\\> B].\n\t\t\t\tdefaultGCData.gcNodes[nodeB] = [];\n\n\t\t\t\t// 6. Run GC and generate summary 2. E = [A -\\> B].\n\t\t\t\tconst timestamps2 = await getUnreferencedTimestamps();\n\t\t\t\tassert(timestamps2.get(nodeA) === undefined, \"A should be referenced\");\n\t\t\t\tassert(timestamps2.get(nodeB) === undefined, \"B should be referenced\");\n\n\t\t\t\tconst nodeCTime2 = timestamps2.get(nodeC);\n\t\t\t\tassert(\n\t\t\t\t\tnodeCTime2 !== undefined && nodeCTime2 > nodeCTime1,\n\t\t\t\t\t\"C's timestamp should have updated\",\n\t\t\t\t);\n\t\t\t});\n\n\t\t\t/**\n\t\t\t * Validates that we can detect multiple references that were added and then removed by the same node.\n\t\t\t * 1. Summary 1 at t1. V = [A*, B, C]. E = []. B and C have unreferenced time t1.\n\t\t\t * 2. Reference from A to B added. E = [A -\\> B].\n\t\t\t * 3. Reference from A to C added. E = [A -\\> B, A -\\> C].\n\t\t\t * 4. Reference from A to B removed. E = [A -\\> C].\n\t\t\t * 5. Reference from A to C removed. E = [].\n\t\t\t * 6. Summary 2 at t2. V = [A*, B]. E = []. B and C have unreferenced time t2.\n\t\t\t * Validates that the unreferenced time for B and C is t2 which is \\> t1.\n\t\t\t */\n\t\t\tit(`Scenario 5 - Multiple references added and then removed by same node`, async () => {\n\t\t\t\t// Initialize nodes A, B and C.\n\t\t\t\tdefaultGCData.gcNodes[\"/\"] = [nodeA];\n\t\t\t\tdefaultGCData.gcNodes[nodeA] = [];\n\t\t\t\tdefaultGCData.gcNodes[nodeB] = [];\n\t\t\t\tdefaultGCData.gcNodes[nodeC] = [];\n\n\t\t\t\t// 1. Run GC and generate summary 1. E = [].\n\t\t\t\tconst timestamps1 = await getUnreferencedTimestamps();\n\t\t\t\tassert(timestamps1.get(nodeA) === undefined, \"A should be referenced\");\n\n\t\t\t\tconst nodeBTime1 = timestamps1.get(nodeB);\n\t\t\t\tconst nodeCTime1 = timestamps1.get(nodeC);\n\t\t\t\tassert(nodeBTime1 !== undefined, \"B should have unreferenced timestamp\");\n\t\t\t\tassert(nodeCTime1 !== undefined, \"C should have unreferenced timestamp\");\n\n\t\t\t\t// 2. Add reference from A to B. E = [A -\\> B].\n\t\t\t\tgarbageCollector.addedOutboundReference(nodeA, nodeB);\n\t\t\t\tdefaultGCData.gcNodes[nodeA] = [nodeB];\n\n\t\t\t\t// 3. Add reference from A to C. E = [A -\\> B, A -\\> C].\n\t\t\t\tgarbageCollector.addedOutboundReference(nodeA, nodeC);\n\t\t\t\tdefaultGCData.gcNodes[nodeA] = [nodeB, nodeC];\n\n\t\t\t\t// 4. Remove reference from A to B. E = [A -\\> C].\n\t\t\t\tdefaultGCData.gcNodes[nodeA] = [nodeC];\n\n\t\t\t\t// 5. Remove reference from A to C. E = [].\n\t\t\t\tdefaultGCData.gcNodes[nodeA] = [];\n\n\t\t\t\t// 6. Run GC and generate summary 2. E = [].\n\t\t\t\tconst timestamps2 = await getUnreferencedTimestamps();\n\t\t\t\tassert(timestamps2.get(nodeA) === undefined, \"A should be referenced\");\n\n\t\t\t\tconst nodeBTime2 = timestamps2.get(nodeB);\n\t\t\t\tconst nodeCTime2 = timestamps2.get(nodeC);\n\t\t\t\tassert(\n\t\t\t\t\tnodeCTime2 !== undefined && nodeCTime2 > nodeCTime1,\n\t\t\t\t\t\"C's timestamp should have updated\",\n\t\t\t\t);\n\t\t\t\tassert(\n\t\t\t\t\tnodeBTime2 !== undefined && nodeBTime2 > nodeBTime1,\n\t\t\t\t\t\"B's timestamp should have updated\",\n\t\t\t\t);\n\t\t\t});\n\n\t\t\t/**\n\t\t\t * Validates that we generate error on detecting reference during GC that was not notified explicitly.\n\t\t\t * 1. Summary 1 at t1. V = [A*]. E = [].\n\t\t\t * 2. Node B is created. E = [].\n\t\t\t * 3. Reference from A to B added without notifying GC. E = [A -\\> B].\n\t\t\t * 4. Summary 2 at t2. V = [A*, B]. E = [A -\\> B].\n\t\t\t * Validates that we log an error since B is detected as a referenced node but its reference was notified\n\t\t\t * to GC.\n\t\t\t */\n\t\t\tit(`Scenario 6 - Reference added without notifying GC`, async () => {\n\t\t\t\t// Initialize nodes A & D.\n\t\t\t\tdefaultGCData.gcNodes[\"/\"] = [nodeA, nodeD];\n\t\t\t\tdefaultGCData.gcNodes[nodeA] = [];\n\t\t\t\tdefaultGCData.gcNodes[nodeD] = [];\n\n\t\t\t\t// 1. Run GC and generate summary 1. E = [].\n\t\t\t\tconst timestamps1 = await getUnreferencedTimestamps();\n\t\t\t\tassert(timestamps1.get(nodeA) === undefined, \"A should be referenced\");\n\t\t\t\tassert(timestamps1.get(nodeD) === undefined, \"D should be referenced\");\n\n\t\t\t\t// 2. Create nodes B & C. E = [].\n\t\t\t\tdefaultGCData.gcNodes[nodeB] = [];\n\t\t\t\tdefaultGCData.gcNodes[nodeC] = [];\n\n\t\t\t\t// 3. Add reference from A to B, A to C, A to E, D to C, and E to A without calling addedOutboundReference.\n\t\t\t\t// E = [A -\\> B, A -\\> C, A -\\> E, D -\\> C, E -\\> A].\n\t\t\t\tdefaultGCData.gcNodes[nodeA] = [nodeB, nodeC, nodeE];\n\t\t\t\tdefaultGCData.gcNodes[nodeD] = [nodeC];\n\t\t\t\tdefaultGCData.gcNodes[nodeE] = [nodeA];\n\n\t\t\t\t// 4. Add reference from A to D with calling addedOutboundReference\n\t\t\t\tdefaultGCData.gcNodes[nodeA].push(nodeD);\n\t\t\t\tgarbageCollector.addedOutboundReference(nodeA, nodeD);\n\n\t\t\t\t// 5. Run GC and generate summary 2. E = [A -\\> B, A -\\> C, A -\\> E, D -\\> C, E -\\> A].\n\t\t\t\tawait getUnreferencedTimestamps();\n\n\t\t\t\t// Validate that we got the \"gcUnknownOutboundReferences\" error.\n\t\t\t\tconst unknownReferencesEvent = \"GarbageCollector:gcUnknownOutboundReferences\";\n\t\t\t\tconst eventsFound = mockLogger.matchEvents(\n\t\t\t\t\t[\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\teventName: unknownReferencesEvent,\n\t\t\t\t\t\t\t...tagCodeArtifacts({\n\t\t\t\t\t\t\t\tid: \"/A\",\n\t\t\t\t\t\t\t\troutes: JSON.stringify([\"/B\", \"/C\"]),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\teventName: unknownReferencesEvent,\n\t\t\t\t\t\t\t...tagCodeArtifacts({\n\t\t\t\t\t\t\t\tid: \"/D\",\n\t\t\t\t\t\t\t\troutes: JSON.stringify([\"/C\"]),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\ttrue /* inlineDetailsProp */,\n\t\t\t\t);\n\t\t\t\tassert(eventsFound, `Expected unknownReferenceEvent event!`);\n\t\t\t});\n\t\t});\n\n\t\tdescribe(\"References to unreferenced nodes\", () => {\n\t\t\t/**\n\t\t\t * Validates that we can detect references that are added from an unreferenced node to another.\n\t\t\t * 1. Summary 1 at t1. V = [A*, B, C]. E = []. B and C have unreferenced time t1.\n\t\t\t * 2. Reference from B to C. E = [B -\\> C].\n\t\t\t * 3. Summary 2 at t2. V = [A*, B, C]. E = [B -\\> C]. B and C have unreferenced time t1.\n\t\t\t * Validates that the unreferenced time for B and C is still t1.\n\t\t\t */\n\t\t\tit(`Scenario 1 - Reference added to unreferenced node`, async () => {\n\t\t\t\t// Initialize nodes A, B and C.\n\t\t\t\tdefaultGCData.gcNodes[\"/\"] = [nodeA];\n\t\t\t\tdefaultGCData.gcNodes[nodeA] = [];\n\t\t\t\tdefaultGCData.gcNodes[nodeB] = [];\n\t\t\t\tdefaultGCData.gcNodes[nodeC] = [];\n\n\t\t\t\t// 1. Run GC and generate summary 1. E = [B -\\> C].\n\t\t\t\tconst timestamps1 = await getUnreferencedTimestamps();\n\t\t\t\tassert(timestamps1.get(nodeA) === undefined, \"A should be referenced\");\n\n\t\t\t\tconst nodeBTime1 = timestamps1.get(nodeB);\n\t\t\t\tconst nodeCTime1 = timestamps1.get(nodeC);\n\t\t\t\tassert(nodeBTime1 !== undefined, \"B should have unreferenced timestamp\");\n\t\t\t\tassert(nodeCTime1 !== undefined, \"C should have unreferenced timestamp\");\n\n\t\t\t\t// 2. Add reference from B to C. E = [B -\\> C].\n\t\t\t\tgarbageCollector.addedOutboundReference(nodeB, nodeC);\n\t\t\t\tdefaultGCData.gcNodes[nodeB] = [nodeC];\n\n\t\t\t\t// 3. Run GC and generate summary 2. E = [B -\\> C].\n\t\t\t\tconst timestamps2 = await getUnreferencedTimestamps();\n\t\t\t\tassert(timestamps2.get(nodeA) === undefined, \"A should be referenced\");\n\n\t\t\t\tconst nodeBTime2 = timestamps2.get(nodeB);\n\t\t\t\tconst nodeCTime2 = timestamps2.get(nodeC);\n\t\t\t\tassert(nodeBTime2 === nodeBTime1, \"B's timestamp should be unchanged\");\n\t\t\t\tassert(\n\t\t\t\t\tnodeCTime2 !== undefined && nodeCTime2 > nodeCTime1,\n\t\t\t\t\t\"C's timestamp should have updated\",\n\t\t\t\t);\n\t\t\t});\n\n\t\t\t/*\n\t\t\t * Validates that we can detect references that are added from an unreferenced node to a list of\n\t\t\t * unreferenced nodes, i.e., nodes with references to each other but are overall unreferenced.\n\t\t\t * 1. Summary 1 at t1. V = [A*, B, C, D]. E = [C -\\> D]. B, C and D have unreferenced time t1.\n\t\t\t * 2. Op adds reference from B to C. E = [B -\\> C, C -\\> D].\n\t\t\t * 3. Summary 2 at t2. V = [A*, B, C]. E = [B -\\> C, C -\\> D]. C and D have unreferenced time t2.\n\t\t\t * Validates that the unreferenced time for C and D is t2 which is > t1.\n\t\t\t */\n\t\t\tit(`Scenario 2 - Reference added to a list of unreferenced nodes from an unreferenced node`, async () => {\n\t\t\t\t// Initialize nodes A, B and C.\n\t\t\t\tdefaultGCData.gcNodes[\"/\"] = [nodeA];\n\t\t\t\tdefaultGCData.gcNodes[nodeA] = [];\n\t\t\t\tdefaultGCData.gcNodes[nodeB] = [];\n\t\t\t\tdefaultGCData.gcNodes[nodeC] = [nodeD];\n\t\t\t\tdefaultGCData.gcNodes[nodeD] = [];\n\n\t\t\t\t// 1. Run GC and generate summary 1. E = [B -\\> C].\n\t\t\t\tconst timestamps1 = await getUnreferencedTimestamps();\n\t\t\t\tassert(timestamps1.get(nodeA) === undefined, \"A should be referenced\");\n\n\t\t\t\tconst nodeBTime1 = timestamps1.get(nodeB);\n\t\t\t\tconst nodeCTime1 = timestamps1.get(nodeC);\n\t\t\t\tconst nodeDTime1 = timestamps1.get(nodeC);\n\t\t\t\tassert(nodeBTime1 !== undefined, \"B should have unreferenced timestamp\");\n\t\t\t\tassert(nodeCTime1 !== undefined, \"C should have unreferenced timestamp\");\n\t\t\t\tassert(nodeDTime1 !== undefined, \"C should have unreferenced timestamp\");\n\n\t\t\t\t// 2. Add reference from B to C. E = [B -\\> C, C-\\> D].\n\t\t\t\tgarbageCollector.addedOutboundReference(nodeB, nodeC);\n\t\t\t\tdefaultGCData.gcNodes[nodeB] = [nodeC];\n\n\t\t\t\t// 3. Run GC and generate summary 2. E = [B -\\> C. C -\\> D].\n\t\t\t\tconst timestamps2 = await getUnreferencedTimestamps();\n\t\t\t\tassert(timestamps2.get(nodeA) === undefined, \"A should be referenced\");\n\n\t\t\t\tconst nodeBTime2 = timestamps2.get(nodeB);\n\t\t\t\tconst nodeCTime2 = timestamps2.get(nodeC);\n\t\t\t\tconst nodeDTime2 = timestamps2.get(nodeD);\n\t\t\t\tassert(nodeBTime2 === nodeBTime1, \"B's timestamp should be unchanged\");\n\t\t\t\tassert(\n\t\t\t\t\tnodeCTime2 !== undefined && nodeCTime2 > nodeCTime1,\n\t\t\t\t\t\"C's timestamp should have updated\",\n\t\t\t\t);\n\t\t\t\tassert(\n\t\t\t\t\tnodeDTime2 !== undefined && nodeDTime2 > nodeDTime1,\n\t\t\t\t\t\"D's timestamp should have updated\",\n\t\t\t\t);\n\t\t\t});\n\n\t\t\t/*\n\t\t\t * Validates that we can detect references that are added from an unreferenced node to a list of\n\t\t\t * unreferenced nodes, i.e., nodes with references to each other but are overall unreferenced. Then\n\t\t\t * a reference between the list is removed\n\t\t\t * 1. Summary 1 at t1. V = [A*, B, C, D]. E = [C -> D]. B, C and D have unreferenced time t1.\n\t\t\t * 2. Op adds reference from B to C. E = [B -> C, C -> D].\n\t\t\t * 3. Op removes reference from C to D. E = [B -> C].\n\t\t\t * 4. Summary 2 at t2. V = [A*, B, C]. E = [B -> C]. C and D have unreferenced time t2.\n\t\t\t * Validates that the unreferenced time for C and D is t2 which is > t1.\n\t\t\t */\n\t\t\tit(`Scenario 3 - Reference added to a list of unreferenced nodes and a reference is removed`, async () => {\n\t\t\t\t// Initialize nodes A, B and C.\n\t\t\t\tdefaultGCData.gcNodes[\"/\"] = [nodeA];\n\t\t\t\tdefaultGCData.gcNodes[nodeA] = [];\n\t\t\t\tdefaultGCData.gcNodes[nodeB] = [];\n\t\t\t\tdefaultGCData.gcNodes[nodeC] = [nodeD];\n\t\t\t\tdefaultGCData.gcNodes[nodeD] = [];\n\n\t\t\t\t// 1. Run GC and generate summary 1. E = [B -\\> C].\n\t\t\t\tconst timestamps1 = await getUnreferencedTimestamps();\n\t\t\t\tassert(timestamps1.get(nodeA) === undefined, \"A should be referenced\");\n\n\t\t\t\tconst nodeBTime1 = timestamps1.get(nodeB);\n\t\t\t\tconst nodeCTime1 = timestamps1.get(nodeC);\n\t\t\t\tconst nodeDTime1 = timestamps1.get(nodeC);\n\t\t\t\tassert(nodeBTime1 !== undefined, \"B should have unreferenced timestamp\");\n\t\t\t\tassert(nodeCTime1 !== undefined, \"C should have unreferenced timestamp\");\n\t\t\t\tassert(nodeDTime1 !== undefined, \"C should have unreferenced timestamp\");\n\n\t\t\t\t// 2. Add reference from B to C. E = [B -\\> C, C-\\> D].\n\t\t\t\tgarbageCollector.addedOutboundReference(nodeB, nodeC);\n\t\t\t\tdefaultGCData.gcNodes[nodeB] = [nodeC];\n\n\t\t\t\t// 3. Remove reference from C to D. E = [B -\\> C].\n\t\t\t\tdefaultGCData.gcNodes[nodeC] = [];\n\n\t\t\t\t// 3. Run GC and generate summary 2. E = [B -\\> C].\n\t\t\t\tconst timestamps2 = await getUnreferencedTimestamps();\n\t\t\t\tassert(timestamps2.get(nodeA) === undefined, \"A should be referenced\");\n\n\t\t\t\tconst nodeBTime2 = timestamps2.get(nodeB);\n\t\t\t\tconst nodeCTime2 = timestamps2.get(nodeC);\n\t\t\t\tconst nodeDTime2 = timestamps2.get(nodeD);\n\t\t\t\tassert(nodeBTime2 === nodeBTime1, \"B's timestamp should be unchanged\");\n\t\t\t\tassert(\n\t\t\t\t\tnodeCTime2 !== undefined && nodeCTime2 > nodeCTime1,\n\t\t\t\t\t\"C's timestamp should have updated\",\n\t\t\t\t);\n\t\t\t\tassert(\n\t\t\t\t\tnodeDTime2 !== undefined && nodeDTime2 > nodeDTime1,\n\t\t\t\t\t\"D's timestamp should have updated\",\n\t\t\t\t);\n\t\t\t});\n\t\t});\n\t});\n\n\tdescribe(\"No changes to GC between summaries\", () => {\n\t\tconst fullTree = false;\n\t\tconst trackState = true;\n\t\tlet garbageCollector: IGarbageCollector;\n\n\t\tbeforeEach(() => {\n\t\t\t// Initialize nodes A & D.\n\t\t\tdefaultGCData.gcNodes = {};\n\t\t\tdefaultGCData.gcNodes[\"/\"] = nodes;\n\t\t});\n\n\t\tconst checkGCSummaryType = (\n\t\t\tsummary: ISummarizeResult | undefined,\n\t\t\texpectedBlobType: SummaryType,\n\t\t\tsummaryNumber: string,\n\t\t) => {\n\t\t\tassert(summary !== undefined, `Expected a summary on ${summaryNumber} summarize`);\n\t\t\tassert(\n\t\t\t\tsummary.summary.type === expectedBlobType,\n\t\t\t\t`Expected summary type ${expectedBlobType} on ${summaryNumber} summarize, got ${summary.summary.type}`,\n\t\t\t);\n\t\t};\n\n\t\tit(\"creates a blob handle when no version specified\", async () => {\n\t\t\tgarbageCollector = createGarbageCollector();\n\n\t\t\tawait garbageCollector.collectGarbage({});\n\t\t\tconst tree1 = garbageCollector.summarize(fullTree, trackState);\n\n\t\t\tcheckGCSummaryType(tree1, SummaryType.Tree, \"first\");\n\n\t\t\tawait garbageCollector.refreshLatestSummary({\n\t\t\t\tisSummaryTracked: true,\n\t\t\t\tisSummaryNewer: true,\n\t\t\t});\n\t\t\tawait garbageCollector.collectGarbage({});\n\t\t\tconst tree2 = garbageCollector.summarize(fullTree, trackState);\n\n\t\t\tcheckGCSummaryType(tree2, SummaryType.Handle, \"second\");\n\t\t});\n\t});\n\n\tit(\"resets gc state when loading from an old snapshot format\", async () => {\n\t\t// Create GC details for node 3's GC blob whose unreferenced time was > timeout ms ago.\n\t\t// This means this node should time out as soon as its data is loaded.\n\t\tconst node3GCDetails: IGarbageCollectionSummaryDetailsLegacy = {\n\t\t\tgcData: { gcNodes: { \"/\": [] } },\n\t\t\tunrefTimestamp: Date.now() - defaultTombstoneTimeoutMs * 100,\n\t\t};\n\t\tconst node3Snapshot = getDummySnapshotTree();\n\t\tconst gcBlobId = \"node3GCDetails\";\n\t\tconst attributesBlobId = \"attributesBlob\";\n\t\tnode3Snapshot.blobs[gcTreeKey] = gcBlobId;\n\t\tnode3Snapshot.blobs[dataStoreAttributesBlobName] = attributesBlobId;\n\n\t\t// Create a base snapshot that contains snapshot tree of node 3.\n\t\tconst channelsTree = getDummySnapshotTree();\n\t\tchannelsTree.trees[nodes[3].slice(1)] = node3Snapshot;\n\t\tconst baseSnapshot = getDummySnapshotTree();\n\t\tbaseSnapshot.trees[channelsTreeName] = channelsTree;\n\n\t\t// Set up the getNodeGCDetails function to return the GC details for node 3 when asked by garbage collector.\n\t\tconst gcBlobsMap = new Map([\n\t\t\t[gcBlobId, node3GCDetails],\n\t\t\t[attributesBlobId, {}],\n\t\t]);\n\t\tconst garbageCollector = createGarbageCollector({\n\t\t\tcreateParams: { baseSnapshot },\n\t\t\tgcBlobsMap,\n\t\t\tgcMetadata: {\n\t\t\t\ttombstoneTimeoutMs: defaultTombstoneTimeoutMs,\n\t\t\t},\n\t\t});\n\n\t\t// GC state and tombstone state should be discarded but deleted nodes should be read from base snapshot.\n\t\tconst baseSnapshotData = await garbageCollector.baseSnapshotDataP;\n\t\tassert(\n\t\t\tbaseSnapshotData === undefined,\n\t\t\t\"base snapshot should not be defined for old snapshots where we wrote the gc data in the channels\",\n\t\t);\n\n\t\t// Initialize from the base state and validate that tombstones has 0 entry because it was discarded.\n\t\t// Deleted nodes should have one entry because it is still used.\n\t\tawait garbageCollector.initializeBaseState();\n\t\tassert.strictEqual(garbageCollector.tombstones.length, 0, \"Expecting 0 tombstone nodes\");\n\t\tassert.strictEqual(garbageCollector.deletedNodes.size, 0, \"Expecting 0 deleted nodes\");\n\t});\n\n\tdescribe(\"Future GC op type compatibility\", () => {\n\t\tconst gcMessageFromFuture: Record<string, unknown> = {\n\t\t\ttype: \"FUTURE_MESSAGE\",\n\t\t\thello: \"HELLO\",\n\t\t};\n\n\t\tlet garbageCollector: IGarbageCollector;\n\t\tbeforeEach(async () => {\n\t\t\tgarbageCollector = createGarbageCollector({\n\t\t\t\tcreateParams: { gcOptions: { enableGCSweep: true } },\n\t\t\t});\n\t\t});\n\n\t\tit(\"can submit GC op compat behavior\", async () => {\n\t\t\tconst gcWithPrivates = garbageCollector as GcWithPrivates;\n\t\t\tconst containerRuntimeGCMessage: Omit<\n\t\t\t\tContainerRuntimeGCMessage,\n\t\t\t\t\"type\" | \"contents\"\n\t\t\t> & {\n\t\t\t\ttype: string;\n\t\t\t\tcontents: any;\n\t\t\t} = {\n\t\t\t\ttype: ContainerMessageType.GC,\n\t\t\t\tcontents: gcMessageFromFuture,\n\t\t\t\tcompatDetails: { behavior: \"Ignore\" },\n\t\t\t};\n\n\t\t\tassert.doesNotThrow(\n\t\t\t\t() =>\n\t\t\t\t\tgcWithPrivates.submitMessage(\n\t\t\t\t\t\tcontainerRuntimeGCMessage as ContainerRuntimeGCMessage,\n\t\t\t\t\t),\n\t\t\t\t\"Cannot submit GC message with compatDetails\",\n\t\t\t);\n\t\t});\n\n\t\tit(\"process remote op with unrecognized type and 'Ignore' compat behavior\", async () => {\n\t\t\tconst containerRuntimeGCMessage: ContainerRuntimeGCMessage = {\n\t\t\t\ttype: ContainerMessageType.GC,\n\t\t\t\tcontents: gcMessageFromFuture as unknown as GarbageCollectionMessage,\n\t\t\t\tcompatDetails: { behavior: \"Ignore\" },\n\t\t\t};\n\t\t\tgarbageCollector.processMessage(containerRuntimeGCMessage, false /* local */);\n\t\t});\n\n\t\tit(\"process remote op with unrecognized type and 'FailToProcess' compat behavior\", async () => {\n\t\t\tconst containerRuntimeGCMessage: ContainerRuntimeGCMessage = {\n\t\t\t\ttype: ContainerMessageType.GC,\n\t\t\t\tcontents: gcMessageFromFuture as unknown as GarbageCollectionMessage,\n\t\t\t\tcompatDetails: { behavior: \"FailToProcess\" },\n\t\t\t};\n\t\t\tassert.throws(\n\t\t\t\t() => garbageCollector.processMessage(containerRuntimeGCMessage, false /* local */),\n\t\t\t\t(error: IErrorBase) => error.errorType === ContainerErrorTypes.dataProcessingError,\n\t\t\t\t\"Garbage collection message of unknown type FROM_THE_FUTURE\",\n\t\t\t);\n\t\t});\n\n\t\tit(\"process remote op with unrecognized type and no compat behavior\", async () => {\n\t\t\tconst containerRuntimeGCMessage: ContainerRuntimeGCMessage = {\n\t\t\t\ttype: ContainerMessageType.GC,\n\t\t\t\tcontents: gcMessageFromFuture as unknown as GarbageCollectionMessage,\n\t\t\t};\n\t\t\tassert.throws(\n\t\t\t\t() => garbageCollector.processMessage(containerRuntimeGCMessage, false /* local */),\n\t\t\t\t(error: IErrorBase) => error.errorType === ContainerErrorTypes.dataProcessingError,\n\t\t\t\t\"Garbage collection message of unknown type FROM_THE_FUTURE\",\n\t\t\t);\n\t\t});\n\t});\n});\n"]}
|