@fluid-experimental/tree 0.58.3000-61081 → 0.59.2000-61729
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/README.md +156 -43
- package/dist/ChangeTypes.d.ts +9 -14
- package/dist/ChangeTypes.d.ts.map +1 -1
- package/dist/ChangeTypes.js.map +1 -1
- package/dist/Checkout.d.ts.map +1 -1
- package/dist/Checkout.js +3 -2
- package/dist/Checkout.js.map +1 -1
- package/dist/LogViewer.d.ts +2 -3
- package/dist/LogViewer.d.ts.map +1 -1
- package/dist/LogViewer.js +5 -4
- package/dist/LogViewer.js.map +1 -1
- package/dist/NodeIdUtilities.d.ts +26 -11
- package/dist/NodeIdUtilities.d.ts.map +1 -1
- package/dist/NodeIdUtilities.js.map +1 -1
- package/dist/SharedTree.d.ts +61 -22
- package/dist/SharedTree.d.ts.map +1 -1
- package/dist/SharedTree.js +75 -30
- package/dist/SharedTree.js.map +1 -1
- package/dist/Transaction.d.ts +22 -4
- package/dist/Transaction.d.ts.map +1 -1
- package/dist/Transaction.js +27 -11
- package/dist/Transaction.js.map +1 -1
- package/dist/TransactionInternal.d.ts +3 -6
- package/dist/TransactionInternal.d.ts.map +1 -1
- package/dist/TransactionInternal.js +8 -4
- package/dist/TransactionInternal.js.map +1 -1
- package/dist/TreeCompressor.d.ts +0 -1
- package/dist/TreeCompressor.d.ts.map +1 -1
- package/dist/TreeCompressor.js +31 -26
- package/dist/TreeCompressor.js.map +1 -1
- package/dist/TreeView.d.ts.map +1 -1
- package/dist/TreeView.js +3 -2
- package/dist/TreeView.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/docs/Write-Format.md +19 -0
- package/lib/ChangeTypes.d.ts +9 -14
- package/lib/ChangeTypes.d.ts.map +1 -1
- package/lib/ChangeTypes.js.map +1 -1
- package/lib/Checkout.d.ts.map +1 -1
- package/lib/Checkout.js +3 -2
- package/lib/Checkout.js.map +1 -1
- package/lib/LogViewer.d.ts +2 -3
- package/lib/LogViewer.d.ts.map +1 -1
- package/lib/LogViewer.js +5 -4
- package/lib/LogViewer.js.map +1 -1
- package/lib/NodeIdUtilities.d.ts +26 -11
- package/lib/NodeIdUtilities.d.ts.map +1 -1
- package/lib/NodeIdUtilities.js.map +1 -1
- package/lib/SharedTree.d.ts +61 -22
- package/lib/SharedTree.d.ts.map +1 -1
- package/lib/SharedTree.js +75 -30
- package/lib/SharedTree.js.map +1 -1
- package/lib/Transaction.d.ts +22 -4
- package/lib/Transaction.d.ts.map +1 -1
- package/lib/Transaction.js +26 -10
- package/lib/Transaction.js.map +1 -1
- package/lib/TransactionInternal.d.ts +3 -6
- package/lib/TransactionInternal.d.ts.map +1 -1
- package/lib/TransactionInternal.js +8 -4
- package/lib/TransactionInternal.js.map +1 -1
- package/lib/TreeCompressor.d.ts +0 -1
- package/lib/TreeCompressor.d.ts.map +1 -1
- package/lib/TreeCompressor.js +31 -26
- package/lib/TreeCompressor.js.map +1 -1
- package/lib/TreeView.d.ts.map +1 -1
- package/lib/TreeView.js +3 -2
- package/lib/TreeView.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/test/LogViewer.tests.js +13 -10
- package/lib/test/LogViewer.tests.js.map +1 -1
- package/lib/test/Transaction.tests.js +36 -2
- package/lib/test/Transaction.tests.js.map +1 -1
- package/lib/test/TreeView.tests.js +29 -0
- package/lib/test/TreeView.tests.js.map +1 -1
- package/lib/test/Virtualization.tests.js +1 -2
- package/lib/test/Virtualization.tests.js.map +1 -1
- package/lib/test/fuzz/SharedTreeFuzzTests.d.ts.map +1 -1
- package/lib/test/fuzz/SharedTreeFuzzTests.js +19 -2
- package/lib/test/fuzz/SharedTreeFuzzTests.js.map +1 -1
- package/lib/test/utilities/SharedTreeVersioningTests.d.ts.map +1 -1
- package/lib/test/utilities/SharedTreeVersioningTests.js +26 -1
- package/lib/test/utilities/SharedTreeVersioningTests.js.map +1 -1
- package/package.json +18 -18
- package/src/ChangeTypes.ts +9 -14
- package/src/Checkout.ts +3 -3
- package/src/LogViewer.ts +4 -4
- package/src/NodeIdUtilities.ts +26 -11
- package/src/SharedTree.ts +81 -28
- package/src/Transaction.ts +39 -13
- package/src/TransactionInternal.ts +9 -10
- package/src/TreeCompressor.ts +31 -40
- package/src/TreeView.ts +3 -2
- package/src/index.ts +0 -1
- package/docs/Future.md +0 -155
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Transaction.tests.js","sourceRoot":"","sources":["../../src/test/Transaction.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 { EditStatus, WriteFormat } from '../persisted-types';\nimport { Change, StablePlace, StableRange } from '../ChangeTypes';\nimport { Transaction } from '../Transaction';\nimport { SharedTree } from '../SharedTree';\nimport { TestTree } from './utilities/TestNode';\nimport { setUpTestSharedTree, setUpTestTree } from './utilities/TestUtilities';\n\ndescribe('Transaction', () => {\n\tfunction createTestTransaction(): { tree: SharedTree; testTree: TestTree; transaction: Transaction } {\n\t\tconst { tree } = setUpTestSharedTree({ writeFormat: WriteFormat.v0_1_1 });\n\t\tconst testTree = setUpTestTree(tree);\n\t\treturn { tree, testTree, transaction: new Transaction(tree) };\n\t}\n\n\tfunction createValidChange(testTree: TestTree): Change {\n\t\treturn Change.delete(StableRange.only(testTree.left));\n\t}\n\n\tfunction createInvalidChange(testTree: TestTree): Change {\n\t\treturn Change.delete(StableRange.only(testTree.generateNodeId()));\n\t}\n\n\tfunction createMalformedChange(testTree: TestTree): Change {\n\t\treturn Change.insert(Number.NaN, StablePlace.after(testTree.left));\n\t}\n\n\tit('can apply an edit to the tree', () => {\n\t\tconst { tree, testTree, transaction } = createTestTransaction();\n\t\tconst editCountBefore = tree.edits.length;\n\t\ttransaction.apply(createValidChange(testTree));\n\t\ttransaction.closeAndCommit();\n\t\texpect(tree.edits.length).to.equal(editCountBefore + 1);\n\t\texpect(tree.currentView.getTrait(testTree.left.traitLocation).length).to.equal(0);\n\t});\n\n\tit('has correct edit status when applied', () => {\n\t\tconst { testTree, transaction } = createTestTransaction();\n\t\texpect(transaction.apply(createValidChange(testTree))).to.equal(EditStatus.Applied);\n\t\texpect(transaction.status).to.equal(EditStatus.Applied);\n\t\ttransaction.closeAndCommit();\n\t});\n\n\tit('has correct edit status when invalid', () => {\n\t\tconst { testTree, transaction } = createTestTransaction();\n\t\texpect(transaction.apply(createInvalidChange(testTree))).to.equal(EditStatus.Invalid);\n\t\texpect(transaction.status).to.equal(EditStatus.Invalid);\n\t\ttransaction.closeAndCommit();\n\t});\n\n\tit('has correct edit status when malformed', () => {\n\t\tconst { testTree, transaction } = createTestTransaction();\n\t\texpect(transaction.apply(createMalformedChange(testTree))).to.equal(EditStatus.Malformed);\n\t\texpect(transaction.status).to.equal(EditStatus.Malformed);\n\t\ttransaction.closeAndCommit();\n\t});\n\n\tit('can apply multiple changes at once', () => {\n\t\tconst { tree, testTree, transaction } = createTestTransaction();\n\t\ttransaction.apply(Change.move(StableRange.only(testTree.left), StablePlace.after(testTree.right)));\n\t\ttransaction.closeAndCommit();\n\t\texpect(tree.currentView.getTrait(testTree.left.traitLocation).length).to.equal(0);\n\t\texpect(tree.currentView.getTrait(testTree.right.traitLocation).length).to.equal(2);\n\t});\n\n\tit('does not apply empty edits', () => {\n\t\tconst { tree, transaction } = createTestTransaction();\n\t\tconst editCountBefore = tree.edits.length;\n\t\ttransaction.apply([]);\n\t\ttransaction.closeAndCommit();\n\t\texpect(tree.edits.length).to.equal(editCountBefore);\n\t});\n\n\tit('does not apply a batch of changes if any of them fail', () => {\n\t\tconst { testTree, transaction } = createTestTransaction();\n\t\tconst change = createValidChange(testTree);\n\t\texpect(transaction.apply(change, change)).to.equal(EditStatus.Invalid); // Second change is invalid\n\t\texpect(transaction.status).to.equal(EditStatus.Invalid);\n\t\ttransaction.closeAndCommit();\n\t});\n\n\tit('is open when created', () => {\n\t\tconst { transaction } = createTestTransaction();\n\t\texpect(transaction.isOpen).to.be.true;\n\t});\n\n\tit('closes when a change fails to apply', () => {\n\t\tconst { testTree, transaction } = createTestTransaction();\n\t\ttransaction.apply(createInvalidChange(testTree));\n\t\texpect(transaction.isOpen).to.be.false;\n\t});\n\n\tit('closes when an edit is applied', () => {\n\t\tconst { testTree, transaction } = createTestTransaction();\n\t\texpect(transaction.isOpen).to.be.true;\n\t\ttransaction.apply(createValidChange(testTree));\n\t\texpect(transaction.isOpen).to.be.true;\n\t\ttransaction.closeAndCommit();\n\t\texpect(transaction.isOpen).to.be.false;\n\t});\n});\n"]}
|
|
1
|
+
{"version":3,"file":"Transaction.tests.js","sourceRoot":"","sources":["../../src/test/Transaction.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 { EditStatus, WriteFormat } from '../persisted-types';\nimport { Change, StablePlace, StableRange } from '../ChangeTypes';\nimport { Transaction, TransactionEvent } from '../Transaction';\nimport { SharedTree } from '../SharedTree';\nimport { TreeView } from '../TreeView';\nimport { TestTree } from './utilities/TestNode';\nimport { setUpTestSharedTree, setUpTestTree } from './utilities/TestUtilities';\nimport { expectDefined } from './utilities/TestCommon';\n\ndescribe('Transaction', () => {\n\tfunction createTestTransaction(): { tree: SharedTree; testTree: TestTree; transaction: Transaction } {\n\t\tconst { tree } = setUpTestSharedTree({ writeFormat: WriteFormat.v0_1_1 });\n\t\tconst testTree = setUpTestTree(tree);\n\t\treturn { tree, testTree, transaction: new Transaction(tree) };\n\t}\n\n\tfunction createValidChange(testTree: TestTree): Change {\n\t\treturn Change.delete(StableRange.only(testTree.left));\n\t}\n\n\tfunction createValidChanges(testTree: TestTree): Change[] {\n\t\treturn Change.move(StableRange.only(testTree.left), StablePlace.after(testTree.right));\n\t}\n\n\tfunction createInvalidChange(testTree: TestTree): Change {\n\t\treturn Change.delete(StableRange.only(testTree.generateNodeId()));\n\t}\n\n\tfunction createMalformedChange(testTree: TestTree): Change {\n\t\treturn Change.insert(Number.NaN, StablePlace.after(testTree.left));\n\t}\n\n\tit('can apply an edit to the tree', () => {\n\t\tconst { tree, testTree, transaction } = createTestTransaction();\n\t\tconst editCountBefore = tree.edits.length;\n\t\ttransaction.apply(createValidChange(testTree));\n\t\ttransaction.closeAndCommit();\n\t\texpect(tree.edits.length).to.equal(editCountBefore + 1);\n\t\texpect(tree.currentView.getTrait(testTree.left.traitLocation).length).to.equal(0);\n\t});\n\n\tit('has correct edit status when applied', () => {\n\t\tconst { testTree, transaction } = createTestTransaction();\n\t\texpect(transaction.apply(createValidChange(testTree))).to.equal(EditStatus.Applied);\n\t\texpect(transaction.status).to.equal(EditStatus.Applied);\n\t\ttransaction.closeAndCommit();\n\t});\n\n\tit('has correct edit status when invalid', () => {\n\t\tconst { testTree, transaction } = createTestTransaction();\n\t\texpect(transaction.apply(createInvalidChange(testTree))).to.equal(EditStatus.Invalid);\n\t\texpect(transaction.status).to.equal(EditStatus.Invalid);\n\t\ttransaction.closeAndCommit();\n\t});\n\n\tit('has correct edit status when malformed', () => {\n\t\tconst { testTree, transaction } = createTestTransaction();\n\t\texpect(transaction.apply(createMalformedChange(testTree))).to.equal(EditStatus.Malformed);\n\t\texpect(transaction.status).to.equal(EditStatus.Malformed);\n\t\ttransaction.closeAndCommit();\n\t});\n\n\tit('can apply multiple changes at once', () => {\n\t\tconst { tree, testTree, transaction } = createTestTransaction();\n\t\ttransaction.apply(createValidChanges(testTree));\n\t\ttransaction.closeAndCommit();\n\t\texpect(tree.currentView.getTrait(testTree.left.traitLocation).length).to.equal(0);\n\t\texpect(tree.currentView.getTrait(testTree.right.traitLocation).length).to.equal(2);\n\t});\n\n\tit('does not apply empty edits', () => {\n\t\tconst { tree, transaction } = createTestTransaction();\n\t\tconst editCountBefore = tree.edits.length;\n\t\ttransaction.apply([]);\n\t\ttransaction.closeAndCommit();\n\t\texpect(tree.edits.length).to.equal(editCountBefore);\n\t});\n\n\tit('does not apply a batch of changes if any of them fail', () => {\n\t\tconst { testTree, transaction } = createTestTransaction();\n\t\tconst change = createValidChange(testTree);\n\t\texpect(transaction.apply(change, change)).to.equal(EditStatus.Invalid); // Second change is invalid\n\t\texpect(transaction.status).to.equal(EditStatus.Invalid);\n\t\ttransaction.closeAndCommit();\n\t});\n\n\tit('is open when created', () => {\n\t\tconst { transaction } = createTestTransaction();\n\t\texpect(transaction.isOpen).to.be.true;\n\t});\n\n\tit('closes when a change fails to apply', () => {\n\t\tconst { testTree, transaction } = createTestTransaction();\n\t\ttransaction.apply(createInvalidChange(testTree));\n\t\texpect(transaction.isOpen).to.be.false;\n\t});\n\n\tit('closes when an edit is applied', () => {\n\t\tconst { testTree, transaction } = createTestTransaction();\n\t\texpect(transaction.isOpen).to.be.true;\n\t\ttransaction.apply(createValidChange(testTree));\n\t\texpect(transaction.isOpen).to.be.true;\n\t\ttransaction.closeAndCommit();\n\t\texpect(transaction.isOpen).to.be.false;\n\t});\n\n\tit('emits view change events', () => {\n\t\tconst { testTree, transaction } = createTestTransaction();\n\t\tlet beforeView: TreeView | undefined;\n\t\tlet afterView: TreeView | undefined;\n\t\ttransaction.addListener(TransactionEvent.ViewChange, (before, after) => {\n\t\t\tbeforeView = before;\n\t\t\tafterView = after;\n\t\t});\n\t\tconst beforeViewExpected = transaction.currentView;\n\t\ttransaction.apply(createValidChange(testTree));\n\t\tconst afterViewExpected = transaction.currentView;\n\t\texpect(expectDefined(beforeView).equals(beforeViewExpected)).to.be.true;\n\t\texpect(expectDefined(afterView).equals(afterViewExpected)).to.be.true;\n\t});\n\n\tit('emits only one view change event per apply', () => {\n\t\tconst { testTree, transaction } = createTestTransaction();\n\t\tlet eventCount = 0;\n\t\ttransaction.addListener(TransactionEvent.ViewChange, () => {\n\t\t\teventCount += 1;\n\t\t});\n\t\ttransaction.apply(createValidChanges(testTree));\n\t\texpect(eventCount).to.equal(1);\n\t});\n\n\tit('does not emit view change events when there are no changes', () => {\n\t\tconst { transaction } = createTestTransaction();\n\t\ttransaction.on(TransactionEvent.ViewChange, () => {\n\t\t\texpect.fail();\n\t\t});\n\t\ttransaction.apply([]);\n\t});\n});\n"]}
|
|
@@ -143,5 +143,34 @@ describe('TreeView', () => {
|
|
|
143
143
|
}
|
|
144
144
|
}
|
|
145
145
|
});
|
|
146
|
+
// Regression test for the issue fixed in #9824
|
|
147
|
+
it('can be iterated in a consistent order', () => {
|
|
148
|
+
const [id1, id2, id3] = Array.from({ length: 3 }).map(() => testTree.generateNodeId());
|
|
149
|
+
const label1 = 'traitLabelA';
|
|
150
|
+
const label2 = 'traitLabelB';
|
|
151
|
+
const { definition } = testTree;
|
|
152
|
+
const tree1 = {
|
|
153
|
+
identifier: id1,
|
|
154
|
+
definition,
|
|
155
|
+
traits: {
|
|
156
|
+
[label1]: [{ identifier: id2, definition, traits: {} }],
|
|
157
|
+
[label2]: [{ identifier: id3, definition, traits: {} }],
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
// Like tree1, but defined with the labels in the opposite order and with different node ids under each trait.
|
|
161
|
+
const tree2 = {
|
|
162
|
+
identifier: id1,
|
|
163
|
+
definition,
|
|
164
|
+
traits: {
|
|
165
|
+
[label2]: [{ identifier: id2, definition, traits: {} }],
|
|
166
|
+
[label1]: [{ identifier: id3, definition, traits: {} }],
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
const view1 = RevisionView.fromTree(tree1);
|
|
170
|
+
const view2 = RevisionView.fromTree(tree2);
|
|
171
|
+
expect(Array.from(view1).map((node) => node.identifier)).to.deep.equal([id1, id2, id3]);
|
|
172
|
+
// Child iteration should be sorted on trait labels.
|
|
173
|
+
expect(Array.from(view2).map((node) => node.identifier)).to.deep.equal([id1, id3, id2]);
|
|
174
|
+
});
|
|
146
175
|
});
|
|
147
176
|
//# sourceMappingURL=TreeView.tests.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TreeView.tests.js","sourceRoot":"","sources":["../../src/test/TreeView.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 { Definition } from '../Identifiers';\nimport { RevisionView } from '../RevisionView';\nimport { ChangeNode } from '../persisted-types';\nimport { refreshTestTree } from './utilities/TestUtilities';\nimport { TestNode } from './utilities/TestNode';\nimport { expectDefined } from './utilities/TestCommon';\n\ndescribe('TreeView', () => {\n\tconst testTree = refreshTestTree();\n\n\tdescribe('can compute deltas', () => {\n\t\tit('that are the same object', () => {\n\t\t\tconst view = testTree.view;\n\t\t\texpect(view.delta(view)).deep.equals({\n\t\t\t\tchanged: [],\n\t\t\t\tadded: [],\n\t\t\t\tremoved: [],\n\t\t\t});\n\t\t});\n\n\t\tit('that have the same tree', () => {\n\t\t\tconst viewA = RevisionView.fromTree<TestNode>(testTree);\n\t\t\tconst viewB = RevisionView.fromTree<TestNode>(testTree);\n\t\t\texpect(viewA.delta(viewB)).deep.equals({\n\t\t\t\tchanged: [],\n\t\t\t\tadded: [],\n\t\t\t\tremoved: [],\n\t\t\t});\n\t\t});\n\n\t\tit('with different root ids', () => {\n\t\t\tconst viewA = RevisionView.fromTree(testTree.buildLeaf(testTree.generateNodeId()));\n\t\t\tconst viewB = RevisionView.fromTree(testTree.buildLeaf(testTree.generateNodeId()));\n\t\t\texpect(() => viewA.delta(viewB)).to.throw('Delta can only be calculated between views that share a root');\n\t\t});\n\n\t\tit('with different subtrees', () => {\n\t\t\tconst rootId = testTree.generateNodeId();\n\n\t\t\tconst leafA = testTree.buildLeaf(testTree.generateNodeId());\n\t\t\tconst leafB = testTree.buildLeaf(testTree.generateNodeId());\n\n\t\t\tconst subtreeA = {\n\t\t\t\tidentifier: testTree.generateNodeId(),\n\t\t\t\tdefinition: 'node' as Definition,\n\t\t\t\ttraits: { children: [leafA] },\n\t\t\t};\n\t\t\tconst subtreeB = {\n\t\t\t\tidentifier: testTree.generateNodeId(),\n\t\t\t\tdefinition: 'node' as Definition,\n\t\t\t\ttraits: { children: [leafB] },\n\t\t\t};\n\n\t\t\tconst rootA: ChangeNode = {\n\t\t\t\tidentifier: rootId,\n\t\t\t\tdefinition: 'node' as Definition,\n\t\t\t\ttraits: {\n\t\t\t\t\tchildren: [subtreeA],\n\t\t\t\t},\n\t\t\t};\n\t\t\tconst rootB: ChangeNode = {\n\t\t\t\tidentifier: rootId,\n\t\t\t\tdefinition: 'node' as Definition,\n\t\t\t\ttraits: {\n\t\t\t\t\tchildren: [subtreeB],\n\t\t\t\t},\n\t\t\t};\n\n\t\t\tconst viewA = RevisionView.fromTree(rootA);\n\t\t\tconst viewB = RevisionView.fromTree(rootB);\n\t\t\tconst delta = viewA.delta(viewB);\n\t\t\texpect(delta.changed).deep.equals([rootId]);\n\t\t\texpect(delta.removed.length).equals(2);\n\t\t\texpect(delta.added.length).equals(2);\n\t\t\texpect(delta.removed).contains(subtreeA.identifier);\n\t\t\texpect(delta.removed).contains(leafA.identifier);\n\t\t\texpect(delta.added).contains(subtreeB.identifier);\n\t\t\texpect(delta.added).contains(leafB.identifier);\n\t\t});\n\n\t\tit('with different payloads', () => {\n\t\t\tconst rootId = testTree.generateNodeId();\n\t\t\tconst nodeA: ChangeNode = {\n\t\t\t\tidentifier: rootId,\n\t\t\t\tdefinition: 'node' as Definition,\n\t\t\t\tpayload: 'test1',\n\t\t\t\ttraits: {},\n\t\t\t};\n\t\t\tconst nodeB: ChangeNode = {\n\t\t\t\tidentifier: rootId,\n\t\t\t\tdefinition: 'node' as Definition,\n\t\t\t\tpayload: 'test2',\n\t\t\t\ttraits: {},\n\t\t\t};\n\n\t\t\tconst viewA = RevisionView.fromTree(nodeA);\n\t\t\tconst viewB = RevisionView.fromTree(nodeB);\n\t\t\tconst delta = viewA.delta(viewB);\n\t\t\texpect(delta.changed).deep.equals([rootId]);\n\t\t\texpect(delta.removed).deep.equals([]);\n\t\t\texpect(delta.added).deep.equals([]);\n\t\t});\n\n\t\tit('after an insert', () => {\n\t\t\tconst viewA = testTree.view;\n\t\t\tconst insertedNode = testTree.buildLeaf(testTree.generateNodeId());\n\t\t\tconst treeB: ChangeNode = {\n\t\t\t\tidentifier: testTree.identifier,\n\t\t\t\tdefinition: testTree.definition,\n\t\t\t\ttraits: { ...testTree.traits, left: [insertedNode, testTree.left] },\n\t\t\t};\n\t\t\tconst viewB = RevisionView.fromTree(treeB);\n\t\t\tconst delta = viewA.delta(viewB);\n\t\t\texpect(delta.changed).deep.equals([testTree.identifier]);\n\t\t\texpect(delta.removed).deep.equals([]);\n\t\t\texpect(delta.added).deep.equals([insertedNode.identifier]);\n\t\t});\n\n\t\tit('after a delete', () => {\n\t\t\tconst viewA = testTree.view;\n\t\t\tconst treeB: ChangeNode = {\n\t\t\t\tidentifier: testTree.identifier,\n\t\t\t\tdefinition: testTree.definition,\n\t\t\t\ttraits: { ...testTree.traits, left: [] },\n\t\t\t};\n\t\t\tconst viewB = RevisionView.fromTree(treeB);\n\t\t\tconst delta = viewA.delta(viewB);\n\t\t\texpect(delta.changed).deep.equals([testTree.identifier]);\n\t\t\texpect(delta.removed).deep.equals([testTree.left.identifier]);\n\t\t\texpect(delta.added).deep.equals([]);\n\t\t});\n\n\t\tit('after a move', () => {\n\t\t\tconst viewA = testTree.view;\n\t\t\tconst treeB: ChangeNode = {\n\t\t\t\tidentifier: testTree.identifier,\n\t\t\t\tdefinition: testTree.definition,\n\t\t\t\ttraits: { ...testTree.traits, left: [], right: [testTree.right, testTree.left] },\n\t\t\t};\n\t\t\tconst viewB = RevisionView.fromTree(treeB);\n\t\t\tconst delta = viewA.delta(viewB);\n\t\t\texpect(delta.changed).deep.equals([testTree.identifier]);\n\t\t\texpect(delta.removed).deep.equals([]);\n\t\t\texpect(delta.added).deep.equals([]);\n\t\t});\n\t});\n\n\tit('correctly returns node parentage', () => {\n\t\tconst view = testTree.view;\n\t\tfor (const node of view) {\n\t\t\tconst parentNode = view.tryGetParentViewNode(node.identifier);\n\t\t\tif (parentNode !== undefined) {\n\t\t\t\tconst parentage = expectDefined(node.parentage);\n\t\t\t\texpect(parentage.label).to.equal(view.getTraitLabel(node.identifier));\n\t\t\t\texpect(parentage.parent).to.equal(parentNode.identifier);\n\t\t\t}\n\t\t}\n\t});\n});\n"]}
|
|
1
|
+
{"version":3,"file":"TreeView.tests.js","sourceRoot":"","sources":["../../src/test/TreeView.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 { Definition, TraitLabel } from '../Identifiers';\nimport { RevisionView } from '../RevisionView';\nimport { ChangeNode } from '../persisted-types';\nimport { refreshTestTree } from './utilities/TestUtilities';\nimport { TestNode } from './utilities/TestNode';\nimport { expectDefined } from './utilities/TestCommon';\n\ndescribe('TreeView', () => {\n\tconst testTree = refreshTestTree();\n\n\tdescribe('can compute deltas', () => {\n\t\tit('that are the same object', () => {\n\t\t\tconst view = testTree.view;\n\t\t\texpect(view.delta(view)).deep.equals({\n\t\t\t\tchanged: [],\n\t\t\t\tadded: [],\n\t\t\t\tremoved: [],\n\t\t\t});\n\t\t});\n\n\t\tit('that have the same tree', () => {\n\t\t\tconst viewA = RevisionView.fromTree<TestNode>(testTree);\n\t\t\tconst viewB = RevisionView.fromTree<TestNode>(testTree);\n\t\t\texpect(viewA.delta(viewB)).deep.equals({\n\t\t\t\tchanged: [],\n\t\t\t\tadded: [],\n\t\t\t\tremoved: [],\n\t\t\t});\n\t\t});\n\n\t\tit('with different root ids', () => {\n\t\t\tconst viewA = RevisionView.fromTree(testTree.buildLeaf(testTree.generateNodeId()));\n\t\t\tconst viewB = RevisionView.fromTree(testTree.buildLeaf(testTree.generateNodeId()));\n\t\t\texpect(() => viewA.delta(viewB)).to.throw('Delta can only be calculated between views that share a root');\n\t\t});\n\n\t\tit('with different subtrees', () => {\n\t\t\tconst rootId = testTree.generateNodeId();\n\n\t\t\tconst leafA = testTree.buildLeaf(testTree.generateNodeId());\n\t\t\tconst leafB = testTree.buildLeaf(testTree.generateNodeId());\n\n\t\t\tconst subtreeA = {\n\t\t\t\tidentifier: testTree.generateNodeId(),\n\t\t\t\tdefinition: 'node' as Definition,\n\t\t\t\ttraits: { children: [leafA] },\n\t\t\t};\n\t\t\tconst subtreeB = {\n\t\t\t\tidentifier: testTree.generateNodeId(),\n\t\t\t\tdefinition: 'node' as Definition,\n\t\t\t\ttraits: { children: [leafB] },\n\t\t\t};\n\n\t\t\tconst rootA: ChangeNode = {\n\t\t\t\tidentifier: rootId,\n\t\t\t\tdefinition: 'node' as Definition,\n\t\t\t\ttraits: {\n\t\t\t\t\tchildren: [subtreeA],\n\t\t\t\t},\n\t\t\t};\n\t\t\tconst rootB: ChangeNode = {\n\t\t\t\tidentifier: rootId,\n\t\t\t\tdefinition: 'node' as Definition,\n\t\t\t\ttraits: {\n\t\t\t\t\tchildren: [subtreeB],\n\t\t\t\t},\n\t\t\t};\n\n\t\t\tconst viewA = RevisionView.fromTree(rootA);\n\t\t\tconst viewB = RevisionView.fromTree(rootB);\n\t\t\tconst delta = viewA.delta(viewB);\n\t\t\texpect(delta.changed).deep.equals([rootId]);\n\t\t\texpect(delta.removed.length).equals(2);\n\t\t\texpect(delta.added.length).equals(2);\n\t\t\texpect(delta.removed).contains(subtreeA.identifier);\n\t\t\texpect(delta.removed).contains(leafA.identifier);\n\t\t\texpect(delta.added).contains(subtreeB.identifier);\n\t\t\texpect(delta.added).contains(leafB.identifier);\n\t\t});\n\n\t\tit('with different payloads', () => {\n\t\t\tconst rootId = testTree.generateNodeId();\n\t\t\tconst nodeA: ChangeNode = {\n\t\t\t\tidentifier: rootId,\n\t\t\t\tdefinition: 'node' as Definition,\n\t\t\t\tpayload: 'test1',\n\t\t\t\ttraits: {},\n\t\t\t};\n\t\t\tconst nodeB: ChangeNode = {\n\t\t\t\tidentifier: rootId,\n\t\t\t\tdefinition: 'node' as Definition,\n\t\t\t\tpayload: 'test2',\n\t\t\t\ttraits: {},\n\t\t\t};\n\n\t\t\tconst viewA = RevisionView.fromTree(nodeA);\n\t\t\tconst viewB = RevisionView.fromTree(nodeB);\n\t\t\tconst delta = viewA.delta(viewB);\n\t\t\texpect(delta.changed).deep.equals([rootId]);\n\t\t\texpect(delta.removed).deep.equals([]);\n\t\t\texpect(delta.added).deep.equals([]);\n\t\t});\n\n\t\tit('after an insert', () => {\n\t\t\tconst viewA = testTree.view;\n\t\t\tconst insertedNode = testTree.buildLeaf(testTree.generateNodeId());\n\t\t\tconst treeB: ChangeNode = {\n\t\t\t\tidentifier: testTree.identifier,\n\t\t\t\tdefinition: testTree.definition,\n\t\t\t\ttraits: { ...testTree.traits, left: [insertedNode, testTree.left] },\n\t\t\t};\n\t\t\tconst viewB = RevisionView.fromTree(treeB);\n\t\t\tconst delta = viewA.delta(viewB);\n\t\t\texpect(delta.changed).deep.equals([testTree.identifier]);\n\t\t\texpect(delta.removed).deep.equals([]);\n\t\t\texpect(delta.added).deep.equals([insertedNode.identifier]);\n\t\t});\n\n\t\tit('after a delete', () => {\n\t\t\tconst viewA = testTree.view;\n\t\t\tconst treeB: ChangeNode = {\n\t\t\t\tidentifier: testTree.identifier,\n\t\t\t\tdefinition: testTree.definition,\n\t\t\t\ttraits: { ...testTree.traits, left: [] },\n\t\t\t};\n\t\t\tconst viewB = RevisionView.fromTree(treeB);\n\t\t\tconst delta = viewA.delta(viewB);\n\t\t\texpect(delta.changed).deep.equals([testTree.identifier]);\n\t\t\texpect(delta.removed).deep.equals([testTree.left.identifier]);\n\t\t\texpect(delta.added).deep.equals([]);\n\t\t});\n\n\t\tit('after a move', () => {\n\t\t\tconst viewA = testTree.view;\n\t\t\tconst treeB: ChangeNode = {\n\t\t\t\tidentifier: testTree.identifier,\n\t\t\t\tdefinition: testTree.definition,\n\t\t\t\ttraits: { ...testTree.traits, left: [], right: [testTree.right, testTree.left] },\n\t\t\t};\n\t\t\tconst viewB = RevisionView.fromTree(treeB);\n\t\t\tconst delta = viewA.delta(viewB);\n\t\t\texpect(delta.changed).deep.equals([testTree.identifier]);\n\t\t\texpect(delta.removed).deep.equals([]);\n\t\t\texpect(delta.added).deep.equals([]);\n\t\t});\n\t});\n\n\tit('correctly returns node parentage', () => {\n\t\tconst view = testTree.view;\n\t\tfor (const node of view) {\n\t\t\tconst parentNode = view.tryGetParentViewNode(node.identifier);\n\t\t\tif (parentNode !== undefined) {\n\t\t\t\tconst parentage = expectDefined(node.parentage);\n\t\t\t\texpect(parentage.label).to.equal(view.getTraitLabel(node.identifier));\n\t\t\t\texpect(parentage.parent).to.equal(parentNode.identifier);\n\t\t\t}\n\t\t}\n\t});\n\n\t// Regression test for the issue fixed in #9824\n\tit('can be iterated in a consistent order', () => {\n\t\tconst [id1, id2, id3] = Array.from({ length: 3 }).map(() => testTree.generateNodeId());\n\t\tconst label1 = 'traitLabelA' as TraitLabel;\n\t\tconst label2 = 'traitLabelB' as TraitLabel;\n\t\tconst { definition } = testTree;\n\t\tconst tree1: ChangeNode = {\n\t\t\tidentifier: id1,\n\t\t\tdefinition,\n\t\t\ttraits: {\n\t\t\t\t[label1]: [{ identifier: id2, definition, traits: {} }],\n\t\t\t\t[label2]: [{ identifier: id3, definition, traits: {} }],\n\t\t\t},\n\t\t};\n\t\t// Like tree1, but defined with the labels in the opposite order and with different node ids under each trait.\n\t\tconst tree2: ChangeNode = {\n\t\t\tidentifier: id1,\n\t\t\tdefinition,\n\t\t\ttraits: {\n\t\t\t\t[label2]: [{ identifier: id2, definition, traits: {} }],\n\t\t\t\t[label1]: [{ identifier: id3, definition, traits: {} }],\n\t\t\t},\n\t\t};\n\t\tconst view1 = RevisionView.fromTree(tree1);\n\t\tconst view2 = RevisionView.fromTree(tree2);\n\t\texpect(Array.from(view1).map((node) => node.identifier)).to.deep.equal([id1, id2, id3]);\n\t\t// Child iteration should be sorted on trait labels.\n\t\texpect(Array.from(view2).map((node) => node.identifier)).to.deep.equal([id1, id3, id2]);\n\t});\n});\n"]}
|
|
@@ -12,7 +12,6 @@ import { IdCompressor } from '../id-compressor';
|
|
|
12
12
|
import { createSessionId } from '../id-compressor/NumericUuid';
|
|
13
13
|
import { SharedTreeEncoder_0_1_1 } from '../SharedTreeEncoder';
|
|
14
14
|
import { CachingLogViewer } from '../LogViewer';
|
|
15
|
-
import { GenericTransaction, TransactionInternal } from '../TransactionInternal';
|
|
16
15
|
import { RevisionView } from '../RevisionView';
|
|
17
16
|
import { MutableStringInterner } from '../StringInterner';
|
|
18
17
|
import { applyNoop, createStableEdits, makeNodeIdContext, setUpLocalServerTestSharedTree, } from './utilities/TestUtilities';
|
|
@@ -33,7 +32,7 @@ describe('SharedTree history virtualization', () => {
|
|
|
33
32
|
for (let i = 0; i < edits.length; i++) {
|
|
34
33
|
editLog.addSequencedEdit(edits[i], { sequenceNumber: i + 1, referenceSequenceNumber: i });
|
|
35
34
|
}
|
|
36
|
-
const logViewer = new CachingLogViewer(editLog, RevisionView.fromTree(initialTree, context, true), undefined, true
|
|
35
|
+
const logViewer = new CachingLogViewer(editLog, RevisionView.fromTree(initialTree, context, true), undefined, true);
|
|
37
36
|
const internedStrings = [
|
|
38
37
|
SimpleTestTree.definition,
|
|
39
38
|
SimpleTestTree.traitLabel,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Virtualization.tests.js","sourceRoot":"","sources":["../../src/test/Virtualization.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 { TestObjectProvider } from '@fluidframework/test-utils';\nimport { EditLog } from '../EditLog';\nimport { assertNotUndefined } from '../Common';\nimport { initialTree } from '../InitialTree';\nimport { SharedTree } from '../SharedTree';\nimport {\n\tChangeInternal,\n\tEdit,\n\tPayload,\n\treservedIdCount,\n\tFluidEditHandle,\n\tSharedTreeSummary,\n\tWriteFormat,\n\teditsPerChunk,\n} from '../persisted-types';\nimport { SharedTreeDiagnosticEvent } from '../EventTypes';\nimport { IdCompressor } from '../id-compressor';\nimport { createSessionId } from '../id-compressor/NumericUuid';\nimport { SharedTreeEncoder_0_1_1 } from '../SharedTreeEncoder';\nimport { CachingLogViewer } from '../LogViewer';\nimport { GenericTransaction, TransactionInternal } from '../TransactionInternal';\nimport { RevisionView } from '../RevisionView';\nimport { MutableStringInterner } from '../StringInterner';\nimport {\n\tapplyNoop,\n\tcreateStableEdits,\n\tmakeNodeIdContext,\n\tsetUpLocalServerTestSharedTree,\n} from './utilities/TestUtilities';\nimport { SimpleTestTree } from './utilities/TestNode';\n\ndescribe('SharedTree history virtualization', () => {\n\tlet sharedTree: SharedTree;\n\tlet testObjectProvider: TestObjectProvider;\n\tlet editChunksUploaded = 0;\n\tconst editCount = 250;\n\tconst expectedFullChunkCount = Math.floor(editCount / editsPerChunk);\n\n\t// Create a summary used to test catchup blobbing\n\tfunction createCatchUpSummary(numberOfEdits: number, payload?: (i: number) => Payload): SharedTreeSummary {\n\t\tconst idCompressor = new IdCompressor(createSessionId(), reservedIdCount);\n\t\tconst context = makeNodeIdContext(idCompressor);\n\t\tconst edits = createStableEdits(numberOfEdits, context, payload);\n\t\tidCompressor.finalizeCreationRange(idCompressor.takeNextCreationRange());\n\t\tconst editLog = new EditLog<ChangeInternal>();\n\t\tfor (let i = 0; i < edits.length; i++) {\n\t\t\teditLog.addSequencedEdit(edits[i], { sequenceNumber: i + 1, referenceSequenceNumber: i });\n\t\t}\n\t\tconst logViewer = new CachingLogViewer(\n\t\t\teditLog,\n\t\t\tRevisionView.fromTree(initialTree, context, true),\n\t\t\tundefined,\n\t\t\ttrue,\n\t\t\tundefined,\n\t\t\tundefined,\n\t\t\t(view) => new GenericTransaction(view, new TransactionInternal.Policy())\n\t\t);\n\n\t\tconst internedStrings = [\n\t\t\tSimpleTestTree.definition,\n\t\t\tSimpleTestTree.traitLabel,\n\t\t\tSimpleTestTree.leftTraitLabel,\n\t\t\tSimpleTestTree.rightTraitLabel,\n\t\t];\n\t\tconst interner = new MutableStringInterner(internedStrings);\n\t\tconst encoder = new SharedTreeEncoder_0_1_1(true);\n\t\treturn encoder.encodeSummary(\n\t\t\teditLog,\n\t\t\tlogViewer.getRevisionViewInSession(Number.POSITIVE_INFINITY),\n\t\t\tcontext,\n\t\t\tcontext,\n\t\t\tinterner,\n\t\t\tidCompressor.serialize(false)\n\t\t);\n\t}\n\n\tbeforeEach(async () => {\n\t\tconst testingComponents = await setUpLocalServerTestSharedTree({\n\t\t\tsummarizeHistory: true,\n\t\t\twriteFormat: WriteFormat.v0_1_1,\n\t\t});\n\t\tsharedTree = testingComponents.tree;\n\t\ttestObjectProvider = testingComponents.testObjectProvider;\n\n\t\tsharedTree.on(SharedTreeDiagnosticEvent.EditChunkUploaded, () => {\n\t\t\teditChunksUploaded++;\n\t\t});\n\t});\n\n\tafterEach(() => {\n\t\teditChunksUploaded = 0;\n\t});\n\n\t// Replace sharedTree with one that writes summary format 0.0.2\n\tconst useSharedTreeSummaryv0_0_2 = async () => {\n\t\tconst testingComponents = await setUpLocalServerTestSharedTree({\n\t\t\tsummarizeHistory: true,\n\t\t\twriteFormat: WriteFormat.v0_0_2,\n\t\t});\n\t\tsharedTree = testingComponents.tree;\n\t\ttestObjectProvider = testingComponents.testObjectProvider;\n\n\t\tsharedTree.on(SharedTreeDiagnosticEvent.EditChunkUploaded, () => {\n\t\t\teditChunksUploaded++;\n\t\t});\n\t};\n\n\t// Adds edits to sharedTree1 to make up the specified number of chunks.\n\tconst addNewEditChunks = async (numberOfChunks = 1, additionalEdits = 0) => {\n\t\tconst expectedEdits: Edit<unknown>[] = [];\n\n\t\t// Add some edits to create a chunk with.\n\t\twhile (expectedEdits.length < (sharedTree.edits as EditLog).editsPerChunk * numberOfChunks + additionalEdits) {\n\t\t\texpectedEdits.push(applyNoop(sharedTree));\n\t\t}\n\n\t\t// `ensureSynchronized` does not guarantee blob upload\n\t\tawait new Promise((resolve) => setImmediate(resolve));\n\t\t// Wait for the ops to to be submitted and processed across the containers.\n\t\tawait testObjectProvider.ensureSynchronized();\n\n\t\treturn expectedEdits;\n\t};\n\n\tit('can upload edit chunks and load chunks from handles', async () => {\n\t\tconst expectedEdits: Edit<unknown>[] = await addNewEditChunks();\n\n\t\tconst summary = sharedTree.saveSummary() as SharedTreeSummary;\n\n\t\tconst { editHistory } = summary;\n\t\tconst { editChunks } = assertNotUndefined(editHistory);\n\t\texpect(editChunks.length).to.equal(1);\n\t\texpect(typeof (editChunks[0].chunk as FluidEditHandle).get).to.equal('function');\n\n\t\t// Load a second tree using the summary\n\t\tconst { tree: sharedTree2 } = await setUpLocalServerTestSharedTree({\n\t\t\ttestObjectProvider,\n\t\t\twriteFormat: WriteFormat.v0_1_1,\n\t\t});\n\n\t\tsharedTree2.loadSummary(summary);\n\n\t\t// Ensure chunked edit can be retrieved\n\t\texpect((await sharedTree2.edits.getEditAtIndex(2)).id).to.equal(expectedEdits[2].id);\n\t});\n\n\tit('can upload catchup blobs', async () => {\n\t\tlet catchUpBlobsUploaded = 0;\n\t\tsharedTree.on(SharedTreeDiagnosticEvent.CatchUpBlobUploaded, () => {\n\t\t\tcatchUpBlobsUploaded++;\n\t\t});\n\n\t\t// Wait for the op to to be submitted and processed across the containers.\n\t\tawait testObjectProvider.ensureSynchronized();\n\n\t\tsharedTree.loadSummary(createCatchUpSummary(250));\n\n\t\tawait testObjectProvider.ensureSynchronized();\n\t\texpect(catchUpBlobsUploaded).to.equal(expectedFullChunkCount);\n\n\t\tconst { editHistory } = sharedTree.saveSummary() as SharedTreeSummary;\n\t\tconst { editChunks } = assertNotUndefined(editHistory);\n\t\texpect(editChunks.length).to.equal(expectedFullChunkCount + 1);\n\t\texpect(typeof (editChunks[0].chunk as FluidEditHandle).get).to.equal('function');\n\t});\n\n\tit('only uploads catchup blobs from one client', async () => {\n\t\t// Create more connected trees\n\t\tconst { tree: sharedTree2 } = await setUpLocalServerTestSharedTree({\n\t\t\ttestObjectProvider,\n\t\t\tsummarizeHistory: true,\n\t\t\twriteFormat: WriteFormat.v0_1_1,\n\t\t});\n\t\tconst { tree: sharedTree3 } = await setUpLocalServerTestSharedTree({\n\t\t\ttestObjectProvider,\n\t\t\tsummarizeHistory: true,\n\t\t\twriteFormat: WriteFormat.v0_1_1,\n\t\t});\n\n\t\tlet catchUpBlobsUploaded = 0;\n\t\tsharedTree.on(SharedTreeDiagnosticEvent.CatchUpBlobUploaded, () => {\n\t\t\tcatchUpBlobsUploaded++;\n\t\t});\n\t\tsharedTree2.on(SharedTreeDiagnosticEvent.CatchUpBlobUploaded, () => {\n\t\t\tcatchUpBlobsUploaded++;\n\t\t});\n\t\tsharedTree3.on(SharedTreeDiagnosticEvent.CatchUpBlobUploaded, () => {\n\t\t\tcatchUpBlobsUploaded++;\n\t\t});\n\n\t\t// Wait for processing again in case there are more no ops\n\t\tawait testObjectProvider.ensureSynchronized();\n\n\t\t// Try to load summaries on all the trees\n\t\tconst summary = createCatchUpSummary(250);\n\t\tsharedTree.loadSummary(summary);\n\t\tsharedTree2.loadSummary(summary);\n\t\tsharedTree3.loadSummary(summary);\n\n\t\t// `ensureSynchronized` does not guarantee blob upload\n\t\tawait new Promise((resolve) => setImmediate(resolve));\n\t\tawait testObjectProvider.ensureSynchronized();\n\t\texpect(catchUpBlobsUploaded).to.equal(expectedFullChunkCount);\n\n\t\t// Make sure the trees are still the same\n\t\texpect(sharedTree.equals(sharedTree2)).to.be.true;\n\t\texpect(sharedTree.equals(sharedTree3)).to.be.true;\n\t});\n\n\tit(\"doesn't upload incomplete chunks\", async () => {\n\t\tawait addNewEditChunks(0, 50);\n\t\texpect(editChunksUploaded).to.equal(0);\n\t});\n\n\tit('can upload full chunks with incomplete chunks in the edit log', async () => {\n\t\ttestObjectProvider.logger.registerExpectedEvent(\n\t\t\t{ eventName: 'fluid:telemetry:Batching:LengthTooBig' },\n\t\t\t{ eventName: 'fluid:telemetry:Batching:LengthTooBig' }\n\t\t);\n\t\tawait addNewEditChunks(1, 50);\n\t\texpect(editChunksUploaded).to.equal(1);\n\t});\n\n\tit('correctly saves handles and their corresponding starting revisions to the summary', async () => {\n\t\ttestObjectProvider.logger.registerExpectedEvent(\n\t\t\t{ eventName: 'fluid:telemetry:Batching:LengthTooBig' },\n\t\t\t{ eventName: 'fluid:telemetry:Batching:LengthTooBig' }\n\t\t);\n\t\tawait addNewEditChunks(4);\n\n\t\tconst { editHistory } = sharedTree.saveSummary() as SharedTreeSummary;\n\t\tconst { editChunks } = assertNotUndefined(editHistory);\n\t\texpect(editChunks.length).to.equal(4);\n\n\t\t// Make sure each starting revision is correct and each chunk in the summary is a handle\n\t\teditChunks.forEach(({ startRevision, chunk }, index) => {\n\t\t\texpect(startRevision).to.equal(index * (sharedTree.edits as EditLog).editsPerChunk);\n\t\t\texpect(typeof (chunk as FluidEditHandle).get).to.equal('function');\n\t\t});\n\t});\n\n\tit('sends handle ops to connected clients when chunks are uploaded', async () => {\n\t\tconst { tree: sharedTree2 } = await setUpLocalServerTestSharedTree({\n\t\t\ttestObjectProvider,\n\t\t\tsummarizeHistory: true,\n\t\t\twriteFormat: WriteFormat.v0_1_1,\n\t\t});\n\t\tconst { tree: sharedTree3 } = await setUpLocalServerTestSharedTree({\n\t\t\ttestObjectProvider,\n\t\t\tsummarizeHistory: true,\n\t\t\twriteFormat: WriteFormat.v0_1_1,\n\t\t});\n\n\t\t// All shared trees should have no edits or chunks\n\t\texpect((sharedTree.saveSummary() as SharedTreeSummary).editHistory?.editChunks.length).to.equal(0);\n\t\texpect((sharedTree2.saveSummary() as SharedTreeSummary).editHistory?.editChunks.length).to.equal(0);\n\t\texpect((sharedTree3.saveSummary() as SharedTreeSummary).editHistory?.editChunks.length).to.equal(0);\n\n\t\tawait addNewEditChunks();\n\n\t\t// All shared trees should have the new handle\n\t\tconst sharedTreeSummary = sharedTree.saveSummary() as SharedTreeSummary;\n\t\tconst sharedTree2Summary = sharedTree2.saveSummary() as SharedTreeSummary;\n\t\tconst sharedTree3Summary = sharedTree3.saveSummary() as SharedTreeSummary;\n\t\tconst sharedTreeChunk = assertNotUndefined(sharedTreeSummary.editHistory).editChunks[0].chunk;\n\t\tconst sharedTree2Chunk = assertNotUndefined(sharedTree2Summary.editHistory).editChunks[0].chunk;\n\t\tconst sharedTree3Chunk = assertNotUndefined(sharedTree3Summary.editHistory).editChunks[0].chunk;\n\n\t\t// Make sure the chunk of the first shared tree is a handle\n\t\texpect(typeof (sharedTreeChunk as FluidEditHandle).get).to.equal('function');\n\n\t\tconst sharedTreeHandleRoute = (sharedTreeChunk as any).absolutePath;\n\t\tconst sharedTree2HandleRoute = (sharedTree2Chunk as any).absolutePath;\n\t\tconst sharedTree3HandleRoute = (sharedTree3Chunk as any).absolutePath;\n\n\t\t// Make sure the handle route of the first shared tree is a string\n\t\texpect(typeof sharedTreeHandleRoute).to.equal('string');\n\n\t\texpect(sharedTreeHandleRoute).to.equal(sharedTree2HandleRoute);\n\t\texpect(sharedTree2HandleRoute).to.equal(sharedTree3HandleRoute);\n\t});\n\n\tit('does not cause misaligned chunks', async () => {\n\t\ttestObjectProvider.logger.registerExpectedEvent(\n\t\t\t{ eventName: 'fluid:telemetry:Batching:LengthTooBig' },\n\t\t\t{ eventName: 'fluid:telemetry:Batching:LengthTooBig' },\n\t\t\t{ eventName: 'fluid:telemetry:Batching:LengthTooBig' }\n\t\t);\n\t\tawait addNewEditChunks(1, 50);\n\n\t\tconst summary = sharedTree.saveSummary();\n\n\t\t// Connect another client\n\t\tconst { tree: sharedTree2 } = await setUpLocalServerTestSharedTree({\n\t\t\ttestObjectProvider,\n\t\t\tsummarizeHistory: true,\n\t\t\twriteFormat: WriteFormat.v0_1_1,\n\t\t});\n\n\t\tlet unexpectedHistoryChunk = false;\n\t\tsharedTree2.on(SharedTreeDiagnosticEvent.UnexpectedHistoryChunk, () => {\n\t\t\tunexpectedHistoryChunk = true;\n\t\t});\n\n\t\tsharedTree2.loadSummary(summary);\n\n\t\t// Finish off the incomplete chunk\n\t\tawait addNewEditChunks();\n\n\t\texpect(unexpectedHistoryChunk).to.be.false;\n\t});\n\n\tit('does not cause misaligned chunks for format version 0.0.2', async () => {\n\t\tawait useSharedTreeSummaryv0_0_2();\n\t\ttestObjectProvider.logger.registerExpectedEvent(\n\t\t\t{ eventName: 'fluid:telemetry:Batching:LengthTooBig' },\n\t\t\t{ eventName: 'fluid:telemetry:Batching:LengthTooBig' },\n\t\t\t{ eventName: 'fluid:telemetry:Batching:LengthTooBig' }\n\t\t);\n\n\t\t// Add enough edits for a chunk and a half\n\t\tawait addNewEditChunks(1, 50);\n\n\t\t// Connect another client\n\t\tconst { tree: sharedTree2 } = await setUpLocalServerTestSharedTree({\n\t\t\ttestObjectProvider,\n\t\t\tsummarizeHistory: true,\n\t\t\twriteFormat: WriteFormat.v0_0_2,\n\t\t});\n\n\t\tlet unexpectedHistoryChunk = false;\n\t\tsharedTree2.on(SharedTreeDiagnosticEvent.UnexpectedHistoryChunk, () => {\n\t\t\tunexpectedHistoryChunk = true;\n\t\t});\n\n\t\tsharedTree2.loadSummary(sharedTree.saveSummary());\n\n\t\t// Finish off the incomplete chunk\n\t\tawait addNewEditChunks();\n\n\t\texpect(unexpectedHistoryChunk).to.be.false;\n\t});\n\n\tit('does not upload blobs larger than 4MB', async () => {\n\t\ttestObjectProvider.logger.registerExpectedEvent({\n\t\t\teventName: 'fluid:telemetry:FluidDataStoreRuntime:SharedTree:EditChunkUploadFailure',\n\t\t});\n\t\tconst numberOfEdits = editsPerChunk;\n\t\tconst fourMegas = 2 ** 22;\n\t\t// Without the 1.1, we would generate 100 edits of size roughly 40kb here, but not all of them end up in the first edit chunk\n\t\t// due to some setup edits.\n\t\t// So we'd barely land within the 4MB limit. Bumping each payload size by 10% is enough to account for this.\n\t\tconst bigPayload = 'a'.repeat(Math.ceil((1.1 * fourMegas) / numberOfEdits));\n\t\tconst fakeSummary = createCatchUpSummary(numberOfEdits, () => bigPayload);\n\t\tsharedTree.loadSummary(fakeSummary);\n\t\t// `ensureSynchronized` does not guarantee blob upload\n\t\tawait new Promise((resolve) => setImmediate(resolve));\n\t\tawait testObjectProvider.ensureSynchronized();\n\t\texpect(editChunksUploaded).to.equal(0);\n\t});\n});\n"]}
|
|
1
|
+
{"version":3,"file":"Virtualization.tests.js","sourceRoot":"","sources":["../../src/test/Virtualization.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 { TestObjectProvider } from '@fluidframework/test-utils';\nimport { EditLog } from '../EditLog';\nimport { assertNotUndefined } from '../Common';\nimport { initialTree } from '../InitialTree';\nimport { SharedTree } from '../SharedTree';\nimport {\n\tChangeInternal,\n\tEdit,\n\tPayload,\n\treservedIdCount,\n\tFluidEditHandle,\n\tSharedTreeSummary,\n\tWriteFormat,\n\teditsPerChunk,\n} from '../persisted-types';\nimport { SharedTreeDiagnosticEvent } from '../EventTypes';\nimport { IdCompressor } from '../id-compressor';\nimport { createSessionId } from '../id-compressor/NumericUuid';\nimport { SharedTreeEncoder_0_1_1 } from '../SharedTreeEncoder';\nimport { CachingLogViewer } from '../LogViewer';\nimport { RevisionView } from '../RevisionView';\nimport { MutableStringInterner } from '../StringInterner';\nimport {\n\tapplyNoop,\n\tcreateStableEdits,\n\tmakeNodeIdContext,\n\tsetUpLocalServerTestSharedTree,\n} from './utilities/TestUtilities';\nimport { SimpleTestTree } from './utilities/TestNode';\n\ndescribe('SharedTree history virtualization', () => {\n\tlet sharedTree: SharedTree;\n\tlet testObjectProvider: TestObjectProvider;\n\tlet editChunksUploaded = 0;\n\tconst editCount = 250;\n\tconst expectedFullChunkCount = Math.floor(editCount / editsPerChunk);\n\n\t// Create a summary used to test catchup blobbing\n\tfunction createCatchUpSummary(numberOfEdits: number, payload?: (i: number) => Payload): SharedTreeSummary {\n\t\tconst idCompressor = new IdCompressor(createSessionId(), reservedIdCount);\n\t\tconst context = makeNodeIdContext(idCompressor);\n\t\tconst edits = createStableEdits(numberOfEdits, context, payload);\n\t\tidCompressor.finalizeCreationRange(idCompressor.takeNextCreationRange());\n\t\tconst editLog = new EditLog<ChangeInternal>();\n\t\tfor (let i = 0; i < edits.length; i++) {\n\t\t\teditLog.addSequencedEdit(edits[i], { sequenceNumber: i + 1, referenceSequenceNumber: i });\n\t\t}\n\t\tconst logViewer = new CachingLogViewer(\n\t\t\teditLog,\n\t\t\tRevisionView.fromTree(initialTree, context, true),\n\t\t\tundefined,\n\t\t\ttrue\n\t\t);\n\n\t\tconst internedStrings = [\n\t\t\tSimpleTestTree.definition,\n\t\t\tSimpleTestTree.traitLabel,\n\t\t\tSimpleTestTree.leftTraitLabel,\n\t\t\tSimpleTestTree.rightTraitLabel,\n\t\t];\n\t\tconst interner = new MutableStringInterner(internedStrings);\n\t\tconst encoder = new SharedTreeEncoder_0_1_1(true);\n\t\treturn encoder.encodeSummary(\n\t\t\teditLog,\n\t\t\tlogViewer.getRevisionViewInSession(Number.POSITIVE_INFINITY),\n\t\t\tcontext,\n\t\t\tcontext,\n\t\t\tinterner,\n\t\t\tidCompressor.serialize(false)\n\t\t);\n\t}\n\n\tbeforeEach(async () => {\n\t\tconst testingComponents = await setUpLocalServerTestSharedTree({\n\t\t\tsummarizeHistory: true,\n\t\t\twriteFormat: WriteFormat.v0_1_1,\n\t\t});\n\t\tsharedTree = testingComponents.tree;\n\t\ttestObjectProvider = testingComponents.testObjectProvider;\n\n\t\tsharedTree.on(SharedTreeDiagnosticEvent.EditChunkUploaded, () => {\n\t\t\teditChunksUploaded++;\n\t\t});\n\t});\n\n\tafterEach(() => {\n\t\teditChunksUploaded = 0;\n\t});\n\n\t// Replace sharedTree with one that writes summary format 0.0.2\n\tconst useSharedTreeSummaryv0_0_2 = async () => {\n\t\tconst testingComponents = await setUpLocalServerTestSharedTree({\n\t\t\tsummarizeHistory: true,\n\t\t\twriteFormat: WriteFormat.v0_0_2,\n\t\t});\n\t\tsharedTree = testingComponents.tree;\n\t\ttestObjectProvider = testingComponents.testObjectProvider;\n\n\t\tsharedTree.on(SharedTreeDiagnosticEvent.EditChunkUploaded, () => {\n\t\t\teditChunksUploaded++;\n\t\t});\n\t};\n\n\t// Adds edits to sharedTree1 to make up the specified number of chunks.\n\tconst addNewEditChunks = async (numberOfChunks = 1, additionalEdits = 0) => {\n\t\tconst expectedEdits: Edit<unknown>[] = [];\n\n\t\t// Add some edits to create a chunk with.\n\t\twhile (expectedEdits.length < (sharedTree.edits as EditLog).editsPerChunk * numberOfChunks + additionalEdits) {\n\t\t\texpectedEdits.push(applyNoop(sharedTree));\n\t\t}\n\n\t\t// `ensureSynchronized` does not guarantee blob upload\n\t\tawait new Promise((resolve) => setImmediate(resolve));\n\t\t// Wait for the ops to to be submitted and processed across the containers.\n\t\tawait testObjectProvider.ensureSynchronized();\n\n\t\treturn expectedEdits;\n\t};\n\n\tit('can upload edit chunks and load chunks from handles', async () => {\n\t\tconst expectedEdits: Edit<unknown>[] = await addNewEditChunks();\n\n\t\tconst summary = sharedTree.saveSummary() as SharedTreeSummary;\n\n\t\tconst { editHistory } = summary;\n\t\tconst { editChunks } = assertNotUndefined(editHistory);\n\t\texpect(editChunks.length).to.equal(1);\n\t\texpect(typeof (editChunks[0].chunk as FluidEditHandle).get).to.equal('function');\n\n\t\t// Load a second tree using the summary\n\t\tconst { tree: sharedTree2 } = await setUpLocalServerTestSharedTree({\n\t\t\ttestObjectProvider,\n\t\t\twriteFormat: WriteFormat.v0_1_1,\n\t\t});\n\n\t\tsharedTree2.loadSummary(summary);\n\n\t\t// Ensure chunked edit can be retrieved\n\t\texpect((await sharedTree2.edits.getEditAtIndex(2)).id).to.equal(expectedEdits[2].id);\n\t});\n\n\tit('can upload catchup blobs', async () => {\n\t\tlet catchUpBlobsUploaded = 0;\n\t\tsharedTree.on(SharedTreeDiagnosticEvent.CatchUpBlobUploaded, () => {\n\t\t\tcatchUpBlobsUploaded++;\n\t\t});\n\n\t\t// Wait for the op to to be submitted and processed across the containers.\n\t\tawait testObjectProvider.ensureSynchronized();\n\n\t\tsharedTree.loadSummary(createCatchUpSummary(250));\n\n\t\tawait testObjectProvider.ensureSynchronized();\n\t\texpect(catchUpBlobsUploaded).to.equal(expectedFullChunkCount);\n\n\t\tconst { editHistory } = sharedTree.saveSummary() as SharedTreeSummary;\n\t\tconst { editChunks } = assertNotUndefined(editHistory);\n\t\texpect(editChunks.length).to.equal(expectedFullChunkCount + 1);\n\t\texpect(typeof (editChunks[0].chunk as FluidEditHandle).get).to.equal('function');\n\t});\n\n\tit('only uploads catchup blobs from one client', async () => {\n\t\t// Create more connected trees\n\t\tconst { tree: sharedTree2 } = await setUpLocalServerTestSharedTree({\n\t\t\ttestObjectProvider,\n\t\t\tsummarizeHistory: true,\n\t\t\twriteFormat: WriteFormat.v0_1_1,\n\t\t});\n\t\tconst { tree: sharedTree3 } = await setUpLocalServerTestSharedTree({\n\t\t\ttestObjectProvider,\n\t\t\tsummarizeHistory: true,\n\t\t\twriteFormat: WriteFormat.v0_1_1,\n\t\t});\n\n\t\tlet catchUpBlobsUploaded = 0;\n\t\tsharedTree.on(SharedTreeDiagnosticEvent.CatchUpBlobUploaded, () => {\n\t\t\tcatchUpBlobsUploaded++;\n\t\t});\n\t\tsharedTree2.on(SharedTreeDiagnosticEvent.CatchUpBlobUploaded, () => {\n\t\t\tcatchUpBlobsUploaded++;\n\t\t});\n\t\tsharedTree3.on(SharedTreeDiagnosticEvent.CatchUpBlobUploaded, () => {\n\t\t\tcatchUpBlobsUploaded++;\n\t\t});\n\n\t\t// Wait for processing again in case there are more no ops\n\t\tawait testObjectProvider.ensureSynchronized();\n\n\t\t// Try to load summaries on all the trees\n\t\tconst summary = createCatchUpSummary(250);\n\t\tsharedTree.loadSummary(summary);\n\t\tsharedTree2.loadSummary(summary);\n\t\tsharedTree3.loadSummary(summary);\n\n\t\t// `ensureSynchronized` does not guarantee blob upload\n\t\tawait new Promise((resolve) => setImmediate(resolve));\n\t\tawait testObjectProvider.ensureSynchronized();\n\t\texpect(catchUpBlobsUploaded).to.equal(expectedFullChunkCount);\n\n\t\t// Make sure the trees are still the same\n\t\texpect(sharedTree.equals(sharedTree2)).to.be.true;\n\t\texpect(sharedTree.equals(sharedTree3)).to.be.true;\n\t});\n\n\tit(\"doesn't upload incomplete chunks\", async () => {\n\t\tawait addNewEditChunks(0, 50);\n\t\texpect(editChunksUploaded).to.equal(0);\n\t});\n\n\tit('can upload full chunks with incomplete chunks in the edit log', async () => {\n\t\ttestObjectProvider.logger.registerExpectedEvent(\n\t\t\t{ eventName: 'fluid:telemetry:Batching:LengthTooBig' },\n\t\t\t{ eventName: 'fluid:telemetry:Batching:LengthTooBig' }\n\t\t);\n\t\tawait addNewEditChunks(1, 50);\n\t\texpect(editChunksUploaded).to.equal(1);\n\t});\n\n\tit('correctly saves handles and their corresponding starting revisions to the summary', async () => {\n\t\ttestObjectProvider.logger.registerExpectedEvent(\n\t\t\t{ eventName: 'fluid:telemetry:Batching:LengthTooBig' },\n\t\t\t{ eventName: 'fluid:telemetry:Batching:LengthTooBig' }\n\t\t);\n\t\tawait addNewEditChunks(4);\n\n\t\tconst { editHistory } = sharedTree.saveSummary() as SharedTreeSummary;\n\t\tconst { editChunks } = assertNotUndefined(editHistory);\n\t\texpect(editChunks.length).to.equal(4);\n\n\t\t// Make sure each starting revision is correct and each chunk in the summary is a handle\n\t\teditChunks.forEach(({ startRevision, chunk }, index) => {\n\t\t\texpect(startRevision).to.equal(index * (sharedTree.edits as EditLog).editsPerChunk);\n\t\t\texpect(typeof (chunk as FluidEditHandle).get).to.equal('function');\n\t\t});\n\t});\n\n\tit('sends handle ops to connected clients when chunks are uploaded', async () => {\n\t\tconst { tree: sharedTree2 } = await setUpLocalServerTestSharedTree({\n\t\t\ttestObjectProvider,\n\t\t\tsummarizeHistory: true,\n\t\t\twriteFormat: WriteFormat.v0_1_1,\n\t\t});\n\t\tconst { tree: sharedTree3 } = await setUpLocalServerTestSharedTree({\n\t\t\ttestObjectProvider,\n\t\t\tsummarizeHistory: true,\n\t\t\twriteFormat: WriteFormat.v0_1_1,\n\t\t});\n\n\t\t// All shared trees should have no edits or chunks\n\t\texpect((sharedTree.saveSummary() as SharedTreeSummary).editHistory?.editChunks.length).to.equal(0);\n\t\texpect((sharedTree2.saveSummary() as SharedTreeSummary).editHistory?.editChunks.length).to.equal(0);\n\t\texpect((sharedTree3.saveSummary() as SharedTreeSummary).editHistory?.editChunks.length).to.equal(0);\n\n\t\tawait addNewEditChunks();\n\n\t\t// All shared trees should have the new handle\n\t\tconst sharedTreeSummary = sharedTree.saveSummary() as SharedTreeSummary;\n\t\tconst sharedTree2Summary = sharedTree2.saveSummary() as SharedTreeSummary;\n\t\tconst sharedTree3Summary = sharedTree3.saveSummary() as SharedTreeSummary;\n\t\tconst sharedTreeChunk = assertNotUndefined(sharedTreeSummary.editHistory).editChunks[0].chunk;\n\t\tconst sharedTree2Chunk = assertNotUndefined(sharedTree2Summary.editHistory).editChunks[0].chunk;\n\t\tconst sharedTree3Chunk = assertNotUndefined(sharedTree3Summary.editHistory).editChunks[0].chunk;\n\n\t\t// Make sure the chunk of the first shared tree is a handle\n\t\texpect(typeof (sharedTreeChunk as FluidEditHandle).get).to.equal('function');\n\n\t\tconst sharedTreeHandleRoute = (sharedTreeChunk as any).absolutePath;\n\t\tconst sharedTree2HandleRoute = (sharedTree2Chunk as any).absolutePath;\n\t\tconst sharedTree3HandleRoute = (sharedTree3Chunk as any).absolutePath;\n\n\t\t// Make sure the handle route of the first shared tree is a string\n\t\texpect(typeof sharedTreeHandleRoute).to.equal('string');\n\n\t\texpect(sharedTreeHandleRoute).to.equal(sharedTree2HandleRoute);\n\t\texpect(sharedTree2HandleRoute).to.equal(sharedTree3HandleRoute);\n\t});\n\n\tit('does not cause misaligned chunks', async () => {\n\t\ttestObjectProvider.logger.registerExpectedEvent(\n\t\t\t{ eventName: 'fluid:telemetry:Batching:LengthTooBig' },\n\t\t\t{ eventName: 'fluid:telemetry:Batching:LengthTooBig' },\n\t\t\t{ eventName: 'fluid:telemetry:Batching:LengthTooBig' }\n\t\t);\n\t\tawait addNewEditChunks(1, 50);\n\n\t\tconst summary = sharedTree.saveSummary();\n\n\t\t// Connect another client\n\t\tconst { tree: sharedTree2 } = await setUpLocalServerTestSharedTree({\n\t\t\ttestObjectProvider,\n\t\t\tsummarizeHistory: true,\n\t\t\twriteFormat: WriteFormat.v0_1_1,\n\t\t});\n\n\t\tlet unexpectedHistoryChunk = false;\n\t\tsharedTree2.on(SharedTreeDiagnosticEvent.UnexpectedHistoryChunk, () => {\n\t\t\tunexpectedHistoryChunk = true;\n\t\t});\n\n\t\tsharedTree2.loadSummary(summary);\n\n\t\t// Finish off the incomplete chunk\n\t\tawait addNewEditChunks();\n\n\t\texpect(unexpectedHistoryChunk).to.be.false;\n\t});\n\n\tit('does not cause misaligned chunks for format version 0.0.2', async () => {\n\t\tawait useSharedTreeSummaryv0_0_2();\n\t\ttestObjectProvider.logger.registerExpectedEvent(\n\t\t\t{ eventName: 'fluid:telemetry:Batching:LengthTooBig' },\n\t\t\t{ eventName: 'fluid:telemetry:Batching:LengthTooBig' },\n\t\t\t{ eventName: 'fluid:telemetry:Batching:LengthTooBig' }\n\t\t);\n\n\t\t// Add enough edits for a chunk and a half\n\t\tawait addNewEditChunks(1, 50);\n\n\t\t// Connect another client\n\t\tconst { tree: sharedTree2 } = await setUpLocalServerTestSharedTree({\n\t\t\ttestObjectProvider,\n\t\t\tsummarizeHistory: true,\n\t\t\twriteFormat: WriteFormat.v0_0_2,\n\t\t});\n\n\t\tlet unexpectedHistoryChunk = false;\n\t\tsharedTree2.on(SharedTreeDiagnosticEvent.UnexpectedHistoryChunk, () => {\n\t\t\tunexpectedHistoryChunk = true;\n\t\t});\n\n\t\tsharedTree2.loadSummary(sharedTree.saveSummary());\n\n\t\t// Finish off the incomplete chunk\n\t\tawait addNewEditChunks();\n\n\t\texpect(unexpectedHistoryChunk).to.be.false;\n\t});\n\n\tit('does not upload blobs larger than 4MB', async () => {\n\t\ttestObjectProvider.logger.registerExpectedEvent({\n\t\t\teventName: 'fluid:telemetry:FluidDataStoreRuntime:SharedTree:EditChunkUploadFailure',\n\t\t});\n\t\tconst numberOfEdits = editsPerChunk;\n\t\tconst fourMegas = 2 ** 22;\n\t\t// Without the 1.1, we would generate 100 edits of size roughly 40kb here, but not all of them end up in the first edit chunk\n\t\t// due to some setup edits.\n\t\t// So we'd barely land within the 4MB limit. Bumping each payload size by 10% is enough to account for this.\n\t\tconst bigPayload = 'a'.repeat(Math.ceil((1.1 * fourMegas) / numberOfEdits));\n\t\tconst fakeSummary = createCatchUpSummary(numberOfEdits, () => bigPayload);\n\t\tsharedTree.loadSummary(fakeSummary);\n\t\t// `ensureSynchronized` does not guarantee blob upload\n\t\tawait new Promise((resolve) => setImmediate(resolve));\n\t\tawait testObjectProvider.ensureSynchronized();\n\t\texpect(editChunksUploaded).to.equal(0);\n\t});\n});\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SharedTreeFuzzTests.d.ts","sourceRoot":"","sources":["../../../src/test/fuzz/SharedTreeFuzzTests.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"SharedTreeFuzzTests.d.ts","sourceRoot":"","sources":["../../../src/test/fuzz/SharedTreeFuzzTests.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH,OAAO,EAAE,aAAa,EAA8B,cAAc,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAS/F;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CACvC,SAAS,EAAE,cAAc,CAAC,SAAS,EAAE,SAAS,CAAC,EAC/C,IAAI,EAAE,MAAM,EACZ,gBAAgB,GAAE,OAAc,EAChC,QAAQ,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACtE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CA8GlC;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAkI1D"}
|
|
@@ -9,6 +9,7 @@ import { expect } from 'chai';
|
|
|
9
9
|
import { setUpLocalServerTestSharedTree, testDocumentsPathBase } from '../utilities/TestUtilities';
|
|
10
10
|
import { WriteFormat } from '../../persisted-types';
|
|
11
11
|
import { fail } from '../../Common';
|
|
12
|
+
import { areRevisionViewsSemanticallyEqual } from '../../EditUtilities';
|
|
12
13
|
import { done } from './Types';
|
|
13
14
|
import { chain, makeOpGenerator, take } from './Generators';
|
|
14
15
|
const directory = join(testDocumentsPathBase, 'fuzz-tests');
|
|
@@ -85,7 +86,23 @@ export async function performFuzzActions(generator, seed, synchronizeAtEnd = tru
|
|
|
85
86
|
fail('Attempted to synchronize with undefined testObjectProvider');
|
|
86
87
|
}
|
|
87
88
|
await testObjectProvider.ensureSynchronized();
|
|
88
|
-
|
|
89
|
+
const trees = [...state.activeCollaborators, ...state.passiveCollaborators];
|
|
90
|
+
if (trees.length > 1) {
|
|
91
|
+
const first = trees[0].tree;
|
|
92
|
+
for (let i = 1; i < trees.length; i++) {
|
|
93
|
+
const tree = trees[i].tree;
|
|
94
|
+
const editLogA = first.editsInternal;
|
|
95
|
+
const editLogB = tree.editsInternal;
|
|
96
|
+
const minEdits = Math.min(editLogA.length, editLogB.length);
|
|
97
|
+
for (let j = 0; j < minEdits - 1; j++) {
|
|
98
|
+
const editA = await editLogA.getEditAtIndex(editLogA.length - j - 1);
|
|
99
|
+
const editB = await editLogB.getEditAtIndex(editLogB.length - j - 1);
|
|
100
|
+
expect(editA.id).to.equal(editB.id);
|
|
101
|
+
}
|
|
102
|
+
expect(areRevisionViewsSemanticallyEqual(tree.currentView, tree, first.currentView, first))
|
|
103
|
+
.to.be.true;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
89
106
|
break;
|
|
90
107
|
}
|
|
91
108
|
default:
|
|
@@ -123,7 +140,7 @@ export function runSharedTreeFuzzTests(title) {
|
|
|
123
140
|
mkdirSync(directory);
|
|
124
141
|
}
|
|
125
142
|
await performFuzzActions(generatorFactory(), seed + adjustSeed, true, saveInfo);
|
|
126
|
-
}).timeout(
|
|
143
|
+
}).timeout(10000);
|
|
127
144
|
}
|
|
128
145
|
function runMixedVersionTests(summarizeHistory, testsPerSuite) {
|
|
129
146
|
describe('using 0.0.2 and 0.1.1 trees', () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SharedTreeFuzzTests.js","sourceRoot":"","sources":["../../../src/test/fuzz/SharedTreeFuzzTests.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 { promises as fs, existsSync, mkdirSync } from 'fs';\nimport { join } from 'path';\nimport Prando from 'prando';\nimport { expect } from 'chai';\nimport { setUpLocalServerTestSharedTree, testDocumentsPathBase } from '../utilities/TestUtilities';\nimport { WriteFormat } from '../../persisted-types';\nimport { fail } from '../../Common';\nimport { FuzzTestState, done, EditGenerationConfig, AsyncGenerator, Operation } from './Types';\nimport { chain, makeOpGenerator, take } from './Generators';\n\nconst directory = join(testDocumentsPathBase, 'fuzz-tests');\n\n// TODO: Kludge: Use this to change the seed such that the tests avoid hitting bugs in the Fluid Framework.\n// Should be removed once fuzz tests pass reliably with any seed.\nconst adjustSeed = 2;\n\n/**\n * Performs random actions on a set of clients.\n * @param generator finite generator for a sequence of Operations to test. The test will run until this generator is exhausted.\n * @param seed the seed for the random generation of the fuzz actions\n * @param synchronizeAtEnd if provided, all client will have all operations delivered from the server at the end of the test\n * @param saveInfo optionally provide an operation number at which a history of all operations will be saved to disk at a given filepath.\n * This can be useful for debugging why a fuzz test may have failed.\n */\nexport async function performFuzzActions(\n\tgenerator: AsyncGenerator<Operation, undefined>,\n\tseed: number,\n\tsynchronizeAtEnd: boolean = true,\n\tsaveInfo?: { saveAt?: number; saveOnFailure: boolean; filepath: string }\n): Promise<Required<FuzzTestState>> {\n\tconst rand = new Prando(seed);\n\n\t// Note: the direct fields of `state` aren't mutated, but it is mutated transitively.\n\tconst state: FuzzTestState = { rand, passiveCollaborators: [], activeCollaborators: [] };\n\tconst { activeCollaborators, passiveCollaborators } = state;\n\tconst operations: Operation[] = [];\n\tfor (\n\t\tlet operation = await generator(state, undefined);\n\t\toperation !== done;\n\t\toperation = await generator(state, undefined)\n\t) {\n\t\toperations.push(operation);\n\t\tif (saveInfo !== undefined && operations.length === saveInfo.saveAt) {\n\t\t\tawait fs.writeFile(saveInfo.filepath, JSON.stringify(operations));\n\t\t}\n\n\t\ttry {\n\t\t\tswitch (operation.type) {\n\t\t\t\tcase 'edit': {\n\t\t\t\t\tconst { index, contents } = operation;\n\t\t\t\t\tconst { tree } = activeCollaborators[index];\n\t\t\t\t\tswitch (contents.fuzzType) {\n\t\t\t\t\t\tcase 'insert':\n\t\t\t\t\t\t\ttree.applyEdit(contents.build, contents.insert);\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'delete':\n\t\t\t\t\t\t\ttree.applyEdit(contents);\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'move':\n\t\t\t\t\t\t\ttree.applyEdit(contents.detach, contents.insert);\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'setPayload':\n\t\t\t\t\t\t\ttree.applyEdit(contents);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tfail('Invalid edit.');\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'join': {\n\t\t\t\t\tconst { isObserver, summarizeHistory, writeFormat } = operation;\n\t\t\t\t\tconst { container, tree, testObjectProvider } = await setUpLocalServerTestSharedTree({\n\t\t\t\t\t\twriteFormat,\n\t\t\t\t\t\tsummarizeHistory,\n\t\t\t\t\t\ttestObjectProvider: state.testObjectProvider,\n\t\t\t\t\t});\n\t\t\t\t\tif (state.testObjectProvider === undefined) {\n\t\t\t\t\t\tstate.testObjectProvider = testObjectProvider;\n\t\t\t\t\t}\n\t\t\t\t\t(isObserver ? passiveCollaborators : activeCollaborators).push({ container, tree });\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'leave': {\n\t\t\t\t\tconst { index, isObserver } = operation;\n\t\t\t\t\tconst treeList = isObserver ? passiveCollaborators : activeCollaborators;\n\t\t\t\t\ttreeList[index].container.close();\n\t\t\t\t\ttreeList.splice(index, 1);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'synchronize': {\n\t\t\t\t\tconst { testObjectProvider } = state;\n\t\t\t\t\tif (testObjectProvider === undefined) {\n\t\t\t\t\t\tfail('Attempted to synchronize with undefined testObjectProvider');\n\t\t\t\t\t}\n\t\t\t\t\tawait testObjectProvider.ensureSynchronized();\n\t\t\t\t\t// May want to validate state here\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new Error('Unknown operation.');\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tconsole.log(`Error encountered on operation number ${operations.length}`);\n\t\t\tif (saveInfo !== undefined && saveInfo.saveOnFailure) {\n\t\t\t\tawait fs.writeFile(saveInfo.filepath, JSON.stringify(operations));\n\t\t\t}\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\tif (synchronizeAtEnd) {\n\t\tawait state.testObjectProvider?.ensureSynchronized();\n\t\tconst trees = [...activeCollaborators.map(({ tree }) => tree), ...passiveCollaborators.map(({ tree }) => tree)];\n\t\tfor (let i = 0; i < trees.length - 1; i++) {\n\t\t\texpect(trees[i].equals(trees[i + 1]));\n\t\t}\n\t}\n\n\treturn state as Required<FuzzTestState>;\n}\n\nexport function runSharedTreeFuzzTests(title: string): void {\n\t// Some useful tips for debugging fuzz tests:\n\t// - A JSON dump of the operation sequence can be written to disk by passing `true` for `saveOnFailure`.\n\t// - Different shared-tree instances can be distinguished (e.g. in logs) by using `tree.getRuntime().clientId`\n\tdescribe(title, () => {\n\t\tfunction runTest(\n\t\t\tgeneratorFactory: () => AsyncGenerator<Operation, undefined>,\n\t\t\tseed: number,\n\t\t\tsaveOnFailure?: boolean\n\t\t): void {\n\t\t\tit(`with seed ${seed}`, async () => {\n\t\t\t\tconst saveInfo =\n\t\t\t\t\tsaveOnFailure !== undefined\n\t\t\t\t\t\t? { filepath: join(directory, `test-history-${seed}.json`), saveOnFailure }\n\t\t\t\t\t\t: undefined;\n\t\t\t\tif (saveInfo !== undefined && !existsSync(directory)) {\n\t\t\t\t\tmkdirSync(directory);\n\t\t\t\t}\n\t\t\t\tawait performFuzzActions(generatorFactory(), seed + adjustSeed, true, saveInfo);\n\t\t\t}).timeout(5000);\n\t\t}\n\n\t\tfunction runMixedVersionTests(summarizeHistory: boolean, testsPerSuite: number): void {\n\t\t\tdescribe('using 0.0.2 and 0.1.1 trees', () => {\n\t\t\t\tfor (let seed = 0; seed < testsPerSuite; seed++) {\n\t\t\t\t\trunTest(\n\t\t\t\t\t\t() => take(1000, makeOpGenerator({ joinConfig: { summarizeHistory: [summarizeHistory] } })),\n\t\t\t\t\t\tseed\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tdescribe('using only version 0.0.2', () => {\n\t\t\t\tfor (let seed = 0; seed < testsPerSuite; seed++) {\n\t\t\t\t\trunTest(\n\t\t\t\t\t\t() =>\n\t\t\t\t\t\t\ttake(\n\t\t\t\t\t\t\t\t1000,\n\t\t\t\t\t\t\t\tmakeOpGenerator({\n\t\t\t\t\t\t\t\t\tjoinConfig: {\n\t\t\t\t\t\t\t\t\t\twriteFormat: [WriteFormat.v0_0_2],\n\t\t\t\t\t\t\t\t\t\tsummarizeHistory: [summarizeHistory],\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\tseed\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tdescribe('using only version 0.1.1', () => {\n\t\t\t\tfor (let seed = 0; seed < testsPerSuite; seed++) {\n\t\t\t\t\trunTest(\n\t\t\t\t\t\t() =>\n\t\t\t\t\t\t\ttake(\n\t\t\t\t\t\t\t\t1000,\n\t\t\t\t\t\t\t\tmakeOpGenerator({\n\t\t\t\t\t\t\t\t\tjoinConfig: {\n\t\t\t\t\t\t\t\t\t\twriteFormat: [WriteFormat.v0_1_1],\n\t\t\t\t\t\t\t\t\t\tsummarizeHistory: [summarizeHistory],\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\tseed\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tdescribe('upgrading halfway through', () => {\n\t\t\t\tconst testLength = 500;\n\t\t\t\tconst maximumActiveCollaborators = 10;\n\t\t\t\tconst maximumPassiveCollaborators = 5;\n\t\t\t\tconst editConfig: EditGenerationConfig = { maxTreeSize: 1000 };\n\t\t\t\tconst generatorFactory = () =>\n\t\t\t\t\tchain(\n\t\t\t\t\t\ttake(\n\t\t\t\t\t\t\ttestLength / 2 - 1,\n\t\t\t\t\t\t\tmakeOpGenerator({\n\t\t\t\t\t\t\t\teditConfig,\n\t\t\t\t\t\t\t\tjoinConfig: {\n\t\t\t\t\t\t\t\t\tmaximumActiveCollaborators,\n\t\t\t\t\t\t\t\t\tmaximumPassiveCollaborators,\n\t\t\t\t\t\t\t\t\twriteFormat: [WriteFormat.v0_0_2],\n\t\t\t\t\t\t\t\t\tsummarizeHistory: [summarizeHistory],\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t),\n\t\t\t\t\t\ttake(\n\t\t\t\t\t\t\t1,\n\t\t\t\t\t\t\tmakeOpGenerator({\n\t\t\t\t\t\t\t\tjoinConfig: {\n\t\t\t\t\t\t\t\t\tmaximumActiveCollaborators: maximumActiveCollaborators + 1,\n\t\t\t\t\t\t\t\t\tmaximumPassiveCollaborators,\n\t\t\t\t\t\t\t\t\twriteFormat: [WriteFormat.v0_1_1],\n\t\t\t\t\t\t\t\t\tsummarizeHistory: [summarizeHistory],\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\teditWeight: 0,\n\t\t\t\t\t\t\t\tjoinWeight: 1,\n\t\t\t\t\t\t\t\tleaveWeight: 0,\n\t\t\t\t\t\t\t\tsynchronizeWeight: 0,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t),\n\t\t\t\t\t\ttake(\n\t\t\t\t\t\t\ttestLength / 2,\n\t\t\t\t\t\t\tmakeOpGenerator({\n\t\t\t\t\t\t\t\teditConfig,\n\t\t\t\t\t\t\t\tjoinConfig: {\n\t\t\t\t\t\t\t\t\tmaximumActiveCollaborators,\n\t\t\t\t\t\t\t\t\tmaximumPassiveCollaborators,\n\t\t\t\t\t\t\t\t\tsummarizeHistory: [summarizeHistory],\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\n\t\t\t\tfor (let seed = 0; seed < testsPerSuite; seed++) {\n\t\t\t\t\trunTest(generatorFactory, seed);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tconst testCount = 1;\n\t\tdescribe('with no-history summarization', () => {\n\t\t\trunMixedVersionTests(false, testCount);\n\t\t});\n\n\t\tdescribe('with history summarization', () => {\n\t\t\trunMixedVersionTests(true, testCount);\n\t\t});\n\t});\n}\n"]}
|
|
1
|
+
{"version":3,"file":"SharedTreeFuzzTests.js","sourceRoot":"","sources":["../../../src/test/fuzz/SharedTreeFuzzTests.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 { promises as fs, existsSync, mkdirSync } from 'fs';\nimport { join } from 'path';\nimport Prando from 'prando';\nimport { expect } from 'chai';\nimport { setUpLocalServerTestSharedTree, testDocumentsPathBase } from '../utilities/TestUtilities';\nimport { ChangeInternal, WriteFormat } from '../../persisted-types';\nimport { fail } from '../../Common';\nimport { areRevisionViewsSemanticallyEqual } from '../../EditUtilities';\nimport { EditLog } from '../../EditLog';\nimport { FuzzTestState, done, EditGenerationConfig, AsyncGenerator, Operation } from './Types';\nimport { chain, makeOpGenerator, take } from './Generators';\n\nconst directory = join(testDocumentsPathBase, 'fuzz-tests');\n\n// TODO: Kludge: Use this to change the seed such that the tests avoid hitting bugs in the Fluid Framework.\n// Should be removed once fuzz tests pass reliably with any seed.\nconst adjustSeed = 2;\n\n/**\n * Performs random actions on a set of clients.\n * @param generator finite generator for a sequence of Operations to test. The test will run until this generator is exhausted.\n * @param seed the seed for the random generation of the fuzz actions\n * @param synchronizeAtEnd if provided, all client will have all operations delivered from the server at the end of the test\n * @param saveInfo optionally provide an operation number at which a history of all operations will be saved to disk at a given filepath.\n * This can be useful for debugging why a fuzz test may have failed.\n */\nexport async function performFuzzActions(\n\tgenerator: AsyncGenerator<Operation, undefined>,\n\tseed: number,\n\tsynchronizeAtEnd: boolean = true,\n\tsaveInfo?: { saveAt?: number; saveOnFailure: boolean; filepath: string }\n): Promise<Required<FuzzTestState>> {\n\tconst rand = new Prando(seed);\n\n\t// Note: the direct fields of `state` aren't mutated, but it is mutated transitively.\n\tconst state: FuzzTestState = { rand, passiveCollaborators: [], activeCollaborators: [] };\n\tconst { activeCollaborators, passiveCollaborators } = state;\n\tconst operations: Operation[] = [];\n\tfor (\n\t\tlet operation = await generator(state, undefined);\n\t\toperation !== done;\n\t\toperation = await generator(state, undefined)\n\t) {\n\t\toperations.push(operation);\n\t\tif (saveInfo !== undefined && operations.length === saveInfo.saveAt) {\n\t\t\tawait fs.writeFile(saveInfo.filepath, JSON.stringify(operations));\n\t\t}\n\n\t\ttry {\n\t\t\tswitch (operation.type) {\n\t\t\t\tcase 'edit': {\n\t\t\t\t\tconst { index, contents } = operation;\n\t\t\t\t\tconst { tree } = activeCollaborators[index];\n\t\t\t\t\tswitch (contents.fuzzType) {\n\t\t\t\t\t\tcase 'insert':\n\t\t\t\t\t\t\ttree.applyEdit(contents.build, contents.insert);\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'delete':\n\t\t\t\t\t\t\ttree.applyEdit(contents);\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'move':\n\t\t\t\t\t\t\ttree.applyEdit(contents.detach, contents.insert);\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'setPayload':\n\t\t\t\t\t\t\ttree.applyEdit(contents);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tfail('Invalid edit.');\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'join': {\n\t\t\t\t\tconst { isObserver, summarizeHistory, writeFormat } = operation;\n\t\t\t\t\tconst { container, tree, testObjectProvider } = await setUpLocalServerTestSharedTree({\n\t\t\t\t\t\twriteFormat,\n\t\t\t\t\t\tsummarizeHistory,\n\t\t\t\t\t\ttestObjectProvider: state.testObjectProvider,\n\t\t\t\t\t});\n\t\t\t\t\tif (state.testObjectProvider === undefined) {\n\t\t\t\t\t\tstate.testObjectProvider = testObjectProvider;\n\t\t\t\t\t}\n\t\t\t\t\t(isObserver ? passiveCollaborators : activeCollaborators).push({ container, tree });\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'leave': {\n\t\t\t\t\tconst { index, isObserver } = operation;\n\t\t\t\t\tconst treeList = isObserver ? passiveCollaborators : activeCollaborators;\n\t\t\t\t\ttreeList[index].container.close();\n\t\t\t\t\ttreeList.splice(index, 1);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'synchronize': {\n\t\t\t\t\tconst { testObjectProvider } = state;\n\t\t\t\t\tif (testObjectProvider === undefined) {\n\t\t\t\t\t\tfail('Attempted to synchronize with undefined testObjectProvider');\n\t\t\t\t\t}\n\t\t\t\t\tawait testObjectProvider.ensureSynchronized();\n\t\t\t\t\tconst trees = [...state.activeCollaborators, ...state.passiveCollaborators];\n\t\t\t\t\tif (trees.length > 1) {\n\t\t\t\t\t\tconst first = trees[0].tree;\n\t\t\t\t\t\tfor (let i = 1; i < trees.length; i++) {\n\t\t\t\t\t\t\tconst tree = trees[i].tree;\n\t\t\t\t\t\t\tconst editLogA = first.editsInternal as EditLog<ChangeInternal>;\n\t\t\t\t\t\t\tconst editLogB = tree.editsInternal as EditLog<ChangeInternal>;\n\t\t\t\t\t\t\tconst minEdits = Math.min(editLogA.length, editLogB.length);\n\t\t\t\t\t\t\tfor (let j = 0; j < minEdits - 1; j++) {\n\t\t\t\t\t\t\t\tconst editA = await editLogA.getEditAtIndex(editLogA.length - j - 1);\n\t\t\t\t\t\t\t\tconst editB = await editLogB.getEditAtIndex(editLogB.length - j - 1);\n\t\t\t\t\t\t\t\texpect(editA.id).to.equal(editB.id);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\texpect(areRevisionViewsSemanticallyEqual(tree.currentView, tree, first.currentView, first))\n\t\t\t\t\t\t\t\t.to.be.true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new Error('Unknown operation.');\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tconsole.log(`Error encountered on operation number ${operations.length}`);\n\t\t\tif (saveInfo !== undefined && saveInfo.saveOnFailure) {\n\t\t\t\tawait fs.writeFile(saveInfo.filepath, JSON.stringify(operations));\n\t\t\t}\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\tif (synchronizeAtEnd) {\n\t\tawait state.testObjectProvider?.ensureSynchronized();\n\t\tconst trees = [...activeCollaborators.map(({ tree }) => tree), ...passiveCollaborators.map(({ tree }) => tree)];\n\t\tfor (let i = 0; i < trees.length - 1; i++) {\n\t\t\texpect(trees[i].equals(trees[i + 1]));\n\t\t}\n\t}\n\n\treturn state as Required<FuzzTestState>;\n}\n\nexport function runSharedTreeFuzzTests(title: string): void {\n\t// Some useful tips for debugging fuzz tests:\n\t// - A JSON dump of the operation sequence can be written to disk by passing `true` for `saveOnFailure`.\n\t// - Different shared-tree instances can be distinguished (e.g. in logs) by using `tree.getRuntime().clientId`\n\tdescribe(title, () => {\n\t\tfunction runTest(\n\t\t\tgeneratorFactory: () => AsyncGenerator<Operation, undefined>,\n\t\t\tseed: number,\n\t\t\tsaveOnFailure?: boolean\n\t\t): void {\n\t\t\tit(`with seed ${seed}`, async () => {\n\t\t\t\tconst saveInfo =\n\t\t\t\t\tsaveOnFailure !== undefined\n\t\t\t\t\t\t? { filepath: join(directory, `test-history-${seed}.json`), saveOnFailure }\n\t\t\t\t\t\t: undefined;\n\t\t\t\tif (saveInfo !== undefined && !existsSync(directory)) {\n\t\t\t\t\tmkdirSync(directory);\n\t\t\t\t}\n\t\t\t\tawait performFuzzActions(generatorFactory(), seed + adjustSeed, true, saveInfo);\n\t\t\t}).timeout(10000);\n\t\t}\n\n\t\tfunction runMixedVersionTests(summarizeHistory: boolean, testsPerSuite: number): void {\n\t\t\tdescribe('using 0.0.2 and 0.1.1 trees', () => {\n\t\t\t\tfor (let seed = 0; seed < testsPerSuite; seed++) {\n\t\t\t\t\trunTest(\n\t\t\t\t\t\t() => take(1000, makeOpGenerator({ joinConfig: { summarizeHistory: [summarizeHistory] } })),\n\t\t\t\t\t\tseed\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tdescribe('using only version 0.0.2', () => {\n\t\t\t\tfor (let seed = 0; seed < testsPerSuite; seed++) {\n\t\t\t\t\trunTest(\n\t\t\t\t\t\t() =>\n\t\t\t\t\t\t\ttake(\n\t\t\t\t\t\t\t\t1000,\n\t\t\t\t\t\t\t\tmakeOpGenerator({\n\t\t\t\t\t\t\t\t\tjoinConfig: {\n\t\t\t\t\t\t\t\t\t\twriteFormat: [WriteFormat.v0_0_2],\n\t\t\t\t\t\t\t\t\t\tsummarizeHistory: [summarizeHistory],\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\tseed\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tdescribe('using only version 0.1.1', () => {\n\t\t\t\tfor (let seed = 0; seed < testsPerSuite; seed++) {\n\t\t\t\t\trunTest(\n\t\t\t\t\t\t() =>\n\t\t\t\t\t\t\ttake(\n\t\t\t\t\t\t\t\t1000,\n\t\t\t\t\t\t\t\tmakeOpGenerator({\n\t\t\t\t\t\t\t\t\tjoinConfig: {\n\t\t\t\t\t\t\t\t\t\twriteFormat: [WriteFormat.v0_1_1],\n\t\t\t\t\t\t\t\t\t\tsummarizeHistory: [summarizeHistory],\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\tseed\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tdescribe('upgrading halfway through', () => {\n\t\t\t\tconst testLength = 500;\n\t\t\t\tconst maximumActiveCollaborators = 10;\n\t\t\t\tconst maximumPassiveCollaborators = 5;\n\t\t\t\tconst editConfig: EditGenerationConfig = { maxTreeSize: 1000 };\n\t\t\t\tconst generatorFactory = () =>\n\t\t\t\t\tchain(\n\t\t\t\t\t\ttake(\n\t\t\t\t\t\t\ttestLength / 2 - 1,\n\t\t\t\t\t\t\tmakeOpGenerator({\n\t\t\t\t\t\t\t\teditConfig,\n\t\t\t\t\t\t\t\tjoinConfig: {\n\t\t\t\t\t\t\t\t\tmaximumActiveCollaborators,\n\t\t\t\t\t\t\t\t\tmaximumPassiveCollaborators,\n\t\t\t\t\t\t\t\t\twriteFormat: [WriteFormat.v0_0_2],\n\t\t\t\t\t\t\t\t\tsummarizeHistory: [summarizeHistory],\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t),\n\t\t\t\t\t\ttake(\n\t\t\t\t\t\t\t1,\n\t\t\t\t\t\t\tmakeOpGenerator({\n\t\t\t\t\t\t\t\tjoinConfig: {\n\t\t\t\t\t\t\t\t\tmaximumActiveCollaborators: maximumActiveCollaborators + 1,\n\t\t\t\t\t\t\t\t\tmaximumPassiveCollaborators,\n\t\t\t\t\t\t\t\t\twriteFormat: [WriteFormat.v0_1_1],\n\t\t\t\t\t\t\t\t\tsummarizeHistory: [summarizeHistory],\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\teditWeight: 0,\n\t\t\t\t\t\t\t\tjoinWeight: 1,\n\t\t\t\t\t\t\t\tleaveWeight: 0,\n\t\t\t\t\t\t\t\tsynchronizeWeight: 0,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t),\n\t\t\t\t\t\ttake(\n\t\t\t\t\t\t\ttestLength / 2,\n\t\t\t\t\t\t\tmakeOpGenerator({\n\t\t\t\t\t\t\t\teditConfig,\n\t\t\t\t\t\t\t\tjoinConfig: {\n\t\t\t\t\t\t\t\t\tmaximumActiveCollaborators,\n\t\t\t\t\t\t\t\t\tmaximumPassiveCollaborators,\n\t\t\t\t\t\t\t\t\tsummarizeHistory: [summarizeHistory],\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\n\t\t\t\tfor (let seed = 0; seed < testsPerSuite; seed++) {\n\t\t\t\t\trunTest(generatorFactory, seed);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tconst testCount = 1;\n\t\tdescribe('with no-history summarization', () => {\n\t\t\trunMixedVersionTests(false, testCount);\n\t\t});\n\n\t\tdescribe('with history summarization', () => {\n\t\t\trunMixedVersionTests(true, testCount);\n\t\t});\n\t});\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SharedTreeVersioningTests.d.ts","sourceRoot":"","sources":["../../../src/test/utilities/SharedTreeVersioningTests.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"SharedTreeVersioningTests.d.ts","sourceRoot":"","sources":["../../../src/test/utilities/SharedTreeVersioningTests.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAgBH,OAAO,EAIN,2BAA2B,EAC3B,wBAAwB,EAIxB,MAAM,iBAAiB,CAAC;AAOzB;;;GAGG;AACH,wBAAgB,4BAA4B,CAC3C,KAAK,EAAE,MAAM,EACb,mBAAmB,EAAE,CAAC,OAAO,CAAC,EAAE,wBAAwB,KAAK,2BAA2B,QAkexF"}
|
|
@@ -2,14 +2,16 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
+
import { LoaderHeader } from '@fluidframework/container-definitions';
|
|
5
6
|
import { expect } from 'chai';
|
|
6
7
|
import { StableRange, StablePlace, Change } from '../../ChangeTypes';
|
|
8
|
+
import { areRevisionViewsSemanticallyEqual } from '../../EditUtilities';
|
|
7
9
|
import { SharedTreeDiagnosticEvent } from '../../EventTypes';
|
|
8
10
|
import { SharedTreeOpType, WriteFormat } from '../../persisted-types';
|
|
9
11
|
import { TreeNodeHandle } from '../../TreeNodeHandle';
|
|
10
12
|
import { applyTestEdits } from '../Summary.tests';
|
|
11
13
|
import { buildLeaf } from './TestNode';
|
|
12
|
-
import { applyNoop, setUpLocalServerTestSharedTree, setUpTestTree, spyOnSubmittedOps, } from './TestUtilities';
|
|
14
|
+
import { applyNoop, setUpLocalServerTestSharedTree, setUpTestTree, spyOnSubmittedOps, testTrait, waitForSummary, } from './TestUtilities';
|
|
13
15
|
function spyOnVersionChanges(tree) {
|
|
14
16
|
const versions = [];
|
|
15
17
|
tree.on(SharedTreeDiagnosticEvent.WriteVersionChanged, (version) => versions.push(version));
|
|
@@ -295,6 +297,29 @@ export function runSharedTreeVersioningTests(title, setUpTestSharedTree) {
|
|
|
295
297
|
}
|
|
296
298
|
expect(tree1.equals(tree2)).to.be.true;
|
|
297
299
|
});
|
|
300
|
+
it('interns strings correctly after upgrading from 0.0.2', async () => {
|
|
301
|
+
const { testObjectProvider, tree: tree1, container, } = await setUpLocalServerTestSharedTree({
|
|
302
|
+
writeFormat: WriteFormat.v0_0_2,
|
|
303
|
+
summarizeHistory: false,
|
|
304
|
+
});
|
|
305
|
+
const internedDefinition = 'internedDefinition';
|
|
306
|
+
const id = tree1.generateNodeId();
|
|
307
|
+
tree1.applyEdit(...Change.insertTree({ definition: internedDefinition, identifier: id }, StablePlace.atStartOf(testTrait(tree1.currentView))));
|
|
308
|
+
tree1.applyEdit(Change.delete(StableRange.only(id)));
|
|
309
|
+
await testObjectProvider.ensureSynchronized();
|
|
310
|
+
const summaryVersion = await waitForSummary(container);
|
|
311
|
+
const { tree: tree2 } = await setUpLocalServerTestSharedTree({
|
|
312
|
+
writeFormat: WriteFormat.v0_1_1,
|
|
313
|
+
testObjectProvider,
|
|
314
|
+
headers: { [LoaderHeader.version]: summaryVersion },
|
|
315
|
+
});
|
|
316
|
+
await testObjectProvider.ensureSynchronized();
|
|
317
|
+
expect(tree1.getWriteFormat()).to.equal(WriteFormat.v0_1_1);
|
|
318
|
+
expect(tree2.getWriteFormat()).to.equal(WriteFormat.v0_1_1);
|
|
319
|
+
tree1.applyEdit(...Change.insertTree({ definition: internedDefinition, identifier: tree1.generateNodeId() }, StablePlace.atStartOf(testTrait(tree1.currentView))));
|
|
320
|
+
await testObjectProvider.ensureSynchronized();
|
|
321
|
+
expect(areRevisionViewsSemanticallyEqual(tree1.currentView, tree1, tree2.currentView, tree2)).to.be.true;
|
|
322
|
+
}).timeout(10000);
|
|
298
323
|
describe('telemetry', () => {
|
|
299
324
|
const events = [];
|
|
300
325
|
const logger = { send: (event) => events.push(event) };
|