@fluid-experimental/tree 1.0.0 → 1.1.0-76254
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/dist/EditLog.d.ts.map +1 -1
- package/dist/EditLog.js +4 -7
- package/dist/EditLog.js.map +1 -1
- package/dist/LogViewer.d.ts.map +1 -1
- package/dist/LogViewer.js +1 -7
- package/dist/LogViewer.js.map +1 -1
- package/dist/SharedTree.d.ts.map +1 -1
- package/dist/SharedTree.js +12 -12
- package/dist/SharedTree.js.map +1 -1
- package/dist/SharedTreeEncoder.d.ts.map +1 -1
- package/dist/SharedTreeEncoder.js +6 -12
- package/dist/SharedTreeEncoder.js.map +1 -1
- package/dist/TransactionInternal.d.ts.map +1 -1
- package/dist/TransactionInternal.js +4 -7
- package/dist/TransactionInternal.js.map +1 -1
- package/dist/id-compressor/IdCompressor.d.ts +3 -1
- package/dist/id-compressor/IdCompressor.d.ts.map +1 -1
- package/dist/id-compressor/IdCompressor.js +45 -17
- package/dist/id-compressor/IdCompressor.js.map +1 -1
- package/lib/EditLog.d.ts.map +1 -1
- package/lib/EditLog.js +4 -7
- package/lib/EditLog.js.map +1 -1
- package/lib/LogViewer.d.ts.map +1 -1
- package/lib/LogViewer.js +1 -7
- package/lib/LogViewer.js.map +1 -1
- package/lib/SharedTree.d.ts.map +1 -1
- package/lib/SharedTree.js +12 -12
- package/lib/SharedTree.js.map +1 -1
- package/lib/SharedTreeEncoder.d.ts.map +1 -1
- package/lib/SharedTreeEncoder.js +6 -12
- package/lib/SharedTreeEncoder.js.map +1 -1
- package/lib/TransactionInternal.d.ts.map +1 -1
- package/lib/TransactionInternal.js +4 -7
- package/lib/TransactionInternal.js.map +1 -1
- package/lib/id-compressor/IdCompressor.d.ts +3 -1
- package/lib/id-compressor/IdCompressor.d.ts.map +1 -1
- package/lib/id-compressor/IdCompressor.js +45 -17
- package/lib/id-compressor/IdCompressor.js.map +1 -1
- package/lib/test/MergeHealthTelemetryHeartbeat.tests.js +1 -1
- package/lib/test/MergeHealthTelemetryHeartbeat.tests.js.map +1 -1
- package/lib/test/SessionIdNormalizer.tests.js +4 -6
- package/lib/test/SessionIdNormalizer.tests.js.map +1 -1
- package/lib/test/Summary.tests.js +3 -6
- package/lib/test/Summary.tests.js.map +1 -1
- package/lib/test/utilities/SharedTreeTests.d.ts.map +1 -1
- package/lib/test/utilities/SharedTreeTests.js +33 -11
- package/lib/test/utilities/SharedTreeTests.js.map +1 -1
- package/lib/test/utilities/TestNode.d.ts.map +1 -1
- package/lib/test/utilities/TestNode.js +2 -12
- package/lib/test/utilities/TestNode.js.map +1 -1
- package/package.json +18 -18
- package/src/EditLog.ts +21 -23
- package/src/LogViewer.ts +1 -6
- package/src/SharedTree.ts +17 -16
- package/src/SharedTreeEncoder.ts +6 -17
- package/src/TransactionInternal.ts +11 -13
- package/src/id-compressor/IdCompressor.ts +46 -15
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MergeHealthTelemetryHeartbeat.tests.js","sourceRoot":"","sources":["../../src/test/MergeHealthTelemetryHeartbeat.tests.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 { expect } from 'chai';\nimport { ITelemetryBaseEvent } from '@fluidframework/common-definitions';\nimport { MockContainerRuntimeFactory } from '@fluidframework/test-runtime-utils';\nimport { SharedTreeMergeHealthTelemetryHeartbeat } from '../MergeHealth';\nimport { SequencedEditAppliedEventArguments, SharedTree } from '../SharedTree';\nimport { RevisionView } from '../RevisionView';\nimport { Change, ChangeType, StablePlace, StableRange } from '../ChangeTypes';\nimport { ConstraintEffect, EditStatus } from '../persisted-types';\nimport { TransactionInternal } from '../TransactionInternal';\nimport { buildLeaf, TestTree } from './utilities/TestNode';\nimport { setUpTestSharedTree, setUpTestTree } from './utilities/TestUtilities';\n\nasync function setupHeartbeat() {\n\tconst events: ITelemetryBaseEvent[] = [];\n\tconst { tree, containerRuntimeFactory } = setUpTestSharedTree({\n\t\tlocalMode: false,\n\t\tlogger: { send: (event) => events.push(event) },\n\t\tallowInvalid: true,\n\t});\n\tconst testTree = setUpTestTree(tree);\n\tconst { tree: concurrentTree } = setUpTestSharedTree({\n\t\tcontainerRuntimeFactory,\n\t\tid: 'secondTestSharedTree',\n\t\tlocalMode: false,\n\t\tallowInvalid: true,\n\t});\n\tconst heartbeat = new SharedTreeMergeHealthTelemetryHeartbeat();\n\tcontainerRuntimeFactory.processAllMessages();\n\tawait tree.logViewer.getRevisionView(Number.POSITIVE_INFINITY);\n\theartbeat.attachTree(tree);\n\treturn {\n\t\ttree,\n\t\ttestTree,\n\t\tconcurrentTree,\n\t\tcontainerRuntimeFactory,\n\t\tevents,\n\t\theartbeat,\n\t};\n}\n\nasync function flush(tree: SharedTree, containerRuntimeFactory: MockContainerRuntimeFactory): Promise<RevisionView> {\n\tcontainerRuntimeFactory.processAllMessages();\n\treturn tree.logViewer.getRevisionView(Number.POSITIVE_INFINITY);\n}\n\nfunction itAggregates(\n\tnameOfAggregatedData: string,\n\tparamFunc: (params: { tree: SharedTree; testTree: TestTree; concurrentTree: SharedTree }) => {\n\t\tedits: Change[][];\n\t\tconcurrentEdits?: Change[][];\n\t\taction: (ITelemetryBaseEvent) => void;\n\t}\n): Mocha.Test {\n\treturn it(`Aggregates ${nameOfAggregatedData}`, async () => {\n\t\tconst { tree, testTree, concurrentTree, containerRuntimeFactory, events, heartbeat } = await setupHeartbeat();\n\t\tconst params = paramFunc({ tree, testTree, concurrentTree });\n\t\theartbeat.clearData();\n\t\tif (params.concurrentEdits !== undefined) {\n\t\t\tfor (const edit of params.concurrentEdits) {\n\t\t\t\tconcurrentTree.applyEdit(...edit);\n\t\t\t}\n\t\t}\n\t\tfor (const edit of params.edits) {\n\t\t\ttree.applyEdit(...edit);\n\t\t}\n\t\tawait flush(tree, containerRuntimeFactory);\n\t\theartbeat.flushHeartbeat();\n\t\texpect(events.length).greaterThan(0);\n\t\tparams.action(events[events.length - 1]);\n\t});\n}\n\nfunction itAggregatesMocked(\n\tnameOfAggregatedData: string,\n\tparams: readonly Partial<Record<keyof SequencedEditAppliedEventArguments, unknown>>[],\n\taction: (ITelemetryBaseEvent) => void\n): Mocha.Test {\n\treturn it(`Aggregates mocked ${nameOfAggregatedData}`, () => {\n\t\tconst events: ITelemetryBaseEvent[] = [];\n\t\tconst logger = { send: (event) => events.push(event) };\n\t\tconst heartbeat = new SharedTreeMergeHealthTelemetryHeartbeat();\n\t\tlet savedListener!: (...args: any[]) => void;\n\t\tconst mockTree = {\n\t\t\ton: (event: string, listener: (...args: any[]) => void) => {\n\t\t\t\tsavedListener = listener;\n\t\t\t},\n\t\t};\n\t\theartbeat.attachTree(mockTree as SharedTree);\n\t\tfor (const param of params) {\n\t\t\tsavedListener({\n\t\t\t\ttree: mockTree,\n\t\t\t\tlogger,\n\t\t\t\tedit: {},\n\t\t\t\treconciliationPath: [],\n\t\t\t\tsteps: [],\n\t\t\t\twasLocal: true,\n\t\t\t\toutcome: {\n\t\t\t\t\tstatus: EditStatus.Applied,\n\t\t\t\t},\n\t\t\t\t...param,\n\t\t\t});\n\t\t}\n\t\theartbeat.flushHeartbeat();\n\t\texpect(events.length).greaterThan(0);\n\t\tconst event = events[events.length - 1];\n\t\taction(event);\n\t});\n}\n\ndescribe('SharedTreeMergeHealthTelemetryHeartbeat', () => {\n\tit('Does not automatically send data synchronously', async () => {\n\t\tconst { tree, testTree, containerRuntimeFactory, events, heartbeat } = await setupHeartbeat();\n\t\ttree.applyEdit(...Change.insertTree([testTree.buildLeaf()], StablePlace.after(testTree.left)));\n\t\tawait flush(tree, containerRuntimeFactory);\n\t\t// Expect some data to have made it to the heartbeat\n\t\texpect(heartbeat.getStats(tree).editCount).equals(1);\n\t\t// Expect no data was sent to the logger\n\t\texpect(events).deep.equals([]);\n\t});\n\n\tit('Can be flushed synchronously', async () => {\n\t\tconst { tree, testTree, containerRuntimeFactory, events, heartbeat } = await setupHeartbeat();\n\t\ttree.applyEdit(...Change.insertTree([testTree.buildLeaf()], StablePlace.after(testTree.left)));\n\t\tawait flush(tree, containerRuntimeFactory);\n\t\theartbeat.flushHeartbeat();\n\t\texpect(events.length).equals(1);\n\t\texpect(events[0]).contains({\n\t\t\tcategory: 'Heartbeat',\n\t\t\teventName: 'SharedTree:SequencedEditApplied:EditMergeHealth',\n\t\t});\n\t});\n\n\tit('Does not send data if no local edits have been made', async () => {\n\t\tconst { tree, testTree, concurrentTree, containerRuntimeFactory, events, heartbeat } = await setupHeartbeat();\n\t\tconcurrentTree.applyEdit(\n\t\t\t...Change.insertTree([buildLeaf()], StablePlace.after(testTree.left.translateId(concurrentTree)))\n\t\t);\n\t\tawait flush(tree, containerRuntimeFactory);\n\t\theartbeat.flushHeartbeat();\n\t\texpect(events.length).equals(0);\n\t});\n\n\tdescribe('Aggregates merge health data', () => {\n\t\titAggregates('edit counts', ({ testTree }) => ({\n\t\t\tedits: [\n\t\t\t\tChange.insertTree([testTree.buildLeaf()], StablePlace.after(testTree.left)),\n\t\t\t\tChange.insertTree(\n\t\t\t\t\t[testTree.buildLeaf()],\n\t\t\t\t\tStablePlace.after(testTree.buildLeaf(testTree.generateNodeId()))\n\t\t\t\t),\n\t\t\t],\n\t\t\taction: (event) => {\n\t\t\t\texpect(event.editCount).equals(2);\n\t\t\t\texpect(event.failedEditCount).equals(1);\n\t\t\t},\n\t\t}));\n\n\t\titAggregates('preventable place failures', ({ testTree, concurrentTree }) => ({\n\t\t\tconcurrentEdits: [[Change.delete(StableRange.only(testTree.left.translateId(concurrentTree)))]],\n\t\t\tedits: [Change.insertTree([testTree.buildLeaf()], StablePlace.after(testTree.left))],\n\t\t\taction: (event) => {\n\t\t\t\texpect(event.failedEditCount).equals(1);\n\t\t\t\texpect(event.badPlaceCount).equals(1);\n\t\t\t\texpect(event.deletedSiblingBadPlaceCount).equals(1);\n\t\t\t\texpect(event.deletedAncestorBadPlaceCount).equals(0);\n\t\t\t},\n\t\t}));\n\n\t\titAggregates(\n\t\t\t'failures for the parent of a sibling-based place being deleted',\n\t\t\t({ testTree, concurrentTree }) => ({\n\t\t\t\tconcurrentEdits: [[Change.delete(StableRange.only(testTree.translateId(concurrentTree)))]],\n\t\t\t\tedits: [Change.insertTree([testTree.buildLeaf()], StablePlace.after(testTree.left))],\n\t\t\t\taction: (event) => {\n\t\t\t\t\texpect(event.failedEditCount).equals(1);\n\t\t\t\t\texpect(event.badPlaceCount).equals(1);\n\t\t\t\t\texpect(event.deletedSiblingBadPlaceCount).equals(1);\n\t\t\t\t\texpect(event.deletedAncestorBadPlaceCount).equals(0);\n\t\t\t\t},\n\t\t\t})\n\t\t);\n\n\t\titAggregates(\n\t\t\t'failures for a range made of valid places in different traits',\n\t\t\t({ testTree, concurrentTree }) => ({\n\t\t\t\t// Move the \"right\" node to another trait to make the range invalid\n\t\t\t\tconcurrentEdits: [\n\t\t\t\t\tChange.move(\n\t\t\t\t\t\tStableRange.only(testTree.left.translateId(concurrentTree)),\n\t\t\t\t\t\tStablePlace.atEndOf(testTree.right.traitLocation.translate(concurrentTree))\n\t\t\t\t\t),\n\t\t\t\t],\n\t\t\t\tedits: [\n\t\t\t\t\t[\n\t\t\t\t\t\tChange.delete(\n\t\t\t\t\t\t\tStableRange.from(StablePlace.before(testTree.left)).to(\n\t\t\t\t\t\t\t\tStablePlace.atEndOf(testTree.left.traitLocation)\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],\n\t\t\t\taction: (event) => {\n\t\t\t\t\texpect(event.failedEditCount).equals(1);\n\t\t\t\t\texpect(event.badRangeCount).equals(1);\n\t\t\t\t\texpect(event.deletedSiblingBadRangeCount).equals(0);\n\t\t\t\t\texpect(event.updatedRangeHasPlacesInDifferentTraitsCount).equals(1);\n\t\t\t\t},\n\t\t\t})\n\t\t);\n\n\t\titAggregates('failures for a range made of valid places that are inverted', ({ testTree, concurrentTree }) => ({\n\t\t\t// Move the \"right\" node to the start of the trait to make the range inverted\n\t\t\tconcurrentEdits: [\n\t\t\t\tChange.move(\n\t\t\t\t\tStableRange.only(testTree.right.translateId(concurrentTree)),\n\t\t\t\t\tStablePlace.atStartOf(testTree.left.traitLocation.translate(concurrentTree))\n\t\t\t\t),\n\t\t\t],\n\t\t\tedits: [\n\t\t\t\t[\n\t\t\t\t\tChange.delete(\n\t\t\t\t\t\tStableRange.from(StablePlace.after(testTree.left)).to(StablePlace.before(testTree.right))\n\t\t\t\t\t),\n\t\t\t\t],\n\t\t\t],\n\t\t\taction: (event) => {\n\t\t\t\texpect(event.failedEditCount).equals(1);\n\t\t\t\texpect(event.badRangeCount).equals(1);\n\t\t\t\texpect(event.deletedSiblingBadRangeCount).equals(0);\n\t\t\t\texpect(event.updatedRangeInvertedCount).equals(1);\n\t\t\t},\n\t\t}));\n\n\t\titAggregates(\n\t\t\t'failures for the parent of a parent-based place being deleted',\n\t\t\t({ testTree, concurrentTree }) => ({\n\t\t\t\tconcurrentEdits: [[Change.delete(StableRange.only(testTree.left.translateId(concurrentTree)))]],\n\t\t\t\tedits: [\n\t\t\t\t\tChange.insertTree(\n\t\t\t\t\t\t[testTree.buildLeaf()],\n\t\t\t\t\t\tStablePlace.atStartOf({ parent: testTree.left.identifier, label: testTree.left.traitLabel })\n\t\t\t\t\t),\n\t\t\t\t],\n\t\t\t\taction: (event) => {\n\t\t\t\t\texpect(event.failedEditCount).equals(1);\n\t\t\t\t\texpect(event.badPlaceCount).equals(1);\n\t\t\t\t\texpect(event.deletedSiblingBadPlaceCount).equals(0);\n\t\t\t\t\texpect(event.deletedAncestorBadPlaceCount).equals(1);\n\t\t\t\t},\n\t\t\t})\n\t\t);\n\n\t\titAggregates('preventable range failures', ({ testTree, concurrentTree }) => ({\n\t\t\tconcurrentEdits: [[Change.delete(StableRange.only(testTree.left.translateId(concurrentTree)))]],\n\t\t\tedits: [[Change.delete(StableRange.only(testTree.left))]],\n\t\t\taction: (event) => {\n\t\t\t\texpect(event.failedEditCount).equals(1);\n\t\t\t\texpect(event.badRangeCount).equals(1);\n\t\t\t},\n\t\t}));\n\n\t\titAggregates('range constraint violations', ({ testTree, concurrentTree }) => ({\n\t\t\tconcurrentEdits: [[Change.delete(StableRange.only(testTree.left.translateId(concurrentTree)))]],\n\t\t\tedits: [\n\t\t\t\t[\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: ChangeType.Constraint,\n\t\t\t\t\t\ttoConstrain: StableRange.only(testTree.left),\n\t\t\t\t\t\teffect: ConstraintEffect.InvalidAndDiscard,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t],\n\t\t\taction: (event) => {\n\t\t\t\texpect(event.failedEditCount).equals(1);\n\t\t\t\texpect(event.constraintViolationCount).equals(1);\n\t\t\t\texpect(event.rangeConstraintViolationCount).equals(1);\n\t\t\t},\n\t\t}));\n\n\t\titAggregates('length constraint violations', ({ testTree, concurrentTree }) => ({\n\t\t\tconcurrentEdits: [\n\t\t\t\tChange.move(\n\t\t\t\t\tStableRange.only(testTree.right.translateId(concurrentTree)),\n\t\t\t\t\tStablePlace.after(testTree.left.translateId(concurrentTree))\n\t\t\t\t),\n\t\t\t],\n\t\t\tedits: [\n\t\t\t\t[\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: ChangeType.Constraint,\n\t\t\t\t\t\ttoConstrain: StableRange.all(testTree.left.traitLocation),\n\t\t\t\t\t\tlength: 1,\n\t\t\t\t\t\teffect: ConstraintEffect.InvalidAndDiscard,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t],\n\t\t\taction: (event) => {\n\t\t\t\texpect(event.failedEditCount).equals(1);\n\t\t\t\texpect(event.constraintViolationCount).equals(1);\n\t\t\t\texpect(event.lengthConstraintViolationCount).equals(1);\n\t\t\t},\n\t\t}));\n\n\t\titAggregates('parent constraint violations', ({ testTree, concurrentTree }) => ({\n\t\t\tconcurrentEdits: [\n\t\t\t\tChange.move(\n\t\t\t\t\tStableRange.only(testTree.right.translateId(concurrentTree)),\n\t\t\t\t\tStablePlace.atStartOf({\n\t\t\t\t\t\tparent: testTree.left.translateId(concurrentTree),\n\t\t\t\t\t\tlabel: testTree.left.traitLabel,\n\t\t\t\t\t})\n\t\t\t\t),\n\t\t\t],\n\t\t\tedits: [\n\t\t\t\t[\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: ChangeType.Constraint,\n\t\t\t\t\t\ttoConstrain: StableRange.only(testTree.right),\n\t\t\t\t\t\tparentNode: testTree.identifier,\n\t\t\t\t\t\teffect: ConstraintEffect.InvalidAndDiscard,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t],\n\t\t\taction: (event) => {\n\t\t\t\texpect(event.failedEditCount).equals(1);\n\t\t\t\texpect(event.constraintViolationCount).equals(1);\n\t\t\t\texpect(event.parentConstraintViolationCount).equals(1);\n\t\t\t},\n\t\t}));\n\n\t\titAggregates('label constraint violations', ({ testTree, concurrentTree }) => ({\n\t\t\tconcurrentEdits: [\n\t\t\t\tChange.move(\n\t\t\t\t\tStableRange.only(testTree.left.translateId(concurrentTree)),\n\t\t\t\t\tStablePlace.after(testTree.right.translateId(concurrentTree))\n\t\t\t\t),\n\t\t\t],\n\t\t\tedits: [\n\t\t\t\t[\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: ChangeType.Constraint,\n\t\t\t\t\t\ttoConstrain: StableRange.only(testTree.left),\n\t\t\t\t\t\tlabel: testTree.left.traitLabel,\n\t\t\t\t\t\teffect: ConstraintEffect.InvalidAndDiscard,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t],\n\t\t\taction: (event) => {\n\t\t\t\texpect(event.failedEditCount).equals(1);\n\t\t\t\texpect(event.constraintViolationCount).equals(1);\n\t\t\t\texpect(event.labelConstraintViolationCount).equals(1);\n\t\t\t},\n\t\t}));\n\n\t\titAggregates('failures due to ID collisions', ({ testTree, concurrentTree }) => {\n\t\t\tconst duplicateOverride = 'duplicate ID';\n\t\t\treturn {\n\t\t\t\tconcurrentEdits: [\n\t\t\t\t\tChange.insertTree(\n\t\t\t\t\t\t[buildLeaf(concurrentTree.generateNodeId(duplicateOverride))],\n\t\t\t\t\t\tStablePlace.after(testTree.left.translateId(concurrentTree))\n\t\t\t\t\t),\n\t\t\t\t],\n\t\t\t\tedits: [\n\t\t\t\t\tChange.insertTree(\n\t\t\t\t\t\t[testTree.buildLeaf(testTree.generateNodeId(duplicateOverride))],\n\t\t\t\t\t\tStablePlace.after(testTree.left)\n\t\t\t\t\t),\n\t\t\t\t],\n\t\t\t\taction: (event) => {\n\t\t\t\t\texpect(event.failedEditCount).equals(1);\n\t\t\t\t\texpect(event.idAlreadyInUseCount).equals(1);\n\t\t\t\t},\n\t\t\t};\n\t\t});\n\n\t\titAggregates('failures due unknown IDs', ({ testTree, concurrentTree }) => ({\n\t\t\tconcurrentEdits: [[Change.delete(StableRange.only(testTree.left.translateId(concurrentTree)))]],\n\t\t\tedits: [[Change.clearPayload(testTree.left.identifier)]],\n\t\t\taction: (event) => {\n\t\t\t\texpect(event.failedEditCount).equals(1);\n\t\t\t\texpect(event.unknownIdCount).equals(1);\n\t\t\t},\n\t\t}));\n\n\t\t// This test uses itAggregatesMocked to streamline the test code\n\t\titAggregatesMocked(\n\t\t\t'path length',\n\t\t\t[\n\t\t\t\t{ reconciliationPath: { length: 0 } },\n\t\t\t\t{ reconciliationPath: { length: 1 } },\n\t\t\t\t{ reconciliationPath: { length: 1 } },\n\t\t\t\t{ reconciliationPath: { length: 2 } },\n\t\t\t\t{ reconciliationPath: { length: 42 } },\n\t\t\t],\n\t\t\t(event) => {\n\t\t\t\texpect(event.pathLengths).equals('0:1,1:2,2:1,42:1');\n\t\t\t}\n\t\t);\n\n\t\t// This test uses itAggregatesMocked because multiple attempts are currently not being made\n\t\titAggregatesMocked(\n\t\t\t'maximum attempt number for an edit',\n\t\t\t[\n\t\t\t\t{\n\t\t\t\t\tedit: { pastAttemptCount: 40 },\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tedit: { pastAttemptCount: 42 },\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tedit: { pastAttemptCount: 41 },\n\t\t\t\t},\n\t\t\t],\n\t\t\t(event) => {\n\t\t\t\texpect(event.maxAttemptCount).equals(42);\n\t\t\t}\n\t\t);\n\n\t\t// This test uses itAggregatesMocked because there should be no way for a sequenced edit to become a malformed edit in\n\t\t// the face of concurrent edits.\n\t\titAggregatesMocked(\n\t\t\t'failures due malformed edits',\n\t\t\t[\n\t\t\t\t{\n\t\t\t\t\toutcome: {\n\t\t\t\t\t\tstatus: EditStatus.Malformed,\n\t\t\t\t\t\tfailure: { kind: TransactionInternal.FailureKind.UnusedDetachedSequence },\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t],\n\t\t\t(event) => {\n\t\t\t\t// This test has to mock a lot of things because there should be no way for a sequenced edit to become a malformed edit in the\n\t\t\t\t// face of concurrent edits.\n\t\t\t\texpect(event.failedEditCount).equals(1);\n\t\t\t\texpect(event.malformedEditCount).equals(1);\n\t\t\t}\n\t\t);\n\t});\n});\n"]}
|
|
1
|
+
{"version":3,"file":"MergeHealthTelemetryHeartbeat.tests.js","sourceRoot":"","sources":["../../src/test/MergeHealthTelemetryHeartbeat.tests.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 { expect } from 'chai';\nimport { ITelemetryBaseEvent } from '@fluidframework/common-definitions';\nimport { MockContainerRuntimeFactory } from '@fluidframework/test-runtime-utils';\nimport { SharedTreeMergeHealthTelemetryHeartbeat } from '../MergeHealth';\nimport { SequencedEditAppliedEventArguments, SharedTree } from '../SharedTree';\nimport { RevisionView } from '../RevisionView';\nimport { Change, ChangeType, StablePlace, StableRange } from '../ChangeTypes';\nimport { ConstraintEffect, EditStatus } from '../persisted-types';\nimport { TransactionInternal } from '../TransactionInternal';\nimport { buildLeaf, TestTree } from './utilities/TestNode';\nimport { setUpTestSharedTree, setUpTestTree } from './utilities/TestUtilities';\n\nasync function setupHeartbeat() {\n\tconst events: ITelemetryBaseEvent[] = [];\n\tconst { tree, containerRuntimeFactory } = setUpTestSharedTree({\n\t\tlocalMode: false,\n\t\tlogger: { send: (event) => !event.eventName.includes('IdCompressor') && events.push(event) },\n\t\tallowInvalid: true,\n\t});\n\tconst testTree = setUpTestTree(tree);\n\tconst { tree: concurrentTree } = setUpTestSharedTree({\n\t\tcontainerRuntimeFactory,\n\t\tid: 'secondTestSharedTree',\n\t\tlocalMode: false,\n\t\tallowInvalid: true,\n\t});\n\tconst heartbeat = new SharedTreeMergeHealthTelemetryHeartbeat();\n\tcontainerRuntimeFactory.processAllMessages();\n\tawait tree.logViewer.getRevisionView(Number.POSITIVE_INFINITY);\n\theartbeat.attachTree(tree);\n\treturn {\n\t\ttree,\n\t\ttestTree,\n\t\tconcurrentTree,\n\t\tcontainerRuntimeFactory,\n\t\tevents,\n\t\theartbeat,\n\t};\n}\n\nasync function flush(tree: SharedTree, containerRuntimeFactory: MockContainerRuntimeFactory): Promise<RevisionView> {\n\tcontainerRuntimeFactory.processAllMessages();\n\treturn tree.logViewer.getRevisionView(Number.POSITIVE_INFINITY);\n}\n\nfunction itAggregates(\n\tnameOfAggregatedData: string,\n\tparamFunc: (params: { tree: SharedTree; testTree: TestTree; concurrentTree: SharedTree }) => {\n\t\tedits: Change[][];\n\t\tconcurrentEdits?: Change[][];\n\t\taction: (ITelemetryBaseEvent) => void;\n\t}\n): Mocha.Test {\n\treturn it(`Aggregates ${nameOfAggregatedData}`, async () => {\n\t\tconst { tree, testTree, concurrentTree, containerRuntimeFactory, events, heartbeat } = await setupHeartbeat();\n\t\tconst params = paramFunc({ tree, testTree, concurrentTree });\n\t\theartbeat.clearData();\n\t\tif (params.concurrentEdits !== undefined) {\n\t\t\tfor (const edit of params.concurrentEdits) {\n\t\t\t\tconcurrentTree.applyEdit(...edit);\n\t\t\t}\n\t\t}\n\t\tfor (const edit of params.edits) {\n\t\t\ttree.applyEdit(...edit);\n\t\t}\n\t\tawait flush(tree, containerRuntimeFactory);\n\t\theartbeat.flushHeartbeat();\n\t\texpect(events.length).greaterThan(0);\n\t\tparams.action(events[events.length - 1]);\n\t});\n}\n\nfunction itAggregatesMocked(\n\tnameOfAggregatedData: string,\n\tparams: readonly Partial<Record<keyof SequencedEditAppliedEventArguments, unknown>>[],\n\taction: (ITelemetryBaseEvent) => void\n): Mocha.Test {\n\treturn it(`Aggregates mocked ${nameOfAggregatedData}`, () => {\n\t\tconst events: ITelemetryBaseEvent[] = [];\n\t\tconst logger = { send: (event) => events.push(event) };\n\t\tconst heartbeat = new SharedTreeMergeHealthTelemetryHeartbeat();\n\t\tlet savedListener!: (...args: any[]) => void;\n\t\tconst mockTree = {\n\t\t\ton: (event: string, listener: (...args: any[]) => void) => {\n\t\t\t\tsavedListener = listener;\n\t\t\t},\n\t\t};\n\t\theartbeat.attachTree(mockTree as SharedTree);\n\t\tfor (const param of params) {\n\t\t\tsavedListener({\n\t\t\t\ttree: mockTree,\n\t\t\t\tlogger,\n\t\t\t\tedit: {},\n\t\t\t\treconciliationPath: [],\n\t\t\t\tsteps: [],\n\t\t\t\twasLocal: true,\n\t\t\t\toutcome: {\n\t\t\t\t\tstatus: EditStatus.Applied,\n\t\t\t\t},\n\t\t\t\t...param,\n\t\t\t});\n\t\t}\n\t\theartbeat.flushHeartbeat();\n\t\texpect(events.length).greaterThan(0);\n\t\tconst event = events[events.length - 1];\n\t\taction(event);\n\t});\n}\n\ndescribe('SharedTreeMergeHealthTelemetryHeartbeat', () => {\n\tit('Does not automatically send data synchronously', async () => {\n\t\tconst { tree, testTree, containerRuntimeFactory, events, heartbeat } = await setupHeartbeat();\n\t\ttree.applyEdit(...Change.insertTree([testTree.buildLeaf()], StablePlace.after(testTree.left)));\n\t\tawait flush(tree, containerRuntimeFactory);\n\t\t// Expect some data to have made it to the heartbeat\n\t\texpect(heartbeat.getStats(tree).editCount).equals(1);\n\t\t// Expect no data was sent to the logger\n\t\texpect(events).deep.equals([]);\n\t});\n\n\tit('Can be flushed synchronously', async () => {\n\t\tconst { tree, testTree, containerRuntimeFactory, events, heartbeat } = await setupHeartbeat();\n\t\ttree.applyEdit(...Change.insertTree([testTree.buildLeaf()], StablePlace.after(testTree.left)));\n\t\tawait flush(tree, containerRuntimeFactory);\n\t\theartbeat.flushHeartbeat();\n\t\texpect(events.length).equals(1);\n\t\texpect(events[0]).contains({\n\t\t\tcategory: 'Heartbeat',\n\t\t\teventName: 'SharedTree:SequencedEditApplied:EditMergeHealth',\n\t\t});\n\t});\n\n\tit('Does not send data if no local edits have been made', async () => {\n\t\tconst { tree, testTree, concurrentTree, containerRuntimeFactory, events, heartbeat } = await setupHeartbeat();\n\t\tconcurrentTree.applyEdit(\n\t\t\t...Change.insertTree([buildLeaf()], StablePlace.after(testTree.left.translateId(concurrentTree)))\n\t\t);\n\t\tawait flush(tree, containerRuntimeFactory);\n\t\theartbeat.flushHeartbeat();\n\t\texpect(events.length).equals(0);\n\t});\n\n\tdescribe('Aggregates merge health data', () => {\n\t\titAggregates('edit counts', ({ testTree }) => ({\n\t\t\tedits: [\n\t\t\t\tChange.insertTree([testTree.buildLeaf()], StablePlace.after(testTree.left)),\n\t\t\t\tChange.insertTree(\n\t\t\t\t\t[testTree.buildLeaf()],\n\t\t\t\t\tStablePlace.after(testTree.buildLeaf(testTree.generateNodeId()))\n\t\t\t\t),\n\t\t\t],\n\t\t\taction: (event) => {\n\t\t\t\texpect(event.editCount).equals(2);\n\t\t\t\texpect(event.failedEditCount).equals(1);\n\t\t\t},\n\t\t}));\n\n\t\titAggregates('preventable place failures', ({ testTree, concurrentTree }) => ({\n\t\t\tconcurrentEdits: [[Change.delete(StableRange.only(testTree.left.translateId(concurrentTree)))]],\n\t\t\tedits: [Change.insertTree([testTree.buildLeaf()], StablePlace.after(testTree.left))],\n\t\t\taction: (event) => {\n\t\t\t\texpect(event.failedEditCount).equals(1);\n\t\t\t\texpect(event.badPlaceCount).equals(1);\n\t\t\t\texpect(event.deletedSiblingBadPlaceCount).equals(1);\n\t\t\t\texpect(event.deletedAncestorBadPlaceCount).equals(0);\n\t\t\t},\n\t\t}));\n\n\t\titAggregates(\n\t\t\t'failures for the parent of a sibling-based place being deleted',\n\t\t\t({ testTree, concurrentTree }) => ({\n\t\t\t\tconcurrentEdits: [[Change.delete(StableRange.only(testTree.translateId(concurrentTree)))]],\n\t\t\t\tedits: [Change.insertTree([testTree.buildLeaf()], StablePlace.after(testTree.left))],\n\t\t\t\taction: (event) => {\n\t\t\t\t\texpect(event.failedEditCount).equals(1);\n\t\t\t\t\texpect(event.badPlaceCount).equals(1);\n\t\t\t\t\texpect(event.deletedSiblingBadPlaceCount).equals(1);\n\t\t\t\t\texpect(event.deletedAncestorBadPlaceCount).equals(0);\n\t\t\t\t},\n\t\t\t})\n\t\t);\n\n\t\titAggregates(\n\t\t\t'failures for a range made of valid places in different traits',\n\t\t\t({ testTree, concurrentTree }) => ({\n\t\t\t\t// Move the \"right\" node to another trait to make the range invalid\n\t\t\t\tconcurrentEdits: [\n\t\t\t\t\tChange.move(\n\t\t\t\t\t\tStableRange.only(testTree.left.translateId(concurrentTree)),\n\t\t\t\t\t\tStablePlace.atEndOf(testTree.right.traitLocation.translate(concurrentTree))\n\t\t\t\t\t),\n\t\t\t\t],\n\t\t\t\tedits: [\n\t\t\t\t\t[\n\t\t\t\t\t\tChange.delete(\n\t\t\t\t\t\t\tStableRange.from(StablePlace.before(testTree.left)).to(\n\t\t\t\t\t\t\t\tStablePlace.atEndOf(testTree.left.traitLocation)\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],\n\t\t\t\taction: (event) => {\n\t\t\t\t\texpect(event.failedEditCount).equals(1);\n\t\t\t\t\texpect(event.badRangeCount).equals(1);\n\t\t\t\t\texpect(event.deletedSiblingBadRangeCount).equals(0);\n\t\t\t\t\texpect(event.updatedRangeHasPlacesInDifferentTraitsCount).equals(1);\n\t\t\t\t},\n\t\t\t})\n\t\t);\n\n\t\titAggregates('failures for a range made of valid places that are inverted', ({ testTree, concurrentTree }) => ({\n\t\t\t// Move the \"right\" node to the start of the trait to make the range inverted\n\t\t\tconcurrentEdits: [\n\t\t\t\tChange.move(\n\t\t\t\t\tStableRange.only(testTree.right.translateId(concurrentTree)),\n\t\t\t\t\tStablePlace.atStartOf(testTree.left.traitLocation.translate(concurrentTree))\n\t\t\t\t),\n\t\t\t],\n\t\t\tedits: [\n\t\t\t\t[\n\t\t\t\t\tChange.delete(\n\t\t\t\t\t\tStableRange.from(StablePlace.after(testTree.left)).to(StablePlace.before(testTree.right))\n\t\t\t\t\t),\n\t\t\t\t],\n\t\t\t],\n\t\t\taction: (event) => {\n\t\t\t\texpect(event.failedEditCount).equals(1);\n\t\t\t\texpect(event.badRangeCount).equals(1);\n\t\t\t\texpect(event.deletedSiblingBadRangeCount).equals(0);\n\t\t\t\texpect(event.updatedRangeInvertedCount).equals(1);\n\t\t\t},\n\t\t}));\n\n\t\titAggregates(\n\t\t\t'failures for the parent of a parent-based place being deleted',\n\t\t\t({ testTree, concurrentTree }) => ({\n\t\t\t\tconcurrentEdits: [[Change.delete(StableRange.only(testTree.left.translateId(concurrentTree)))]],\n\t\t\t\tedits: [\n\t\t\t\t\tChange.insertTree(\n\t\t\t\t\t\t[testTree.buildLeaf()],\n\t\t\t\t\t\tStablePlace.atStartOf({ parent: testTree.left.identifier, label: testTree.left.traitLabel })\n\t\t\t\t\t),\n\t\t\t\t],\n\t\t\t\taction: (event) => {\n\t\t\t\t\texpect(event.failedEditCount).equals(1);\n\t\t\t\t\texpect(event.badPlaceCount).equals(1);\n\t\t\t\t\texpect(event.deletedSiblingBadPlaceCount).equals(0);\n\t\t\t\t\texpect(event.deletedAncestorBadPlaceCount).equals(1);\n\t\t\t\t},\n\t\t\t})\n\t\t);\n\n\t\titAggregates('preventable range failures', ({ testTree, concurrentTree }) => ({\n\t\t\tconcurrentEdits: [[Change.delete(StableRange.only(testTree.left.translateId(concurrentTree)))]],\n\t\t\tedits: [[Change.delete(StableRange.only(testTree.left))]],\n\t\t\taction: (event) => {\n\t\t\t\texpect(event.failedEditCount).equals(1);\n\t\t\t\texpect(event.badRangeCount).equals(1);\n\t\t\t},\n\t\t}));\n\n\t\titAggregates('range constraint violations', ({ testTree, concurrentTree }) => ({\n\t\t\tconcurrentEdits: [[Change.delete(StableRange.only(testTree.left.translateId(concurrentTree)))]],\n\t\t\tedits: [\n\t\t\t\t[\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: ChangeType.Constraint,\n\t\t\t\t\t\ttoConstrain: StableRange.only(testTree.left),\n\t\t\t\t\t\teffect: ConstraintEffect.InvalidAndDiscard,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t],\n\t\t\taction: (event) => {\n\t\t\t\texpect(event.failedEditCount).equals(1);\n\t\t\t\texpect(event.constraintViolationCount).equals(1);\n\t\t\t\texpect(event.rangeConstraintViolationCount).equals(1);\n\t\t\t},\n\t\t}));\n\n\t\titAggregates('length constraint violations', ({ testTree, concurrentTree }) => ({\n\t\t\tconcurrentEdits: [\n\t\t\t\tChange.move(\n\t\t\t\t\tStableRange.only(testTree.right.translateId(concurrentTree)),\n\t\t\t\t\tStablePlace.after(testTree.left.translateId(concurrentTree))\n\t\t\t\t),\n\t\t\t],\n\t\t\tedits: [\n\t\t\t\t[\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: ChangeType.Constraint,\n\t\t\t\t\t\ttoConstrain: StableRange.all(testTree.left.traitLocation),\n\t\t\t\t\t\tlength: 1,\n\t\t\t\t\t\teffect: ConstraintEffect.InvalidAndDiscard,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t],\n\t\t\taction: (event) => {\n\t\t\t\texpect(event.failedEditCount).equals(1);\n\t\t\t\texpect(event.constraintViolationCount).equals(1);\n\t\t\t\texpect(event.lengthConstraintViolationCount).equals(1);\n\t\t\t},\n\t\t}));\n\n\t\titAggregates('parent constraint violations', ({ testTree, concurrentTree }) => ({\n\t\t\tconcurrentEdits: [\n\t\t\t\tChange.move(\n\t\t\t\t\tStableRange.only(testTree.right.translateId(concurrentTree)),\n\t\t\t\t\tStablePlace.atStartOf({\n\t\t\t\t\t\tparent: testTree.left.translateId(concurrentTree),\n\t\t\t\t\t\tlabel: testTree.left.traitLabel,\n\t\t\t\t\t})\n\t\t\t\t),\n\t\t\t],\n\t\t\tedits: [\n\t\t\t\t[\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: ChangeType.Constraint,\n\t\t\t\t\t\ttoConstrain: StableRange.only(testTree.right),\n\t\t\t\t\t\tparentNode: testTree.identifier,\n\t\t\t\t\t\teffect: ConstraintEffect.InvalidAndDiscard,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t],\n\t\t\taction: (event) => {\n\t\t\t\texpect(event.failedEditCount).equals(1);\n\t\t\t\texpect(event.constraintViolationCount).equals(1);\n\t\t\t\texpect(event.parentConstraintViolationCount).equals(1);\n\t\t\t},\n\t\t}));\n\n\t\titAggregates('label constraint violations', ({ testTree, concurrentTree }) => ({\n\t\t\tconcurrentEdits: [\n\t\t\t\tChange.move(\n\t\t\t\t\tStableRange.only(testTree.left.translateId(concurrentTree)),\n\t\t\t\t\tStablePlace.after(testTree.right.translateId(concurrentTree))\n\t\t\t\t),\n\t\t\t],\n\t\t\tedits: [\n\t\t\t\t[\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: ChangeType.Constraint,\n\t\t\t\t\t\ttoConstrain: StableRange.only(testTree.left),\n\t\t\t\t\t\tlabel: testTree.left.traitLabel,\n\t\t\t\t\t\teffect: ConstraintEffect.InvalidAndDiscard,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t],\n\t\t\taction: (event) => {\n\t\t\t\texpect(event.failedEditCount).equals(1);\n\t\t\t\texpect(event.constraintViolationCount).equals(1);\n\t\t\t\texpect(event.labelConstraintViolationCount).equals(1);\n\t\t\t},\n\t\t}));\n\n\t\titAggregates('failures due to ID collisions', ({ testTree, concurrentTree }) => {\n\t\t\tconst duplicateOverride = 'duplicate ID';\n\t\t\treturn {\n\t\t\t\tconcurrentEdits: [\n\t\t\t\t\tChange.insertTree(\n\t\t\t\t\t\t[buildLeaf(concurrentTree.generateNodeId(duplicateOverride))],\n\t\t\t\t\t\tStablePlace.after(testTree.left.translateId(concurrentTree))\n\t\t\t\t\t),\n\t\t\t\t],\n\t\t\t\tedits: [\n\t\t\t\t\tChange.insertTree(\n\t\t\t\t\t\t[testTree.buildLeaf(testTree.generateNodeId(duplicateOverride))],\n\t\t\t\t\t\tStablePlace.after(testTree.left)\n\t\t\t\t\t),\n\t\t\t\t],\n\t\t\t\taction: (event) => {\n\t\t\t\t\texpect(event.failedEditCount).equals(1);\n\t\t\t\t\texpect(event.idAlreadyInUseCount).equals(1);\n\t\t\t\t},\n\t\t\t};\n\t\t});\n\n\t\titAggregates('failures due unknown IDs', ({ testTree, concurrentTree }) => ({\n\t\t\tconcurrentEdits: [[Change.delete(StableRange.only(testTree.left.translateId(concurrentTree)))]],\n\t\t\tedits: [[Change.clearPayload(testTree.left.identifier)]],\n\t\t\taction: (event) => {\n\t\t\t\texpect(event.failedEditCount).equals(1);\n\t\t\t\texpect(event.unknownIdCount).equals(1);\n\t\t\t},\n\t\t}));\n\n\t\t// This test uses itAggregatesMocked to streamline the test code\n\t\titAggregatesMocked(\n\t\t\t'path length',\n\t\t\t[\n\t\t\t\t{ reconciliationPath: { length: 0 } },\n\t\t\t\t{ reconciliationPath: { length: 1 } },\n\t\t\t\t{ reconciliationPath: { length: 1 } },\n\t\t\t\t{ reconciliationPath: { length: 2 } },\n\t\t\t\t{ reconciliationPath: { length: 42 } },\n\t\t\t],\n\t\t\t(event) => {\n\t\t\t\texpect(event.pathLengths).equals('0:1,1:2,2:1,42:1');\n\t\t\t}\n\t\t);\n\n\t\t// This test uses itAggregatesMocked because multiple attempts are currently not being made\n\t\titAggregatesMocked(\n\t\t\t'maximum attempt number for an edit',\n\t\t\t[\n\t\t\t\t{\n\t\t\t\t\tedit: { pastAttemptCount: 40 },\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tedit: { pastAttemptCount: 42 },\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tedit: { pastAttemptCount: 41 },\n\t\t\t\t},\n\t\t\t],\n\t\t\t(event) => {\n\t\t\t\texpect(event.maxAttemptCount).equals(42);\n\t\t\t}\n\t\t);\n\n\t\t// This test uses itAggregatesMocked because there should be no way for a sequenced edit to become a malformed edit in\n\t\t// the face of concurrent edits.\n\t\titAggregatesMocked(\n\t\t\t'failures due malformed edits',\n\t\t\t[\n\t\t\t\t{\n\t\t\t\t\toutcome: {\n\t\t\t\t\t\tstatus: EditStatus.Malformed,\n\t\t\t\t\t\tfailure: { kind: TransactionInternal.FailureKind.UnusedDetachedSequence },\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t],\n\t\t\t(event) => {\n\t\t\t\t// This test has to mock a lot of things because there should be no way for a sequenced edit to become a malformed edit in the\n\t\t\t\t// face of concurrent edits.\n\t\t\t\texpect(event.failedEditCount).equals(1);\n\t\t\t\texpect(event.malformedEditCount).equals(1);\n\t\t\t}\n\t\t);\n\t});\n});\n"]}
|
|
@@ -246,12 +246,10 @@ function makeTestNormalizer() {
|
|
|
246
246
|
function makeOpGenerator(numOperations) {
|
|
247
247
|
function addLocalIdGenerator(state) {
|
|
248
248
|
const { locals, finals, random } = state;
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
state.currentLocal = -locals.length - 1;
|
|
254
|
-
}
|
|
249
|
+
state.currentLocal =
|
|
250
|
+
locals.length < finals.length && random.bool()
|
|
251
|
+
? -locals.length - (finals.length - locals.length) - 1
|
|
252
|
+
: -locals.length - 1;
|
|
255
253
|
state.prevWasLocal = true;
|
|
256
254
|
return { type: 'addLocalId' };
|
|
257
255
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SessionIdNormalizer.tests.js","sourceRoot":"","sources":["../../src/test/SessionIdNormalizer.tests.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 { benchmark, BenchmarkType } from '@fluid-tools/benchmark';\nimport { expect } from 'chai';\nimport Random from 'random-js';\nimport {\n\tBaseFuzzTestState,\n\tchain,\n\tcreateWeightedGenerator,\n\tmakeRandom,\n\tperformFuzzActions,\n\ttake,\n\tGenerator,\n\tgeneratorFromArray,\n} from '@fluid-internal/stochastic-test-utils';\nimport { assert, fail } from '../Common';\nimport { isFinalId, isLocalId } from '../id-compressor';\nimport { SessionIdNormalizer } from '../id-compressor/SessionIdNormalizer';\nimport { FinalCompressedId, LocalCompressedId, SessionSpaceCompressedId } from '../Identifiers';\n\ndescribe('SessionIdNormalizer', () => {\n\tit('fails when adding finals with no corresponding locals', () => {\n\t\tconst normalizer = makeTestNormalizer();\n\t\texpect(() => normalizer.addFinalIds(final(0), final(1), undefined)).to.throw(\n\t\t\t'Final IDs must be added to an existing local range.'\n\t\t);\n\t});\n\n\tit('fails when adding finals out of order', () => {\n\t\tconst normalizer = makeTestNormalizer();\n\t\tnormalizer.addLocalId();\n\t\texpect(() => normalizer.addFinalIds(final(1), final(0), undefined)).to.throw('Malformed normalization range.');\n\t});\n\n\tit('fails when gaps in finals do not align with a local', () => {\n\t\t/**\n\t\t * Locals: [-1, -2, X, -4]\n\t\t * Finals: [ 0, 1, 2, 5]\n\t\t * Calling `addFinalIds` with first === last === 9 results in the following:\n\t\t * Locals: [-1, -2, X, -4, X]\n\t\t * Finals: [ 0, 1, 2, 5, 9]\n\t\t * ^should fail\n\t\t */\n\t\tconst normalizer = makeTestNormalizer();\n\t\tnormalizer.addLocalId(); // -1\n\t\tnormalizer.addLocalId(); // -2\n\t\tnormalizer.addFinalIds(final(0), final(2), undefined);\n\t\tnormalizer.addLocalId(); // -4\n\t\tnormalizer.addFinalIds(final(5), final(5), undefined);\n\t\texpect(() => normalizer.addFinalIds(final(9), final(9), undefined)).to.throw(\n\t\t\t'Gaps in final space must align to a local.'\n\t\t);\n\t});\n\n\tit('fails when attempting to normalize a local ID that was never registered', () => {\n\t\tconst normalizer = makeTestNormalizer();\n\t\texpect(() => normalizer.getFinalId(-1 as LocalCompressedId)).to.throw(\n\t\t\t'Local ID was never recorded with this normalizer.'\n\t\t);\n\t\tconst local = normalizer.addLocalId();\n\t\tconst secondLocal = (local - 1) as LocalCompressedId;\n\t\texpect(() => normalizer.getFinalId(secondLocal)).to.throw('Local ID was never recorded with this normalizer.');\n\t\tnormalizer.addFinalIds(final(0), final(5), undefined);\n\t\texpect(() => normalizer.getFinalId(secondLocal)).to.throw('Local ID was never recorded with this normalizer.');\n\t});\n\n\titWithNormalizer('can normalize IDs with only local forms', (normalizer) => {\n\t\tconst local1 = normalizer.addLocalId();\n\t\tconst local2 = normalizer.addLocalId();\n\t\tconst local3 = normalizer.addLocalId();\n\t\tconst local4 = normalizer.addLocalId();\n\t\texpect(local1).to.equal(-1);\n\t\texpect(local2).to.equal(-2);\n\t\texpect(local3).to.equal(-3);\n\t\texpect(local4).to.equal(-4);\n\t});\n\n\titWithNormalizer('can normalize IDs with trailing finals', (normalizer) => {\n\t\tnormalizer.addLocalId();\n\t\tnormalizer.addFinalIds(final(0), final(1), undefined);\n\t\tnormalizer.addFinalIds(final(2), final(3), undefined);\n\t\tnormalizer.addFinalIds(final(4), final(10), undefined);\n\t});\n\n\titWithNormalizer('can normalize IDs with trailing locals', (normalizer) => {\n\t\tnormalizer.addLocalId();\n\t\tnormalizer.addFinalIds(final(0), final(1), undefined);\n\t\tnormalizer.addLocalId();\n\t\tnormalizer.addLocalId();\n\t});\n\n\titWithNormalizer('can normalize IDs with a gap in final space', (normalizer) => {\n\t\tnormalizer.addLocalId();\n\t\tnormalizer.addLocalId();\n\t\tnormalizer.addLocalId();\n\t\tnormalizer.addFinalIds(final(0), final(1), undefined);\n\t\tnormalizer.addFinalIds(final(10), final(11), undefined);\n\t});\n\n\titWithNormalizer('can normalize IDs with and without corresponding local forms', (normalizer) => {\n\t\tnormalizer.addLocalId(); // -1\n\t\tnormalizer.addLocalId(); // -2\n\t\tnormalizer.addLocalId(); // -3\n\t\tnormalizer.addFinalIds(final(0), final(3), dummy);\n\t\tnormalizer.addLocalId(); // -5\n\t\tnormalizer.addLocalId(); // -6\n\t\tnormalizer.addFinalIds(final(4), final(5), dummy);\n\t\tnormalizer.addLocalId(); // -7\n\t\tnormalizer.addFinalIds(final(8), final(9), dummy);\n\t\tnormalizer.addLocalId(); // -9\n\t\tnormalizer.addFinalIds(final(14), final(15), dummy);\n\t\tnormalizer.addLocalId(); // -11\n\t\tnormalizer.addLocalId(); // -12\n\t});\n\n\titWithNormalizer('can get the last final ID', (normalizer) => {\n\t\tnormalizer.addLocalId(); // -1\n\t\tnormalizer.addLocalId(); // -2\n\t\tnormalizer.addLocalId(); // -3\n\t\tnormalizer.addLocalId(); // -4\n\t\texpect(normalizer.getLastFinalId()).to.be.undefined;\n\t\tnormalizer.addFinalIds(final(0), final(1), undefined);\n\t\texpect(normalizer.getLastFinalId()).to.equal(1);\n\t\tnormalizer.addFinalIds(final(2), final(2), undefined);\n\t\texpect(normalizer.getLastFinalId()).to.equal(2);\n\t\tnormalizer.addFinalIds(final(10), final(15), undefined);\n\t\texpect(normalizer.getLastFinalId()).to.equal(15);\n\t});\n\n\titWithNormalizer('can normalize IDs after fuzzed inputs', (normalizer) => {\n\t\tfuzzNormalizer(normalizer, 1000, 42);\n\t});\n});\n\ndescribe('SessionIdNormalizer Perf', () => {\n\tconst choiceCount = 1000;\n\tconst type = BenchmarkType.Measurement;\n\tlet normalizer: SessionIdNormalizer<DummyRange>;\n\tlet rand: Random;\n\tlet ids: SessionSpaceCompressedId[];\n\tlet finals: FinalCompressedId[];\n\tlet locals: LocalCompressedId[];\n\tlet localChoices: LocalCompressedId[];\n\tlet finalChoices: FinalCompressedId[];\n\tconst before = () => {\n\t\tnormalizer = new SessionIdNormalizer();\n\t\trand = fuzzNormalizer(normalizer, 10000, 3.14);\n\t\tids = [...normalizer];\n\t\tlocals = ids.filter<LocalCompressedId>((id): id is LocalCompressedId => isLocalId(id));\n\t\tfinals = ids.filter((id) => isFinalId(id)) as FinalCompressedId[];\n\t\tlocalChoices = [];\n\t\tfinalChoices = [];\n\t\tfor (let i = 0; i < choiceCount; i++) {\n\t\t\tlocalChoices.push(rand.pick(locals));\n\t\t\tfinalChoices.push(rand.pick(finals));\n\t\t}\n\t};\n\n\tlet localChoice = 0;\n\tbenchmark({\n\t\ttype,\n\t\ttitle: `normalize a local ID to a final ID`,\n\t\tbefore,\n\t\tbenchmarkFn: () => {\n\t\t\tnormalizer.getFinalId(localChoices[localChoice++ % localChoices.length]);\n\t\t},\n\t});\n\n\tlet finalChoice = 0;\n\tbenchmark({\n\t\ttype,\n\t\ttitle: `normalize a final ID to session space`,\n\t\tbefore,\n\t\tbenchmarkFn: () => {\n\t\t\tnormalizer.getSessionSpaceId(finalChoices[finalChoice++ % finalChoices.length]);\n\t\t},\n\t});\n});\n\nfunction itWithNormalizer(title: string, itFn: (normalizer: SessionIdNormalizer<DummyRange>) => void): void {\n\tit(title, () => {\n\t\tconst locals: (LocalCompressedId | undefined)[] = [];\n\t\tconst finals: (FinalCompressedId | undefined)[] = [];\n\t\tconst normalizer: SessionIdNormalizer<DummyRange> = makeNormalizerProxy(makeTestNormalizer(), locals, finals);\n\n\t\titFn(normalizer);\n\t\tconst allIds = [...normalizer];\n\t\tlet prevLocal: LocalCompressedId | undefined;\n\t\tlet prevFinal: FinalCompressedId | undefined;\n\t\tfor (let i = 0; i < locals.length && i < finals.length; i++) {\n\t\t\tconst localExpected = locals[i];\n\t\t\tconst finalExpected = finals[i];\n\t\t\t// local can be undefined in the case of eager final\n\t\t\t// final can be undefined in the case of trailing locals with no cluster\n\t\t\t// both should never occur\n\t\t\tassert(\n\t\t\t\t(localExpected !== undefined && isLocalId(localExpected)) ||\n\t\t\t\t\t(finalExpected !== undefined && isFinalId(finalExpected)),\n\t\t\t\t'Test error.'\n\t\t\t);\n\t\t\tif (prevFinal !== undefined && finalExpected !== undefined) {\n\t\t\t\tassert(finalExpected > prevFinal, 'Test error.');\n\t\t\t}\n\t\t\tif (prevLocal !== undefined && localExpected !== undefined) {\n\t\t\t\tassert(localExpected < prevLocal, 'Test error.');\n\t\t\t}\n\t\t\tprevLocal = localExpected;\n\t\t\tprevFinal = finalExpected;\n\n\t\t\tconst sessionIdExpected = localExpected === undefined ? finalExpected : localExpected;\n\t\t\tconst sessionIdActualAll = allIds[i];\n\t\t\tconst sessionIdActualNormalized =\n\t\t\t\tfinalExpected === undefined ? localExpected : normalizer.getSessionSpaceId(finalExpected);\n\n\t\t\tif (finalExpected !== undefined) {\n\t\t\t\tconst creationIndex = normalizer.getCreationIndex(finalExpected);\n\t\t\t\texpect(creationIndex).to.equal(i);\n\t\t\t}\n\n\t\t\tconst idByIndex = normalizer.getIdByCreationIndex(i);\n\t\t\texpect(idByIndex).to.equal(localExpected ?? finalExpected);\n\n\t\t\tif (localExpected !== undefined) {\n\t\t\t\tconst normalized = normalizer.getFinalId(localExpected);\n\t\t\t\tif (normalized === undefined) {\n\t\t\t\t\texpect(finalExpected).to.be.undefined;\n\t\t\t\t} else {\n\t\t\t\t\tconst [opIdActualNormalized] = normalized;\n\t\t\t\t\texpect(opIdActualNormalized).to.equal(finalExpected);\n\t\t\t\t}\n\t\t\t}\n\t\t\texpect(sessionIdExpected).to.equal(sessionIdActualAll);\n\t\t\texpect(sessionIdActualAll).to.equal(sessionIdActualNormalized);\n\t\t}\n\t\texpect(normalizer.getLastFinalId()).to.equal(finals[finals.length - 1]);\n\t\tconst roundtripped = SessionIdNormalizer.deserialize(normalizer.serialize(), () => undefined);\n\t\texpect(roundtripped.equals(normalizer)).to.be.true;\n\t});\n}\n\nfunction makeNormalizerProxy(\n\tnormalizer: SessionIdNormalizer<DummyRange>,\n\tlocals: (LocalCompressedId | undefined)[],\n\tfinals: (FinalCompressedId | undefined)[]\n): SessionIdNormalizer<DummyRange> {\n\treturn new Proxy<SessionIdNormalizer<DummyRange>>(normalizer, {\n\t\tget(target, property: keyof SessionIdNormalizer<DummyRange>) {\n\t\t\tif (typeof target[property] === 'function') {\n\t\t\t\tif (property === 'addLocalId') {\n\t\t\t\t\treturn new Proxy(target[property], {\n\t\t\t\t\t\tapply: (func, thisArg, argumentsList) => {\n\t\t\t\t\t\t\tconst local = Reflect.apply(func, thisArg, argumentsList);\n\t\t\t\t\t\t\tif (locals.length > 0) {\n\t\t\t\t\t\t\t\tfor (let i = (locals[locals.length - 1] ?? fail()) - 1; i > local; i--) {\n\t\t\t\t\t\t\t\t\tlocals.push(undefined);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tlocals.push(local);\n\t\t\t\t\t\t\treturn local;\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t} else if (property === 'addFinalIds') {\n\t\t\t\t\treturn new Proxy(target[property], {\n\t\t\t\t\t\tapply: (func, thisArg, argumentsList) => {\n\t\t\t\t\t\t\tconst firstFinal: FinalCompressedId = argumentsList[0];\n\t\t\t\t\t\t\tconst lastFinal: FinalCompressedId = argumentsList[1];\n\t\t\t\t\t\t\tfor (let i = firstFinal; i <= lastFinal; i++) {\n\t\t\t\t\t\t\t\tfinals.push(i);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn Reflect.apply(func, thisArg, argumentsList);\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn Reflect.get(target, property);\n\t\t},\n\t});\n}\n\ntype DummyRange = undefined;\nconst dummy: DummyRange = undefined;\n\nfunction final(num: number): FinalCompressedId {\n\tassert(num >= 0);\n\treturn num as FinalCompressedId;\n}\n\nfunction makeTestNormalizer(): SessionIdNormalizer<DummyRange> {\n\treturn new SessionIdNormalizer<DummyRange>(true);\n}\n\ninterface AddLocalId {\n\ttype: 'addLocalId';\n}\n\ninterface AddFinalIds {\n\ttype: 'addFinalIds';\n\tfirst: FinalCompressedId;\n\tlast: FinalCompressedId;\n}\n\ntype Operation = AddLocalId | AddFinalIds;\n\ninterface FuzzTestState extends BaseFuzzTestState {\n\tnormalizer: SessionIdNormalizer<DummyRange>;\n\tprevWasLocal: boolean;\n\tcurrentLocal: number;\n\tcurrentFinal: number;\n\tlocals: (LocalCompressedId | undefined)[];\n\tfinals: (FinalCompressedId | undefined)[];\n}\n\nfunction makeOpGenerator(numOperations: number): Generator<Operation, FuzzTestState> {\n\tfunction addLocalIdGenerator(state: FuzzTestState): AddLocalId {\n\t\tconst { locals, finals, random } = state;\n\t\tif (locals.length < finals.length && random.bool()) {\n\t\t\tstate.currentLocal = -locals.length - (finals.length - locals.length) - 1;\n\t\t} else {\n\t\t\tstate.currentLocal = -locals.length - 1;\n\t\t}\n\t\tstate.prevWasLocal = true;\n\t\treturn { type: 'addLocalId' };\n\t}\n\n\tfunction addFinalIdsGenerator(state: FuzzTestState): AddFinalIds {\n\t\tconst { locals, finals, random } = state;\n\t\tif (state.prevWasLocal && locals.length > finals.length && random.integer(1, 3) === 3) {\n\t\t\tstate.currentFinal += random.integer(1, 4);\n\t\t}\n\t\tconst lastFinal = state.currentFinal + random.integer(0, 10);\n\t\tconst addFinal: AddFinalIds = { type: 'addFinalIds', first: final(state.currentFinal), last: final(lastFinal) };\n\t\tstate.currentFinal = lastFinal + 1;\n\t\tstate.prevWasLocal = false;\n\t\treturn addFinal;\n\t}\n\n\treturn chain(\n\t\tgeneratorFromArray([{ type: 'addLocalId' }]),\n\t\ttake(\n\t\t\tnumOperations - 1,\n\t\t\tcreateWeightedGenerator<Operation, FuzzTestState>([\n\t\t\t\t[addLocalIdGenerator, 8],\n\t\t\t\t[addFinalIdsGenerator, 2],\n\t\t\t])\n\t\t)\n\t);\n}\n\nfunction fuzzNormalizer(\n\tnormalizerToFuzz: SessionIdNormalizer<DummyRange>,\n\tnumOperations: number,\n\tseed: number\n): Random {\n\tconst locals: (LocalCompressedId | undefined)[] = [];\n\tconst finals: (FinalCompressedId | undefined)[] = [];\n\tconst normalizer: SessionIdNormalizer<DummyRange> = makeNormalizerProxy(normalizerToFuzz, locals, finals);\n\n\tconst initialState: FuzzTestState = {\n\t\trandom: makeRandom(seed),\n\t\tcurrentLocal: -1,\n\t\tcurrentFinal: 0,\n\t\tprevWasLocal: false,\n\t\tnormalizer,\n\t\tlocals,\n\t\tfinals,\n\t};\n\n\tperformFuzzActions(\n\t\tmakeOpGenerator(numOperations),\n\t\t{\n\t\t\taddLocalId: (state) => {\n\t\t\t\tstate.normalizer.addLocalId();\n\t\t\t\treturn state;\n\t\t\t},\n\t\t\taddFinalIds: (state, { first, last }) => {\n\t\t\t\tstate.normalizer.addFinalIds(first, last, undefined);\n\t\t\t\treturn state;\n\t\t\t},\n\t\t},\n\t\tinitialState\n\t);\n\treturn initialState.random;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"SessionIdNormalizer.tests.js","sourceRoot":"","sources":["../../src/test/SessionIdNormalizer.tests.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 { benchmark, BenchmarkType } from '@fluid-tools/benchmark';\nimport { expect } from 'chai';\nimport Random from 'random-js';\nimport {\n\tBaseFuzzTestState,\n\tchain,\n\tcreateWeightedGenerator,\n\tmakeRandom,\n\tperformFuzzActions,\n\ttake,\n\tGenerator,\n\tgeneratorFromArray,\n} from '@fluid-internal/stochastic-test-utils';\nimport { assert, fail } from '../Common';\nimport { isFinalId, isLocalId } from '../id-compressor';\nimport { SessionIdNormalizer } from '../id-compressor/SessionIdNormalizer';\nimport { FinalCompressedId, LocalCompressedId, SessionSpaceCompressedId } from '../Identifiers';\n\ndescribe('SessionIdNormalizer', () => {\n\tit('fails when adding finals with no corresponding locals', () => {\n\t\tconst normalizer = makeTestNormalizer();\n\t\texpect(() => normalizer.addFinalIds(final(0), final(1), undefined)).to.throw(\n\t\t\t'Final IDs must be added to an existing local range.'\n\t\t);\n\t});\n\n\tit('fails when adding finals out of order', () => {\n\t\tconst normalizer = makeTestNormalizer();\n\t\tnormalizer.addLocalId();\n\t\texpect(() => normalizer.addFinalIds(final(1), final(0), undefined)).to.throw('Malformed normalization range.');\n\t});\n\n\tit('fails when gaps in finals do not align with a local', () => {\n\t\t/**\n\t\t * Locals: [-1, -2, X, -4]\n\t\t * Finals: [ 0, 1, 2, 5]\n\t\t * Calling `addFinalIds` with first === last === 9 results in the following:\n\t\t * Locals: [-1, -2, X, -4, X]\n\t\t * Finals: [ 0, 1, 2, 5, 9]\n\t\t * ^should fail\n\t\t */\n\t\tconst normalizer = makeTestNormalizer();\n\t\tnormalizer.addLocalId(); // -1\n\t\tnormalizer.addLocalId(); // -2\n\t\tnormalizer.addFinalIds(final(0), final(2), undefined);\n\t\tnormalizer.addLocalId(); // -4\n\t\tnormalizer.addFinalIds(final(5), final(5), undefined);\n\t\texpect(() => normalizer.addFinalIds(final(9), final(9), undefined)).to.throw(\n\t\t\t'Gaps in final space must align to a local.'\n\t\t);\n\t});\n\n\tit('fails when attempting to normalize a local ID that was never registered', () => {\n\t\tconst normalizer = makeTestNormalizer();\n\t\texpect(() => normalizer.getFinalId(-1 as LocalCompressedId)).to.throw(\n\t\t\t'Local ID was never recorded with this normalizer.'\n\t\t);\n\t\tconst local = normalizer.addLocalId();\n\t\tconst secondLocal = (local - 1) as LocalCompressedId;\n\t\texpect(() => normalizer.getFinalId(secondLocal)).to.throw('Local ID was never recorded with this normalizer.');\n\t\tnormalizer.addFinalIds(final(0), final(5), undefined);\n\t\texpect(() => normalizer.getFinalId(secondLocal)).to.throw('Local ID was never recorded with this normalizer.');\n\t});\n\n\titWithNormalizer('can normalize IDs with only local forms', (normalizer) => {\n\t\tconst local1 = normalizer.addLocalId();\n\t\tconst local2 = normalizer.addLocalId();\n\t\tconst local3 = normalizer.addLocalId();\n\t\tconst local4 = normalizer.addLocalId();\n\t\texpect(local1).to.equal(-1);\n\t\texpect(local2).to.equal(-2);\n\t\texpect(local3).to.equal(-3);\n\t\texpect(local4).to.equal(-4);\n\t});\n\n\titWithNormalizer('can normalize IDs with trailing finals', (normalizer) => {\n\t\tnormalizer.addLocalId();\n\t\tnormalizer.addFinalIds(final(0), final(1), undefined);\n\t\tnormalizer.addFinalIds(final(2), final(3), undefined);\n\t\tnormalizer.addFinalIds(final(4), final(10), undefined);\n\t});\n\n\titWithNormalizer('can normalize IDs with trailing locals', (normalizer) => {\n\t\tnormalizer.addLocalId();\n\t\tnormalizer.addFinalIds(final(0), final(1), undefined);\n\t\tnormalizer.addLocalId();\n\t\tnormalizer.addLocalId();\n\t});\n\n\titWithNormalizer('can normalize IDs with a gap in final space', (normalizer) => {\n\t\tnormalizer.addLocalId();\n\t\tnormalizer.addLocalId();\n\t\tnormalizer.addLocalId();\n\t\tnormalizer.addFinalIds(final(0), final(1), undefined);\n\t\tnormalizer.addFinalIds(final(10), final(11), undefined);\n\t});\n\n\titWithNormalizer('can normalize IDs with and without corresponding local forms', (normalizer) => {\n\t\tnormalizer.addLocalId(); // -1\n\t\tnormalizer.addLocalId(); // -2\n\t\tnormalizer.addLocalId(); // -3\n\t\tnormalizer.addFinalIds(final(0), final(3), dummy);\n\t\tnormalizer.addLocalId(); // -5\n\t\tnormalizer.addLocalId(); // -6\n\t\tnormalizer.addFinalIds(final(4), final(5), dummy);\n\t\tnormalizer.addLocalId(); // -7\n\t\tnormalizer.addFinalIds(final(8), final(9), dummy);\n\t\tnormalizer.addLocalId(); // -9\n\t\tnormalizer.addFinalIds(final(14), final(15), dummy);\n\t\tnormalizer.addLocalId(); // -11\n\t\tnormalizer.addLocalId(); // -12\n\t});\n\n\titWithNormalizer('can get the last final ID', (normalizer) => {\n\t\tnormalizer.addLocalId(); // -1\n\t\tnormalizer.addLocalId(); // -2\n\t\tnormalizer.addLocalId(); // -3\n\t\tnormalizer.addLocalId(); // -4\n\t\texpect(normalizer.getLastFinalId()).to.be.undefined;\n\t\tnormalizer.addFinalIds(final(0), final(1), undefined);\n\t\texpect(normalizer.getLastFinalId()).to.equal(1);\n\t\tnormalizer.addFinalIds(final(2), final(2), undefined);\n\t\texpect(normalizer.getLastFinalId()).to.equal(2);\n\t\tnormalizer.addFinalIds(final(10), final(15), undefined);\n\t\texpect(normalizer.getLastFinalId()).to.equal(15);\n\t});\n\n\titWithNormalizer('can normalize IDs after fuzzed inputs', (normalizer) => {\n\t\tfuzzNormalizer(normalizer, 1000, 42);\n\t});\n});\n\ndescribe('SessionIdNormalizer Perf', () => {\n\tconst choiceCount = 1000;\n\tconst type = BenchmarkType.Measurement;\n\tlet normalizer: SessionIdNormalizer<DummyRange>;\n\tlet rand: Random;\n\tlet ids: SessionSpaceCompressedId[];\n\tlet finals: FinalCompressedId[];\n\tlet locals: LocalCompressedId[];\n\tlet localChoices: LocalCompressedId[];\n\tlet finalChoices: FinalCompressedId[];\n\tconst before = () => {\n\t\tnormalizer = new SessionIdNormalizer();\n\t\trand = fuzzNormalizer(normalizer, 10000, 3.14);\n\t\tids = [...normalizer];\n\t\tlocals = ids.filter<LocalCompressedId>((id): id is LocalCompressedId => isLocalId(id));\n\t\tfinals = ids.filter((id) => isFinalId(id)) as FinalCompressedId[];\n\t\tlocalChoices = [];\n\t\tfinalChoices = [];\n\t\tfor (let i = 0; i < choiceCount; i++) {\n\t\t\tlocalChoices.push(rand.pick(locals));\n\t\t\tfinalChoices.push(rand.pick(finals));\n\t\t}\n\t};\n\n\tlet localChoice = 0;\n\tbenchmark({\n\t\ttype,\n\t\ttitle: `normalize a local ID to a final ID`,\n\t\tbefore,\n\t\tbenchmarkFn: () => {\n\t\t\tnormalizer.getFinalId(localChoices[localChoice++ % localChoices.length]);\n\t\t},\n\t});\n\n\tlet finalChoice = 0;\n\tbenchmark({\n\t\ttype,\n\t\ttitle: `normalize a final ID to session space`,\n\t\tbefore,\n\t\tbenchmarkFn: () => {\n\t\t\tnormalizer.getSessionSpaceId(finalChoices[finalChoice++ % finalChoices.length]);\n\t\t},\n\t});\n});\n\nfunction itWithNormalizer(title: string, itFn: (normalizer: SessionIdNormalizer<DummyRange>) => void): void {\n\tit(title, () => {\n\t\tconst locals: (LocalCompressedId | undefined)[] = [];\n\t\tconst finals: (FinalCompressedId | undefined)[] = [];\n\t\tconst normalizer: SessionIdNormalizer<DummyRange> = makeNormalizerProxy(makeTestNormalizer(), locals, finals);\n\n\t\titFn(normalizer);\n\t\tconst allIds = [...normalizer];\n\t\tlet prevLocal: LocalCompressedId | undefined;\n\t\tlet prevFinal: FinalCompressedId | undefined;\n\t\tfor (let i = 0; i < locals.length && i < finals.length; i++) {\n\t\t\tconst localExpected = locals[i];\n\t\t\tconst finalExpected = finals[i];\n\t\t\t// local can be undefined in the case of eager final\n\t\t\t// final can be undefined in the case of trailing locals with no cluster\n\t\t\t// both should never occur\n\t\t\tassert(\n\t\t\t\t(localExpected !== undefined && isLocalId(localExpected)) ||\n\t\t\t\t\t(finalExpected !== undefined && isFinalId(finalExpected)),\n\t\t\t\t'Test error.'\n\t\t\t);\n\t\t\tif (prevFinal !== undefined && finalExpected !== undefined) {\n\t\t\t\tassert(finalExpected > prevFinal, 'Test error.');\n\t\t\t}\n\t\t\tif (prevLocal !== undefined && localExpected !== undefined) {\n\t\t\t\tassert(localExpected < prevLocal, 'Test error.');\n\t\t\t}\n\t\t\tprevLocal = localExpected;\n\t\t\tprevFinal = finalExpected;\n\n\t\t\tconst sessionIdExpected = localExpected === undefined ? finalExpected : localExpected;\n\t\t\tconst sessionIdActualAll = allIds[i];\n\t\t\tconst sessionIdActualNormalized =\n\t\t\t\tfinalExpected === undefined ? localExpected : normalizer.getSessionSpaceId(finalExpected);\n\n\t\t\tif (finalExpected !== undefined) {\n\t\t\t\tconst creationIndex = normalizer.getCreationIndex(finalExpected);\n\t\t\t\texpect(creationIndex).to.equal(i);\n\t\t\t}\n\n\t\t\tconst idByIndex = normalizer.getIdByCreationIndex(i);\n\t\t\texpect(idByIndex).to.equal(localExpected ?? finalExpected);\n\n\t\t\tif (localExpected !== undefined) {\n\t\t\t\tconst normalized = normalizer.getFinalId(localExpected);\n\t\t\t\tif (normalized === undefined) {\n\t\t\t\t\texpect(finalExpected).to.be.undefined;\n\t\t\t\t} else {\n\t\t\t\t\tconst [opIdActualNormalized] = normalized;\n\t\t\t\t\texpect(opIdActualNormalized).to.equal(finalExpected);\n\t\t\t\t}\n\t\t\t}\n\t\t\texpect(sessionIdExpected).to.equal(sessionIdActualAll);\n\t\t\texpect(sessionIdActualAll).to.equal(sessionIdActualNormalized);\n\t\t}\n\t\texpect(normalizer.getLastFinalId()).to.equal(finals[finals.length - 1]);\n\t\tconst roundtripped = SessionIdNormalizer.deserialize(normalizer.serialize(), () => undefined);\n\t\texpect(roundtripped.equals(normalizer)).to.be.true;\n\t});\n}\n\nfunction makeNormalizerProxy(\n\tnormalizer: SessionIdNormalizer<DummyRange>,\n\tlocals: (LocalCompressedId | undefined)[],\n\tfinals: (FinalCompressedId | undefined)[]\n): SessionIdNormalizer<DummyRange> {\n\treturn new Proxy<SessionIdNormalizer<DummyRange>>(normalizer, {\n\t\tget(target, property: keyof SessionIdNormalizer<DummyRange>) {\n\t\t\tif (typeof target[property] === 'function') {\n\t\t\t\tif (property === 'addLocalId') {\n\t\t\t\t\treturn new Proxy(target[property], {\n\t\t\t\t\t\tapply: (func, thisArg, argumentsList) => {\n\t\t\t\t\t\t\tconst local = Reflect.apply(func, thisArg, argumentsList);\n\t\t\t\t\t\t\tif (locals.length > 0) {\n\t\t\t\t\t\t\t\tfor (let i = (locals[locals.length - 1] ?? fail()) - 1; i > local; i--) {\n\t\t\t\t\t\t\t\t\tlocals.push(undefined);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tlocals.push(local);\n\t\t\t\t\t\t\treturn local;\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t} else if (property === 'addFinalIds') {\n\t\t\t\t\treturn new Proxy(target[property], {\n\t\t\t\t\t\tapply: (func, thisArg, argumentsList) => {\n\t\t\t\t\t\t\tconst firstFinal: FinalCompressedId = argumentsList[0];\n\t\t\t\t\t\t\tconst lastFinal: FinalCompressedId = argumentsList[1];\n\t\t\t\t\t\t\tfor (let i = firstFinal; i <= lastFinal; i++) {\n\t\t\t\t\t\t\t\tfinals.push(i);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn Reflect.apply(func, thisArg, argumentsList);\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn Reflect.get(target, property);\n\t\t},\n\t});\n}\n\ntype DummyRange = undefined;\nconst dummy: DummyRange = undefined;\n\nfunction final(num: number): FinalCompressedId {\n\tassert(num >= 0);\n\treturn num as FinalCompressedId;\n}\n\nfunction makeTestNormalizer(): SessionIdNormalizer<DummyRange> {\n\treturn new SessionIdNormalizer<DummyRange>(true);\n}\n\ninterface AddLocalId {\n\ttype: 'addLocalId';\n}\n\ninterface AddFinalIds {\n\ttype: 'addFinalIds';\n\tfirst: FinalCompressedId;\n\tlast: FinalCompressedId;\n}\n\ntype Operation = AddLocalId | AddFinalIds;\n\ninterface FuzzTestState extends BaseFuzzTestState {\n\tnormalizer: SessionIdNormalizer<DummyRange>;\n\tprevWasLocal: boolean;\n\tcurrentLocal: number;\n\tcurrentFinal: number;\n\tlocals: (LocalCompressedId | undefined)[];\n\tfinals: (FinalCompressedId | undefined)[];\n}\n\nfunction makeOpGenerator(numOperations: number): Generator<Operation, FuzzTestState> {\n\tfunction addLocalIdGenerator(state: FuzzTestState): AddLocalId {\n\t\tconst { locals, finals, random } = state;\n\t\tstate.currentLocal =\n\t\t\tlocals.length < finals.length && random.bool()\n\t\t\t\t? -locals.length - (finals.length - locals.length) - 1\n\t\t\t\t: -locals.length - 1;\n\t\tstate.prevWasLocal = true;\n\t\treturn { type: 'addLocalId' };\n\t}\n\n\tfunction addFinalIdsGenerator(state: FuzzTestState): AddFinalIds {\n\t\tconst { locals, finals, random } = state;\n\t\tif (state.prevWasLocal && locals.length > finals.length && random.integer(1, 3) === 3) {\n\t\t\tstate.currentFinal += random.integer(1, 4);\n\t\t}\n\t\tconst lastFinal = state.currentFinal + random.integer(0, 10);\n\t\tconst addFinal: AddFinalIds = { type: 'addFinalIds', first: final(state.currentFinal), last: final(lastFinal) };\n\t\tstate.currentFinal = lastFinal + 1;\n\t\tstate.prevWasLocal = false;\n\t\treturn addFinal;\n\t}\n\n\treturn chain(\n\t\tgeneratorFromArray([{ type: 'addLocalId' }]),\n\t\ttake(\n\t\t\tnumOperations - 1,\n\t\t\tcreateWeightedGenerator<Operation, FuzzTestState>([\n\t\t\t\t[addLocalIdGenerator, 8],\n\t\t\t\t[addFinalIdsGenerator, 2],\n\t\t\t])\n\t\t)\n\t);\n}\n\nfunction fuzzNormalizer(\n\tnormalizerToFuzz: SessionIdNormalizer<DummyRange>,\n\tnumOperations: number,\n\tseed: number\n): Random {\n\tconst locals: (LocalCompressedId | undefined)[] = [];\n\tconst finals: (FinalCompressedId | undefined)[] = [];\n\tconst normalizer: SessionIdNormalizer<DummyRange> = makeNormalizerProxy(normalizerToFuzz, locals, finals);\n\n\tconst initialState: FuzzTestState = {\n\t\trandom: makeRandom(seed),\n\t\tcurrentLocal: -1,\n\t\tcurrentFinal: 0,\n\t\tprevWasLocal: false,\n\t\tnormalizer,\n\t\tlocals,\n\t\tfinals,\n\t};\n\n\tperformFuzzActions(\n\t\tmakeOpGenerator(numOperations),\n\t\t{\n\t\t\taddLocalId: (state) => {\n\t\t\t\tstate.normalizer.addLocalId();\n\t\t\t\treturn state;\n\t\t\t},\n\t\t\taddFinalIds: (state, { first, last }) => {\n\t\t\t\tstate.normalizer.addFinalIds(first, last, undefined);\n\t\t\t\treturn state;\n\t\t\t},\n\t\t},\n\t\tinitialState\n\t);\n\treturn initialState.random;\n}\n"]}
|
|
@@ -387,12 +387,9 @@ class DeterministicIdGenerator {
|
|
|
387
387
|
return v5((this.editIdCount++).toString(), DeterministicIdGenerator.uuidNamespace);
|
|
388
388
|
}
|
|
389
389
|
getNextNodeId() {
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
else {
|
|
394
|
-
return this.sharedTree.generateNodeId();
|
|
395
|
-
}
|
|
390
|
+
return this.writeFormat === WriteFormat.v0_0_2
|
|
391
|
+
? this.sharedTree.generateNodeId(this.getNextStableId())
|
|
392
|
+
: this.sharedTree.generateNodeId();
|
|
396
393
|
}
|
|
397
394
|
getNextStableId() {
|
|
398
395
|
assert(this.constantIdCompressor !== undefined);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Summary.tests.js","sourceRoot":"","sources":["../../src/test/Summary.tests.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\nimport * as fs from 'fs';\nimport { join } from 'path';\nimport { IsoBuffer } from '@fluidframework/common-utils';\nimport { expect } from 'chai';\nimport { v5 } from 'uuid';\nimport { Change, StablePlace, StableRange } from '../ChangeTypes';\nimport { assert, RecursiveMutable } from '../Common';\nimport { areRevisionViewsSemanticallyEqual } from '../EditUtilities';\nimport { EditId, NodeId, SessionId, StableId, TraitLabel } from '../Identifiers';\nimport { initialTree } from '../InitialTree';\nimport {\n\teditsPerChunk,\n\treservedIdCount,\n\tSharedTreeSummary,\n\tSharedTreeSummary_0_0_2,\n\tWriteFormat,\n} from '../persisted-types';\nimport { getChangeNodeFromView } from '../SerializationUtilities';\nimport { SharedTree } from '../SharedTree';\nimport { deserialize, getSummaryStatistics, SummaryStatistics } from '../SummaryBackCompatibility';\nimport { getUploadedEditChunkContents, UploadedEditChunkContents } from '../SummaryTestUtilities';\nimport { IdCompressor } from '../id-compressor';\nimport { convertEditIds } from '../IdConversion';\nimport { MutableStringInterner } from '../StringInterner';\nimport { sequencedIdNormalizer } from '../NodeIdUtilities';\nimport { expectDefined } from './utilities/TestCommon';\nimport { TestFluidSerializer } from './utilities/TestSerializer';\nimport {\n\tgetEditLogInternal,\n\tgetIdNormalizerFromSharedTree,\n\tmakeNodeIdContext,\n\tsetUpLocalServerTestSharedTree,\n\ttestDocumentsPathBase,\n} from './utilities/TestUtilities';\n\nconst directory = join(testDocumentsPathBase, 'summary-tests');\n\n/** Applies a smattering of interesting edits to the given shared tree in an attempt to cover a variety of use cases */\nexport function applyTestEdits(sharedTree: SharedTree): void {\n\tconst uuid = new DeterministicIdGenerator(sharedTree.getWriteFormat(), sharedTree);\n\n\tfunction applyEdit(changes: Change[]): void {\n\t\tconst internalChanges = changes.map((c) => sharedTree.internalizeChange(c));\n\t\tsharedTree.applyEditInternal({ id: uuid.getNextEditId(), changes: internalChanges });\n\t}\n\n\t/*\n\t * Build a tree that looks like the following:\n\t *\n\t * ROOT\n\t * | 'root'\n\t * [root]\n\t * 'left' / \\ 'right'\n\t * [A] [B, C, D]\n\t * | 'leaf'\n\t * [E('payload')]\n\t */\n\n\tconst cDetachedId = 0;\n\tconst rootDetachedId = 1;\n\tconst aId = uuid.getNextNodeId();\n\tconst cId = uuid.getNextNodeId();\n\tconst dId = uuid.getNextNodeId();\n\n\tapplyEdit([\n\t\tChange.build(\n\t\t\t[\n\t\t\t\t{\n\t\t\t\t\tdefinition: 'C',\n\t\t\t\t\tidentifier: cId,\n\t\t\t\t\ttraits: {\n\t\t\t\t\t\tleaf: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdefinition: 'E',\n\t\t\t\t\t\t\t\tidentifier: uuid.getNextNodeId(),\n\t\t\t\t\t\t\t\tpayload: 'payload',\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},\n\t\t\t],\n\t\t\tcDetachedId\n\t\t),\n\t\tChange.build(\n\t\t\t[\n\t\t\t\t{\n\t\t\t\t\tdefinition: 'Root',\n\t\t\t\t\tidentifier: uuid.getNextNodeId(),\n\t\t\t\t\ttraits: {\n\t\t\t\t\t\tleft: [{ definition: 'A', identifier: aId }],\n\t\t\t\t\t\tright: [\n\t\t\t\t\t\t\t{ definition: 'B', identifier: uuid.getNextNodeId() },\n\t\t\t\t\t\t\tcDetachedId,\n\t\t\t\t\t\t\t{ definition: 'D', identifier: dId },\n\t\t\t\t\t\t],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t],\n\t\t\trootDetachedId\n\t\t),\n\t\tChange.insert(\n\t\t\trootDetachedId,\n\t\t\tStablePlace.atStartOf({\n\t\t\t\tlabel: 'root' as TraitLabel,\n\t\t\t\tparent: sharedTree.convertToNodeId(initialTree.identifier),\n\t\t\t})\n\t\t),\n\t]);\n\n\t/**\n\t * Edit the tree\n\t *\n\t * 1. Move C after A\n\t * 2. Delete D\n\t * 3.\n\t * ...\n\t * 102. Set the payload of A to _i_ for all _i_ in 0...100\n\t */\n\n\tapplyEdit([...Change.move(StableRange.only(cId), StablePlace.after(aId))]);\n\tapplyEdit([Change.delete(StableRange.only(dId))]);\n\tfor (let i = 0; i < 100; i++) {\n\t\tapplyEdit([Change.setPayload(aId, i)]);\n\t}\n}\n\nexport async function createSummaryTestTree(writeFormat: WriteFormat, summarizeHistory: boolean): Promise<SharedTree> {\n\tconst { tree, testObjectProvider } = await setUpLocalServerTestSharedTree({\n\t\twriteFormat,\n\t\tsummarizeHistory,\n\t\tuploadEditChunks: summarizeHistory,\n\t});\n\n\tif (writeFormat === WriteFormat.v0_1_1) {\n\t\tconst idCompressor = new IdCompressor('968bee41-bcf7-46d2-8035-6eb163b76c4c' as SessionId, reservedIdCount);\n\t\tconst interner = new MutableStringInterner([initialTree.definition]);\n\t\tconst context = makeNodeIdContext(idCompressor);\n\t\tconst normalizer = sequencedIdNormalizer(context);\n\t\tconst sharedTreeSummaryWithConstantSessionId: SharedTreeSummary = {\n\t\t\tversion: WriteFormat.v0_1_1,\n\t\t\tcurrentTree: summarizeHistory\n\t\t\t\t? [\n\t\t\t\t\t\tinterner.getOrCreateInternedId(initialTree.definition),\n\t\t\t\t\t\tnormalizer.normalizeToOpSpace(context.convertToNodeId(initialTree.identifier)),\n\t\t\t\t ]\n\t\t\t\t: undefined,\n\t\t\teditHistory: {\n\t\t\t\teditIds: [],\n\t\t\t\teditChunks: [],\n\t\t\t},\n\t\t\tidCompressor: idCompressor.serialize(true),\n\t\t\tinternedStrings: interner.getSerializable(),\n\t\t};\n\n\t\ttree.loadSummary(sharedTreeSummaryWithConstantSessionId);\n\t}\n\n\tapplyTestEdits(tree);\n\n\tawait testObjectProvider.ensureSynchronized();\n\treturn tree;\n}\n\nexport function runSummaryTests(title: string): void {\n\tdescribe(title, () => {\n\t\t// Note: this test serializer doesn't handle blobs properly (it just uses JSON.stringify/JSON.parse).\n\t\tconst testSerializer = new TestFluidSerializer();\n\n\t\tconst {\n\t\t\tsummaryFileWithHistory_0_0_2,\n\t\t\tsummaryFileNoHistory_0_0_2,\n\t\t\tsummaryFileEmptyTraits_0_0_2,\n\t\t\tsummaryFileWithHistory_0_1_1,\n\t\t\tsummaryFileNoHistory_0_1_1,\n\t\t\tsummaryFileUpgrade_0_1_1,\n\t\t\tblobsFile,\n\t\t} = loadSummaryTestFiles();\n\n\t\t// Note: Fluid setup gives stable `absolutePath`s for these blobs across sessions. If that were not the case,\n\t\t// this test suite would need to build some kind of map from the blob info saved on disk to the `IFluidHandle`\n\t\t// list returned by uploading these blobs.\n\t\tconst blobsParsed: UploadedEditChunkContents[] = JSON.parse(blobsFile);\n\t\tconst blobs: ArrayBufferLike[] = blobsParsed.map((blob) =>\n\t\t\tIsoBuffer.from(JSON.stringify(blob.chunkContents), 'utf8')\n\t\t);\n\n\t\t// Re-enable this test for an easy way to write the test summary files to disk\n\t\tit.skip('save files to disk', async () => {\n\t\t\tawait makeSummaryTestFiles();\n\t\t});\n\n\t\tdescribe('0.0.2 write format', () => {\n\t\t\tconst setUp002Tree: typeof setUpLocalServerTestSharedTree = async (options) =>\n\t\t\t\tsetUpLocalServerTestSharedTree({ writeFormat: WriteFormat.v0_0_2, ...options });\n\n\t\t\tconst setUp002SummaryTestTree = async (summarizeHistory: boolean): Promise<SharedTree> =>\n\t\t\t\tcreateSummaryTestTree(WriteFormat.v0_0_2, summarizeHistory);\n\n\t\t\tit('Normalizes a denormalized summary containing nodes with empty traits', async () => {\n\t\t\t\tconst { tree } = await setUp002Tree({});\n\t\t\t\ttree.loadSerializedSummary(summaryFileEmptyTraits_0_0_2);\n\n\t\t\t\tconst { tree: expectedTree } = await setUp002Tree({});\n\t\t\t\texpectedTree.loadSerializedSummary(summaryFileWithHistory_0_0_2);\n\t\t\t\texpect(getChangeNodeFromView(tree.currentView)).deep.equals(\n\t\t\t\t\tgetChangeNodeFromView(expectedTree.currentView)\n\t\t\t\t);\n\t\t\t});\n\n\t\t\tit('writes 0.0.2 files without history', async () => {\n\t\t\t\tconst tree = await setUp002SummaryTestTree(false);\n\t\t\t\tconst summary: RecursiveMutable<SharedTreeSummary_0_0_2> = JSON.parse(tree.saveSerializedSummary());\n\t\t\t\tconst expectedSummary: SharedTreeSummary_0_0_2 = JSON.parse(summaryFileNoHistory_0_0_2);\n\t\t\t\t// The edit ID of the single \"no history edit\" is generated randomly. Replace it with the baseline edit for the sake of this test.\n\t\t\t\tsummary.sequencedEdits[0].id = expectedSummary.sequencedEdits[0].id;\n\t\t\t\texpect(summary).to.deep.equal(expectedSummary);\n\t\t\t});\n\n\t\t\tit('writes 0.0.2 files with history', async () => {\n\t\t\t\tconst tree = await setUp002SummaryTestTree(true);\n\t\t\t\texpect(JSON.parse(tree.saveSerializedSummary())).to.deep.equal(\n\t\t\t\t\tJSON.parse(summaryFileWithHistory_0_0_2)\n\t\t\t\t);\n\t\t\t});\n\n\t\t\tdescribe('reading the same version', () => {\n\t\t\t\tit('reads 0.0.2 files without history', async () => {\n\t\t\t\t\tconst { tree } = await setUp002Tree({});\n\t\t\t\t\ttree.loadSerializedSummary(summaryFileNoHistory_0_0_2);\n\t\t\t\t\t// Tree should have exactly one edit, as all \"no history\" summaries do.\n\t\t\t\t\texpect(tree.edits.length).to.equal(1);\n\t\t\t\t\t// Load a baseline tree's own summary with no history to compare with\n\t\t\t\t\tconst summaryNoHistory = (await setUp002SummaryTestTree(false)).saveSummary();\n\t\t\t\t\tconst { tree: expectedTree } = await setUp002Tree({ summarizeHistory: false });\n\t\t\t\t\texpectedTree.loadSummary(summaryNoHistory);\n\t\t\t\t\tawait expectSharedTreesEqual(tree, expectedTree, false);\n\t\t\t\t});\n\n\t\t\t\tit('reads 0.0.2 files with history', async () => {\n\t\t\t\t\tconst { tree } = await setUp002Tree({});\n\t\t\t\t\ttree.loadSerializedSummary(summaryFileWithHistory_0_0_2);\n\t\t\t\t\tconst expectedTree = await setUp002SummaryTestTree(true);\n\t\t\t\t\tawait expectSharedTreesEqual(tree, expectedTree);\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tdescribe('reading next version', () => {\n\t\t\t\tit('reads 0.1.1', async () => {\n\t\t\t\t\tconst { tree } = await setUp002Tree({});\n\t\t\t\t\ttree.loadSerializedSummary(summaryFileWithHistory_0_1_1);\n\t\t\t\t\t// TODO: There may need to be a testObjectProvider synchronization here to upload\n\t\t\t\t\t// blobs from this summary.\n\t\t\t\t\t// We should also look at how this test asserts behavior w.r.t blobs.\n\t\t\t\t\tconst newSummary = JSON.parse(tree.saveSerializedSummary());\n\t\t\t\t\tconst expectedSummary = JSON.parse(summaryFileWithHistory_0_1_1);\n\t\t\t\t\texpect(newSummary).to.deep.equal(expectedSummary);\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tit('gives correct SummaryStatistics', async () => {\n\t\t\t\tconst { tree } = await setUp002Tree({});\n\t\t\t\ttree.loadSerializedSummary(summaryFileWithHistory_0_0_2);\n\t\t\t\tconst editCount = tree.edits.length;\n\t\t\t\tconst summary = deserialize(summaryFileWithHistory_0_0_2, testSerializer);\n\t\t\t\tconst telemetryInfo = getSummaryStatistics(summary);\n\t\t\t\tconst expectedTelemetryInfo: SummaryStatistics = {\n\t\t\t\t\tformatVersion: WriteFormat.v0_0_2,\n\t\t\t\t\thistorySize: editCount,\n\t\t\t\t};\n\t\t\t\texpect(telemetryInfo).to.deep.equals(expectedTelemetryInfo);\n\t\t\t});\n\t\t});\n\n\t\tdescribe('0.1.1 write format', () => {\n\t\t\tconst setUp011Tree: typeof setUpLocalServerTestSharedTree = async (options) =>\n\t\t\t\tsetUpLocalServerTestSharedTree({ writeFormat: WriteFormat.v0_1_1, ...options });\n\n\t\t\tconst setUp011SummaryTestTree = async (summarizeHistory: boolean): Promise<SharedTree> =>\n\t\t\t\tcreateSummaryTestTree(WriteFormat.v0_1_1, summarizeHistory);\n\n\t\t\tit('writes 0.1.1 files without history', async () => {\n\t\t\t\tconst tree = await setUp011SummaryTestTree(false);\n\t\t\t\tconst summary: RecursiveMutable<SharedTreeSummary> = JSON.parse(tree.saveSerializedSummary());\n\t\t\t\tconst expectedSummary: SharedTreeSummary = JSON.parse(summaryFileNoHistory_0_1_1);\n\t\t\t\t// The edit ID of the single \"no history edit\" is generated randomly. Replace it with the baseline edit for the sake of this test.\n\t\t\t\texpectDefined(summary.editHistory).editIds[0] = expectDefined(expectedSummary.editHistory?.editIds[0]);\n\t\t\t\texpect(summary).to.deep.equal(expectedSummary);\n\t\t\t\texpect(await getUploadedEditChunkContents(tree)).to.deep.equal([]);\n\t\t\t});\n\n\t\t\tit('writes 0.1.1 files with history', async () => {\n\t\t\t\tconst tree = await setUp011SummaryTestTree(true);\n\t\t\t\texpect(JSON.parse(tree.saveSerializedSummary())).to.deep.equal(\n\t\t\t\t\tJSON.parse(summaryFileWithHistory_0_1_1)\n\t\t\t\t);\n\t\t\t\texpect(await getUploadedEditChunkContents(tree)).to.deep.equal(blobsParsed);\n\t\t\t});\n\n\t\t\tdescribe('reading the same version', () => {\n\t\t\t\tit('reads 0.1.1 files without history', async () => {\n\t\t\t\t\tconst { tree } = await setUp011Tree({ blobs });\n\t\t\t\t\ttree.loadSerializedSummary(summaryFileNoHistory_0_1_1);\n\t\t\t\t\t// Tree should have exactly one edit, as all \"no history\" summaries do.\n\t\t\t\t\texpect(tree.edits.length).to.equal(1);\n\t\t\t\t\t// Load a baseline tree's own summary with no history to compare with\n\t\t\t\t\tconst summaryNoHistory = (await setUp011SummaryTestTree(false)).saveSummary();\n\t\t\t\t\tconst { tree: expectedTree } = await setUp011Tree({ summarizeHistory: false });\n\t\t\t\t\texpectedTree.loadSummary(summaryNoHistory);\n\t\t\t\t\tawait expectSharedTreesEqual(tree, expectedTree, false);\n\t\t\t\t});\n\n\t\t\t\tit('reads 0.1.1 files with history', async () => {\n\t\t\t\t\tconst { tree } = await setUp011Tree({ blobs });\n\t\t\t\t\ttree.loadSerializedSummary(summaryFileWithHistory_0_1_1);\n\t\t\t\t\tconst expectedTree = await setUp011SummaryTestTree(false);\n\t\t\t\t\tawait expectSharedTreesEqual(tree, expectedTree);\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tdescribe('reading previous versions', () => {\n\t\t\t\tit('reads 0.0.2', async () => {\n\t\t\t\t\tconst expectedTree = await setUp011SummaryTestTree(true);\n\t\t\t\t\tconst { tree } = await setUp011Tree({});\n\t\t\t\t\ttree.loadSerializedSummary(summaryFileWithHistory_0_0_2);\n\t\t\t\t\tawait expectSharedTreesEqual(tree, expectedTree);\n\t\t\t\t\texpect(JSON.parse(tree.saveSerializedSummary())).to.deep.equal(\n\t\t\t\t\t\tJSON.parse(summaryFileWithHistory_0_0_2)\n\t\t\t\t\t);\n\t\t\t\t});\n\n\t\t\t\tit('upgrades 0.0.2', async () => {\n\t\t\t\t\tconst { tree, testObjectProvider } = await setUp011Tree({});\n\t\t\t\t\ttree.loadSerializedSummary(summaryFileWithHistory_0_0_2);\n\t\t\t\t\t// Synchronize to give a chance for the update op to be sequenced.\n\t\t\t\t\tawait testObjectProvider.ensureSynchronized();\n\t\t\t\t\tconst expectedTree = await setUp011SummaryTestTree(true);\n\t\t\t\t\tawait expectSharedTreesEqual(tree, expectedTree);\n\t\t\t\t\texpect(JSON.parse(tree.saveSerializedSummary())).to.deep.equal(\n\t\t\t\t\t\tJSON.parse(summaryFileUpgrade_0_1_1)\n\t\t\t\t\t);\n\t\t\t\t});\n\n\t\t\t\tit('upgrades 0.0.2 that has several stale ops that it resubmits', async () => {\n\t\t\t\t\tconst { tree: resubmitTree, testObjectProvider } = await setUpLocalServerTestSharedTree({\n\t\t\t\t\t\twriteFormat: WriteFormat.v0_0_2,\n\t\t\t\t\t});\n\t\t\t\t\tapplyTestEdits(resubmitTree);\n\t\t\t\t\tconst { tree: tree } = await setUpLocalServerTestSharedTree({\n\t\t\t\t\t\twriteFormat: WriteFormat.v0_1_1,\n\t\t\t\t\t\ttestObjectProvider,\n\t\t\t\t\t});\n\t\t\t\t\tawait testObjectProvider.ensureSynchronized();\n\t\t\t\t\tawait expectSharedTreesEqual(resubmitTree, tree);\n\t\t\t\t\tawait expectSharedTreesEqual(tree, await createSummaryTestTree(WriteFormat.v0_1_1, true));\n\t\t\t\t});\n\n\t\t\t\tit('Normalizes a denormalized summary containing nodes with empty traits', async () => {\n\t\t\t\t\tconst { tree } = await setUp011Tree({});\n\t\t\t\t\ttree.loadSerializedSummary(summaryFileEmptyTraits_0_0_2);\n\n\t\t\t\t\tconst { tree: expectedTree } = await setUp011Tree({});\n\t\t\t\t\texpectedTree.loadSerializedSummary(summaryFileWithHistory_0_0_2);\n\t\t\t\t\texpect(\n\t\t\t\t\t\tareRevisionViewsSemanticallyEqual(\n\t\t\t\t\t\t\ttree.currentView,\n\t\t\t\t\t\t\ttree,\n\t\t\t\t\t\t\texpectedTree.currentView,\n\t\t\t\t\t\t\texpectedTree\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tit('gives correct SummaryStatistics', async () => {\n\t\t\t\tconst { tree } = await setUp011Tree({});\n\t\t\t\ttree.loadSerializedSummary(summaryFileWithHistory_0_1_1);\n\t\t\t\tconst editCount = tree.edits.length;\n\t\t\t\tconst summary = deserialize(summaryFileWithHistory_0_1_1, testSerializer);\n\t\t\t\tconst telemetryInfo = getSummaryStatistics(summary);\n\t\t\t\tconst totalChunks = Math.ceil(editCount / editsPerChunk);\n\t\t\t\tconst expectedTelemetryInfo: SummaryStatistics = {\n\t\t\t\t\tformatVersion: WriteFormat.v0_1_1,\n\t\t\t\t\thistorySize: editCount,\n\t\t\t\t\ttotalNumberOfChunks: totalChunks,\n\t\t\t\t\tuploadedChunks:\n\t\t\t\t\t\t// If the last chunk is bigger than the number of edits per chunk, it has also been uploaded\n\t\t\t\t\t\teditCount - Math.floor(editCount / editsPerChunk) * editsPerChunk < editsPerChunk &&\n\t\t\t\t\t\ttotalChunks !== 0\n\t\t\t\t\t\t\t? totalChunks - 1\n\t\t\t\t\t\t\t: totalChunks,\n\t\t\t\t};\n\t\t\t\texpect(telemetryInfo).to.deep.equals(expectedTelemetryInfo);\n\t\t\t});\n\t\t});\n\t});\n}\n\nasync function expectSharedTreesEqual(\n\tsharedTreeA: SharedTree,\n\tsharedTreeB: SharedTree,\n\tcompareEditIds = true\n): Promise<void> {\n\tif (\n\t\t!areRevisionViewsSemanticallyEqual(sharedTreeA.currentView, sharedTreeA, sharedTreeB.currentView, sharedTreeB)\n\t) {\n\t\texpect.fail('trees have different current views');\n\t}\n\n\tif (sharedTreeA.edits.length !== sharedTreeB.edits.length) {\n\t\texpect.fail('trees have different amounts of edits');\n\t}\n\n\tfor (let i = 0; i < sharedTreeA.edits.length; i++) {\n\t\tconst roundTrip = <T>(obj: T): T => JSON.parse(JSON.stringify(obj)) as T;\n\n\t\tconst editA = roundTrip(\n\t\t\tconvertEditIds(await getEditLogInternal(sharedTreeA).getEditAtIndex(i), (id) =>\n\t\t\t\tsharedTreeA.convertToStableNodeId(id)\n\t\t\t)\n\t\t);\n\t\tconst editB = roundTrip(\n\t\t\tconvertEditIds(await getEditLogInternal(sharedTreeB).getEditAtIndex(i), (id) =>\n\t\t\t\tsharedTreeB.convertToStableNodeId(id)\n\t\t\t)\n\t\t);\n\t\tif (compareEditIds) {\n\t\t\texpect(editA).to.deep.equal(editB, `trees have different edits (index ${i})`);\n\t\t} else {\n\t\t\texpect(editA.changes).to.deep.equal(editB.changes, `edits have different changes (index ${i})`);\n\t\t}\n\t}\n}\n\nfunction loadSummaryTestFiles(): {\n\tsummaryFileWithHistory_0_0_2: string;\n\tsummaryFileNoHistory_0_0_2: string;\n\tsummaryFileEmptyTraits_0_0_2: string;\n\tsummaryFileWithHistory_0_1_1: string;\n\tsummaryFileNoHistory_0_1_1: string;\n\tsummaryFileUpgrade_0_1_1: string;\n\tblobsFile: string;\n} {\n\tconst summaryFileWithHistory_0_0_2 = fs.readFileSync(join(directory, 'summary-0-0-2.json'), 'utf8');\n\tconst summaryFileNoHistory_0_0_2 = fs.readFileSync(join(directory, 'summary-no-history-0-0-2.json'), 'utf8');\n\tconst summaryFileEmptyTraits_0_0_2 = fs.readFileSync(join(directory, 'summary-empty-traits-0-0-2.json'), 'utf8');\n\tconst summaryFileWithHistory_0_1_1 = fs.readFileSync(join(directory, 'summary-0-1-1.json'), 'utf8');\n\tconst summaryFileNoHistory_0_1_1 = fs.readFileSync(join(directory, 'summary-no-history-0-1-1.json'), 'utf8');\n\tconst summaryFileUpgrade_0_1_1 = fs.readFileSync(join(directory, 'summary-upgrade-0-1-1.json'), 'utf8');\n\tconst blobsFile = fs.readFileSync(join(directory, 'blobs-0-1-1.json'), 'utf8');\n\n\treturn {\n\t\tsummaryFileWithHistory_0_0_2,\n\t\tsummaryFileNoHistory_0_0_2,\n\t\tsummaryFileEmptyTraits_0_0_2,\n\t\tsummaryFileWithHistory_0_1_1,\n\t\tsummaryFileNoHistory_0_1_1,\n\t\tsummaryFileUpgrade_0_1_1,\n\t\tblobsFile,\n\t};\n}\n\nasync function makeSummaryTestFiles(): Promise<void> {\n\ttry {\n\t\tfs.accessSync(directory);\n\t} catch {\n\t\tfs.mkdirSync(directory);\n\t}\n\n\tconst treeWithHistory_0_0_2 = await createSummaryTestTree(WriteFormat.v0_0_2, true);\n\tconst treeNoHistory_0_0_2 = await createSummaryTestTree(WriteFormat.v0_0_2, false);\n\tconst treeWithHistory_0_1_1 = await createSummaryTestTree(WriteFormat.v0_1_1, true);\n\tconst treeNoHistory_0_1_1 = await createSummaryTestTree(WriteFormat.v0_1_1, false);\n\n\tfs.writeFileSync(join(directory, `summary-0-0-2.json`), treeWithHistory_0_0_2.saveSerializedSummary());\n\tfs.writeFileSync(join(directory, `summary-no-history-0-0-2.json`), treeNoHistory_0_0_2.saveSerializedSummary());\n\tfs.writeFileSync(join(directory, `summary-0-1-1.json`), treeWithHistory_0_1_1.saveSerializedSummary());\n\tfs.writeFileSync(join(directory, `summary-no-history-0-1-1.json`), treeNoHistory_0_1_1.saveSerializedSummary());\n\n\tconst blobs = await getUploadedEditChunkContents(treeWithHistory_0_1_1);\n\tassert(blobs.length > 0);\n\tfs.writeFileSync(join(directory, `blobs-0-1-1.json`), JSON.stringify(blobs));\n\n\tconst { tree: upgradedTree, testObjectProvider } = await setUpLocalServerTestSharedTree({\n\t\twriteFormat: WriteFormat.v0_1_1,\n\t\tsummarizeHistory: true,\n\t});\n\tupgradedTree.loadSummary(treeWithHistory_0_0_2.saveSummary());\n\tawait testObjectProvider.ensureSynchronized();\n\tfs.writeFileSync(join(directory, `summary-upgrade-0-1-1.json`), upgradedTree.saveSerializedSummary());\n}\n\n/** Every instance of this class generates the same sequence of v5 UUIDs */\nclass DeterministicIdGenerator {\n\tpublic static readonly sessionId = '968bee41-bcf7-46d2-8035-6eb163b76c4c' as SessionId;\n\tprivate static readonly uuidNamespace = '44864298-500e-4cf8-9f44-a249e5b3a286';\n\tprivate editIdCount = 0;\n\tprivate readonly constantIdCompressor?: IdCompressor;\n\n\tpublic constructor(public readonly writeFormat: WriteFormat, private readonly sharedTree: SharedTree) {\n\t\tif (this.writeFormat === WriteFormat.v0_1_1) {\n\t\t\tassert(getIdNormalizerFromSharedTree(sharedTree).localSessionId === DeterministicIdGenerator.sessionId);\n\t\t} else {\n\t\t\tassert(getIdNormalizerFromSharedTree(sharedTree).localSessionId !== DeterministicIdGenerator.sessionId);\n\t\t\tthis.constantIdCompressor = new IdCompressor(DeterministicIdGenerator.sessionId, reservedIdCount);\n\t\t}\n\t}\n\n\tpublic getNextEditId(): EditId {\n\t\treturn v5((this.editIdCount++).toString(), DeterministicIdGenerator.uuidNamespace) as EditId;\n\t}\n\n\tpublic getNextNodeId(): NodeId {\n\t\tif (this.writeFormat === WriteFormat.v0_0_2) {\n\t\t\treturn this.sharedTree.generateNodeId(this.getNextStableId());\n\t\t} else {\n\t\t\treturn this.sharedTree.generateNodeId();\n\t\t}\n\t}\n\n\tprivate getNextStableId(): StableId {\n\t\tassert(this.constantIdCompressor !== undefined);\n\t\treturn this.constantIdCompressor.decompress(this.constantIdCompressor.generateCompressedId()) as StableId;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"Summary.tests.js","sourceRoot":"","sources":["../../src/test/Summary.tests.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\nimport * as fs from 'fs';\nimport { join } from 'path';\nimport { IsoBuffer } from '@fluidframework/common-utils';\nimport { expect } from 'chai';\nimport { v5 } from 'uuid';\nimport { Change, StablePlace, StableRange } from '../ChangeTypes';\nimport { assert, RecursiveMutable } from '../Common';\nimport { areRevisionViewsSemanticallyEqual } from '../EditUtilities';\nimport { EditId, NodeId, SessionId, StableId, TraitLabel } from '../Identifiers';\nimport { initialTree } from '../InitialTree';\nimport {\n\teditsPerChunk,\n\treservedIdCount,\n\tSharedTreeSummary,\n\tSharedTreeSummary_0_0_2,\n\tWriteFormat,\n} from '../persisted-types';\nimport { getChangeNodeFromView } from '../SerializationUtilities';\nimport { SharedTree } from '../SharedTree';\nimport { deserialize, getSummaryStatistics, SummaryStatistics } from '../SummaryBackCompatibility';\nimport { getUploadedEditChunkContents, UploadedEditChunkContents } from '../SummaryTestUtilities';\nimport { IdCompressor } from '../id-compressor';\nimport { convertEditIds } from '../IdConversion';\nimport { MutableStringInterner } from '../StringInterner';\nimport { sequencedIdNormalizer } from '../NodeIdUtilities';\nimport { expectDefined } from './utilities/TestCommon';\nimport { TestFluidSerializer } from './utilities/TestSerializer';\nimport {\n\tgetEditLogInternal,\n\tgetIdNormalizerFromSharedTree,\n\tmakeNodeIdContext,\n\tsetUpLocalServerTestSharedTree,\n\ttestDocumentsPathBase,\n} from './utilities/TestUtilities';\n\nconst directory = join(testDocumentsPathBase, 'summary-tests');\n\n/** Applies a smattering of interesting edits to the given shared tree in an attempt to cover a variety of use cases */\nexport function applyTestEdits(sharedTree: SharedTree): void {\n\tconst uuid = new DeterministicIdGenerator(sharedTree.getWriteFormat(), sharedTree);\n\n\tfunction applyEdit(changes: Change[]): void {\n\t\tconst internalChanges = changes.map((c) => sharedTree.internalizeChange(c));\n\t\tsharedTree.applyEditInternal({ id: uuid.getNextEditId(), changes: internalChanges });\n\t}\n\n\t/*\n\t * Build a tree that looks like the following:\n\t *\n\t * ROOT\n\t * | 'root'\n\t * [root]\n\t * 'left' / \\ 'right'\n\t * [A] [B, C, D]\n\t * | 'leaf'\n\t * [E('payload')]\n\t */\n\n\tconst cDetachedId = 0;\n\tconst rootDetachedId = 1;\n\tconst aId = uuid.getNextNodeId();\n\tconst cId = uuid.getNextNodeId();\n\tconst dId = uuid.getNextNodeId();\n\n\tapplyEdit([\n\t\tChange.build(\n\t\t\t[\n\t\t\t\t{\n\t\t\t\t\tdefinition: 'C',\n\t\t\t\t\tidentifier: cId,\n\t\t\t\t\ttraits: {\n\t\t\t\t\t\tleaf: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdefinition: 'E',\n\t\t\t\t\t\t\t\tidentifier: uuid.getNextNodeId(),\n\t\t\t\t\t\t\t\tpayload: 'payload',\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},\n\t\t\t],\n\t\t\tcDetachedId\n\t\t),\n\t\tChange.build(\n\t\t\t[\n\t\t\t\t{\n\t\t\t\t\tdefinition: 'Root',\n\t\t\t\t\tidentifier: uuid.getNextNodeId(),\n\t\t\t\t\ttraits: {\n\t\t\t\t\t\tleft: [{ definition: 'A', identifier: aId }],\n\t\t\t\t\t\tright: [\n\t\t\t\t\t\t\t{ definition: 'B', identifier: uuid.getNextNodeId() },\n\t\t\t\t\t\t\tcDetachedId,\n\t\t\t\t\t\t\t{ definition: 'D', identifier: dId },\n\t\t\t\t\t\t],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t],\n\t\t\trootDetachedId\n\t\t),\n\t\tChange.insert(\n\t\t\trootDetachedId,\n\t\t\tStablePlace.atStartOf({\n\t\t\t\tlabel: 'root' as TraitLabel,\n\t\t\t\tparent: sharedTree.convertToNodeId(initialTree.identifier),\n\t\t\t})\n\t\t),\n\t]);\n\n\t/**\n\t * Edit the tree\n\t *\n\t * 1. Move C after A\n\t * 2. Delete D\n\t * 3.\n\t * ...\n\t * 102. Set the payload of A to _i_ for all _i_ in 0...100\n\t */\n\n\tapplyEdit([...Change.move(StableRange.only(cId), StablePlace.after(aId))]);\n\tapplyEdit([Change.delete(StableRange.only(dId))]);\n\tfor (let i = 0; i < 100; i++) {\n\t\tapplyEdit([Change.setPayload(aId, i)]);\n\t}\n}\n\nexport async function createSummaryTestTree(writeFormat: WriteFormat, summarizeHistory: boolean): Promise<SharedTree> {\n\tconst { tree, testObjectProvider } = await setUpLocalServerTestSharedTree({\n\t\twriteFormat,\n\t\tsummarizeHistory,\n\t\tuploadEditChunks: summarizeHistory,\n\t});\n\n\tif (writeFormat === WriteFormat.v0_1_1) {\n\t\tconst idCompressor = new IdCompressor('968bee41-bcf7-46d2-8035-6eb163b76c4c' as SessionId, reservedIdCount);\n\t\tconst interner = new MutableStringInterner([initialTree.definition]);\n\t\tconst context = makeNodeIdContext(idCompressor);\n\t\tconst normalizer = sequencedIdNormalizer(context);\n\t\tconst sharedTreeSummaryWithConstantSessionId: SharedTreeSummary = {\n\t\t\tversion: WriteFormat.v0_1_1,\n\t\t\tcurrentTree: summarizeHistory\n\t\t\t\t? [\n\t\t\t\t\t\tinterner.getOrCreateInternedId(initialTree.definition),\n\t\t\t\t\t\tnormalizer.normalizeToOpSpace(context.convertToNodeId(initialTree.identifier)),\n\t\t\t\t ]\n\t\t\t\t: undefined,\n\t\t\teditHistory: {\n\t\t\t\teditIds: [],\n\t\t\t\teditChunks: [],\n\t\t\t},\n\t\t\tidCompressor: idCompressor.serialize(true),\n\t\t\tinternedStrings: interner.getSerializable(),\n\t\t};\n\n\t\ttree.loadSummary(sharedTreeSummaryWithConstantSessionId);\n\t}\n\n\tapplyTestEdits(tree);\n\n\tawait testObjectProvider.ensureSynchronized();\n\treturn tree;\n}\n\nexport function runSummaryTests(title: string): void {\n\tdescribe(title, () => {\n\t\t// Note: this test serializer doesn't handle blobs properly (it just uses JSON.stringify/JSON.parse).\n\t\tconst testSerializer = new TestFluidSerializer();\n\n\t\tconst {\n\t\t\tsummaryFileWithHistory_0_0_2,\n\t\t\tsummaryFileNoHistory_0_0_2,\n\t\t\tsummaryFileEmptyTraits_0_0_2,\n\t\t\tsummaryFileWithHistory_0_1_1,\n\t\t\tsummaryFileNoHistory_0_1_1,\n\t\t\tsummaryFileUpgrade_0_1_1,\n\t\t\tblobsFile,\n\t\t} = loadSummaryTestFiles();\n\n\t\t// Note: Fluid setup gives stable `absolutePath`s for these blobs across sessions. If that were not the case,\n\t\t// this test suite would need to build some kind of map from the blob info saved on disk to the `IFluidHandle`\n\t\t// list returned by uploading these blobs.\n\t\tconst blobsParsed: UploadedEditChunkContents[] = JSON.parse(blobsFile);\n\t\tconst blobs: ArrayBufferLike[] = blobsParsed.map((blob) =>\n\t\t\tIsoBuffer.from(JSON.stringify(blob.chunkContents), 'utf8')\n\t\t);\n\n\t\t// Re-enable this test for an easy way to write the test summary files to disk\n\t\tit.skip('save files to disk', async () => {\n\t\t\tawait makeSummaryTestFiles();\n\t\t});\n\n\t\tdescribe('0.0.2 write format', () => {\n\t\t\tconst setUp002Tree: typeof setUpLocalServerTestSharedTree = async (options) =>\n\t\t\t\tsetUpLocalServerTestSharedTree({ writeFormat: WriteFormat.v0_0_2, ...options });\n\n\t\t\tconst setUp002SummaryTestTree = async (summarizeHistory: boolean): Promise<SharedTree> =>\n\t\t\t\tcreateSummaryTestTree(WriteFormat.v0_0_2, summarizeHistory);\n\n\t\t\tit('Normalizes a denormalized summary containing nodes with empty traits', async () => {\n\t\t\t\tconst { tree } = await setUp002Tree({});\n\t\t\t\ttree.loadSerializedSummary(summaryFileEmptyTraits_0_0_2);\n\n\t\t\t\tconst { tree: expectedTree } = await setUp002Tree({});\n\t\t\t\texpectedTree.loadSerializedSummary(summaryFileWithHistory_0_0_2);\n\t\t\t\texpect(getChangeNodeFromView(tree.currentView)).deep.equals(\n\t\t\t\t\tgetChangeNodeFromView(expectedTree.currentView)\n\t\t\t\t);\n\t\t\t});\n\n\t\t\tit('writes 0.0.2 files without history', async () => {\n\t\t\t\tconst tree = await setUp002SummaryTestTree(false);\n\t\t\t\tconst summary: RecursiveMutable<SharedTreeSummary_0_0_2> = JSON.parse(tree.saveSerializedSummary());\n\t\t\t\tconst expectedSummary: SharedTreeSummary_0_0_2 = JSON.parse(summaryFileNoHistory_0_0_2);\n\t\t\t\t// The edit ID of the single \"no history edit\" is generated randomly. Replace it with the baseline edit for the sake of this test.\n\t\t\t\tsummary.sequencedEdits[0].id = expectedSummary.sequencedEdits[0].id;\n\t\t\t\texpect(summary).to.deep.equal(expectedSummary);\n\t\t\t});\n\n\t\t\tit('writes 0.0.2 files with history', async () => {\n\t\t\t\tconst tree = await setUp002SummaryTestTree(true);\n\t\t\t\texpect(JSON.parse(tree.saveSerializedSummary())).to.deep.equal(\n\t\t\t\t\tJSON.parse(summaryFileWithHistory_0_0_2)\n\t\t\t\t);\n\t\t\t});\n\n\t\t\tdescribe('reading the same version', () => {\n\t\t\t\tit('reads 0.0.2 files without history', async () => {\n\t\t\t\t\tconst { tree } = await setUp002Tree({});\n\t\t\t\t\ttree.loadSerializedSummary(summaryFileNoHistory_0_0_2);\n\t\t\t\t\t// Tree should have exactly one edit, as all \"no history\" summaries do.\n\t\t\t\t\texpect(tree.edits.length).to.equal(1);\n\t\t\t\t\t// Load a baseline tree's own summary with no history to compare with\n\t\t\t\t\tconst summaryNoHistory = (await setUp002SummaryTestTree(false)).saveSummary();\n\t\t\t\t\tconst { tree: expectedTree } = await setUp002Tree({ summarizeHistory: false });\n\t\t\t\t\texpectedTree.loadSummary(summaryNoHistory);\n\t\t\t\t\tawait expectSharedTreesEqual(tree, expectedTree, false);\n\t\t\t\t});\n\n\t\t\t\tit('reads 0.0.2 files with history', async () => {\n\t\t\t\t\tconst { tree } = await setUp002Tree({});\n\t\t\t\t\ttree.loadSerializedSummary(summaryFileWithHistory_0_0_2);\n\t\t\t\t\tconst expectedTree = await setUp002SummaryTestTree(true);\n\t\t\t\t\tawait expectSharedTreesEqual(tree, expectedTree);\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tdescribe('reading next version', () => {\n\t\t\t\tit('reads 0.1.1', async () => {\n\t\t\t\t\tconst { tree } = await setUp002Tree({});\n\t\t\t\t\ttree.loadSerializedSummary(summaryFileWithHistory_0_1_1);\n\t\t\t\t\t// TODO: There may need to be a testObjectProvider synchronization here to upload\n\t\t\t\t\t// blobs from this summary.\n\t\t\t\t\t// We should also look at how this test asserts behavior w.r.t blobs.\n\t\t\t\t\tconst newSummary = JSON.parse(tree.saveSerializedSummary());\n\t\t\t\t\tconst expectedSummary = JSON.parse(summaryFileWithHistory_0_1_1);\n\t\t\t\t\texpect(newSummary).to.deep.equal(expectedSummary);\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tit('gives correct SummaryStatistics', async () => {\n\t\t\t\tconst { tree } = await setUp002Tree({});\n\t\t\t\ttree.loadSerializedSummary(summaryFileWithHistory_0_0_2);\n\t\t\t\tconst editCount = tree.edits.length;\n\t\t\t\tconst summary = deserialize(summaryFileWithHistory_0_0_2, testSerializer);\n\t\t\t\tconst telemetryInfo = getSummaryStatistics(summary);\n\t\t\t\tconst expectedTelemetryInfo: SummaryStatistics = {\n\t\t\t\t\tformatVersion: WriteFormat.v0_0_2,\n\t\t\t\t\thistorySize: editCount,\n\t\t\t\t};\n\t\t\t\texpect(telemetryInfo).to.deep.equals(expectedTelemetryInfo);\n\t\t\t});\n\t\t});\n\n\t\tdescribe('0.1.1 write format', () => {\n\t\t\tconst setUp011Tree: typeof setUpLocalServerTestSharedTree = async (options) =>\n\t\t\t\tsetUpLocalServerTestSharedTree({ writeFormat: WriteFormat.v0_1_1, ...options });\n\n\t\t\tconst setUp011SummaryTestTree = async (summarizeHistory: boolean): Promise<SharedTree> =>\n\t\t\t\tcreateSummaryTestTree(WriteFormat.v0_1_1, summarizeHistory);\n\n\t\t\tit('writes 0.1.1 files without history', async () => {\n\t\t\t\tconst tree = await setUp011SummaryTestTree(false);\n\t\t\t\tconst summary: RecursiveMutable<SharedTreeSummary> = JSON.parse(tree.saveSerializedSummary());\n\t\t\t\tconst expectedSummary: SharedTreeSummary = JSON.parse(summaryFileNoHistory_0_1_1);\n\t\t\t\t// The edit ID of the single \"no history edit\" is generated randomly. Replace it with the baseline edit for the sake of this test.\n\t\t\t\texpectDefined(summary.editHistory).editIds[0] = expectDefined(expectedSummary.editHistory?.editIds[0]);\n\t\t\t\texpect(summary).to.deep.equal(expectedSummary);\n\t\t\t\texpect(await getUploadedEditChunkContents(tree)).to.deep.equal([]);\n\t\t\t});\n\n\t\t\tit('writes 0.1.1 files with history', async () => {\n\t\t\t\tconst tree = await setUp011SummaryTestTree(true);\n\t\t\t\texpect(JSON.parse(tree.saveSerializedSummary())).to.deep.equal(\n\t\t\t\t\tJSON.parse(summaryFileWithHistory_0_1_1)\n\t\t\t\t);\n\t\t\t\texpect(await getUploadedEditChunkContents(tree)).to.deep.equal(blobsParsed);\n\t\t\t});\n\n\t\t\tdescribe('reading the same version', () => {\n\t\t\t\tit('reads 0.1.1 files without history', async () => {\n\t\t\t\t\tconst { tree } = await setUp011Tree({ blobs });\n\t\t\t\t\ttree.loadSerializedSummary(summaryFileNoHistory_0_1_1);\n\t\t\t\t\t// Tree should have exactly one edit, as all \"no history\" summaries do.\n\t\t\t\t\texpect(tree.edits.length).to.equal(1);\n\t\t\t\t\t// Load a baseline tree's own summary with no history to compare with\n\t\t\t\t\tconst summaryNoHistory = (await setUp011SummaryTestTree(false)).saveSummary();\n\t\t\t\t\tconst { tree: expectedTree } = await setUp011Tree({ summarizeHistory: false });\n\t\t\t\t\texpectedTree.loadSummary(summaryNoHistory);\n\t\t\t\t\tawait expectSharedTreesEqual(tree, expectedTree, false);\n\t\t\t\t});\n\n\t\t\t\tit('reads 0.1.1 files with history', async () => {\n\t\t\t\t\tconst { tree } = await setUp011Tree({ blobs });\n\t\t\t\t\ttree.loadSerializedSummary(summaryFileWithHistory_0_1_1);\n\t\t\t\t\tconst expectedTree = await setUp011SummaryTestTree(false);\n\t\t\t\t\tawait expectSharedTreesEqual(tree, expectedTree);\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tdescribe('reading previous versions', () => {\n\t\t\t\tit('reads 0.0.2', async () => {\n\t\t\t\t\tconst expectedTree = await setUp011SummaryTestTree(true);\n\t\t\t\t\tconst { tree } = await setUp011Tree({});\n\t\t\t\t\ttree.loadSerializedSummary(summaryFileWithHistory_0_0_2);\n\t\t\t\t\tawait expectSharedTreesEqual(tree, expectedTree);\n\t\t\t\t\texpect(JSON.parse(tree.saveSerializedSummary())).to.deep.equal(\n\t\t\t\t\t\tJSON.parse(summaryFileWithHistory_0_0_2)\n\t\t\t\t\t);\n\t\t\t\t});\n\n\t\t\t\tit('upgrades 0.0.2', async () => {\n\t\t\t\t\tconst { tree, testObjectProvider } = await setUp011Tree({});\n\t\t\t\t\ttree.loadSerializedSummary(summaryFileWithHistory_0_0_2);\n\t\t\t\t\t// Synchronize to give a chance for the update op to be sequenced.\n\t\t\t\t\tawait testObjectProvider.ensureSynchronized();\n\t\t\t\t\tconst expectedTree = await setUp011SummaryTestTree(true);\n\t\t\t\t\tawait expectSharedTreesEqual(tree, expectedTree);\n\t\t\t\t\texpect(JSON.parse(tree.saveSerializedSummary())).to.deep.equal(\n\t\t\t\t\t\tJSON.parse(summaryFileUpgrade_0_1_1)\n\t\t\t\t\t);\n\t\t\t\t});\n\n\t\t\t\tit('upgrades 0.0.2 that has several stale ops that it resubmits', async () => {\n\t\t\t\t\tconst { tree: resubmitTree, testObjectProvider } = await setUpLocalServerTestSharedTree({\n\t\t\t\t\t\twriteFormat: WriteFormat.v0_0_2,\n\t\t\t\t\t});\n\t\t\t\t\tapplyTestEdits(resubmitTree);\n\t\t\t\t\tconst { tree: tree } = await setUpLocalServerTestSharedTree({\n\t\t\t\t\t\twriteFormat: WriteFormat.v0_1_1,\n\t\t\t\t\t\ttestObjectProvider,\n\t\t\t\t\t});\n\t\t\t\t\tawait testObjectProvider.ensureSynchronized();\n\t\t\t\t\tawait expectSharedTreesEqual(resubmitTree, tree);\n\t\t\t\t\tawait expectSharedTreesEqual(tree, await createSummaryTestTree(WriteFormat.v0_1_1, true));\n\t\t\t\t});\n\n\t\t\t\tit('Normalizes a denormalized summary containing nodes with empty traits', async () => {\n\t\t\t\t\tconst { tree } = await setUp011Tree({});\n\t\t\t\t\ttree.loadSerializedSummary(summaryFileEmptyTraits_0_0_2);\n\n\t\t\t\t\tconst { tree: expectedTree } = await setUp011Tree({});\n\t\t\t\t\texpectedTree.loadSerializedSummary(summaryFileWithHistory_0_0_2);\n\t\t\t\t\texpect(\n\t\t\t\t\t\tareRevisionViewsSemanticallyEqual(\n\t\t\t\t\t\t\ttree.currentView,\n\t\t\t\t\t\t\ttree,\n\t\t\t\t\t\t\texpectedTree.currentView,\n\t\t\t\t\t\t\texpectedTree\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tit('gives correct SummaryStatistics', async () => {\n\t\t\t\tconst { tree } = await setUp011Tree({});\n\t\t\t\ttree.loadSerializedSummary(summaryFileWithHistory_0_1_1);\n\t\t\t\tconst editCount = tree.edits.length;\n\t\t\t\tconst summary = deserialize(summaryFileWithHistory_0_1_1, testSerializer);\n\t\t\t\tconst telemetryInfo = getSummaryStatistics(summary);\n\t\t\t\tconst totalChunks = Math.ceil(editCount / editsPerChunk);\n\t\t\t\tconst expectedTelemetryInfo: SummaryStatistics = {\n\t\t\t\t\tformatVersion: WriteFormat.v0_1_1,\n\t\t\t\t\thistorySize: editCount,\n\t\t\t\t\ttotalNumberOfChunks: totalChunks,\n\t\t\t\t\tuploadedChunks:\n\t\t\t\t\t\t// If the last chunk is bigger than the number of edits per chunk, it has also been uploaded\n\t\t\t\t\t\teditCount - Math.floor(editCount / editsPerChunk) * editsPerChunk < editsPerChunk &&\n\t\t\t\t\t\ttotalChunks !== 0\n\t\t\t\t\t\t\t? totalChunks - 1\n\t\t\t\t\t\t\t: totalChunks,\n\t\t\t\t};\n\t\t\t\texpect(telemetryInfo).to.deep.equals(expectedTelemetryInfo);\n\t\t\t});\n\t\t});\n\t});\n}\n\nasync function expectSharedTreesEqual(\n\tsharedTreeA: SharedTree,\n\tsharedTreeB: SharedTree,\n\tcompareEditIds = true\n): Promise<void> {\n\tif (\n\t\t!areRevisionViewsSemanticallyEqual(sharedTreeA.currentView, sharedTreeA, sharedTreeB.currentView, sharedTreeB)\n\t) {\n\t\texpect.fail('trees have different current views');\n\t}\n\n\tif (sharedTreeA.edits.length !== sharedTreeB.edits.length) {\n\t\texpect.fail('trees have different amounts of edits');\n\t}\n\n\tfor (let i = 0; i < sharedTreeA.edits.length; i++) {\n\t\tconst roundTrip = <T>(obj: T): T => JSON.parse(JSON.stringify(obj)) as T;\n\n\t\tconst editA = roundTrip(\n\t\t\tconvertEditIds(await getEditLogInternal(sharedTreeA).getEditAtIndex(i), (id) =>\n\t\t\t\tsharedTreeA.convertToStableNodeId(id)\n\t\t\t)\n\t\t);\n\t\tconst editB = roundTrip(\n\t\t\tconvertEditIds(await getEditLogInternal(sharedTreeB).getEditAtIndex(i), (id) =>\n\t\t\t\tsharedTreeB.convertToStableNodeId(id)\n\t\t\t)\n\t\t);\n\t\tif (compareEditIds) {\n\t\t\texpect(editA).to.deep.equal(editB, `trees have different edits (index ${i})`);\n\t\t} else {\n\t\t\texpect(editA.changes).to.deep.equal(editB.changes, `edits have different changes (index ${i})`);\n\t\t}\n\t}\n}\n\nfunction loadSummaryTestFiles(): {\n\tsummaryFileWithHistory_0_0_2: string;\n\tsummaryFileNoHistory_0_0_2: string;\n\tsummaryFileEmptyTraits_0_0_2: string;\n\tsummaryFileWithHistory_0_1_1: string;\n\tsummaryFileNoHistory_0_1_1: string;\n\tsummaryFileUpgrade_0_1_1: string;\n\tblobsFile: string;\n} {\n\tconst summaryFileWithHistory_0_0_2 = fs.readFileSync(join(directory, 'summary-0-0-2.json'), 'utf8');\n\tconst summaryFileNoHistory_0_0_2 = fs.readFileSync(join(directory, 'summary-no-history-0-0-2.json'), 'utf8');\n\tconst summaryFileEmptyTraits_0_0_2 = fs.readFileSync(join(directory, 'summary-empty-traits-0-0-2.json'), 'utf8');\n\tconst summaryFileWithHistory_0_1_1 = fs.readFileSync(join(directory, 'summary-0-1-1.json'), 'utf8');\n\tconst summaryFileNoHistory_0_1_1 = fs.readFileSync(join(directory, 'summary-no-history-0-1-1.json'), 'utf8');\n\tconst summaryFileUpgrade_0_1_1 = fs.readFileSync(join(directory, 'summary-upgrade-0-1-1.json'), 'utf8');\n\tconst blobsFile = fs.readFileSync(join(directory, 'blobs-0-1-1.json'), 'utf8');\n\n\treturn {\n\t\tsummaryFileWithHistory_0_0_2,\n\t\tsummaryFileNoHistory_0_0_2,\n\t\tsummaryFileEmptyTraits_0_0_2,\n\t\tsummaryFileWithHistory_0_1_1,\n\t\tsummaryFileNoHistory_0_1_1,\n\t\tsummaryFileUpgrade_0_1_1,\n\t\tblobsFile,\n\t};\n}\n\nasync function makeSummaryTestFiles(): Promise<void> {\n\ttry {\n\t\tfs.accessSync(directory);\n\t} catch {\n\t\tfs.mkdirSync(directory);\n\t}\n\n\tconst treeWithHistory_0_0_2 = await createSummaryTestTree(WriteFormat.v0_0_2, true);\n\tconst treeNoHistory_0_0_2 = await createSummaryTestTree(WriteFormat.v0_0_2, false);\n\tconst treeWithHistory_0_1_1 = await createSummaryTestTree(WriteFormat.v0_1_1, true);\n\tconst treeNoHistory_0_1_1 = await createSummaryTestTree(WriteFormat.v0_1_1, false);\n\n\tfs.writeFileSync(join(directory, `summary-0-0-2.json`), treeWithHistory_0_0_2.saveSerializedSummary());\n\tfs.writeFileSync(join(directory, `summary-no-history-0-0-2.json`), treeNoHistory_0_0_2.saveSerializedSummary());\n\tfs.writeFileSync(join(directory, `summary-0-1-1.json`), treeWithHistory_0_1_1.saveSerializedSummary());\n\tfs.writeFileSync(join(directory, `summary-no-history-0-1-1.json`), treeNoHistory_0_1_1.saveSerializedSummary());\n\n\tconst blobs = await getUploadedEditChunkContents(treeWithHistory_0_1_1);\n\tassert(blobs.length > 0);\n\tfs.writeFileSync(join(directory, `blobs-0-1-1.json`), JSON.stringify(blobs));\n\n\tconst { tree: upgradedTree, testObjectProvider } = await setUpLocalServerTestSharedTree({\n\t\twriteFormat: WriteFormat.v0_1_1,\n\t\tsummarizeHistory: true,\n\t});\n\tupgradedTree.loadSummary(treeWithHistory_0_0_2.saveSummary());\n\tawait testObjectProvider.ensureSynchronized();\n\tfs.writeFileSync(join(directory, `summary-upgrade-0-1-1.json`), upgradedTree.saveSerializedSummary());\n}\n\n/** Every instance of this class generates the same sequence of v5 UUIDs */\nclass DeterministicIdGenerator {\n\tpublic static readonly sessionId = '968bee41-bcf7-46d2-8035-6eb163b76c4c' as SessionId;\n\tprivate static readonly uuidNamespace = '44864298-500e-4cf8-9f44-a249e5b3a286';\n\tprivate editIdCount = 0;\n\tprivate readonly constantIdCompressor?: IdCompressor;\n\n\tpublic constructor(public readonly writeFormat: WriteFormat, private readonly sharedTree: SharedTree) {\n\t\tif (this.writeFormat === WriteFormat.v0_1_1) {\n\t\t\tassert(getIdNormalizerFromSharedTree(sharedTree).localSessionId === DeterministicIdGenerator.sessionId);\n\t\t} else {\n\t\t\tassert(getIdNormalizerFromSharedTree(sharedTree).localSessionId !== DeterministicIdGenerator.sessionId);\n\t\t\tthis.constantIdCompressor = new IdCompressor(DeterministicIdGenerator.sessionId, reservedIdCount);\n\t\t}\n\t}\n\n\tpublic getNextEditId(): EditId {\n\t\treturn v5((this.editIdCount++).toString(), DeterministicIdGenerator.uuidNamespace) as EditId;\n\t}\n\n\tpublic getNextNodeId(): NodeId {\n\t\treturn this.writeFormat === WriteFormat.v0_0_2\n\t\t\t? this.sharedTree.generateNodeId(this.getNextStableId())\n\t\t\t: this.sharedTree.generateNodeId();\n\t}\n\n\tprivate getNextStableId(): StableId {\n\t\tassert(this.constantIdCompressor !== undefined);\n\t\treturn this.constantIdCompressor.decompress(this.constantIdCompressor.generateCompressedId()) as StableId;\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SharedTreeTests.d.ts","sourceRoot":"","sources":["../../../src/test/utilities/SharedTreeTests.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAuBH,OAAO,EAeN,WAAW,EACX,MAAM,uBAAuB,CAAC;AAa/B,OAAO,EAGN,2BAA2B,EAC3B,wBAAwB,EAcxB,MAAM,iBAAiB,CAAC;AAazB;;;GAGG;AACH,wBAAgB,4BAA4B,CAC3C,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,WAAW,EACxB,qCAAqC,EAAE,CAAC,OAAO,CAAC,EAAE,wBAAwB,KAAK,2BAA2B,
|
|
1
|
+
{"version":3,"file":"SharedTreeTests.d.ts","sourceRoot":"","sources":["../../../src/test/utilities/SharedTreeTests.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAuBH,OAAO,EAeN,WAAW,EACX,MAAM,uBAAuB,CAAC;AAa/B,OAAO,EAGN,2BAA2B,EAC3B,wBAAwB,EAcxB,MAAM,iBAAiB,CAAC;AAazB;;;GAGG;AACH,wBAAgB,4BAA4B,CAC3C,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,WAAW,EACxB,qCAAqC,EAAE,CAAC,OAAO,CAAC,EAAE,wBAAwB,KAAK,2BAA2B,QA0/C1G"}
|
|
@@ -246,6 +246,32 @@ export function runSharedTreeOperationsTests(title, writeFormat, setUpTestShared
|
|
|
246
246
|
localMode: false,
|
|
247
247
|
};
|
|
248
248
|
}
|
|
249
|
+
if (writeFormat === WriteFormat.v0_0_2) {
|
|
250
|
+
it('applies unversioned ops in the 0.0.2 format', () => {
|
|
251
|
+
var _a, _b, _c;
|
|
252
|
+
const { tree: sharedTree1, containerRuntimeFactory } = setUpTestSharedTree(tree1Options);
|
|
253
|
+
const { sharedTree: sharedTree2, testTree: testTree2 } = createSimpleTestTree(createSecondTreeOptions(containerRuntimeFactory));
|
|
254
|
+
containerRuntimeFactory.processAllMessages();
|
|
255
|
+
const originalPushMessage = containerRuntimeFactory.pushMessage.bind(containerRuntimeFactory);
|
|
256
|
+
containerRuntimeFactory.pushMessage = (msg) => {
|
|
257
|
+
// Drop the version property to replicate ops created before the version property existed
|
|
258
|
+
msg.contents.version = undefined;
|
|
259
|
+
originalPushMessage(msg);
|
|
260
|
+
};
|
|
261
|
+
// Ensure that an edit can be passed and processed between two trees as normal
|
|
262
|
+
sharedTree2.applyEdit(Change.delete(StableRange.only(testTree2.right)));
|
|
263
|
+
const getTestTreeRoot = (sharedTree) => new TreeNodeHandle(sharedTree.currentView, sharedTree.convertToNodeId(sharedTree2.convertToStableNodeId(testTree2.identifier)));
|
|
264
|
+
let root1 = getTestTreeRoot(sharedTree1);
|
|
265
|
+
let root2 = getTestTreeRoot(sharedTree2);
|
|
266
|
+
expect(Array.from(root1.traits[testTree2.right.traitLabel])).to.have.length(1);
|
|
267
|
+
expect(Array.from((_a = root2.traits[testTree2.right.traitLabel]) !== null && _a !== void 0 ? _a : [])).to.have.length(0);
|
|
268
|
+
containerRuntimeFactory.processAllMessages();
|
|
269
|
+
root1 = getTestTreeRoot(sharedTree1);
|
|
270
|
+
root2 = getTestTreeRoot(sharedTree2);
|
|
271
|
+
expect(Array.from((_b = root1.traits[testTree2.right.traitLabel]) !== null && _b !== void 0 ? _b : [])).to.have.length(0);
|
|
272
|
+
expect(Array.from((_c = root2.traits[testTree2.right.traitLabel]) !== null && _c !== void 0 ? _c : [])).to.have.length(0);
|
|
273
|
+
});
|
|
274
|
+
}
|
|
249
275
|
it('should apply remote changes and converge', () => {
|
|
250
276
|
const { tree: sharedTree1, containerRuntimeFactory } = setUpTestSharedTree(tree1Options);
|
|
251
277
|
const { tree: sharedTree2 } = setUpTestSharedTree(createSecondTreeOptions(containerRuntimeFactory));
|
|
@@ -515,13 +541,9 @@ export function runSharedTreeOperationsTests(title, writeFormat, setUpTestShared
|
|
|
515
541
|
}
|
|
516
542
|
const serialized = serialize(sharedTree.saveSummary(), testSerializer, testHandle);
|
|
517
543
|
const treeContent = JSON.parse(serialized);
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
}
|
|
522
|
-
else {
|
|
523
|
-
parsedTree = new SharedTreeEncoder_0_0_2(true).decodeSummary(treeContent);
|
|
524
|
-
}
|
|
544
|
+
const parsedTree = writeFormat === WriteFormat.v0_1_1
|
|
545
|
+
? new SharedTreeEncoder_0_1_1(true).decodeSummary(treeContent, sharedTree.attributionId)
|
|
546
|
+
: new SharedTreeEncoder_0_0_2(true).decodeSummary(treeContent);
|
|
525
547
|
expect(parsedTree.currentTree).to.not.be.undefined;
|
|
526
548
|
const testRoot = assertArrayOfOne(assertNotUndefined((_a = parsedTree.currentTree) === null || _a === void 0 ? void 0 : _a.traits[testTree.traitLabel]));
|
|
527
549
|
expect(testRoot).to.not.be.undefined;
|
|
@@ -685,7 +707,7 @@ export function runSharedTreeOperationsTests(title, writeFormat, setUpTestShared
|
|
|
685
707
|
it('is logged for invalid locally generated edits when those edits are sequenced', async () => {
|
|
686
708
|
const events = [];
|
|
687
709
|
const { sharedTree, testTree, containerRuntimeFactory } = createSimpleTestTree({
|
|
688
|
-
logger: { send: (event) => events.push(event) },
|
|
710
|
+
logger: { send: (event) => !event.eventName.includes('IdCompressor') && events.push(event) },
|
|
689
711
|
allowInvalid: true,
|
|
690
712
|
});
|
|
691
713
|
useFailedSequencedEditTelemetry(sharedTree);
|
|
@@ -702,7 +724,7 @@ export function runSharedTreeOperationsTests(title, writeFormat, setUpTestShared
|
|
|
702
724
|
it('can be disabled and re-enabled', async () => {
|
|
703
725
|
const events = [];
|
|
704
726
|
const { sharedTree, testTree, containerRuntimeFactory } = createSimpleTestTree({
|
|
705
|
-
logger: { send: (event) => events.push(event) },
|
|
727
|
+
logger: { send: (event) => !event.eventName.includes('IdCompressor') && events.push(event) },
|
|
706
728
|
allowInvalid: true,
|
|
707
729
|
});
|
|
708
730
|
const { disable } = useFailedSequencedEditTelemetry(sharedTree);
|
|
@@ -727,7 +749,7 @@ export function runSharedTreeOperationsTests(title, writeFormat, setUpTestShared
|
|
|
727
749
|
it('is not logged for valid edits', async () => {
|
|
728
750
|
const events = [];
|
|
729
751
|
const { sharedTree, testTree, containerRuntimeFactory } = createSimpleTestTree({
|
|
730
|
-
logger: { send: (event) => events.push(event) },
|
|
752
|
+
logger: { send: (event) => !event.eventName.includes('IdCompressor') && events.push(event) },
|
|
731
753
|
});
|
|
732
754
|
useFailedSequencedEditTelemetry(sharedTree);
|
|
733
755
|
sharedTree.applyEdit(...Change.insertTree(testTree.buildLeaf(), StablePlace.after(testTree.left)));
|
|
@@ -738,7 +760,7 @@ export function runSharedTreeOperationsTests(title, writeFormat, setUpTestShared
|
|
|
738
760
|
it('is not logged for remote edits', async () => {
|
|
739
761
|
const events = [];
|
|
740
762
|
const { sharedTree: sharedTree1, containerRuntimeFactory } = createSimpleTestTree({
|
|
741
|
-
logger: { send: (event) => events.push(event) },
|
|
763
|
+
logger: { send: (event) => !event.eventName.includes('IdCompressor') && events.push(event) },
|
|
742
764
|
allowInvalid: true,
|
|
743
765
|
localMode: false,
|
|
744
766
|
});
|