Skip to content

Commit 9601ff4

Browse files
authored
Merge pull request #431 from streamich/traces-2
Update editing traces tests
2 parents 5979096 + 8859b59 commit 9601ff4

File tree

7 files changed

+97
-4
lines changed

7 files changed

+97
-4
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@
117117
"js-base64": "^3.7.2",
118118
"js-sdsl": "^4.4.0",
119119
"jsbi": "^4.3.0",
120-
"json-crdt-traces": "https://github.com/streamich/json-crdt-traces#5f68a13baf798897d39b87d7028b0b3cd5a50a6c",
120+
"json-crdt-traces": "https://github.com/streamich/json-crdt-traces#02718a7a5d09e0dc6c31ea7d45a9ce3cbb0bf085",
121121
"json-logic-js": "^2.0.1",
122122
"json-pack-napi": "^0.0.2",
123123
"load-script": "^2.0.0",
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import * as path from 'path';
2+
import * as fs from 'fs';
3+
import {Patch} from '../../../json-crdt-patch';
4+
import {CborDecoder} from '../../../json-pack/cbor/CborDecoder';
5+
import {Model} from '../../model';
6+
import {bufferToUint8Array} from '../../../util/buffers/bufferToUint8Array';
7+
8+
export const loadFuzzerTrace = (traceName: string): [batch: Patch[], model: Model] => {
9+
const root = path.resolve(__dirname, '..', '..', '..', '..');
10+
const dir = path.join(root, 'node_modules', 'json-crdt-traces', 'traces', 'fuzzer', 'processed', traceName);
11+
const patchFile = path.join(dir, 'patches.bin');
12+
const modelFile = path.join(dir, 'model.bin');
13+
const buf = fs.readFileSync(patchFile);
14+
const modelBuf = bufferToUint8Array(fs.readFileSync(modelFile));
15+
const model = Model.fromBinary(modelBuf);
16+
const cborDecoder = new CborDecoder();
17+
const data = cborDecoder.read(buf) as Uint8Array[];
18+
const batch = data.map((blob) => Patch.fromBinary(blob));
19+
return [batch, model];
20+
};

src/json-crdt/__tests__/editing-traces.spec.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {sequentialTraceNames, traces} from '../__bench__/util/traces';
33
import {editors} from '../__bench__/util/editors';
44
import {Model} from '../model';
55
import {loadConcurrentTrace} from '../__bench__/util/concurrent-trace';
6+
import {loadFuzzerTrace} from '../__bench__/util/fuzzer-traces';
67

78
describe('sequential traces', () => {
89
const editor = editors['json-joy'];
@@ -15,7 +16,7 @@ describe('sequential traces', () => {
1516
}
1617
});
1718

18-
describe.skip('concurrent traces', () => {
19+
describe('concurrent traces', () => {
1920
const traces: string[] = ['friendsforever'];
2021
for (const traceName of traces) {
2122
test(`"${traceName}" trace`, async () => {
@@ -26,3 +27,27 @@ describe.skip('concurrent traces', () => {
2627
});
2728
}
2829
});
30+
31+
describe('fuzzer traces', () => {
32+
const traces = [
33+
<const>'trace-1',
34+
<const>'trace-2',
35+
<const>'trace-3',
36+
<const>'long',
37+
<const>'short',
38+
<const>'low-concurrency',
39+
<const>'high-concurrency',
40+
<const>'str-only',
41+
<const>'bin-only',
42+
];
43+
44+
for (const traceName of traces) {
45+
test(`"${traceName}" trace`, async () => {
46+
const [batch, doc] = loadFuzzerTrace(traceName);
47+
const model = Model.withLogicalClock(1000000);
48+
model.applyBatch(batch);
49+
expect(Model.fromBinary(model.toBinary()).toString()).toBe(doc.toString());
50+
expect(model.view()).toStrictEqual(doc.view());
51+
});
52+
}
53+
});

src/json-crdt/__tests__/fuzzer/JsonCrdtFuzzer.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {FuzzerOptions} from './types';
55
import {RandomJson} from '../../../json-random/RandomJson';
66
import {generateInteger} from './util';
77
import {PatchBuilder} from '../../../json-crdt-patch/PatchBuilder';
8+
import {Patch} from '../../../json-crdt-patch';
89

910
export const defaultFuzzerOptions: FuzzerOptions = {
1011
startingValue: undefined,
@@ -18,12 +19,14 @@ export const defaultFuzzerOptions: FuzzerOptions = {
1819
concurrentPeers: [1, 6],
1920
patchesPerPeer: [0, 12],
2021
testCodecs: true,
22+
collectPatches: false,
2123
};
2224

2325
export class JsonCrdtFuzzer {
2426
public opts: FuzzerOptions;
2527
public model: Model;
2628
public picker: Picker;
29+
public patches: Patch[] = [];
2730

2831
constructor(opts: Partial<FuzzerOptions> = {}) {
2932
this.opts = {...defaultFuzzerOptions, ...opts};
@@ -39,6 +42,7 @@ export class JsonCrdtFuzzer {
3942
const builder = new PatchBuilder(this.model.clock);
4043
builder.root(builder.json(json));
4144
const patch = builder.flush();
45+
this.patches.push(patch);
4246
this.model.applyPatch(patch);
4347
}
4448

@@ -47,6 +51,7 @@ export class JsonCrdtFuzzer {
4751
const session = new SessionLogical(this, concurrency);
4852
session.generateEdits();
4953
session.synchronize();
54+
if (this.opts.collectPatches) for (const patches of session.patches) this.patches.push(...patches);
5055
return session;
5156
}
5257
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/* tslint:disable no-console */
2+
// Run: npx ts-node src/json-crdt/__tests__/fuzzer/generate-trace.ts
3+
4+
import {Patch} from '../../../json-crdt-patch';
5+
import {Model} from '../../model';
6+
import {JsonCrdtFuzzer} from './JsonCrdtFuzzer';
7+
import {CborEncoder} from '../../../json-pack/cbor/CborEncoder';
8+
import {Writer} from '../../../util/buffers/Writer';
9+
import * as fs from 'fs';
10+
11+
const sessionNum = 100;
12+
const fuzzer = new JsonCrdtFuzzer({
13+
// concurrentPeers: [20, 100],
14+
// startingValue: new Uint8Array([1, 2, 3]),
15+
collectPatches: true,
16+
});
17+
fuzzer.setupModel();
18+
19+
for (let ses = 0; ses < sessionNum; ses++) {
20+
fuzzer.executeConcurrentSession();
21+
}
22+
23+
const patches: Patch[] = [];
24+
const dupes: Set<string> = new Set();
25+
for (const patch of fuzzer.patches) {
26+
const key = `${patch.getId()?.sid}_${patch.getId()?.time}`;
27+
if (dupes.has(key)) continue;
28+
dupes.add(key);
29+
patches.push(patch);
30+
}
31+
32+
const model = Model.withLogicalClock();
33+
model.applyBatch(patches);
34+
const cborEncoder = new CborEncoder(new Writer());
35+
fs.writeFileSync(__dirname + '/trace.cbor', cborEncoder.encode(patches.map((p) => p.toBinary())));
36+
37+
// console.log(Buffer.from(jsonEncoder.encode(encoded)).toString());
38+
console.log(model.view());
39+
console.log(fuzzer.model.view());
40+
// console.log(model + '');

src/json-crdt/__tests__/fuzzer/types.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,7 @@ export interface FuzzerOptions {
3434

3535
/** Do not generate "__proto__" as a string, so it does not appear as object key. */
3636
noProtoString?: boolean;
37+
38+
/** Whether to collect all generated patches. */
39+
collectPatches?: boolean;
3740
}

yarn.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3664,9 +3664,9 @@ jsesc@^2.5.1:
36643664
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"
36653665
integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==
36663666

3667-
"json-crdt-traces@https://github.com/streamich/json-crdt-traces#5f68a13baf798897d39b87d7028b0b3cd5a50a6c":
3667+
"json-crdt-traces@https://github.com/streamich/json-crdt-traces#02718a7a5d09e0dc6c31ea7d45a9ce3cbb0bf085":
36683668
version "0.0.1"
3669-
resolved "https://github.com/streamich/json-crdt-traces#5f68a13baf798897d39b87d7028b0b3cd5a50a6c"
3669+
resolved "https://github.com/streamich/json-crdt-traces#02718a7a5d09e0dc6c31ea7d45a9ce3cbb0bf085"
36703670

36713671
json-logic-js@^2.0.1:
36723672
version "2.0.2"

0 commit comments

Comments
 (0)