@fluidframework/container-runtime 2.0.0-rc.2.0.2 → 2.0.0-rc.2.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/api-report/container-runtime.api.md +32 -4
- package/dist/channelCollection.d.ts +7 -3
- package/dist/channelCollection.d.ts.map +1 -1
- package/dist/channelCollection.js +80 -22
- package/dist/channelCollection.js.map +1 -1
- package/dist/container-runtime-alpha.d.ts +14 -4
- package/dist/container-runtime-beta.d.ts +6 -0
- package/dist/container-runtime-public.d.ts +6 -0
- package/dist/container-runtime-untrimmed.d.ts +43 -4
- package/dist/containerRuntime.d.ts +6 -0
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +16 -4
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStoreContext.d.ts +1 -1
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +12 -2
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStoreContexts.d.ts +2 -0
- package/dist/dataStoreContexts.d.ts.map +1 -1
- package/dist/dataStoreContexts.js +7 -0
- package/dist/dataStoreContexts.js.map +1 -1
- package/dist/gc/garbageCollection.d.ts +4 -11
- package/dist/gc/garbageCollection.d.ts.map +1 -1
- package/dist/gc/garbageCollection.js +45 -29
- package/dist/gc/garbageCollection.js.map +1 -1
- package/dist/gc/gcDefinitions.d.ts +26 -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 -4
- package/dist/gc/gcHelpers.d.ts.map +1 -1
- package/dist/gc/gcHelpers.js +14 -2
- package/dist/gc/gcHelpers.js.map +1 -1
- package/dist/gc/gcTelemetry.d.ts +13 -2
- package/dist/gc/gcTelemetry.d.ts.map +1 -1
- package/dist/gc/gcTelemetry.js +24 -21
- package/dist/gc/gcTelemetry.js.map +1 -1
- package/dist/gc/index.d.ts +2 -2
- package/dist/gc/index.d.ts.map +1 -1
- package/dist/gc/index.js +2 -2
- package/dist/gc/index.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.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/lib/channelCollection.d.ts +7 -3
- package/lib/channelCollection.d.ts.map +1 -1
- package/lib/channelCollection.js +82 -24
- package/lib/channelCollection.js.map +1 -1
- package/lib/container-runtime-alpha.d.ts +14 -4
- package/lib/container-runtime-beta.d.ts +6 -0
- package/lib/container-runtime-public.d.ts +6 -0
- package/lib/container-runtime-untrimmed.d.ts +43 -4
- package/lib/containerRuntime.d.ts +6 -0
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +15 -3
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStoreContext.d.ts +1 -1
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +12 -2
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStoreContexts.d.ts +2 -0
- package/lib/dataStoreContexts.d.ts.map +1 -1
- package/lib/dataStoreContexts.js +7 -0
- package/lib/dataStoreContexts.js.map +1 -1
- package/lib/gc/garbageCollection.d.ts +4 -11
- package/lib/gc/garbageCollection.d.ts.map +1 -1
- package/lib/gc/garbageCollection.js +47 -31
- package/lib/gc/garbageCollection.js.map +1 -1
- package/lib/gc/gcDefinitions.d.ts +26 -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 -4
- package/lib/gc/gcHelpers.d.ts.map +1 -1
- package/lib/gc/gcHelpers.js +12 -1
- package/lib/gc/gcHelpers.js.map +1 -1
- package/lib/gc/gcTelemetry.d.ts +13 -2
- package/lib/gc/gcTelemetry.d.ts.map +1 -1
- package/lib/gc/gcTelemetry.js +24 -21
- package/lib/gc/gcTelemetry.js.map +1 -1
- package/lib/gc/index.d.ts +2 -2
- 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 +2 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/test/gc/garbageCollection.spec.js +23 -14
- package/lib/test/gc/garbageCollection.spec.js.map +1 -1
- package/lib/test/gc/gcHelpers.spec.js +69 -1
- package/lib/test/gc/gcHelpers.spec.js.map +1 -1
- package/lib/test/gc/gcTelemetry.spec.js +31 -3
- package/lib/test/gc/gcTelemetry.spec.js.map +1 -1
- package/package.json +16 -16
- package/src/channelCollection.ts +107 -43
- package/src/containerRuntime.ts +17 -23
- package/src/dataStoreContext.ts +14 -2
- package/src/dataStoreContexts.ts +12 -0
- package/src/gc/garbageCollection.ts +63 -41
- package/src/gc/gcDefinitions.ts +21 -9
- package/src/gc/gcHelpers.ts +14 -1
- package/src/gc/gcTelemetry.ts +56 -47
- package/src/gc/index.ts +2 -1
- package/src/index.ts +3 -0
- package/src/packageVersion.ts +1 -1
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { strict as assert } from "assert";
|
|
6
6
|
// eslint-disable-next-line import/no-internal-modules
|
|
7
|
-
import { shouldAllowGcSweep } from "../../gc/gcHelpers.js";
|
|
7
|
+
import { dataStoreNodePathOnly, shouldAllowGcSweep, urlToGCNodePath } from "../../gc/gcHelpers.js";
|
|
8
8
|
describe("Garbage Collection Helpers Tests", () => {
|
|
9
9
|
describe("[TEMP] shouldAllowGcTombstoneEnforcement - Show behavior change as it's replaced by shouldAllowGcSweep", () => {
|
|
10
10
|
const testCases = [
|
|
@@ -106,5 +106,73 @@ describe("Garbage Collection Helpers Tests", () => {
|
|
|
106
106
|
});
|
|
107
107
|
});
|
|
108
108
|
});
|
|
109
|
+
describe("dataStoreNodePathOnly", () => {
|
|
110
|
+
const testCases = [
|
|
111
|
+
{
|
|
112
|
+
path: "/",
|
|
113
|
+
expected: "/",
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
path: "/a",
|
|
117
|
+
expected: "/a",
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
path: "/a/b",
|
|
121
|
+
expected: "/a",
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
path: "/a/b/c",
|
|
125
|
+
expected: "/a",
|
|
126
|
+
},
|
|
127
|
+
];
|
|
128
|
+
testCases.forEach(({ path, expected }) => {
|
|
129
|
+
it(`path=${path}`, () => {
|
|
130
|
+
const result = dataStoreNodePathOnly(path);
|
|
131
|
+
assert.equal(result, expected);
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
describe("urlToGCNodePath", () => {
|
|
136
|
+
const testCases = [
|
|
137
|
+
{
|
|
138
|
+
url: "/a",
|
|
139
|
+
expected: "/a",
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
url: "/a/",
|
|
143
|
+
expected: "/a",
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
url: "/a/b",
|
|
147
|
+
expected: "/a/b",
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
url: "/a/b/",
|
|
151
|
+
expected: "/a/b",
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
url: "/a?x=1",
|
|
155
|
+
expected: "/a",
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
url: "/a/?x=1",
|
|
159
|
+
expected: "/a",
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
url: "/a/b?x=1",
|
|
163
|
+
expected: "/a/b",
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
url: "/a/b/?x=1",
|
|
167
|
+
expected: "/a/b",
|
|
168
|
+
},
|
|
169
|
+
];
|
|
170
|
+
testCases.forEach(({ url, expected }) => {
|
|
171
|
+
it(`url=${url}`, () => {
|
|
172
|
+
const result = urlToGCNodePath(url);
|
|
173
|
+
assert.equal(result, expected);
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
});
|
|
109
177
|
});
|
|
110
178
|
//# sourceMappingURL=gcHelpers.spec.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gcHelpers.spec.js","sourceRoot":"","sources":["../../../src/test/gc/gcHelpers.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,IAAI,MAAM,EAAE,MAAM,QAAQ,CAAC;AAE1C,sDAAsD;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"gcHelpers.spec.js","sourceRoot":"","sources":["../../../src/test/gc/gcHelpers.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 { GCFeatureMatrix } from \"../../gc/index.js\";\n// eslint-disable-next-line import/no-internal-modules\nimport { dataStoreNodePathOnly, shouldAllowGcSweep, urlToGCNodePath } from \"../../gc/gcHelpers.js\";\n\ndescribe(\"Garbage Collection Helpers Tests\", () => {\n\tdescribe(\"[TEMP] shouldAllowGcTombstoneEnforcement - Show behavior change as it's replaced by shouldAllowGcSweep\", () => {\n\t\tconst testCases: {\n\t\t\tpersisted: number | undefined;\n\t\t\tcurrent: number | undefined;\n\t\t\texpectedShouldAllowValue: boolean;\n\t\t}[] = [\n\t\t\t{\n\t\t\t\tpersisted: undefined,\n\t\t\t\tcurrent: undefined,\n\t\t\t\texpectedShouldAllowValue: true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpersisted: undefined,\n\t\t\t\tcurrent: 1,\n\t\t\t\texpectedShouldAllowValue: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpersisted: 1,\n\t\t\t\tcurrent: undefined,\n\t\t\t\texpectedShouldAllowValue: true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpersisted: 1,\n\t\t\t\tcurrent: 1,\n\t\t\t\texpectedShouldAllowValue: true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpersisted: 1,\n\t\t\t\tcurrent: 2,\n\t\t\t\texpectedShouldAllowValue: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpersisted: 2,\n\t\t\t\tcurrent: 1,\n\t\t\t\texpectedShouldAllowValue: false,\n\t\t\t},\n\t\t];\n\t\ttestCases.forEach(({ persisted, current, expectedShouldAllowValue }) => {\n\t\t\tit(`persisted=${persisted}, current=${current}`, () => {\n\t\t\t\tconst shouldAllow = shouldAllowGcSweep({ tombstoneGeneration: persisted }, current);\n\t\t\t\tassert.equal(shouldAllow, expectedShouldAllowValue);\n\t\t\t});\n\t\t});\n\t});\n\n\tdescribe(\"shouldAllowGcSweep\", () => {\n\t\tconst testCases: {\n\t\t\tpersisted: GCFeatureMatrix;\n\t\t\tcurrent: number | undefined;\n\t\t\texpectedShouldAllowValue: boolean;\n\t\t}[] = [\n\t\t\t{\n\t\t\t\tpersisted: {},\n\t\t\t\tcurrent: undefined,\n\t\t\t\texpectedShouldAllowValue: true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpersisted: { gcGeneration: 1 },\n\t\t\t\tcurrent: undefined,\n\t\t\t\texpectedShouldAllowValue: true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpersisted: {},\n\t\t\t\tcurrent: 0,\n\t\t\t\texpectedShouldAllowValue: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpersisted: { tombstoneGeneration: 0 },\n\t\t\t\tcurrent: 0,\n\t\t\t\texpectedShouldAllowValue: true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpersisted: { tombstoneGeneration: 1 },\n\t\t\t\tcurrent: 1,\n\t\t\t\texpectedShouldAllowValue: true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpersisted: { tombstoneGeneration: 1 },\n\t\t\t\tcurrent: 0,\n\t\t\t\texpectedShouldAllowValue: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpersisted: { gcGeneration: 0 },\n\t\t\t\tcurrent: 0,\n\t\t\t\texpectedShouldAllowValue: true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpersisted: { gcGeneration: 1 },\n\t\t\t\tcurrent: 1,\n\t\t\t\texpectedShouldAllowValue: true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpersisted: { gcGeneration: 1 },\n\t\t\t\tcurrent: 2,\n\t\t\t\texpectedShouldAllowValue: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpersisted: { gcGeneration: 2 },\n\t\t\t\tcurrent: 1,\n\t\t\t\texpectedShouldAllowValue: false,\n\t\t\t},\n\t\t];\n\t\ttestCases.forEach(({ persisted, current, expectedShouldAllowValue }) => {\n\t\t\tit(`persisted=${JSON.stringify(persisted)}, current=${current}`, () => {\n\t\t\t\tconst shouldAllow = shouldAllowGcSweep(persisted, current);\n\t\t\t\tassert.equal(shouldAllow, expectedShouldAllowValue);\n\t\t\t});\n\t\t});\n\t});\n\n\tdescribe(\"dataStoreNodePathOnly\", () => {\n\t\tconst testCases: {\n\t\t\tpath: string;\n\t\t\texpected: string;\n\t\t}[] = [\n\t\t\t{\n\t\t\t\tpath: \"/\",\n\t\t\t\texpected: \"/\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tpath: \"/a\",\n\t\t\t\texpected: \"/a\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tpath: \"/a/b\",\n\t\t\t\texpected: \"/a\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tpath: \"/a/b/c\",\n\t\t\t\texpected: \"/a\",\n\t\t\t},\n\t\t];\n\t\ttestCases.forEach(({ path, expected }) => {\n\t\t\tit(`path=${path}`, () => {\n\t\t\t\tconst result = dataStoreNodePathOnly(path);\n\t\t\t\tassert.equal(result, expected);\n\t\t\t});\n\t\t});\n\t});\n\n\tdescribe(\"urlToGCNodePath\", () => {\n\t\tconst testCases: {\n\t\t\turl: string;\n\t\t\texpected: string;\n\t\t}[] = [\n\t\t\t{\n\t\t\t\turl: \"/a\",\n\t\t\t\texpected: \"/a\",\n\t\t\t},\n\t\t\t{\n\t\t\t\turl: \"/a/\",\n\t\t\t\texpected: \"/a\",\n\t\t\t},\n\t\t\t{\n\t\t\t\turl: \"/a/b\",\n\t\t\t\texpected: \"/a/b\",\n\t\t\t},\n\t\t\t{\n\t\t\t\turl: \"/a/b/\",\n\t\t\t\texpected: \"/a/b\",\n\t\t\t},\n\t\t\t{\n\t\t\t\turl: \"/a?x=1\",\n\t\t\t\texpected: \"/a\",\n\t\t\t},\n\t\t\t{\n\t\t\t\turl: \"/a/?x=1\",\n\t\t\t\texpected: \"/a\",\n\t\t\t},\n\t\t\t{\n\t\t\t\turl: \"/a/b?x=1\",\n\t\t\t\texpected: \"/a/b\",\n\t\t\t},\n\t\t\t{\n\t\t\t\turl: \"/a/b/?x=1\",\n\t\t\t\texpected: \"/a/b\",\n\t\t\t},\n\t\t];\n\t\ttestCases.forEach(({ url, expected }) => {\n\t\t\tit(`url=${url}`, () => {\n\t\t\t\tconst result = urlToGCNodePath(url);\n\t\t\t\tassert.equal(result, expected);\n\t\t\t});\n\t\t});\n\t});\n});\n"]}
|
|
@@ -75,7 +75,7 @@ describe("GC Telemetry Tracker", () => {
|
|
|
75
75
|
// Mock node loaded and changed activity for the given nodes.
|
|
76
76
|
function mockNodeChanges(nodeIds) {
|
|
77
77
|
nodeIds.forEach((id) => {
|
|
78
|
-
telemetryTracker.nodeUsed({
|
|
78
|
+
telemetryTracker.nodeUsed(id, {
|
|
79
79
|
id,
|
|
80
80
|
usageType: "Loaded",
|
|
81
81
|
currentReferenceTimestampMs: Date.now(),
|
|
@@ -83,7 +83,7 @@ describe("GC Telemetry Tracker", () => {
|
|
|
83
83
|
completedGCRuns: 0,
|
|
84
84
|
isTombstoned: false,
|
|
85
85
|
});
|
|
86
|
-
telemetryTracker.nodeUsed({
|
|
86
|
+
telemetryTracker.nodeUsed(id, {
|
|
87
87
|
id,
|
|
88
88
|
usageType: "Changed",
|
|
89
89
|
currentReferenceTimestampMs: Date.now(),
|
|
@@ -95,7 +95,7 @@ describe("GC Telemetry Tracker", () => {
|
|
|
95
95
|
}
|
|
96
96
|
// Mock node revived activity for the given nodes.
|
|
97
97
|
function reviveNode(fromId, toId, isTombstoned = false) {
|
|
98
|
-
telemetryTracker.nodeUsed({
|
|
98
|
+
telemetryTracker.nodeUsed(toId, {
|
|
99
99
|
id: toId,
|
|
100
100
|
usageType: "Revived",
|
|
101
101
|
currentReferenceTimestampMs: Date.now(),
|
|
@@ -338,6 +338,34 @@ describe("GC Telemetry Tracker", () => {
|
|
|
338
338
|
},
|
|
339
339
|
], "revived event not as expected");
|
|
340
340
|
});
|
|
341
|
+
it("generates events properly for untracked subDataStore paths", async () => {
|
|
342
|
+
// Mark node 1 as unreferenced.
|
|
343
|
+
markNodesUnreferenced([nodes[1]]);
|
|
344
|
+
// We'll mock a Loaded event for this path, passing the DataStore path as trackedId to ensure coverage
|
|
345
|
+
const subDataStorePath = `${nodes[1]}/something`;
|
|
346
|
+
// Expire the timeout, update nodes and validate that all events for node 1 are logged.
|
|
347
|
+
clock.tick(timeout);
|
|
348
|
+
telemetryTracker.nodeUsed(nodes[1], {
|
|
349
|
+
id: subDataStorePath,
|
|
350
|
+
usageType: "Loaded",
|
|
351
|
+
currentReferenceTimestampMs: Date.now(),
|
|
352
|
+
packagePath: testPkgPath,
|
|
353
|
+
completedGCRuns: 0,
|
|
354
|
+
isTombstoned: false,
|
|
355
|
+
});
|
|
356
|
+
await simulateGCToTriggerEvents(isSummarizerClient);
|
|
357
|
+
const expectedEvents = [];
|
|
358
|
+
expectedEvents.push({
|
|
359
|
+
eventName: loadedEventName,
|
|
360
|
+
timeout,
|
|
361
|
+
...tagCodeArtifacts({ id: subDataStorePath, pkg: testPkgPath.join("/") }),
|
|
362
|
+
createContainerRuntimeVersion: pkgVersion,
|
|
363
|
+
isTombstoned: false,
|
|
364
|
+
trackedId: nodes[1],
|
|
365
|
+
type: "SubDataStore",
|
|
366
|
+
});
|
|
367
|
+
assertMatchEvents(expectedEvents, "all events not as expected");
|
|
368
|
+
});
|
|
341
369
|
it("generates events once per node", async () => {
|
|
342
370
|
// Mark node 2 as unreferenced.
|
|
343
371
|
markNodesUnreferenced([nodes[2]]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gcTelemetry.spec.js","sourceRoot":"","sources":["../../../src/test/gc/gcTelemetry.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 } from \"sinon\";\nimport { ITelemetryBaseEvent } from \"@fluidframework/core-interfaces\";\nimport { IGarbageCollectionData } from \"@fluidframework/runtime-definitions\";\nimport {\n\tMockLogger,\n\tTelemetryDataTag,\n\tmixinMonitoringContext,\n\tMonitoringContext,\n\tcreateChildLogger,\n\ttagCodeArtifacts,\n} from \"@fluidframework/telemetry-utils\";\nimport {\n\tGCNodeType,\n\tGCTelemetryTracker,\n\tdefaultSessionExpiryDurationMs,\n\toneDayMs,\n\tUnreferencedStateTracker,\n\tcloneGCData,\n\tIGarbageCollectorConfigs,\n\tstableGCVersion,\n} from \"../../gc/index.js\";\nimport { pkgVersion } from \"../../packageVersion.js\";\nimport { BlobManager } from \"../../blobManager.js\";\n\ndescribe(\"GC Telemetry Tracker\", () => {\n\tconst defaultSnapshotCacheExpiryMs = 5 * 24 * 60 * 60 * 1000;\n\tconst tombstoneTimeoutMs =\n\t\tdefaultSessionExpiryDurationMs + defaultSnapshotCacheExpiryMs + oneDayMs;\n\tconst inactiveTimeoutMs = 500;\n\n\t// Nodes in the reference graph.\n\tconst nodes: string[] = [\"/node1\", \"/node2\", \"/node3\", \"/node4\"];\n\n\tconst testPkgPath = [\"testPkg\"];\n\t// The package data is tagged in the telemetry event.\n\tconst eventPkg = { value: testPkgPath.join(\"/\"), tag: TelemetryDataTag.CodeArtifact };\n\n\tlet mockLogger: MockLogger;\n\tlet mc: MonitoringContext;\n\tlet clock: SinonFakeTimers;\n\tlet sweepGracePeriodMs = 1000; // Default case for these tests\n\tlet unreferencedNodesState: Map<string, UnreferencedStateTracker> = new Map();\n\tlet telemetryTracker: GCTelemetryTracker;\n\n\tfunction createTelemetryTracker(\n\t\tenableSweep: boolean,\n\t\tisSummarizerClient = true,\n\t): GCTelemetryTracker {\n\t\t// Node types are as follows based on the path:\n\t\t// Path starting with \"/_blobs\" - blob.\n\t\t// Path with one part such as \"/id1\" - data stores.\n\t\t// Path with two parts such as \"/id1/id2\" - sub data stores.\n\t\t// Everything else - other.\n\t\tconst getNodeType = (nodePath: string) => {\n\t\t\tif (nodePath.split(\"/\")[1] === BlobManager.basePath) {\n\t\t\t\treturn GCNodeType.Blob;\n\t\t\t}\n\t\t\tif (nodePath.split(\"/\").length === 2) {\n\t\t\t\treturn GCNodeType.DataStore;\n\t\t\t}\n\t\t\tif (nodePath.split(\"/\").length === 3) {\n\t\t\t\treturn GCNodeType.SubDataStore;\n\t\t\t}\n\t\t\treturn GCNodeType.Other;\n\t\t};\n\t\tconst configs: IGarbageCollectorConfigs = {\n\t\t\tgcEnabled: true,\n\t\t\tsweepEnabled: false,\n\t\t\tshouldRunGC: true,\n\t\t\tshouldRunSweep: \"NO\",\n\t\t\trunFullGC: false,\n\t\t\ttestMode: false,\n\t\t\ttombstoneMode: false,\n\t\t\tinactiveTimeoutMs,\n\t\t\tsessionExpiryTimeoutMs: defaultSessionExpiryDurationMs,\n\t\t\ttombstoneTimeoutMs: enableSweep ? tombstoneTimeoutMs : undefined,\n\t\t\tsweepGracePeriodMs,\n\t\t\tthrowOnTombstoneLoad: false,\n\t\t\tthrowOnTombstoneUsage: false,\n\t\t\tthrowOnInactiveLoad: false,\n\t\t\tpersistedGcFeatureMatrix: undefined,\n\t\t\tgcVersionInBaseSnapshot: stableGCVersion,\n\t\t\tgcVersionInEffect: stableGCVersion,\n\t\t};\n\t\tconst tracker = new GCTelemetryTracker(\n\t\t\tmc,\n\t\t\tconfigs,\n\t\t\tisSummarizerClient,\n\t\t\t{ createContainerRuntimeVersion: pkgVersion },\n\t\t\tgetNodeType,\n\t\t\t(nodeId: string) => unreferencedNodesState.get(nodeId),\n\t\t\tasync (nodeId: string) => testPkgPath,\n\t\t);\n\t\treturn tracker;\n\t}\n\n\t/**\n\t * For each node in nodeIds, add an entry in `unreferencedNodesState` indicating that the node was\n\t * just unreferenced.\n\t */\n\tfunction markNodesUnreferenced(nodeIds: string[]) {\n\t\tnodeIds.forEach((nodeId) => {\n\t\t\tunreferencedNodesState.set(\n\t\t\t\tnodeId,\n\t\t\t\tnew UnreferencedStateTracker(\n\t\t\t\t\tDate.now(),\n\t\t\t\t\tinactiveTimeoutMs,\n\t\t\t\t\tDate.now(),\n\t\t\t\t\ttombstoneTimeoutMs,\n\t\t\t\t\tsweepGracePeriodMs,\n\t\t\t\t),\n\t\t\t);\n\t\t});\n\t}\n\n\t// Mock node loaded and changed activity for the given nodes.\n\tfunction mockNodeChanges(nodeIds: string[]) {\n\t\tnodeIds.forEach((id) => {\n\t\t\ttelemetryTracker.nodeUsed({\n\t\t\t\tid,\n\t\t\t\tusageType: \"Loaded\",\n\t\t\t\tcurrentReferenceTimestampMs: Date.now(),\n\t\t\t\tpackagePath: testPkgPath,\n\t\t\t\tcompletedGCRuns: 0,\n\t\t\t\tisTombstoned: false,\n\t\t\t});\n\t\t\ttelemetryTracker.nodeUsed({\n\t\t\t\tid,\n\t\t\t\tusageType: \"Changed\",\n\t\t\t\tcurrentReferenceTimestampMs: Date.now(),\n\t\t\t\tpackagePath: testPkgPath,\n\t\t\t\tcompletedGCRuns: 0,\n\t\t\t\tisTombstoned: false,\n\t\t\t});\n\t\t});\n\t}\n\n\t// Mock node revived activity for the given nodes.\n\tfunction reviveNode(fromId: string, toId: string, isTombstoned = false) {\n\t\ttelemetryTracker.nodeUsed({\n\t\t\tid: toId,\n\t\t\tusageType: \"Revived\",\n\t\t\tcurrentReferenceTimestampMs: Date.now(),\n\t\t\tpackagePath: testPkgPath,\n\t\t\tcompletedGCRuns: 0,\n\t\t\tisTombstoned,\n\t\t\tfromId,\n\t\t});\n\t\tunreferencedNodesState.delete(toId);\n\t}\n\n\t/**\n\t * For summarizer clients, inactive / sweep ready events are not logged when on node usage. They are logged when GC\n\t * runs next time. This emulates that by calling the functions in the telemetry tracker that are called when GC runs.\n\t */\n\tasync function simulateGCToTriggerEvents(isSummarizerClient: boolean) {\n\t\tif (!isSummarizerClient) {\n\t\t\treturn;\n\t\t}\n\t\tawait telemetryTracker.logPendingEvents(mc.logger);\n\t}\n\n\tbefore(() => {\n\t\tclock = useFakeTimers();\n\t});\n\n\tbeforeEach(() => {\n\t\tmockLogger = new MockLogger();\n\t\tmc = mixinMonitoringContext(\n\t\t\tcreateChildLogger({ logger: mockLogger, namespace: \"GarbageCollector\" }),\n\t\t);\n\t\tunreferencedNodesState = new Map();\n\t});\n\n\tafterEach(() => {\n\t\tclock.reset();\n\t\tmockLogger.clear();\n\t\tsweepGracePeriodMs = 1000; // Default case for these tests\n\t});\n\n\tafter(() => {\n\t\tclock.restore();\n\t});\n\n\t// Tests that are run once for summarizer client and once for interactive client.\n\tconst clientTypeTests = (isSummarizerClient: boolean) => {\n\t\t/**\n\t\t * Asserts that the events are as expected based on whether its a summarizer client or not. In non-summarizer\n\t\t * clients, only \"InactiveObject_Loaded\", \"TombstoneReadyObject_Loaded\" and \"SweepReadyObject_Loaded\" events are logged.\n\t\t * \"_Changed\" and \"_Revived\" events are not logged.\n\t\t */\n\t\tfunction assertMatchEvents(\n\t\t\tevents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\t\tmessage: string,\n\t\t) {\n\t\t\tconst expectedEvents: Omit<ITelemetryBaseEvent, \"category\">[] = [];\n\t\t\tconst unexpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[] = [];\n\t\t\t// For non-summarizer clients, events that are not \"Loaded\" are unexpected. Everything else is expected.\n\t\t\tfor (const event of events) {\n\t\t\t\tconst eventName = event.eventName as string;\n\t\t\t\tif (!isSummarizerClient && !eventName.includes(\"Loaded\")) {\n\t\t\t\t\tunexpectedEvents.push(event);\n\t\t\t\t} else {\n\t\t\t\t\texpectedEvents.push(event);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Note that mock logger clears all events after one of the `match` functions is called. Since we call match\n\t\t\t// functions twice, cache the events and repopulate the mock logger with if after the first match call.\n\t\t\tconst cachedEvents = Array.from(mockLogger.events);\n\t\t\tmockLogger.assertMatch(expectedEvents, message, true /* inlineDetailsProp */);\n\t\t\tmockLogger.events = cachedEvents;\n\t\t\tmockLogger.assertMatchNone(unexpectedEvents, message, true /* inlineDetailsProp */);\n\t\t}\n\n\t\tit(\"generates inactive, tombstone ready, and sweep ready events when nodes are used after time out\", async () => {\n\t\t\ttelemetryTracker = createTelemetryTracker(true /* enable Sweep */, isSummarizerClient);\n\t\t\t// Mark nodes 2 and 3 as unreferenced.\n\t\t\tmarkNodesUnreferenced([nodes[2], nodes[3]]);\n\n\t\t\t// Advance the clock to trigger inactive timeout and validate that inactive events are as expected.\n\t\t\tclock.tick(inactiveTimeoutMs + 1);\n\t\t\tmockNodeChanges(nodes);\n\t\t\tawait simulateGCToTriggerEvents(isSummarizerClient);\n\t\t\tassertMatchEvents(\n\t\t\t\t[\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"GarbageCollector:InactiveObject_Loaded\",\n\t\t\t\t\t\ttimeout: inactiveTimeoutMs,\n\t\t\t\t\t\t...tagCodeArtifacts({ id: nodes[2] }),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"GarbageCollector:InactiveObject_Changed\",\n\t\t\t\t\t\ttimeout: inactiveTimeoutMs,\n\t\t\t\t\t\t...tagCodeArtifacts({ id: nodes[2] }),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"GarbageCollector:InactiveObject_Loaded\",\n\t\t\t\t\t\ttimeout: inactiveTimeoutMs,\n\t\t\t\t\t\t...tagCodeArtifacts({ id: nodes[3] }),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"GarbageCollector:InactiveObject_Changed\",\n\t\t\t\t\t\ttimeout: inactiveTimeoutMs,\n\t\t\t\t\t\t...tagCodeArtifacts({ id: nodes[3] }),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\t\"inactive events not as expected\",\n\t\t\t);\n\n\t\t\t// Advance the clock to trigger tombstone timeout and validate that TombstoneReady events are as expected.\n\t\t\tclock.tick(tombstoneTimeoutMs - inactiveTimeoutMs);\n\t\t\tmockNodeChanges(nodes);\n\t\t\tawait simulateGCToTriggerEvents(isSummarizerClient);\n\t\t\tassertMatchEvents(\n\t\t\t\t[\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"GarbageCollector:TombstoneReadyObject_Loaded\",\n\t\t\t\t\t\ttimeout: tombstoneTimeoutMs,\n\t\t\t\t\t\t...tagCodeArtifacts({ id: nodes[2] }),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"GarbageCollector:TombstoneReadyObject_Changed\",\n\t\t\t\t\t\ttimeout: tombstoneTimeoutMs,\n\t\t\t\t\t\t...tagCodeArtifacts({ id: nodes[2] }),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"GarbageCollector:TombstoneReadyObject_Loaded\",\n\t\t\t\t\t\ttimeout: tombstoneTimeoutMs,\n\t\t\t\t\t\t...tagCodeArtifacts({ id: nodes[3] }),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"GarbageCollector:TombstoneReadyObject_Changed\",\n\t\t\t\t\t\ttimeout: tombstoneTimeoutMs,\n\t\t\t\t\t\t...tagCodeArtifacts({ id: nodes[3] }),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\t\"tombstone ready events not as expected\",\n\t\t\t);\n\n\t\t\t// Advance the clock by the delay and validate that SweepReady events are as expected.\n\t\t\tclock.tick(sweepGracePeriodMs);\n\t\t\tmockNodeChanges(nodes);\n\t\t\tawait simulateGCToTriggerEvents(isSummarizerClient);\n\t\t\tassertMatchEvents(\n\t\t\t\t[\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"GarbageCollector:SweepReadyObject_Loaded\",\n\t\t\t\t\t\ttimeout: tombstoneTimeoutMs + sweepGracePeriodMs,\n\t\t\t\t\t\t...tagCodeArtifacts({ id: nodes[2] }),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"GarbageCollector:SweepReadyObject_Changed\",\n\t\t\t\t\t\ttimeout: tombstoneTimeoutMs + sweepGracePeriodMs,\n\t\t\t\t\t\t...tagCodeArtifacts({ id: nodes[2] }),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"GarbageCollector:SweepReadyObject_Loaded\",\n\t\t\t\t\t\ttimeout: tombstoneTimeoutMs + sweepGracePeriodMs,\n\t\t\t\t\t\t...tagCodeArtifacts({ id: nodes[3] }),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"GarbageCollector:SweepReadyObject_Changed\",\n\t\t\t\t\t\ttimeout: tombstoneTimeoutMs + sweepGracePeriodMs,\n\t\t\t\t\t\t...tagCodeArtifacts({ id: nodes[3] }),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\t\"sweep ready events not as expected\",\n\t\t\t);\n\t\t});\n\n\t\tit(\"generates tombstone revived events when nodes are used after they are tombstoned\", async () => {\n\t\t\ttelemetryTracker = createTelemetryTracker(true /* enable Sweep */, isSummarizerClient);\n\t\t\t// Mark node 2 as unreferenced.\n\t\t\tmarkNodesUnreferenced([nodes[2]]);\n\n\t\t\t// Advance the clock to trigger tombstone timeout and validate that tombstone revived event is as expected.\n\t\t\tclock.tick(tombstoneTimeoutMs + 1);\n\t\t\treviveNode(nodes[1], nodes[2], true /* isTombstoned */);\n\t\t\tmockLogger.assertMatch(\n\t\t\t\t[\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"GarbageCollector:GC_Tombstone_DataStore_Revived\",\n\t\t\t\t\t\tpkg: eventPkg,\n\t\t\t\t\t\t...tagCodeArtifacts({ id: nodes[2] }),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\t\"inactive events not as expected\",\n\t\t\t);\n\t\t});\n\n\t\t/** Tests that validate either the relevant events are logged as expected. */\n\t\tconst unreferencedPhasesEventTests = (\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\tbeforeEach(() => {\n\t\t\t\tif (sweepGracePeriodMsOverride !== undefined) {\n\t\t\t\t\tsweepGracePeriodMs = sweepGracePeriodMsOverride;\n\t\t\t\t}\n\t\t\t\ttelemetryTracker = createTelemetryTracker(\n\t\t\t\t\tmode !== \"inactive\" /* enableSweep */,\n\t\t\t\t\tisSummarizerClient,\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\tmockNodeChanges(nodes);\n\t\t\t\tawait simulateGCToTriggerEvents(isSummarizerClient);\n\t\t\t\tvalidateNoEvents();\n\n\t\t\t\t// Advance the clock to just before the timeout expires, update nodes and validate no events.\n\t\t\t\tclock.tick(timeout - 1);\n\t\t\t\tmockNodeChanges(nodes);\n\t\t\t\tawait simulateGCToTriggerEvents(isSummarizerClient);\n\t\t\t\tvalidateNoEvents();\n\n\t\t\t\t// Advance the clock to expire the timeout, update nodes and validate no events.\n\t\t\t\tclock.tick(1);\n\t\t\t\tmockNodeChanges(nodes);\n\t\t\t\tawait simulateGCToTriggerEvents(isSummarizerClient);\n\t\t\t\tvalidateNoEvents();\n\t\t\t});\n\n\t\t\tit(\"generates events for nodes that are used after state changes\", async () => {\n\t\t\t\t// Mark nodes 1 and 2 as unreferenced.\n\t\t\t\tmarkNodesUnreferenced([nodes[1], nodes[2]]);\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\tmockNodeChanges(nodes);\n\t\t\t\tawait simulateGCToTriggerEvents(isSummarizerClient);\n\t\t\t\tvalidateNoEvents();\n\n\t\t\t\t// Expire the timeout, update nodes and validate that all events for node 1 and node 2 are logged.\n\t\t\t\tclock.tick(1);\n\t\t\t\tmockNodeChanges(nodes);\n\t\t\t\tawait simulateGCToTriggerEvents(isSummarizerClient);\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[1], 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[1], 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[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);\n\t\t\t\tassertMatchEvents(expectedEvents, \"all events not as expected\");\n\n\t\t\t\t// Revived node 2 and validate that revived event is as expected.\n\t\t\t\treviveNode(nodes[0], nodes[2]);\n\t\t\t\tawait simulateGCToTriggerEvents(isSummarizerClient);\n\t\t\t\tassertMatchEvents(\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[0],\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 as expected\",\n\t\t\t\t);\n\t\t\t});\n\n\t\t\tit(\"generates events once per node\", async () => {\n\t\t\t\t// Mark node 2 as unreferenced.\n\t\t\t\tmarkNodesUnreferenced([nodes[2]]);\n\t\t\t\tawait simulateGCToTriggerEvents(isSummarizerClient);\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\tmockNodeChanges(nodes);\n\t\t\t\tawait simulateGCToTriggerEvents(isSummarizerClient);\n\t\t\t\tvalidateNoEvents();\n\n\t\t\t\t// Expire the timeout, updated nodes and validate that events are logged as expected.\n\t\t\t\tclock.tick(1);\n\t\t\t\tmockNodeChanges(nodes);\n\t\t\t\tawait simulateGCToTriggerEvents(isSummarizerClient);\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] }),\n\t\t\t\t\t\tpkg: eventPkg,\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] }),\n\t\t\t\t\t\tpkg: eventPkg,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tassertMatchEvents(expectedEvents, \"all events not as expected\");\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\tmockNodeChanges(nodes);\n\t\t\t\tawait simulateGCToTriggerEvents(isSummarizerClient);\n\t\t\t\tvalidateNoEvents();\n\t\t\t});\n\n\t\t\t// This test is only relevant for summarizer client because it does not log changed events if the node is revived.\n\t\t\tif (isSummarizerClient) {\n\t\t\t\tit(\"generates only revived event in summarizer when a node is updated and revived\", async () => {\n\t\t\t\t\t// Mark node 2 as unreferenced.\n\t\t\t\t\tmarkNodesUnreferenced([nodes[2]]);\n\n\t\t\t\t\t// Advance the clock just before the timeout and validate no unexpected events are logged.\n\t\t\t\t\tclock.tick(timeout - 1);\n\t\t\t\t\tmockNodeChanges(nodes);\n\t\t\t\t\tawait simulateGCToTriggerEvents(isSummarizerClient);\n\n\t\t\t\t\tvalidateNoEvents();\n\n\t\t\t\t\t// Expire the timeout and validate that only revived event is generated for node 2.\n\t\t\t\t\tclock.tick(1);\n\t\t\t\t\tmockNodeChanges([nodes[2]]);\n\t\t\t\t\treviveNode(nodes[1], nodes[2]);\n\t\t\t\t\tawait simulateGCToTriggerEvents(isSummarizerClient);\n\n\t\t\t\t\tfor (const event of mockLogger.events) {\n\t\t\t\t\t\tassert.notStrictEqual(\n\t\t\t\t\t\t\tevent.eventName,\n\t\t\t\t\t\t\tloadedEventName,\n\t\t\t\t\t\t\t\"Unexpected loaded event logged\",\n\t\t\t\t\t\t);\n\t\t\t\t\t\tassert.notStrictEqual(\n\t\t\t\t\t\t\tevent.eventName,\n\t\t\t\t\t\t\tchangedEventName,\n\t\t\t\t\t\t\t\"Unexpected changed event logged\",\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tassertMatchEvents(\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\teventName: revivedEventName,\n\t\t\t\t\t\t\t\ttimeout,\n\t\t\t\t\t\t\t\t...tagCodeArtifacts({\n\t\t\t\t\t\t\t\t\tid: nodes[2],\n\t\t\t\t\t\t\t\t\tfromId: nodes[1],\n\t\t\t\t\t\t\t\t\tpkg: testPkgPath.join(\"/\"),\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\"revived event not as expected\",\n\t\t\t\t\t);\n\t\t\t\t});\n\t\t\t}\n\t\t};\n\n\t\tdescribe(\"Inactive events\", () => {\n\t\t\tunreferencedPhasesEventTests(\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\", () => {\n\t\t\tunreferencedPhasesEventTests(\n\t\t\t\ttombstoneTimeoutMs,\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 (with no delay)\", () => {\n\t\t\tunreferencedPhasesEventTests(\n\t\t\t\ttombstoneTimeoutMs,\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\", () => {\n\t\t\tunreferencedPhasesEventTests(\n\t\t\t\ttombstoneTimeoutMs + sweepGracePeriodMs,\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\t};\n\n\tdescribe(\"Summarizer client\", () => {\n\t\tclientTypeTests(true /* isSummarizerClient */);\n\t});\n\n\tdescribe(\"Interactive client\", () => {\n\t\tclientTypeTests(false /* isSummarizerClient */);\n\t});\n\n\tdescribe(\"gcUnknownOutboundReferences telemetry\", () => {\n\t\tconst unknownReferenceEventName = \"GarbageCollector:gcUnknownOutboundReferences\";\n\t\tconst currentGCData: IGarbageCollectionData = { gcNodes: {} };\n\t\tlet previousGCData: IGarbageCollectionData;\n\t\tlet explicitReferences: Map<string, string[]>;\n\n\t\tbeforeEach(() => {\n\t\t\ttelemetryTracker = createTelemetryTracker(\n\t\t\t\ttrue /* enableSweep */,\n\t\t\t\ttrue /* isSummarizerClient */,\n\t\t\t);\n\n\t\t\tcurrentGCData.gcNodes[\"/\"] = [nodes[0]];\n\t\t\tcurrentGCData.gcNodes[nodes[0]] = [nodes[1]];\n\t\t\tcurrentGCData.gcNodes[nodes[1]] = [nodes[0], nodes[2]];\n\t\t\tcurrentGCData.gcNodes[nodes[2]] = [nodes[1], nodes[3]];\n\t\t\tcurrentGCData.gcNodes[nodes[3]] = [nodes[0]];\n\n\t\t\tpreviousGCData = cloneGCData(currentGCData);\n\t\t\texplicitReferences = new Map();\n\t\t});\n\n\t\tit(\"does not log gcUnknownOutboundReferences when there are no new references\", async () => {\n\t\t\ttelemetryTracker.logIfMissingExplicitReferences(\n\t\t\t\tcurrentGCData,\n\t\t\t\tpreviousGCData,\n\t\t\t\texplicitReferences,\n\t\t\t\tmc.logger,\n\t\t\t);\n\n\t\t\tmockLogger.assertMatchNone(\n\t\t\t\t[\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: unknownReferenceEventName,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\t\"There should be no gcUnknownOutboundReferences event\",\n\t\t\t);\n\t\t});\n\n\t\tit(\"logs gcUnknownOutboundReferences when there are unknown data store references\", async () => {\n\t\t\tconst id = nodes[0];\n\t\t\tconst routes = [nodes[2], nodes[3]];\n\t\t\tcurrentGCData.gcNodes[id] = routes;\n\n\t\t\ttelemetryTracker.logIfMissingExplicitReferences(\n\t\t\t\tcurrentGCData,\n\t\t\t\tpreviousGCData,\n\t\t\t\texplicitReferences,\n\t\t\t\tmc.logger,\n\t\t\t);\n\n\t\t\tmockLogger.assertMatch(\n\t\t\t\t[\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: unknownReferenceEventName,\n\t\t\t\t\t\t...tagCodeArtifacts({ id, routes: JSON.stringify(routes) }),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\t\"gcUnknownOutboundReferences event not logged as expected\",\n\t\t\t);\n\t\t});\n\n\t\tit(\"logs gcUnknownOutboundReferences when there are multiple unknown data store references\", async () => {\n\t\t\tconst id1 = nodes[0];\n\t\t\tconst routes1 = [nodes[2], nodes[3]];\n\t\t\tconst id2 = nodes[3];\n\t\t\tconst routes2 = [nodes[1], nodes[2]];\n\t\t\tcurrentGCData.gcNodes[id1] = routes1;\n\t\t\tcurrentGCData.gcNodes[id2] = routes2;\n\n\t\t\ttelemetryTracker.logIfMissingExplicitReferences(\n\t\t\t\tcurrentGCData,\n\t\t\t\tpreviousGCData,\n\t\t\t\texplicitReferences,\n\t\t\t\tmc.logger,\n\t\t\t);\n\n\t\t\tmockLogger.assertMatch(\n\t\t\t\t[\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: unknownReferenceEventName,\n\t\t\t\t\t\t...tagCodeArtifacts({ id: id1, routes: JSON.stringify(routes1) }),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: unknownReferenceEventName,\n\t\t\t\t\t\t...tagCodeArtifacts({ id: id2, routes: JSON.stringify(routes2) }),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\t\"gcUnknownOutboundReferences event not logged as expected\",\n\t\t\t);\n\t\t});\n\n\t\tit(\"logs gcUnknownOutboundReferences when there are unknown blob references\", async () => {\n\t\t\tconst id = nodes[0];\n\t\t\t// Id of type `/_blobs/id1 is treated as a blob node.\n\t\t\tconst routes = [\"/_blobs/id1\"];\n\t\t\tcurrentGCData.gcNodes[id] = routes;\n\n\t\t\ttelemetryTracker.logIfMissingExplicitReferences(\n\t\t\t\tcurrentGCData,\n\t\t\t\tpreviousGCData,\n\t\t\t\texplicitReferences,\n\t\t\t\tmc.logger,\n\t\t\t);\n\n\t\t\tmockLogger.assertMatch(\n\t\t\t\t[\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: unknownReferenceEventName,\n\t\t\t\t\t\t...tagCodeArtifacts({ id, routes: JSON.stringify(routes) }),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\t\"gcUnknownOutboundReferences event not logged as expected for blob nodes\",\n\t\t\t);\n\t\t});\n\n\t\tit(\"does not log gcUnknownOutboundReferences for back-routes (ex: DDS to data store)\", async () => {\n\t\t\t// Id of type `/id1/id2 is treated as a sub-data store (DDS) node.\n\t\t\tconst id = `${nodes[1]}/dds`;\n\t\t\tconst routes = [nodes[1]];\n\t\t\tcurrentGCData.gcNodes[id] = routes;\n\n\t\t\ttelemetryTracker.logIfMissingExplicitReferences(\n\t\t\t\tcurrentGCData,\n\t\t\t\tpreviousGCData,\n\t\t\t\texplicitReferences,\n\t\t\t\tmc.logger,\n\t\t\t);\n\n\t\t\tmockLogger.assertMatchNone(\n\t\t\t\t[\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: unknownReferenceEventName,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\t\"There should be no gcUnknownOutboundReferences event when back-routes are added\",\n\t\t\t);\n\t\t});\n\n\t\tit(\"does not log gcUnknownOutboundReferences for sub-dataStore routes (ex: to DDS)\", async () => {\n\t\t\tconst id = nodes[1];\n\t\t\t// Id of type `/id1/id2 is treated as a sub-data store (DDS) node.\n\t\t\tconst routes = [`${nodes[1]}/dds`];\n\t\t\tcurrentGCData.gcNodes[id] = routes;\n\n\t\t\ttelemetryTracker.logIfMissingExplicitReferences(\n\t\t\t\tcurrentGCData,\n\t\t\t\tpreviousGCData,\n\t\t\t\texplicitReferences,\n\t\t\t\tmc.logger,\n\t\t\t);\n\n\t\t\tmockLogger.assertMatchNone(\n\t\t\t\t[\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: unknownReferenceEventName,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\t\"There should be no gcUnknownOutboundReferences event when sub-dataStore routes are added\",\n\t\t\t);\n\t\t});\n\n\t\tit(\"does not log gcUnknownOutboundReferences for other routes (ex: unknown routes)\", async () => {\n\t\t\tconst id = nodes[1];\n\t\t\t// Id of type `/id1/id2/ids31` is treated as a other node type.\n\t\t\tconst routes = [`${nodes[1]}/ids2/ids3`];\n\t\t\tcurrentGCData.gcNodes[id] = routes;\n\n\t\t\ttelemetryTracker.logIfMissingExplicitReferences(\n\t\t\t\tcurrentGCData,\n\t\t\t\tpreviousGCData,\n\t\t\t\texplicitReferences,\n\t\t\t\tmc.logger,\n\t\t\t);\n\n\t\t\tmockLogger.assertMatchNone(\n\t\t\t\t[\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: unknownReferenceEventName,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\t\"There should be no gcUnknownOutboundReferences event when other node routes are added\",\n\t\t\t);\n\t\t});\n\t});\n});\n"]}
|
|
1
|
+
{"version":3,"file":"gcTelemetry.spec.js","sourceRoot":"","sources":["../../../src/test/gc/gcTelemetry.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 } from \"sinon\";\nimport { ITelemetryBaseEvent } from \"@fluidframework/core-interfaces\";\nimport { IGarbageCollectionData } from \"@fluidframework/runtime-definitions\";\nimport {\n\tMockLogger,\n\tTelemetryDataTag,\n\tmixinMonitoringContext,\n\tMonitoringContext,\n\tcreateChildLogger,\n\ttagCodeArtifacts,\n} from \"@fluidframework/telemetry-utils\";\nimport {\n\tGCNodeType,\n\tGCTelemetryTracker,\n\tdefaultSessionExpiryDurationMs,\n\toneDayMs,\n\tUnreferencedStateTracker,\n\tcloneGCData,\n\tIGarbageCollectorConfigs,\n\tstableGCVersion,\n} from \"../../gc/index.js\";\nimport { pkgVersion } from \"../../packageVersion.js\";\nimport { BlobManager } from \"../../blobManager.js\";\n\ndescribe(\"GC Telemetry Tracker\", () => {\n\tconst defaultSnapshotCacheExpiryMs = 5 * 24 * 60 * 60 * 1000;\n\tconst tombstoneTimeoutMs =\n\t\tdefaultSessionExpiryDurationMs + defaultSnapshotCacheExpiryMs + oneDayMs;\n\tconst inactiveTimeoutMs = 500;\n\n\t// Nodes in the reference graph.\n\tconst nodes: string[] = [\"/node1\", \"/node2\", \"/node3\", \"/node4\"];\n\n\tconst testPkgPath = [\"testPkg\"];\n\t// The package data is tagged in the telemetry event.\n\tconst eventPkg = { value: testPkgPath.join(\"/\"), tag: TelemetryDataTag.CodeArtifact };\n\n\tlet mockLogger: MockLogger;\n\tlet mc: MonitoringContext;\n\tlet clock: SinonFakeTimers;\n\tlet sweepGracePeriodMs = 1000; // Default case for these tests\n\tlet unreferencedNodesState: Map<string, UnreferencedStateTracker> = new Map();\n\tlet telemetryTracker: GCTelemetryTracker;\n\n\tfunction createTelemetryTracker(\n\t\tenableSweep: boolean,\n\t\tisSummarizerClient = true,\n\t): GCTelemetryTracker {\n\t\t// Node types are as follows based on the path:\n\t\t// Path starting with \"/_blobs\" - blob.\n\t\t// Path with one part such as \"/id1\" - data stores.\n\t\t// Path with two parts such as \"/id1/id2\" - sub data stores.\n\t\t// Everything else - other.\n\t\tconst getNodeType = (nodePath: string) => {\n\t\t\tif (nodePath.split(\"/\")[1] === BlobManager.basePath) {\n\t\t\t\treturn GCNodeType.Blob;\n\t\t\t}\n\t\t\tif (nodePath.split(\"/\").length === 2) {\n\t\t\t\treturn GCNodeType.DataStore;\n\t\t\t}\n\t\t\tif (nodePath.split(\"/\").length === 3) {\n\t\t\t\treturn GCNodeType.SubDataStore;\n\t\t\t}\n\t\t\treturn GCNodeType.Other;\n\t\t};\n\t\tconst configs: IGarbageCollectorConfigs = {\n\t\t\tgcEnabled: true,\n\t\t\tsweepEnabled: false,\n\t\t\tshouldRunGC: true,\n\t\t\tshouldRunSweep: \"NO\",\n\t\t\trunFullGC: false,\n\t\t\ttestMode: false,\n\t\t\ttombstoneMode: false,\n\t\t\tinactiveTimeoutMs,\n\t\t\tsessionExpiryTimeoutMs: defaultSessionExpiryDurationMs,\n\t\t\ttombstoneTimeoutMs: enableSweep ? tombstoneTimeoutMs : undefined,\n\t\t\tsweepGracePeriodMs,\n\t\t\tthrowOnTombstoneLoad: false,\n\t\t\tthrowOnTombstoneUsage: false,\n\t\t\tthrowOnInactiveLoad: false,\n\t\t\tpersistedGcFeatureMatrix: undefined,\n\t\t\tgcVersionInBaseSnapshot: stableGCVersion,\n\t\t\tgcVersionInEffect: stableGCVersion,\n\t\t};\n\t\tconst tracker = new GCTelemetryTracker(\n\t\t\tmc,\n\t\t\tconfigs,\n\t\t\tisSummarizerClient,\n\t\t\t{ createContainerRuntimeVersion: pkgVersion },\n\t\t\tgetNodeType,\n\t\t\t(nodeId: string) => unreferencedNodesState.get(nodeId),\n\t\t\tasync (nodeId: string) => testPkgPath,\n\t\t);\n\t\treturn tracker;\n\t}\n\n\t/**\n\t * For each node in nodeIds, add an entry in `unreferencedNodesState` indicating that the node was\n\t * just unreferenced.\n\t */\n\tfunction markNodesUnreferenced(nodeIds: string[]) {\n\t\tnodeIds.forEach((nodeId) => {\n\t\t\tunreferencedNodesState.set(\n\t\t\t\tnodeId,\n\t\t\t\tnew UnreferencedStateTracker(\n\t\t\t\t\tDate.now(),\n\t\t\t\t\tinactiveTimeoutMs,\n\t\t\t\t\tDate.now(),\n\t\t\t\t\ttombstoneTimeoutMs,\n\t\t\t\t\tsweepGracePeriodMs,\n\t\t\t\t),\n\t\t\t);\n\t\t});\n\t}\n\n\t// Mock node loaded and changed activity for the given nodes.\n\tfunction mockNodeChanges(nodeIds: string[]) {\n\t\tnodeIds.forEach((id) => {\n\t\t\ttelemetryTracker.nodeUsed(id, {\n\t\t\t\tid,\n\t\t\t\tusageType: \"Loaded\",\n\t\t\t\tcurrentReferenceTimestampMs: Date.now(),\n\t\t\t\tpackagePath: testPkgPath,\n\t\t\t\tcompletedGCRuns: 0,\n\t\t\t\tisTombstoned: false,\n\t\t\t});\n\t\t\ttelemetryTracker.nodeUsed(id, {\n\t\t\t\tid,\n\t\t\t\tusageType: \"Changed\",\n\t\t\t\tcurrentReferenceTimestampMs: Date.now(),\n\t\t\t\tpackagePath: testPkgPath,\n\t\t\t\tcompletedGCRuns: 0,\n\t\t\t\tisTombstoned: false,\n\t\t\t});\n\t\t});\n\t}\n\n\t// Mock node revived activity for the given nodes.\n\tfunction reviveNode(fromId: string, toId: string, isTombstoned = false) {\n\t\ttelemetryTracker.nodeUsed(toId, {\n\t\t\tid: toId,\n\t\t\tusageType: \"Revived\",\n\t\t\tcurrentReferenceTimestampMs: Date.now(),\n\t\t\tpackagePath: testPkgPath,\n\t\t\tcompletedGCRuns: 0,\n\t\t\tisTombstoned,\n\t\t\tfromId,\n\t\t});\n\t\tunreferencedNodesState.delete(toId);\n\t}\n\n\t/**\n\t * For summarizer clients, inactive / sweep ready events are not logged when on node usage. They are logged when GC\n\t * runs next time. This emulates that by calling the functions in the telemetry tracker that are called when GC runs.\n\t */\n\tasync function simulateGCToTriggerEvents(isSummarizerClient: boolean) {\n\t\tif (!isSummarizerClient) {\n\t\t\treturn;\n\t\t}\n\t\tawait telemetryTracker.logPendingEvents(mc.logger);\n\t}\n\n\tbefore(() => {\n\t\tclock = useFakeTimers();\n\t});\n\n\tbeforeEach(() => {\n\t\tmockLogger = new MockLogger();\n\t\tmc = mixinMonitoringContext(\n\t\t\tcreateChildLogger({ logger: mockLogger, namespace: \"GarbageCollector\" }),\n\t\t);\n\t\tunreferencedNodesState = new Map();\n\t});\n\n\tafterEach(() => {\n\t\tclock.reset();\n\t\tmockLogger.clear();\n\t\tsweepGracePeriodMs = 1000; // Default case for these tests\n\t});\n\n\tafter(() => {\n\t\tclock.restore();\n\t});\n\n\t// Tests that are run once for summarizer client and once for interactive client.\n\tconst clientTypeTests = (isSummarizerClient: boolean) => {\n\t\t/**\n\t\t * Asserts that the events are as expected based on whether its a summarizer client or not. In non-summarizer\n\t\t * clients, only \"InactiveObject_Loaded\", \"TombstoneReadyObject_Loaded\" and \"SweepReadyObject_Loaded\" events are logged.\n\t\t * \"_Changed\" and \"_Revived\" events are not logged.\n\t\t */\n\t\tfunction assertMatchEvents(\n\t\t\tevents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\t\tmessage: string,\n\t\t) {\n\t\t\tconst expectedEvents: Omit<ITelemetryBaseEvent, \"category\">[] = [];\n\t\t\tconst unexpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[] = [];\n\t\t\t// For non-summarizer clients, events that are not \"Loaded\" are unexpected. Everything else is expected.\n\t\t\tfor (const event of events) {\n\t\t\t\tconst eventName = event.eventName as string;\n\t\t\t\tif (!isSummarizerClient && !eventName.includes(\"Loaded\")) {\n\t\t\t\t\tunexpectedEvents.push(event);\n\t\t\t\t} else {\n\t\t\t\t\texpectedEvents.push(event);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Note that mock logger clears all events after one of the `match` functions is called. Since we call match\n\t\t\t// functions twice, cache the events and repopulate the mock logger with if after the first match call.\n\t\t\tconst cachedEvents = Array.from(mockLogger.events);\n\t\t\tmockLogger.assertMatch(expectedEvents, message, true /* inlineDetailsProp */);\n\t\t\tmockLogger.events = cachedEvents;\n\t\t\tmockLogger.assertMatchNone(unexpectedEvents, message, true /* inlineDetailsProp */);\n\t\t}\n\n\t\tit(\"generates inactive, tombstone ready, and sweep ready events when nodes are used after time out\", async () => {\n\t\t\ttelemetryTracker = createTelemetryTracker(true /* enable Sweep */, isSummarizerClient);\n\t\t\t// Mark nodes 2 and 3 as unreferenced.\n\t\t\tmarkNodesUnreferenced([nodes[2], nodes[3]]);\n\n\t\t\t// Advance the clock to trigger inactive timeout and validate that inactive events are as expected.\n\t\t\tclock.tick(inactiveTimeoutMs + 1);\n\t\t\tmockNodeChanges(nodes);\n\t\t\tawait simulateGCToTriggerEvents(isSummarizerClient);\n\t\t\tassertMatchEvents(\n\t\t\t\t[\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"GarbageCollector:InactiveObject_Loaded\",\n\t\t\t\t\t\ttimeout: inactiveTimeoutMs,\n\t\t\t\t\t\t...tagCodeArtifacts({ id: nodes[2] }),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"GarbageCollector:InactiveObject_Changed\",\n\t\t\t\t\t\ttimeout: inactiveTimeoutMs,\n\t\t\t\t\t\t...tagCodeArtifacts({ id: nodes[2] }),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"GarbageCollector:InactiveObject_Loaded\",\n\t\t\t\t\t\ttimeout: inactiveTimeoutMs,\n\t\t\t\t\t\t...tagCodeArtifacts({ id: nodes[3] }),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"GarbageCollector:InactiveObject_Changed\",\n\t\t\t\t\t\ttimeout: inactiveTimeoutMs,\n\t\t\t\t\t\t...tagCodeArtifacts({ id: nodes[3] }),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\t\"inactive events not as expected\",\n\t\t\t);\n\n\t\t\t// Advance the clock to trigger tombstone timeout and validate that TombstoneReady events are as expected.\n\t\t\tclock.tick(tombstoneTimeoutMs - inactiveTimeoutMs);\n\t\t\tmockNodeChanges(nodes);\n\t\t\tawait simulateGCToTriggerEvents(isSummarizerClient);\n\t\t\tassertMatchEvents(\n\t\t\t\t[\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"GarbageCollector:TombstoneReadyObject_Loaded\",\n\t\t\t\t\t\ttimeout: tombstoneTimeoutMs,\n\t\t\t\t\t\t...tagCodeArtifacts({ id: nodes[2] }),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"GarbageCollector:TombstoneReadyObject_Changed\",\n\t\t\t\t\t\ttimeout: tombstoneTimeoutMs,\n\t\t\t\t\t\t...tagCodeArtifacts({ id: nodes[2] }),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"GarbageCollector:TombstoneReadyObject_Loaded\",\n\t\t\t\t\t\ttimeout: tombstoneTimeoutMs,\n\t\t\t\t\t\t...tagCodeArtifacts({ id: nodes[3] }),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"GarbageCollector:TombstoneReadyObject_Changed\",\n\t\t\t\t\t\ttimeout: tombstoneTimeoutMs,\n\t\t\t\t\t\t...tagCodeArtifacts({ id: nodes[3] }),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\t\"tombstone ready events not as expected\",\n\t\t\t);\n\n\t\t\t// Advance the clock by the delay and validate that SweepReady events are as expected.\n\t\t\tclock.tick(sweepGracePeriodMs);\n\t\t\tmockNodeChanges(nodes);\n\t\t\tawait simulateGCToTriggerEvents(isSummarizerClient);\n\t\t\tassertMatchEvents(\n\t\t\t\t[\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"GarbageCollector:SweepReadyObject_Loaded\",\n\t\t\t\t\t\ttimeout: tombstoneTimeoutMs + sweepGracePeriodMs,\n\t\t\t\t\t\t...tagCodeArtifacts({ id: nodes[2] }),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"GarbageCollector:SweepReadyObject_Changed\",\n\t\t\t\t\t\ttimeout: tombstoneTimeoutMs + sweepGracePeriodMs,\n\t\t\t\t\t\t...tagCodeArtifacts({ id: nodes[2] }),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"GarbageCollector:SweepReadyObject_Loaded\",\n\t\t\t\t\t\ttimeout: tombstoneTimeoutMs + sweepGracePeriodMs,\n\t\t\t\t\t\t...tagCodeArtifacts({ id: nodes[3] }),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"GarbageCollector:SweepReadyObject_Changed\",\n\t\t\t\t\t\ttimeout: tombstoneTimeoutMs + sweepGracePeriodMs,\n\t\t\t\t\t\t...tagCodeArtifacts({ id: nodes[3] }),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\t\"sweep ready events not as expected\",\n\t\t\t);\n\t\t});\n\n\t\tit(\"generates tombstone revived events when nodes are used after they are tombstoned\", async () => {\n\t\t\ttelemetryTracker = createTelemetryTracker(true /* enable Sweep */, isSummarizerClient);\n\t\t\t// Mark node 2 as unreferenced.\n\t\t\tmarkNodesUnreferenced([nodes[2]]);\n\n\t\t\t// Advance the clock to trigger tombstone timeout and validate that tombstone revived event is as expected.\n\t\t\tclock.tick(tombstoneTimeoutMs + 1);\n\t\t\treviveNode(nodes[1], nodes[2], true /* isTombstoned */);\n\t\t\tmockLogger.assertMatch(\n\t\t\t\t[\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"GarbageCollector:GC_Tombstone_DataStore_Revived\",\n\t\t\t\t\t\tpkg: eventPkg,\n\t\t\t\t\t\t...tagCodeArtifacts({ id: nodes[2] }),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\t\"inactive events not as expected\",\n\t\t\t);\n\t\t});\n\n\t\t/** Tests that validate either the relevant events are logged as expected. */\n\t\tconst unreferencedPhasesEventTests = (\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\tbeforeEach(() => {\n\t\t\t\tif (sweepGracePeriodMsOverride !== undefined) {\n\t\t\t\t\tsweepGracePeriodMs = sweepGracePeriodMsOverride;\n\t\t\t\t}\n\t\t\t\ttelemetryTracker = createTelemetryTracker(\n\t\t\t\t\tmode !== \"inactive\" /* enableSweep */,\n\t\t\t\t\tisSummarizerClient,\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\tmockNodeChanges(nodes);\n\t\t\t\tawait simulateGCToTriggerEvents(isSummarizerClient);\n\t\t\t\tvalidateNoEvents();\n\n\t\t\t\t// Advance the clock to just before the timeout expires, update nodes and validate no events.\n\t\t\t\tclock.tick(timeout - 1);\n\t\t\t\tmockNodeChanges(nodes);\n\t\t\t\tawait simulateGCToTriggerEvents(isSummarizerClient);\n\t\t\t\tvalidateNoEvents();\n\n\t\t\t\t// Advance the clock to expire the timeout, update nodes and validate no events.\n\t\t\t\tclock.tick(1);\n\t\t\t\tmockNodeChanges(nodes);\n\t\t\t\tawait simulateGCToTriggerEvents(isSummarizerClient);\n\t\t\t\tvalidateNoEvents();\n\t\t\t});\n\n\t\t\tit(\"generates events for nodes that are used after state changes\", async () => {\n\t\t\t\t// Mark nodes 1 and 2 as unreferenced.\n\t\t\t\tmarkNodesUnreferenced([nodes[1], nodes[2]]);\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\tmockNodeChanges(nodes);\n\t\t\t\tawait simulateGCToTriggerEvents(isSummarizerClient);\n\t\t\t\tvalidateNoEvents();\n\n\t\t\t\t// Expire the timeout, update nodes and validate that all events for node 1 and node 2 are logged.\n\t\t\t\tclock.tick(1);\n\t\t\t\tmockNodeChanges(nodes);\n\t\t\t\tawait simulateGCToTriggerEvents(isSummarizerClient);\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[1], 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[1], 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[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);\n\t\t\t\tassertMatchEvents(expectedEvents, \"all events not as expected\");\n\n\t\t\t\t// Revived node 2 and validate that revived event is as expected.\n\t\t\t\treviveNode(nodes[0], nodes[2]);\n\t\t\t\tawait simulateGCToTriggerEvents(isSummarizerClient);\n\t\t\t\tassertMatchEvents(\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[0],\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 as expected\",\n\t\t\t\t);\n\t\t\t});\n\n\t\t\tit(\"generates events properly for untracked subDataStore paths\", async () => {\n\t\t\t\t// Mark node 1 as unreferenced.\n\t\t\t\tmarkNodesUnreferenced([nodes[1]]);\n\n\t\t\t\t// We'll mock a Loaded event for this path, passing the DataStore path as trackedId to ensure coverage\n\t\t\t\tconst subDataStorePath = `${nodes[1]}/something`;\n\n\t\t\t\t// Expire the timeout, update nodes and validate that all events for node 1 are logged.\n\t\t\t\tclock.tick(timeout);\n\t\t\t\ttelemetryTracker.nodeUsed(nodes[1], {\n\t\t\t\t\tid: subDataStorePath,\n\t\t\t\t\tusageType: \"Loaded\",\n\t\t\t\t\tcurrentReferenceTimestampMs: Date.now(),\n\t\t\t\t\tpackagePath: testPkgPath,\n\t\t\t\t\tcompletedGCRuns: 0,\n\t\t\t\t\tisTombstoned: false,\n\t\t\t\t});\n\t\t\t\tawait simulateGCToTriggerEvents(isSummarizerClient);\n\t\t\t\tconst expectedEvents: Omit<ITelemetryBaseEvent, \"category\">[] = [];\n\t\t\t\texpectedEvents.push({\n\t\t\t\t\teventName: loadedEventName,\n\t\t\t\t\ttimeout,\n\t\t\t\t\t...tagCodeArtifacts({ id: subDataStorePath, pkg: testPkgPath.join(\"/\") }),\n\t\t\t\t\tcreateContainerRuntimeVersion: pkgVersion,\n\t\t\t\t\tisTombstoned: false,\n\t\t\t\t\ttrackedId: nodes[1],\n\t\t\t\t\ttype: \"SubDataStore\",\n\t\t\t\t});\n\t\t\t\tassertMatchEvents(expectedEvents, \"all events not as expected\");\n\t\t\t});\n\n\t\t\tit(\"generates events once per node\", async () => {\n\t\t\t\t// Mark node 2 as unreferenced.\n\t\t\t\tmarkNodesUnreferenced([nodes[2]]);\n\t\t\t\tawait simulateGCToTriggerEvents(isSummarizerClient);\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\tmockNodeChanges(nodes);\n\t\t\t\tawait simulateGCToTriggerEvents(isSummarizerClient);\n\t\t\t\tvalidateNoEvents();\n\n\t\t\t\t// Expire the timeout, updated nodes and validate that events are logged as expected.\n\t\t\t\tclock.tick(1);\n\t\t\t\tmockNodeChanges(nodes);\n\t\t\t\tawait simulateGCToTriggerEvents(isSummarizerClient);\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] }),\n\t\t\t\t\t\tpkg: eventPkg,\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] }),\n\t\t\t\t\t\tpkg: eventPkg,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tassertMatchEvents(expectedEvents, \"all events not as expected\");\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\tmockNodeChanges(nodes);\n\t\t\t\tawait simulateGCToTriggerEvents(isSummarizerClient);\n\t\t\t\tvalidateNoEvents();\n\t\t\t});\n\n\t\t\t// This test is only relevant for summarizer client because it does not log changed events if the node is revived.\n\t\t\tif (isSummarizerClient) {\n\t\t\t\tit(\"generates only revived event in summarizer when a node is updated and revived\", async () => {\n\t\t\t\t\t// Mark node 2 as unreferenced.\n\t\t\t\t\tmarkNodesUnreferenced([nodes[2]]);\n\n\t\t\t\t\t// Advance the clock just before the timeout and validate no unexpected events are logged.\n\t\t\t\t\tclock.tick(timeout - 1);\n\t\t\t\t\tmockNodeChanges(nodes);\n\t\t\t\t\tawait simulateGCToTriggerEvents(isSummarizerClient);\n\n\t\t\t\t\tvalidateNoEvents();\n\n\t\t\t\t\t// Expire the timeout and validate that only revived event is generated for node 2.\n\t\t\t\t\tclock.tick(1);\n\t\t\t\t\tmockNodeChanges([nodes[2]]);\n\t\t\t\t\treviveNode(nodes[1], nodes[2]);\n\t\t\t\t\tawait simulateGCToTriggerEvents(isSummarizerClient);\n\n\t\t\t\t\tfor (const event of mockLogger.events) {\n\t\t\t\t\t\tassert.notStrictEqual(\n\t\t\t\t\t\t\tevent.eventName,\n\t\t\t\t\t\t\tloadedEventName,\n\t\t\t\t\t\t\t\"Unexpected loaded event logged\",\n\t\t\t\t\t\t);\n\t\t\t\t\t\tassert.notStrictEqual(\n\t\t\t\t\t\t\tevent.eventName,\n\t\t\t\t\t\t\tchangedEventName,\n\t\t\t\t\t\t\t\"Unexpected changed event logged\",\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tassertMatchEvents(\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\teventName: revivedEventName,\n\t\t\t\t\t\t\t\ttimeout,\n\t\t\t\t\t\t\t\t...tagCodeArtifacts({\n\t\t\t\t\t\t\t\t\tid: nodes[2],\n\t\t\t\t\t\t\t\t\tfromId: nodes[1],\n\t\t\t\t\t\t\t\t\tpkg: testPkgPath.join(\"/\"),\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\"revived event not as expected\",\n\t\t\t\t\t);\n\t\t\t\t});\n\t\t\t}\n\t\t};\n\n\t\tdescribe(\"Inactive events\", () => {\n\t\t\tunreferencedPhasesEventTests(\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\", () => {\n\t\t\tunreferencedPhasesEventTests(\n\t\t\t\ttombstoneTimeoutMs,\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 (with no delay)\", () => {\n\t\t\tunreferencedPhasesEventTests(\n\t\t\t\ttombstoneTimeoutMs,\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\", () => {\n\t\t\tunreferencedPhasesEventTests(\n\t\t\t\ttombstoneTimeoutMs + sweepGracePeriodMs,\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\t};\n\n\tdescribe(\"Summarizer client\", () => {\n\t\tclientTypeTests(true /* isSummarizerClient */);\n\t});\n\n\tdescribe(\"Interactive client\", () => {\n\t\tclientTypeTests(false /* isSummarizerClient */);\n\t});\n\n\tdescribe(\"gcUnknownOutboundReferences telemetry\", () => {\n\t\tconst unknownReferenceEventName = \"GarbageCollector:gcUnknownOutboundReferences\";\n\t\tconst currentGCData: IGarbageCollectionData = { gcNodes: {} };\n\t\tlet previousGCData: IGarbageCollectionData;\n\t\tlet explicitReferences: Map<string, string[]>;\n\n\t\tbeforeEach(() => {\n\t\t\ttelemetryTracker = createTelemetryTracker(\n\t\t\t\ttrue /* enableSweep */,\n\t\t\t\ttrue /* isSummarizerClient */,\n\t\t\t);\n\n\t\t\tcurrentGCData.gcNodes[\"/\"] = [nodes[0]];\n\t\t\tcurrentGCData.gcNodes[nodes[0]] = [nodes[1]];\n\t\t\tcurrentGCData.gcNodes[nodes[1]] = [nodes[0], nodes[2]];\n\t\t\tcurrentGCData.gcNodes[nodes[2]] = [nodes[1], nodes[3]];\n\t\t\tcurrentGCData.gcNodes[nodes[3]] = [nodes[0]];\n\n\t\t\tpreviousGCData = cloneGCData(currentGCData);\n\t\t\texplicitReferences = new Map();\n\t\t});\n\n\t\tit(\"does not log gcUnknownOutboundReferences when there are no new references\", async () => {\n\t\t\ttelemetryTracker.logIfMissingExplicitReferences(\n\t\t\t\tcurrentGCData,\n\t\t\t\tpreviousGCData,\n\t\t\t\texplicitReferences,\n\t\t\t\tmc.logger,\n\t\t\t);\n\n\t\t\tmockLogger.assertMatchNone(\n\t\t\t\t[\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: unknownReferenceEventName,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\t\"There should be no gcUnknownOutboundReferences event\",\n\t\t\t);\n\t\t});\n\n\t\tit(\"logs gcUnknownOutboundReferences when there are unknown data store references\", async () => {\n\t\t\tconst id = nodes[0];\n\t\t\tconst routes = [nodes[2], nodes[3]];\n\t\t\tcurrentGCData.gcNodes[id] = routes;\n\n\t\t\ttelemetryTracker.logIfMissingExplicitReferences(\n\t\t\t\tcurrentGCData,\n\t\t\t\tpreviousGCData,\n\t\t\t\texplicitReferences,\n\t\t\t\tmc.logger,\n\t\t\t);\n\n\t\t\tmockLogger.assertMatch(\n\t\t\t\t[\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: unknownReferenceEventName,\n\t\t\t\t\t\t...tagCodeArtifacts({ id, routes: JSON.stringify(routes) }),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\t\"gcUnknownOutboundReferences event not logged as expected\",\n\t\t\t);\n\t\t});\n\n\t\tit(\"logs gcUnknownOutboundReferences when there are multiple unknown data store references\", async () => {\n\t\t\tconst id1 = nodes[0];\n\t\t\tconst routes1 = [nodes[2], nodes[3]];\n\t\t\tconst id2 = nodes[3];\n\t\t\tconst routes2 = [nodes[1], nodes[2]];\n\t\t\tcurrentGCData.gcNodes[id1] = routes1;\n\t\t\tcurrentGCData.gcNodes[id2] = routes2;\n\n\t\t\ttelemetryTracker.logIfMissingExplicitReferences(\n\t\t\t\tcurrentGCData,\n\t\t\t\tpreviousGCData,\n\t\t\t\texplicitReferences,\n\t\t\t\tmc.logger,\n\t\t\t);\n\n\t\t\tmockLogger.assertMatch(\n\t\t\t\t[\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: unknownReferenceEventName,\n\t\t\t\t\t\t...tagCodeArtifacts({ id: id1, routes: JSON.stringify(routes1) }),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: unknownReferenceEventName,\n\t\t\t\t\t\t...tagCodeArtifacts({ id: id2, routes: JSON.stringify(routes2) }),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\t\"gcUnknownOutboundReferences event not logged as expected\",\n\t\t\t);\n\t\t});\n\n\t\tit(\"logs gcUnknownOutboundReferences when there are unknown blob references\", async () => {\n\t\t\tconst id = nodes[0];\n\t\t\t// Id of type `/_blobs/id1 is treated as a blob node.\n\t\t\tconst routes = [\"/_blobs/id1\"];\n\t\t\tcurrentGCData.gcNodes[id] = routes;\n\n\t\t\ttelemetryTracker.logIfMissingExplicitReferences(\n\t\t\t\tcurrentGCData,\n\t\t\t\tpreviousGCData,\n\t\t\t\texplicitReferences,\n\t\t\t\tmc.logger,\n\t\t\t);\n\n\t\t\tmockLogger.assertMatch(\n\t\t\t\t[\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: unknownReferenceEventName,\n\t\t\t\t\t\t...tagCodeArtifacts({ id, routes: JSON.stringify(routes) }),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\t\"gcUnknownOutboundReferences event not logged as expected for blob nodes\",\n\t\t\t);\n\t\t});\n\n\t\tit(\"does not log gcUnknownOutboundReferences for back-routes (ex: DDS to data store)\", async () => {\n\t\t\t// Id of type `/id1/id2 is treated as a sub-data store (DDS) node.\n\t\t\tconst id = `${nodes[1]}/dds`;\n\t\t\tconst routes = [nodes[1]];\n\t\t\tcurrentGCData.gcNodes[id] = routes;\n\n\t\t\ttelemetryTracker.logIfMissingExplicitReferences(\n\t\t\t\tcurrentGCData,\n\t\t\t\tpreviousGCData,\n\t\t\t\texplicitReferences,\n\t\t\t\tmc.logger,\n\t\t\t);\n\n\t\t\tmockLogger.assertMatchNone(\n\t\t\t\t[\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: unknownReferenceEventName,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\t\"There should be no gcUnknownOutboundReferences event when back-routes are added\",\n\t\t\t);\n\t\t});\n\n\t\tit(\"does not log gcUnknownOutboundReferences for sub-dataStore routes (ex: to DDS)\", async () => {\n\t\t\tconst id = nodes[1];\n\t\t\t// Id of type `/id1/id2 is treated as a sub-data store (DDS) node.\n\t\t\tconst routes = [`${nodes[1]}/dds`];\n\t\t\tcurrentGCData.gcNodes[id] = routes;\n\n\t\t\ttelemetryTracker.logIfMissingExplicitReferences(\n\t\t\t\tcurrentGCData,\n\t\t\t\tpreviousGCData,\n\t\t\t\texplicitReferences,\n\t\t\t\tmc.logger,\n\t\t\t);\n\n\t\t\tmockLogger.assertMatchNone(\n\t\t\t\t[\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: unknownReferenceEventName,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\t\"There should be no gcUnknownOutboundReferences event when sub-dataStore routes are added\",\n\t\t\t);\n\t\t});\n\n\t\tit(\"does not log gcUnknownOutboundReferences for other routes (ex: unknown routes)\", async () => {\n\t\t\tconst id = nodes[1];\n\t\t\t// Id of type `/id1/id2/ids31` is treated as a other node type.\n\t\t\tconst routes = [`${nodes[1]}/ids2/ids3`];\n\t\t\tcurrentGCData.gcNodes[id] = routes;\n\n\t\t\ttelemetryTracker.logIfMissingExplicitReferences(\n\t\t\t\tcurrentGCData,\n\t\t\t\tpreviousGCData,\n\t\t\t\texplicitReferences,\n\t\t\t\tmc.logger,\n\t\t\t);\n\n\t\t\tmockLogger.assertMatchNone(\n\t\t\t\t[\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: unknownReferenceEventName,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\t\"There should be no gcUnknownOutboundReferences event when other node routes are added\",\n\t\t\t);\n\t\t});\n\t});\n});\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/container-runtime",
|
|
3
|
-
"version": "2.0.0-rc.2.0.
|
|
3
|
+
"version": "2.0.0-rc.2.0.4",
|
|
4
4
|
"description": "Fluid container runtime",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -137,19 +137,19 @@
|
|
|
137
137
|
"temp-directory": "nyc/.nyc_output"
|
|
138
138
|
},
|
|
139
139
|
"dependencies": {
|
|
140
|
-
"@fluid-internal/client-utils": ">=2.0.0-rc.2.0.
|
|
141
|
-
"@fluidframework/container-definitions": ">=2.0.0-rc.2.0.
|
|
142
|
-
"@fluidframework/container-runtime-definitions": ">=2.0.0-rc.2.0.
|
|
143
|
-
"@fluidframework/core-interfaces": ">=2.0.0-rc.2.0.
|
|
144
|
-
"@fluidframework/core-utils": ">=2.0.0-rc.2.0.
|
|
145
|
-
"@fluidframework/datastore": ">=2.0.0-rc.2.0.
|
|
146
|
-
"@fluidframework/driver-definitions": ">=2.0.0-rc.2.0.
|
|
147
|
-
"@fluidframework/driver-utils": ">=2.0.0-rc.2.0.
|
|
148
|
-
"@fluidframework/id-compressor": ">=2.0.0-rc.2.0.
|
|
140
|
+
"@fluid-internal/client-utils": ">=2.0.0-rc.2.0.4 <2.0.0-rc.2.1.0",
|
|
141
|
+
"@fluidframework/container-definitions": ">=2.0.0-rc.2.0.4 <2.0.0-rc.2.1.0",
|
|
142
|
+
"@fluidframework/container-runtime-definitions": ">=2.0.0-rc.2.0.4 <2.0.0-rc.2.1.0",
|
|
143
|
+
"@fluidframework/core-interfaces": ">=2.0.0-rc.2.0.4 <2.0.0-rc.2.1.0",
|
|
144
|
+
"@fluidframework/core-utils": ">=2.0.0-rc.2.0.4 <2.0.0-rc.2.1.0",
|
|
145
|
+
"@fluidframework/datastore": ">=2.0.0-rc.2.0.4 <2.0.0-rc.2.1.0",
|
|
146
|
+
"@fluidframework/driver-definitions": ">=2.0.0-rc.2.0.4 <2.0.0-rc.2.1.0",
|
|
147
|
+
"@fluidframework/driver-utils": ">=2.0.0-rc.2.0.4 <2.0.0-rc.2.1.0",
|
|
148
|
+
"@fluidframework/id-compressor": ">=2.0.0-rc.2.0.4 <2.0.0-rc.2.1.0",
|
|
149
149
|
"@fluidframework/protocol-definitions": "^3.2.0",
|
|
150
|
-
"@fluidframework/runtime-definitions": ">=2.0.0-rc.2.0.
|
|
151
|
-
"@fluidframework/runtime-utils": ">=2.0.0-rc.2.0.
|
|
152
|
-
"@fluidframework/telemetry-utils": ">=2.0.0-rc.2.0.
|
|
150
|
+
"@fluidframework/runtime-definitions": ">=2.0.0-rc.2.0.4 <2.0.0-rc.2.1.0",
|
|
151
|
+
"@fluidframework/runtime-utils": ">=2.0.0-rc.2.0.4 <2.0.0-rc.2.1.0",
|
|
152
|
+
"@fluidframework/telemetry-utils": ">=2.0.0-rc.2.0.4 <2.0.0-rc.2.1.0",
|
|
153
153
|
"@tylerbu/sorted-btree-es6": "^1.8.0",
|
|
154
154
|
"double-ended-queue": "^2.1.0-0",
|
|
155
155
|
"lz4js": "^0.2.0",
|
|
@@ -157,15 +157,15 @@
|
|
|
157
157
|
},
|
|
158
158
|
"devDependencies": {
|
|
159
159
|
"@arethetypeswrong/cli": "^0.13.3",
|
|
160
|
-
"@fluid-internal/mocha-test-setup": ">=2.0.0-rc.2.0.
|
|
161
|
-
"@fluid-private/stochastic-test-utils": ">=2.0.0-rc.2.0.
|
|
160
|
+
"@fluid-internal/mocha-test-setup": ">=2.0.0-rc.2.0.4 <2.0.0-rc.2.1.0",
|
|
161
|
+
"@fluid-private/stochastic-test-utils": ">=2.0.0-rc.2.0.4 <2.0.0-rc.2.1.0",
|
|
162
162
|
"@fluid-tools/benchmark": "^0.48.0",
|
|
163
163
|
"@fluid-tools/build-cli": "^0.34.0",
|
|
164
164
|
"@fluidframework/build-common": "^2.0.3",
|
|
165
165
|
"@fluidframework/build-tools": "^0.34.0",
|
|
166
166
|
"@fluidframework/container-runtime-previous": "npm:@fluidframework/container-runtime@2.0.0-internal.8.0.0",
|
|
167
167
|
"@fluidframework/eslint-config-fluid": "^4.0.0",
|
|
168
|
-
"@fluidframework/test-runtime-utils": ">=2.0.0-rc.2.0.
|
|
168
|
+
"@fluidframework/test-runtime-utils": ">=2.0.0-rc.2.0.4 <2.0.0-rc.2.1.0",
|
|
169
169
|
"@microsoft/api-extractor": "^7.42.3",
|
|
170
170
|
"@types/double-ended-queue": "^2.1.0",
|
|
171
171
|
"@types/mocha": "^9.1.1",
|