Skip to content

Commit ea3e5d1

Browse files
wip
1 parent b92a838 commit ea3e5d1

File tree

2 files changed

+88
-94
lines changed

2 files changed

+88
-94
lines changed

packages/dds/map/src/test/directoryOracle.ts

Lines changed: 57 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@
22
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
33
* Licensed under the MIT License.
44
*/
5-
6-
/* eslint-disable @typescript-eslint/explicit-function-return-type */
7-
85
import { strict as assert } from "node:assert";
96

7+
import type { IEventThisPlaceHolder } from "@fluidframework/core-interfaces";
8+
109
import type {
1110
IDirectory,
1211
IDirectoryValueChanged,
@@ -28,97 +27,92 @@ export class SharedDirectoryOracle {
2827
this.sharedDir.on("subDirectoryDeleted", this.onSubDirDeleted);
2928
this.sharedDir.on("containedValueChanged", this.onContainedValueChanged);
3029

31-
this.captureInitialSnapshot(sharedDir);
30+
this.takeSnapshot(sharedDir);
3231
}
3332

34-
private captureInitialSnapshot(dir: IDirectory): void {
35-
// Capture keys
33+
private takeSnapshot(dir: ISharedDirectory | IDirectory): void {
3634
for (const [key, value] of dir.entries()) {
37-
const pathKey = dir.absolutePath === "/" ? `/${key}` : `${dir.absolutePath}/${key}`;
38-
39-
this.model.set(pathKey, value);
35+
const fullPath = dir.absolutePath === "/" ? `/${key}` : `${dir.absolutePath}/${key}`;
36+
this.model.set(fullPath, value);
4037
}
4138

4239
for (const [, subDir] of dir.subdirectories()) {
43-
// Just recurse to capture keys inside the subdir
44-
this.captureInitialSnapshot(subDir);
40+
this.takeSnapshot(subDir);
4541
}
4642
}
4743

48-
private readonly onValueChanged = (change: IDirectoryValueChanged) => {
44+
private readonly onValueChanged = (
45+
changed: IDirectoryValueChanged,
46+
local: boolean,
47+
target: IEventThisPlaceHolder,
48+
): void => {
4949
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
50-
const { key, previousValue } = change;
51-
const path = change.path ?? "";
52-
53-
const pathKey = path === "/" ? `/${key}` : `${path}/${key}`;
54-
55-
assert.strictEqual(
56-
previousValue,
57-
this.model.get(pathKey),
58-
`Mismatch on previous value for key="${key}"`,
59-
);
50+
const { path, key, previousValue } = changed;
51+
const fullPath = path === "/" ? `/${key}` : `${path}/${key}`;
52+
53+
if (this.model.has(fullPath)) {
54+
const prevVal = this.model.get(fullPath);
55+
assert.strictEqual(
56+
prevVal,
57+
previousValue,
58+
`previous value mismatch at ${fullPath}: expected: ${prevVal}, actual: ${previousValue}`,
59+
);
60+
}
6061

61-
const fuzzDir = this.sharedDir.getWorkingDirectory(path);
62-
if (!fuzzDir) return;
62+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
63+
const newVal = this.sharedDir.get(fullPath);
6364

64-
if (fuzzDir.has(key)) {
65-
this.model.set(pathKey, fuzzDir.get(key));
65+
if (newVal === undefined) {
66+
// deletion
67+
this.model.delete(fullPath);
6668
} else {
67-
this.model.delete(pathKey);
69+
this.model.set(fullPath, newVal);
6870
}
6971
};
7072

71-
private readonly onClear = (local: boolean) => {
73+
private readonly onClear = (local: boolean, target: IEventThisPlaceHolder): void => {
7274
this.model.clear();
7375
};
7476

7577
private readonly onSubDirCreated = (
76-
subdirName: string,
78+
path: string,
7779
local: boolean,
78-
target: ISharedDirectory,
79-
) => {
80-
const { absolutePath } = target;
81-
if (!this.model.has(`${absolutePath}${subdirName}`)) {
82-
this.model.set(`${absolutePath}${subdirName}`, undefined);
83-
}
80+
target: IEventThisPlaceHolder,
81+
): void => {
82+
this.model.set(path, undefined);
8483
};
8584

86-
private readonly onSubDirDeleted = (path: string) => {
87-
const absPath = path.startsWith("/") ? path : `/${path}`;
88-
for (const key of [...this.model.keys()]) {
89-
if (key.startsWith(absPath)) {
90-
const deleted = this.model.delete(key);
91-
if (!deleted) {
92-
assert("not deleted");
93-
}
94-
}
95-
}
85+
private readonly onSubDirDeleted = (
86+
path: string,
87+
local: boolean,
88+
target: IEventThisPlaceHolder,
89+
): void => {
90+
this.model.delete(path);
9691
};
9792

9893
private readonly onContainedValueChanged = (
99-
change: IValueChanged,
94+
changed: IValueChanged,
10095
local: boolean,
101-
target: IDirectory,
102-
) => {
96+
target: IEventThisPlaceHolder,
97+
): void => {
10398
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
104-
const { key, previousValue } = change;
105-
const { absolutePath } = target;
106-
107-
const pathKey = absolutePath === "/" ? `/${key}` : `${absolutePath}/${key}`;
108-
109-
assert.strictEqual(
110-
previousValue,
111-
this.model.get(pathKey),
112-
`Mismatch on previous value for key="${key}"`,
113-
);
99+
const { key, previousValue } = changed;
100+
101+
if (this.model.has(key)) {
102+
const prevVal = this.model.get(key);
103+
assert.strictEqual(
104+
prevVal,
105+
previousValue,
106+
`contained previous value mismatch at ${key}: expected: ${prevVal}, actual: ${previousValue}`,
107+
);
108+
}
114109

115110
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
116-
const newValue = target.get(key);
117-
118-
if (newValue === undefined) {
119-
this.model.delete(pathKey);
111+
const newVal = this.sharedDir.get(key);
112+
if (newVal === undefined) {
113+
this.model.delete(key);
120114
} else {
121-
this.model.set(pathKey, newValue);
115+
this.model.set(key, newVal);
122116
}
123117
};
124118

packages/dds/map/src/test/mocha/directoryFuzzTests.spec.ts

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -138,39 +138,39 @@ describe("SharedDirectory fuzz", () => {
138138
defaultTestCount: 25,
139139
emitter: oracleEmitter,
140140
// Uncomment this line to replay a specific seed from its failure file:
141-
// replay: 0,
141+
only: 0,
142142
saveFailures: { directory: dirPath.join(_dirname, "../../../src/test/mocha/results/2") },
143143
skip: [],
144144
});
145145

146-
createDDSFuzzSuite(
147-
{ ...baseDirModel, workloadName: "default directory 2 with rebasing" },
148-
{
149-
validationStrategy: {
150-
type: "random",
151-
probability: 0.4,
152-
},
153-
rebaseProbability: 0.2,
154-
reconnectProbability: 0.5,
155-
containerRuntimeOptions: {
156-
flushMode: FlushMode.TurnBased,
157-
enableGroupedBatching: true,
158-
},
159-
numberOfClients: 3,
160-
clientJoinOptions: {
161-
// Note: if tests are slow, we may want to tune this down. This mimics behavior before this suite
162-
// was refactored to use the DDS fuzz harness.
163-
maxNumberOfClients: Number.MAX_SAFE_INTEGER,
164-
clientAddProbability: 0.08,
165-
stashableClientProbability: undefined,
166-
},
167-
defaultTestCount: 200,
168-
emitter: oracleEmitter,
169-
// Uncomment this line to replay a specific seed from its failure file:
170-
// replay: 0,
171-
saveFailures: {
172-
directory: dirPath.join(_dirname, "../../../src/test/mocha/results/2"),
173-
},
174-
},
175-
);
146+
// createDDSFuzzSuite(
147+
// { ...baseDirModel, workloadName: "default directory 2 with rebasing" },
148+
// {
149+
// validationStrategy: {
150+
// type: "random",
151+
// probability: 0.4,
152+
// },
153+
// rebaseProbability: 0.2,
154+
// reconnectProbability: 0.5,
155+
// containerRuntimeOptions: {
156+
// flushMode: FlushMode.TurnBased,
157+
// enableGroupedBatching: true,
158+
// },
159+
// numberOfClients: 3,
160+
// clientJoinOptions: {
161+
// // Note: if tests are slow, we may want to tune this down. This mimics behavior before this suite
162+
// // was refactored to use the DDS fuzz harness.
163+
// maxNumberOfClients: Number.MAX_SAFE_INTEGER,
164+
// clientAddProbability: 0.08,
165+
// stashableClientProbability: undefined,
166+
// },
167+
// defaultTestCount: 200,
168+
// emitter: oracleEmitter,
169+
// // Uncomment this line to replay a specific seed from its failure file:
170+
// // replay: 0,
171+
// saveFailures: {
172+
// directory: dirPath.join(_dirname, "../../../src/test/mocha/results/2"),
173+
// },
174+
// },
175+
// );
176176
});

0 commit comments

Comments
 (0)