@fluid-experimental/tree 1.3.3 → 1.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/id-compressor/IdCompressor.d.ts.map +1 -1
- package/dist/id-compressor/IdCompressor.js +26 -18
- package/dist/id-compressor/IdCompressor.js.map +1 -1
- package/dist/id-compressor/SessionIdNormalizer.d.ts +31 -4
- package/dist/id-compressor/SessionIdNormalizer.d.ts.map +1 -1
- package/dist/id-compressor/SessionIdNormalizer.js +64 -18
- package/dist/id-compressor/SessionIdNormalizer.js.map +1 -1
- package/lib/id-compressor/IdCompressor.d.ts.map +1 -1
- package/lib/id-compressor/IdCompressor.js +26 -18
- package/lib/id-compressor/IdCompressor.js.map +1 -1
- package/lib/id-compressor/SessionIdNormalizer.d.ts +31 -4
- package/lib/id-compressor/SessionIdNormalizer.d.ts.map +1 -1
- package/lib/id-compressor/SessionIdNormalizer.js +64 -18
- package/lib/id-compressor/SessionIdNormalizer.js.map +1 -1
- package/lib/test/IdCompressor.tests.js +210 -87
- package/lib/test/IdCompressor.tests.js.map +1 -1
- package/lib/test/SessionIdNormalizer.tests.js +124 -46
- package/lib/test/SessionIdNormalizer.tests.js.map +1 -1
- package/lib/test/utilities/IdCompressorTestUtilities.d.ts +17 -5
- package/lib/test/utilities/IdCompressorTestUtilities.d.ts.map +1 -1
- package/lib/test/utilities/IdCompressorTestUtilities.js +60 -14
- package/lib/test/utilities/IdCompressorTestUtilities.js.map +1 -1
- package/package.json +17 -17
- package/src/id-compressor/IdCompressor.ts +28 -17
- package/src/id-compressor/SessionIdNormalizer.ts +72 -17
|
@@ -11,12 +11,25 @@ import { SessionIdNormalizer } from '../id-compressor/SessionIdNormalizer';
|
|
|
11
11
|
describe('SessionIdNormalizer', () => {
|
|
12
12
|
it('fails when adding finals with no corresponding locals', () => {
|
|
13
13
|
const normalizer = makeTestNormalizer();
|
|
14
|
-
expect(() => normalizer.addFinalIds(final(0), final(1),
|
|
14
|
+
expect(() => normalizer.addFinalIds(final(0), final(1), dummy)).to.throw('Final IDs must be added to an existing local range.');
|
|
15
15
|
});
|
|
16
16
|
it('fails when adding finals out of order', () => {
|
|
17
17
|
const normalizer = makeTestNormalizer();
|
|
18
18
|
normalizer.addLocalId();
|
|
19
|
-
expect(() => normalizer.addFinalIds(final(1), final(0),
|
|
19
|
+
expect(() => normalizer.addFinalIds(final(1), final(0), dummy)).to.throw('Malformed normalization range.');
|
|
20
|
+
});
|
|
21
|
+
it('fails when registering final blocks with no corresponding locals', () => {
|
|
22
|
+
const normalizer = makeTestNormalizer();
|
|
23
|
+
expect(() => normalizer.registerFinalIdBlock(final(0), 5, dummy)).to.throw('Final ID block should not be registered before any locals.');
|
|
24
|
+
normalizer.addLocalId();
|
|
25
|
+
addFinalIds(normalizer, final(0), final(0));
|
|
26
|
+
expect(() => normalizer.registerFinalIdBlock(final(1), 5, dummy)).to.throw('Final ID block should not be registered without an existing local range.');
|
|
27
|
+
});
|
|
28
|
+
it('fails when registering final blocks with an invalid count', () => {
|
|
29
|
+
const normalizer = makeTestNormalizer();
|
|
30
|
+
normalizer.addLocalId();
|
|
31
|
+
expect(() => normalizer.registerFinalIdBlock(final(1), 0, dummy)).to.throw('Malformed normalization block.');
|
|
32
|
+
expect(() => normalizer.registerFinalIdBlock(final(1), -1, dummy)).to.throw('Malformed normalization block.');
|
|
20
33
|
});
|
|
21
34
|
it('fails when gaps in finals do not align with a local', () => {
|
|
22
35
|
/**
|
|
@@ -30,10 +43,52 @@ describe('SessionIdNormalizer', () => {
|
|
|
30
43
|
const normalizer = makeTestNormalizer();
|
|
31
44
|
normalizer.addLocalId(); // -1
|
|
32
45
|
normalizer.addLocalId(); // -2
|
|
33
|
-
|
|
46
|
+
addFinalIds(normalizer, final(0), final(2));
|
|
34
47
|
normalizer.addLocalId(); // -4
|
|
35
|
-
|
|
36
|
-
expect(() =>
|
|
48
|
+
addFinalIds(normalizer, final(5), final(5));
|
|
49
|
+
expect(() => addFinalIds(normalizer, final(9), final(9))).to.throw('Gaps in final space must align to a local.');
|
|
50
|
+
});
|
|
51
|
+
it('aligns outstanding locals when a block of finals is registered', () => {
|
|
52
|
+
/**
|
|
53
|
+
* Locals: [-1, -2, -3, -4]
|
|
54
|
+
* Finals: [ 0, X, X, X]
|
|
55
|
+
* Calling `registerFinalIdBlock` with first === 3, count === 10 results in the following:
|
|
56
|
+
* Locals: [-1, -2, -3, -4]
|
|
57
|
+
* Finals: [ 0, 3, 4, 5]
|
|
58
|
+
*
|
|
59
|
+
*/
|
|
60
|
+
const normalizer = makeTestNormalizer();
|
|
61
|
+
const local1 = normalizer.addLocalId(); // -1
|
|
62
|
+
const local2 = normalizer.addLocalId(); // -2
|
|
63
|
+
const local3 = normalizer.addLocalId(); // -3
|
|
64
|
+
const local4 = normalizer.addLocalId(); // -4
|
|
65
|
+
normalizer.addFinalIds(final(0), final(0), dummy);
|
|
66
|
+
normalizer.registerFinalIdBlock(final(3), 10, dummy);
|
|
67
|
+
const locals = [local1, local2, local3, local4];
|
|
68
|
+
for (let i = 1; i < locals.length; i++) {
|
|
69
|
+
const expectedFinal = final(i + 2);
|
|
70
|
+
const finalObj = normalizer.getFinalId(locals[i]);
|
|
71
|
+
if (finalObj === undefined) {
|
|
72
|
+
expect.fail();
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
expect(finalObj[0]).to.equal(expectedFinal);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const local5 = normalizer.addLocalId();
|
|
79
|
+
expect(local5).to.equal(-5);
|
|
80
|
+
expect(normalizer.getFinalId(local5)).to.be.undefined;
|
|
81
|
+
});
|
|
82
|
+
it('fails to align a block of finals when there are no outstanding local IDs', () => {
|
|
83
|
+
/**
|
|
84
|
+
* Locals: [-1, X]
|
|
85
|
+
* Finals: [ 0, 1]
|
|
86
|
+
* Calling `registerFinalIdBlock` with first === 5, count === 10 should fail.
|
|
87
|
+
*/
|
|
88
|
+
const normalizer = makeTestNormalizer();
|
|
89
|
+
normalizer.addLocalId(); // -1
|
|
90
|
+
normalizer.addFinalIds(final(0), final(1), dummy);
|
|
91
|
+
expect(() => normalizer.registerFinalIdBlock(final(5), 10, dummy)).to.throw('Final ID block should not be registered without an existing local range.');
|
|
37
92
|
});
|
|
38
93
|
it('fails when attempting to normalize a local ID that was never registered', () => {
|
|
39
94
|
const normalizer = makeTestNormalizer();
|
|
@@ -41,7 +96,7 @@ describe('SessionIdNormalizer', () => {
|
|
|
41
96
|
const local = normalizer.addLocalId();
|
|
42
97
|
const secondLocal = (local - 1);
|
|
43
98
|
expect(() => normalizer.getFinalId(secondLocal)).to.throw('Local ID was never recorded with this normalizer.');
|
|
44
|
-
|
|
99
|
+
addFinalIds(normalizer, final(0), final(5));
|
|
45
100
|
expect(() => normalizer.getFinalId(secondLocal)).to.throw('Local ID was never recorded with this normalizer.');
|
|
46
101
|
});
|
|
47
102
|
itWithNormalizer('can normalize IDs with only local forms', (normalizer) => {
|
|
@@ -56,13 +111,13 @@ describe('SessionIdNormalizer', () => {
|
|
|
56
111
|
});
|
|
57
112
|
itWithNormalizer('can normalize IDs with trailing finals', (normalizer) => {
|
|
58
113
|
normalizer.addLocalId();
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
114
|
+
addFinalIds(normalizer, final(0), final(1));
|
|
115
|
+
addFinalIds(normalizer, final(2), final(3));
|
|
116
|
+
addFinalIds(normalizer, final(4), final(10));
|
|
62
117
|
});
|
|
63
118
|
itWithNormalizer('can normalize IDs with trailing locals', (normalizer) => {
|
|
64
119
|
normalizer.addLocalId();
|
|
65
|
-
|
|
120
|
+
addFinalIds(normalizer, final(0), final(1));
|
|
66
121
|
normalizer.addLocalId();
|
|
67
122
|
normalizer.addLocalId();
|
|
68
123
|
});
|
|
@@ -70,21 +125,21 @@ describe('SessionIdNormalizer', () => {
|
|
|
70
125
|
normalizer.addLocalId();
|
|
71
126
|
normalizer.addLocalId();
|
|
72
127
|
normalizer.addLocalId();
|
|
73
|
-
|
|
74
|
-
|
|
128
|
+
addFinalIds(normalizer, final(0), final(1));
|
|
129
|
+
addFinalIds(normalizer, final(10), final(11));
|
|
75
130
|
});
|
|
76
131
|
itWithNormalizer('can normalize IDs with and without corresponding local forms', (normalizer) => {
|
|
77
132
|
normalizer.addLocalId(); // -1
|
|
78
133
|
normalizer.addLocalId(); // -2
|
|
79
134
|
normalizer.addLocalId(); // -3
|
|
80
|
-
|
|
135
|
+
addFinalIds(normalizer, final(0), final(3));
|
|
81
136
|
normalizer.addLocalId(); // -5
|
|
82
137
|
normalizer.addLocalId(); // -6
|
|
83
|
-
|
|
138
|
+
addFinalIds(normalizer, final(4), final(5));
|
|
84
139
|
normalizer.addLocalId(); // -7
|
|
85
|
-
|
|
140
|
+
addFinalIds(normalizer, final(8), final(9));
|
|
86
141
|
normalizer.addLocalId(); // -9
|
|
87
|
-
|
|
142
|
+
addFinalIds(normalizer, final(14), final(15));
|
|
88
143
|
normalizer.addLocalId(); // -11
|
|
89
144
|
normalizer.addLocalId(); // -12
|
|
90
145
|
});
|
|
@@ -94,11 +149,11 @@ describe('SessionIdNormalizer', () => {
|
|
|
94
149
|
normalizer.addLocalId(); // -3
|
|
95
150
|
normalizer.addLocalId(); // -4
|
|
96
151
|
expect(normalizer.getLastFinalId()).to.be.undefined;
|
|
97
|
-
|
|
152
|
+
addFinalIds(normalizer, final(0), final(1));
|
|
98
153
|
expect(normalizer.getLastFinalId()).to.equal(1);
|
|
99
|
-
|
|
154
|
+
addFinalIds(normalizer, final(2), final(2));
|
|
100
155
|
expect(normalizer.getLastFinalId()).to.equal(2);
|
|
101
|
-
|
|
156
|
+
addFinalIds(normalizer, final(10), final(15));
|
|
102
157
|
expect(normalizer.getLastFinalId()).to.equal(15);
|
|
103
158
|
});
|
|
104
159
|
itWithNormalizer('can normalize IDs after fuzzed inputs', (normalizer) => {
|
|
@@ -199,36 +254,55 @@ function itWithNormalizer(title, itFn) {
|
|
|
199
254
|
expect(roundtripped.equals(normalizer)).to.be.true;
|
|
200
255
|
});
|
|
201
256
|
}
|
|
257
|
+
function addFinalIds(normalizer, firstFinal, lastFinal) {
|
|
258
|
+
normalizer.addFinalIds(firstFinal, lastFinal, dummy);
|
|
259
|
+
}
|
|
202
260
|
function makeNormalizerProxy(normalizer, locals, finals) {
|
|
203
261
|
return new Proxy(normalizer, {
|
|
204
262
|
get(target, property) {
|
|
205
263
|
if (typeof target[property] === 'function') {
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
locals.
|
|
264
|
+
switch (property) {
|
|
265
|
+
case 'addLocalId': {
|
|
266
|
+
return new Proxy(target[property], {
|
|
267
|
+
apply: (func, thisArg, argumentsList) => {
|
|
268
|
+
var _a;
|
|
269
|
+
const local = Reflect.apply(func, thisArg, argumentsList);
|
|
270
|
+
if (locals.length > 0) {
|
|
271
|
+
for (let i = ((_a = locals[locals.length - 1]) !== null && _a !== void 0 ? _a : fail()) - 1; i > local; i--) {
|
|
272
|
+
locals.push(undefined);
|
|
273
|
+
}
|
|
214
274
|
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
}
|
|
231
|
-
}
|
|
275
|
+
locals.push(local);
|
|
276
|
+
return local;
|
|
277
|
+
},
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
case 'addFinalIds': {
|
|
281
|
+
return new Proxy(target[property], {
|
|
282
|
+
apply: (func, thisArg, argumentsList) => {
|
|
283
|
+
const firstFinal = argumentsList[0];
|
|
284
|
+
const lastFinal = argumentsList[1];
|
|
285
|
+
for (let i = firstFinal; i <= lastFinal; i++) {
|
|
286
|
+
finals.push(i);
|
|
287
|
+
}
|
|
288
|
+
return Reflect.apply(func, thisArg, argumentsList);
|
|
289
|
+
},
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
case 'registerFinalIdBlock': {
|
|
293
|
+
return new Proxy(target[property], {
|
|
294
|
+
apply: (func, thisArg, argumentsList) => {
|
|
295
|
+
const firstFinal = argumentsList[0];
|
|
296
|
+
const count = argumentsList[1];
|
|
297
|
+
const usedFinals = Math.max(0, Math.min(locals.length - finals.length, count));
|
|
298
|
+
for (let i = firstFinal; i < usedFinals; i++) {
|
|
299
|
+
finals.push(i);
|
|
300
|
+
}
|
|
301
|
+
return Reflect.apply(func, thisArg, argumentsList);
|
|
302
|
+
},
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
// No default
|
|
232
306
|
}
|
|
233
307
|
}
|
|
234
308
|
return Reflect.get(target, property);
|
|
@@ -259,7 +333,11 @@ function makeOpGenerator(numOperations) {
|
|
|
259
333
|
state.currentFinal += random.integer(1, 4);
|
|
260
334
|
}
|
|
261
335
|
const lastFinal = state.currentFinal + random.integer(0, 10);
|
|
262
|
-
const addFinal = {
|
|
336
|
+
const addFinal = {
|
|
337
|
+
type: 'addFinalIds',
|
|
338
|
+
first: final(state.currentFinal),
|
|
339
|
+
last: final(lastFinal),
|
|
340
|
+
};
|
|
263
341
|
state.currentFinal = lastFinal + 1;
|
|
264
342
|
state.prevWasLocal = false;
|
|
265
343
|
return addFinal;
|
|
@@ -288,7 +366,7 @@ function fuzzNormalizer(normalizerToFuzz, numOperations, seed) {
|
|
|
288
366
|
return state;
|
|
289
367
|
},
|
|
290
368
|
addFinalIds: (state, { first, last }) => {
|
|
291
|
-
state.normalizer.addFinalIds(first, last,
|
|
369
|
+
state.normalizer.addFinalIds(first, last, dummy);
|
|
292
370
|
return state;
|
|
293
371
|
},
|
|
294
372
|
}, initialState);
|
|
@@ -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\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"]}
|
|
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), dummy)).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), dummy)).to.throw('Malformed normalization range.');\n\t});\n\n\tit('fails when registering final blocks with no corresponding locals', () => {\n\t\tconst normalizer = makeTestNormalizer();\n\t\texpect(() => normalizer.registerFinalIdBlock(final(0), 5, dummy)).to.throw(\n\t\t\t'Final ID block should not be registered before any locals.'\n\t\t);\n\t\tnormalizer.addLocalId();\n\t\taddFinalIds(normalizer, final(0), final(0));\n\t\texpect(() => normalizer.registerFinalIdBlock(final(1), 5, dummy)).to.throw(\n\t\t\t'Final ID block should not be registered without an existing local range.'\n\t\t);\n\t});\n\n\tit('fails when registering final blocks with an invalid count', () => {\n\t\tconst normalizer = makeTestNormalizer();\n\t\tnormalizer.addLocalId();\n\t\texpect(() => normalizer.registerFinalIdBlock(final(1), 0, dummy)).to.throw('Malformed normalization block.');\n\t\texpect(() => normalizer.registerFinalIdBlock(final(1), -1, dummy)).to.throw('Malformed normalization block.');\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\taddFinalIds(normalizer, final(0), final(2));\n\t\tnormalizer.addLocalId(); // -4\n\t\taddFinalIds(normalizer, final(5), final(5));\n\t\texpect(() => addFinalIds(normalizer, final(9), final(9))).to.throw(\n\t\t\t'Gaps in final space must align to a local.'\n\t\t);\n\t});\n\n\tit('aligns outstanding locals when a block of finals is registered', () => {\n\t\t/**\n\t\t * Locals: [-1, -2, -3, -4]\n\t\t * Finals: [ 0, X, X, X]\n\t\t * Calling `registerFinalIdBlock` with first === 3, count === 10 results in the following:\n\t\t * Locals: [-1, -2, -3, -4]\n\t\t * Finals: [ 0, 3, 4, 5]\n\t\t *\n\t\t */\n\t\tconst normalizer = makeTestNormalizer();\n\t\tconst local1 = normalizer.addLocalId(); // -1\n\t\tconst local2 = normalizer.addLocalId(); // -2\n\t\tconst local3 = normalizer.addLocalId(); // -3\n\t\tconst local4 = normalizer.addLocalId(); // -4\n\t\tnormalizer.addFinalIds(final(0), final(0), dummy);\n\n\t\tnormalizer.registerFinalIdBlock(final(3), 10, dummy);\n\t\tconst locals = [local1, local2, local3, local4];\n\t\tfor (let i = 1; i < locals.length; i++) {\n\t\t\tconst expectedFinal = final(i + 2);\n\t\t\tconst finalObj = normalizer.getFinalId(locals[i]);\n\t\t\tif (finalObj === undefined) {\n\t\t\t\texpect.fail();\n\t\t\t} else {\n\t\t\t\texpect(finalObj[0]).to.equal(expectedFinal);\n\t\t\t}\n\t\t}\n\n\t\tconst local5 = normalizer.addLocalId();\n\t\texpect(local5).to.equal(-5);\n\t\texpect(normalizer.getFinalId(local5)).to.be.undefined;\n\t});\n\n\tit('fails to align a block of finals when there are no outstanding local IDs', () => {\n\t\t/**\n\t\t * Locals: [-1, X]\n\t\t * Finals: [ 0, 1]\n\t\t * Calling `registerFinalIdBlock` with first === 5, count === 10 should fail.\n\t\t */\n\t\tconst normalizer = makeTestNormalizer();\n\t\tnormalizer.addLocalId(); // -1\n\t\tnormalizer.addFinalIds(final(0), final(1), dummy);\n\n\t\texpect(() => normalizer.registerFinalIdBlock(final(5), 10, dummy)).to.throw(\n\t\t\t'Final ID block should not be registered without an existing local range.'\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\taddFinalIds(normalizer, final(0), final(5));\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\taddFinalIds(normalizer, final(0), final(1));\n\t\taddFinalIds(normalizer, final(2), final(3));\n\t\taddFinalIds(normalizer, final(4), final(10));\n\t});\n\n\titWithNormalizer('can normalize IDs with trailing locals', (normalizer) => {\n\t\tnormalizer.addLocalId();\n\t\taddFinalIds(normalizer, final(0), final(1));\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\taddFinalIds(normalizer, final(0), final(1));\n\t\taddFinalIds(normalizer, final(10), final(11));\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\taddFinalIds(normalizer, final(0), final(3));\n\t\tnormalizer.addLocalId(); // -5\n\t\tnormalizer.addLocalId(); // -6\n\t\taddFinalIds(normalizer, final(4), final(5));\n\t\tnormalizer.addLocalId(); // -7\n\t\taddFinalIds(normalizer, final(8), final(9));\n\t\tnormalizer.addLocalId(); // -9\n\t\taddFinalIds(normalizer, final(14), final(15));\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\taddFinalIds(normalizer, final(0), final(1));\n\t\texpect(normalizer.getLastFinalId()).to.equal(1);\n\t\taddFinalIds(normalizer, final(2), final(2));\n\t\texpect(normalizer.getLastFinalId()).to.equal(2);\n\t\taddFinalIds(normalizer, final(10), final(15));\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 addFinalIds(\n\tnormalizer: SessionIdNormalizer<DummyRange>,\n\tfirstFinal: FinalCompressedId,\n\tlastFinal: FinalCompressedId\n): void {\n\tnormalizer.addFinalIds(firstFinal, lastFinal, dummy);\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\tswitch (property) {\n\t\t\t\t\tcase 'addLocalId': {\n\t\t\t\t\t\treturn new Proxy(target[property], {\n\t\t\t\t\t\t\tapply: (func, thisArg, argumentsList) => {\n\t\t\t\t\t\t\t\tconst local = Reflect.apply(func, thisArg, argumentsList);\n\t\t\t\t\t\t\t\tif (locals.length > 0) {\n\t\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\t\tlocals.push(undefined);\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\tlocals.push(local);\n\t\t\t\t\t\t\t\treturn local;\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\tcase 'addFinalIds': {\n\t\t\t\t\t\treturn new Proxy(target[property], {\n\t\t\t\t\t\t\tapply: (func, thisArg, argumentsList) => {\n\t\t\t\t\t\t\t\tconst firstFinal: FinalCompressedId = argumentsList[0];\n\t\t\t\t\t\t\t\tconst lastFinal: FinalCompressedId = argumentsList[1];\n\t\t\t\t\t\t\t\tfor (let i = firstFinal; i <= lastFinal; i++) {\n\t\t\t\t\t\t\t\t\tfinals.push(i);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treturn Reflect.apply(func, thisArg, argumentsList);\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\tcase 'registerFinalIdBlock': {\n\t\t\t\t\t\treturn new Proxy(target[property], {\n\t\t\t\t\t\t\tapply: (func, thisArg, argumentsList) => {\n\t\t\t\t\t\t\t\tconst firstFinal: FinalCompressedId = argumentsList[0];\n\t\t\t\t\t\t\t\tconst count: FinalCompressedId = argumentsList[1];\n\t\t\t\t\t\t\t\tconst usedFinals = Math.max(0, Math.min(locals.length - finals.length, count));\n\t\t\t\t\t\t\t\tfor (let i = firstFinal; i < usedFinals; i++) {\n\t\t\t\t\t\t\t\t\tfinals.push(i);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treturn Reflect.apply(func, thisArg, argumentsList);\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\t// No default\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 = {\n\t\t\ttype: 'addFinalIds',\n\t\t\tfirst: final(state.currentFinal),\n\t\t\tlast: final(lastFinal),\n\t\t};\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, dummy);\n\t\t\t\treturn state;\n\t\t\t},\n\t\t},\n\t\tinitialState\n\t);\n\treturn initialState.random;\n}\n"]}
|
|
@@ -89,6 +89,10 @@ export declare class IdCompressorTestNetwork {
|
|
|
89
89
|
/** All ids that a client has received from the server, in order. */
|
|
90
90
|
private readonly sequencedIdLogs;
|
|
91
91
|
constructor(initialClusterSize?: number, onIdReceived?: ((network: IdCompressorTestNetwork, clientTo: Client, ids: TestIdData[]) => void) | undefined);
|
|
92
|
+
/**
|
|
93
|
+
* Returns the number of undelivered operations for the given client that are in flight in the network.
|
|
94
|
+
*/
|
|
95
|
+
getPendingOperations(destination: Client): number;
|
|
92
96
|
/**
|
|
93
97
|
* Returns an immutable handle to a compressor in the network.
|
|
94
98
|
*/
|
|
@@ -136,7 +140,11 @@ export declare class IdCompressorTestNetwork {
|
|
|
136
140
|
/**
|
|
137
141
|
* Delivers all undelivered ID ranges and cluster capacity changes from the server to the target clients.
|
|
138
142
|
*/
|
|
139
|
-
deliverOperations(clientTakingDelivery:
|
|
143
|
+
deliverOperations(clientTakingDelivery: Client, opsToDeliver?: number): any;
|
|
144
|
+
/**
|
|
145
|
+
* Delivers all undelivered ID ranges and cluster capacity changes from the server to the target clients.
|
|
146
|
+
*/
|
|
147
|
+
deliverOperations(clientTakingDelivery: DestinationClient): any;
|
|
140
148
|
/**
|
|
141
149
|
* Simulate a client disconnecting (and serializing), then reconnecting (and deserializing)
|
|
142
150
|
*/
|
|
@@ -170,9 +178,13 @@ interface AllocateIds {
|
|
|
170
178
|
[index: number]: string;
|
|
171
179
|
};
|
|
172
180
|
}
|
|
173
|
-
interface
|
|
174
|
-
type: '
|
|
175
|
-
|
|
181
|
+
interface DeliverAllOperations {
|
|
182
|
+
type: 'deliverAllOperations';
|
|
183
|
+
}
|
|
184
|
+
interface DeliverSomeOperations {
|
|
185
|
+
type: 'deliverSomeOperations';
|
|
186
|
+
client: Client;
|
|
187
|
+
count: number;
|
|
176
188
|
}
|
|
177
189
|
interface ChangeCapacity {
|
|
178
190
|
type: 'changeCapacity';
|
|
@@ -191,7 +203,7 @@ interface Reconnect {
|
|
|
191
203
|
interface Validate {
|
|
192
204
|
type: 'validate';
|
|
193
205
|
}
|
|
194
|
-
declare type Operation = AllocateIds |
|
|
206
|
+
declare type Operation = AllocateIds | DeliverSomeOperations | DeliverAllOperations | ChangeCapacity | GenerateUnifyingIds | Reconnect | Validate;
|
|
195
207
|
interface FuzzTestState extends BaseFuzzTestState {
|
|
196
208
|
network: IdCompressorTestNetwork;
|
|
197
209
|
activeClients: Client[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IdCompressorTestUtilities.d.ts","sourceRoot":"","sources":["../../../src/test/utilities/IdCompressorTestUtilities.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EACN,SAAS,EAMT,QAAQ,EAER,iBAAiB,EACjB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAA8B,SAAS,EAAqB,MAAM,cAAc,CAAC;AACxF,OAAO,EAAE,YAAY,EAAa,MAAM,kCAAkC,CAAC;AAC3E,OAAO,EAGN,WAAW,EAGX,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAEN,SAAS,EACT,QAAQ,EACR,wBAAwB,EACxB,aAAa,EACb,mBAAmB,EACnB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EACX,eAAe,EACf,wCAAwC,EACxC,mCAAmC,EACnC,MAAM,qBAAqB,CAAC;AAI7B,2CAA2C;AAC3C,oBAAY,MAAM;IACjB,OAAO,YAAY;IACnB,OAAO,YAAY;IACnB,OAAO,YAAY;CACnB;AAED,mEAAmE;AACnE,oBAAY,cAAc;IACzB,WAAW,gBAAgB;CAC3B;AAED,2CAA2C;AAC3C,oBAAY,UAAU;IACrB,GAAG,QAAQ;CACX;AAED;;;GAGG;AACH,oBAAY,iBAAiB,GAAG,MAAM,GAAG,cAAc,CAAC;AACxD,eAAO,MAAM,iBAAiB;;;;;CAAmC,CAAC;AAElE,4DAA4D;AAC5D,oBAAY,iBAAiB,GAAG,MAAM,GAAG,UAAU,CAAC;AACpD,eAAO,MAAM,iBAAiB;;;;;CAA+B,CAAC;AAE9D;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,eAAe,SAAI,EAAE,aAAa,CAAC,EAAE,aAAa,GAAG,YAAY,CAIjH;AAED;;GAEG;AACH,oBAAY,SAAS,CAAC,CAAC,IAAI,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;AAchD;;GAEG;AACH,eAAO,MAAM,UAAU,sBAAmB,CAAC;AAE3C;;GAEG;AACH,eAAO,MAAM,mBAAmB,wBAIL,CAAC;AAE5B,eAAO,MAAM,cAAc,mDAKE,CAAC;AAE9B,6CAA6C;AAC7C,MAAM,WAAW,oBAChB,SAAQ,IAAI,CACX,YAAY,EACZ,sBAAsB,GAAG,2BAA2B,GAAG,uBAAuB,GAAG,uBAAuB,CACxG;IACD,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;CACjC;AAED,6EAA6E;AAC7E,MAAM,WAAW,UAAU;IAC1B,QAAQ,CAAC,EAAE,EAAE,wBAAwB,CAAC;IACtC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,kBAAkB,EAAE,WAAW,CAAC;IACzC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9C,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;CAC9B;AAED;;;GAGG;AACH,qBAAa,uBAAuB;aAgBlB,kBAAkB;IAClC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC;IAhB/B,2CAA2C;IAC3C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA0B;IACtD,oEAAoE;IACpE,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAGxB;IACT,+HAA+H;IAC/H,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAoB;IACnD,qFAAqF;IACrF,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0B;IACjD,oEAAoE;IACpE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA0B;gBAGzC,kBAAkB,SAAI,EACrB,YAAY,CAAC,aAAY,uBAAuB,YAAY,MAAM,OAAO,UAAU,EAAE,KAAK,IAAI,aAAA;IAmBhH;;OAEG;IACI,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,oBAAoB;IAgB1D;;;OAGG;IACI,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY;IAIxD;;;;OAIG;IACI,0BAA0B,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY;IAI/D;;OAEG;IACI,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,UAAU,EAAE;IAItD;;OAEG;IACI,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,UAAU,EAAE;IAI/D;;OAEG;IACI,oBAAoB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE;IAMlF;;OAEG;IACI,qBAAqB,CAAC,kBAAkB,EAAE,MAAM,GAAG,IAAI;IAI9D,OAAO,CAAC,QAAQ;IAwBhB;;;OAGG;IACI,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,mBAAmB,EAAE;IAEhF;;;OAGG;IACI,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE;QAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,GAAG,eAAe;IAsClH;;OAEG;IACI,iBAAiB,CAAC,oBAAoB,EAAE,iBAAiB;
|
|
1
|
+
{"version":3,"file":"IdCompressorTestUtilities.d.ts","sourceRoot":"","sources":["../../../src/test/utilities/IdCompressorTestUtilities.ts"],"names":[],"mappings":"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"}
|
|
@@ -89,6 +89,12 @@ export class IdCompressorTestNetwork {
|
|
|
89
89
|
this.idLogs = clientIds;
|
|
90
90
|
this.sequencedIdLogs = clientSequencedIds;
|
|
91
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Returns the number of undelivered operations for the given client that are in flight in the network.
|
|
94
|
+
*/
|
|
95
|
+
getPendingOperations(destination) {
|
|
96
|
+
return this.serverOperations.length - this.clientProgress.get(destination);
|
|
97
|
+
}
|
|
92
98
|
/**
|
|
93
99
|
* Returns an immutable handle to a compressor in the network.
|
|
94
100
|
*/
|
|
@@ -200,10 +206,21 @@ export class IdCompressorTestNetwork {
|
|
|
200
206
|
/**
|
|
201
207
|
* Delivers all undelivered ID ranges and cluster capacity changes from the server to the target clients.
|
|
202
208
|
*/
|
|
203
|
-
deliverOperations(clientTakingDelivery) {
|
|
209
|
+
deliverOperations(clientTakingDelivery, opsToDeliver) {
|
|
204
210
|
var _a;
|
|
211
|
+
let opIndexBound;
|
|
212
|
+
if (clientTakingDelivery === DestinationClient.All) {
|
|
213
|
+
assert(opsToDeliver === undefined);
|
|
214
|
+
opIndexBound = this.serverOperations.length;
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
opIndexBound =
|
|
218
|
+
opsToDeliver !== undefined
|
|
219
|
+
? this.clientProgress.get(clientTakingDelivery) + opsToDeliver
|
|
220
|
+
: this.serverOperations.length;
|
|
221
|
+
}
|
|
205
222
|
for (const [clientTo, compressorTo] of this.getTargetCompressors(clientTakingDelivery)) {
|
|
206
|
-
for (let i = this.clientProgress.get(clientTo); i <
|
|
223
|
+
for (let i = this.clientProgress.get(clientTo); i < opIndexBound; i++) {
|
|
207
224
|
const operation = this.serverOperations[i];
|
|
208
225
|
if (typeof operation === 'number') {
|
|
209
226
|
compressorTo.clusterCapacity = operation;
|
|
@@ -230,7 +247,7 @@ export class IdCompressorTestNetwork {
|
|
|
230
247
|
}
|
|
231
248
|
}
|
|
232
249
|
}
|
|
233
|
-
this.clientProgress.set(clientTo,
|
|
250
|
+
this.clientProgress.set(clientTo, opIndexBound);
|
|
234
251
|
}
|
|
235
252
|
}
|
|
236
253
|
/**
|
|
@@ -246,6 +263,15 @@ export class IdCompressorTestNetwork {
|
|
|
246
263
|
*/
|
|
247
264
|
assertNetworkState() {
|
|
248
265
|
const sequencedLogs = Object.values(Client).map((client) => [this.compressors.get(client), this.getSequencedIdLog(client)]);
|
|
266
|
+
// First, ensure all clients each generated a unique ID for each of their own calls to generate.
|
|
267
|
+
for (const [compressor, ids] of sequencedLogs) {
|
|
268
|
+
const uuids = new Set();
|
|
269
|
+
for (const idData of ids) {
|
|
270
|
+
const uuid = compressor.decompress(idData.id);
|
|
271
|
+
expect(!uuids.has(uuid), 'Duplicate UUID generated.');
|
|
272
|
+
uuids.add(uuid);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
249
275
|
const maxLogLength = sequencedLogs.map(([_, data]) => data.length).reduce((p, n) => Math.max(p, n));
|
|
250
276
|
function getNextLogWithEntryAt(logsIndex, entryIndex) {
|
|
251
277
|
for (let i = logsIndex; i < sequencedLogs.length; i++) {
|
|
@@ -383,17 +409,17 @@ export function expectSerializes(compressor) {
|
|
|
383
409
|
const chainProcessed = [...chainCount];
|
|
384
410
|
for (const cluster of serialized.clusters) {
|
|
385
411
|
const [sessionIndex] = cluster;
|
|
386
|
-
expect(sessionIndex < serialized.sessions.length);
|
|
412
|
+
expect(sessionIndex < serialized.sessions.length).to.be.true;
|
|
387
413
|
chainCount[sessionIndex]++;
|
|
388
414
|
}
|
|
389
415
|
for (const cluster of serialized.clusters) {
|
|
390
416
|
const [sessionIndex, capacity, maybeSize] = cluster;
|
|
391
417
|
const chainIndex = chainProcessed[sessionIndex];
|
|
392
418
|
if (chainIndex < chainCount[sessionIndex] - 1) {
|
|
393
|
-
expect(maybeSize
|
|
419
|
+
expect(typeof maybeSize !== 'number').to.be.true;
|
|
394
420
|
}
|
|
395
421
|
else {
|
|
396
|
-
expect(maybeSize === undefined || typeof maybeSize !== 'number' || maybeSize < capacity);
|
|
422
|
+
expect(maybeSize === undefined || typeof maybeSize !== 'number' || maybeSize < capacity).to.be.true;
|
|
397
423
|
}
|
|
398
424
|
chainProcessed[sessionIndex]++;
|
|
399
425
|
}
|
|
@@ -452,10 +478,25 @@ export function makeOpGenerator(options) {
|
|
|
452
478
|
newSize: Math.min(Math.floor(random.real(0, 1) ** 2 * maxClusterSize) + 1, maxClusterSize),
|
|
453
479
|
};
|
|
454
480
|
}
|
|
455
|
-
function
|
|
481
|
+
function deliverAllOperationsGenerator() {
|
|
456
482
|
return {
|
|
457
|
-
type: '
|
|
458
|
-
|
|
483
|
+
type: 'deliverAllOperations',
|
|
484
|
+
};
|
|
485
|
+
}
|
|
486
|
+
function deliverSomeOperationsGenerator({ random, selectableClients, network, }) {
|
|
487
|
+
const pendingClients = selectableClients.filter((c) => network.getPendingOperations(c) > 0);
|
|
488
|
+
if (pendingClients.length === 0) {
|
|
489
|
+
return {
|
|
490
|
+
type: 'deliverSomeOperations',
|
|
491
|
+
client: random.pick(selectableClients),
|
|
492
|
+
count: 0,
|
|
493
|
+
};
|
|
494
|
+
}
|
|
495
|
+
const client = random.pick(pendingClients);
|
|
496
|
+
return {
|
|
497
|
+
type: 'deliverSomeOperations',
|
|
498
|
+
client,
|
|
499
|
+
count: random.integer(1, network.getPendingOperations(client)),
|
|
459
500
|
};
|
|
460
501
|
}
|
|
461
502
|
function generateUnifyingIdsGenerator({ activeClients, random }) {
|
|
@@ -468,9 +509,10 @@ export function makeOpGenerator(options) {
|
|
|
468
509
|
}
|
|
469
510
|
return interleave(createWeightedGenerator([
|
|
470
511
|
[changeCapacityGenerator, 1],
|
|
471
|
-
[allocateIdsGenerator,
|
|
472
|
-
[
|
|
473
|
-
[
|
|
512
|
+
[allocateIdsGenerator, 16],
|
|
513
|
+
[deliverAllOperationsGenerator, 2],
|
|
514
|
+
[deliverSomeOperationsGenerator, 6],
|
|
515
|
+
[generateUnifyingIdsGenerator, 2],
|
|
474
516
|
[reconnectGenerator, 1],
|
|
475
517
|
]), take(1, repeat({ type: 'validate' })), validateInterval);
|
|
476
518
|
}
|
|
@@ -502,8 +544,12 @@ export function performFuzzActions(generator, network, seed, observerClient, syn
|
|
|
502
544
|
network.enqueueCapacityChange(op.newSize);
|
|
503
545
|
return Object.assign(Object.assign({}, state), { clusterSize: op.newSize });
|
|
504
546
|
},
|
|
505
|
-
|
|
506
|
-
network.deliverOperations(op.client);
|
|
547
|
+
deliverSomeOperations: (state, op) => {
|
|
548
|
+
network.deliverOperations(op.client, op.count);
|
|
549
|
+
return state;
|
|
550
|
+
},
|
|
551
|
+
deliverAllOperations: (state) => {
|
|
552
|
+
network.deliverOperations(DestinationClient.All);
|
|
507
553
|
return state;
|
|
508
554
|
},
|
|
509
555
|
generateUnifyingIds: (state, { clientA, clientB, uuid }) => {
|