@rotorsoft/act-tck 1.35.0 → 1.36.0
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/.tsbuildinfo +1 -1
- package/dist/@types/store-property-tck.d.ts +12 -0
- package/dist/@types/store-property-tck.d.ts.map +1 -1
- package/dist/@types/store-tck.d.ts +11 -0
- package/dist/@types/store-tck.d.ts.map +1 -1
- package/dist/index.cjs +132 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +132 -26
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
|
@@ -17,6 +17,18 @@ export type StorePropertyTckOptions = {
|
|
|
17
17
|
factory: () => Store | Promise<Store>;
|
|
18
18
|
/** fast-check runs per property. Default 100; lower for durable adapters. */
|
|
19
19
|
numRuns?: number;
|
|
20
|
+
/**
|
|
21
|
+
* Per-property timeout in milliseconds. Default 5000, matching vitest.
|
|
22
|
+
*
|
|
23
|
+
* Every run of a property is a full reset plus a dozen or more round
|
|
24
|
+
* trips, so against a real database the wall time is dominated by I/O and
|
|
25
|
+
* by whatever else the machine is doing. Vitest's default is comfortable
|
|
26
|
+
* in isolation and not under a parallel suite sharing one server, which
|
|
27
|
+
* showed up as this file intermittently timing out rather than failing an
|
|
28
|
+
* assertion. Durable adapters should raise it; the in-memory store has no
|
|
29
|
+
* reason to.
|
|
30
|
+
*/
|
|
31
|
+
timeoutMs?: number;
|
|
20
32
|
};
|
|
21
33
|
export declare const runStorePropertyTck: (options: StorePropertyTckOptions) => void;
|
|
22
34
|
//# sourceMappingURL=store-property-tck.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store-property-tck.d.ts","sourceRoot":"","sources":["../../src/store-property-tck.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAwClD;;;;;;;;;;GAUG;AACH,MAAM,MAAM,uBAAuB,GAAG;IACpC,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,wEAAwE;IACxE,OAAO,EAAE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IACtC,6EAA6E;IAC7E,OAAO,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"store-property-tck.d.ts","sourceRoot":"","sources":["../../src/store-property-tck.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAwClD;;;;;;;;;;GAUG;AACH,MAAM,MAAM,uBAAuB,GAAG;IACpC,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,wEAAwE;IACxE,OAAO,EAAE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IACtC,6EAA6E;IAC7E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;;;;;OAUG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAkBF,eAAO,MAAM,mBAAmB,YAAa,uBAAuB,KAAG,IAyNtE,CAAC"}
|
|
@@ -26,6 +26,17 @@ export type StoreCapabilities = {
|
|
|
26
26
|
* rollback on mid-iteration throw.
|
|
27
27
|
*/
|
|
28
28
|
readonly restore?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Adapter honours `subscribe`'s optional `correlator` argument and answers
|
|
31
|
+
* `correlating` (#1532). When `true`, the TCK runs the correlation-lease
|
|
32
|
+
* suite — exclusive acquisition, renewal by the same holder, re-acquisition
|
|
33
|
+
* after expiry, per-key independence, and the keyed checkpoint.
|
|
34
|
+
*
|
|
35
|
+
* Optional because a store that ignores the argument simply lets every
|
|
36
|
+
* worker scan, which is the pre-#1532 behaviour and remains correct: the
|
|
37
|
+
* marks are idempotent, so the duplication is waste rather than error.
|
|
38
|
+
*/
|
|
39
|
+
readonly lease_correlation?: boolean;
|
|
29
40
|
/**
|
|
30
41
|
* Adapter supports sensitive-data isolation (#566): accepts the
|
|
31
42
|
* optional `pii` field on commit messages, returns it on load
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store-tck.d.ts","sourceRoot":"","sources":["../../src/store-tck.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAQV,KAAK,EAIN,MAAM,sBAAsB,CAAC;AAc9B;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B;;;;;;;OAOG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC;;;;;;;;;OASG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IACpC;;;;;;;;OAQG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAClC;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IACxC;;;;;;;;OAQG;IACH,QAAQ,CAAC,gCAAgC,CAAC,EAAE,OAAO,CAAC;IACpD;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;;;;OAOG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IAC/C;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IACxD;;OAEG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,iBAAiB,CAAC;CAC3C,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,eAAO,MAAM,WAAW,YAAa,eAAe,KAAG,
|
|
1
|
+
{"version":3,"file":"store-tck.d.ts","sourceRoot":"","sources":["../../src/store-tck.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAQV,KAAK,EAIN,MAAM,sBAAsB,CAAC;AAc9B;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B;;;;;;;;;OASG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IACrC;;;;;;;OAOG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC;;;;;;;;;OASG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IACpC;;;;;;;;OAQG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAClC;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IACxC;;;;;;;;OAQG;IACH,QAAQ,CAAC,gCAAgC,CAAC,EAAE,OAAO,CAAC;IACpD;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;;;;OAOG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IAC/C;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IACxD;;OAEG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,iBAAiB,CAAC;CAC3C,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,eAAO,MAAM,WAAW,YAAa,eAAe,KAAG,IAg2JtD,CAAC"}
|
package/dist/index.cjs
CHANGED
|
@@ -962,6 +962,7 @@ var opArb = import_vitest7.fc.oneof(
|
|
|
962
962
|
var events = (count) => Array.from({ length: count }, () => inc(1));
|
|
963
963
|
var runStorePropertyTck = (options) => {
|
|
964
964
|
const numRuns = options.numRuns ?? 100;
|
|
965
|
+
const timeout = options.timeoutMs ?? 5e3;
|
|
965
966
|
(0, import_vitest8.describe)(`TCK / Store properties / ${options.name}`, () => {
|
|
966
967
|
let store;
|
|
967
968
|
(0, import_vitest8.beforeAll)(async () => {
|
|
@@ -1001,7 +1002,8 @@ var runStorePropertyTck = (options) => {
|
|
|
1001
1002
|
(0, import_vitest8.expect)(e.version).toBe(i);
|
|
1002
1003
|
});
|
|
1003
1004
|
}
|
|
1004
|
-
}
|
|
1005
|
+
},
|
|
1006
|
+
timeout
|
|
1005
1007
|
);
|
|
1006
1008
|
import_vitest7.test.prop([import_vitest7.fc.array(commitArb, { minLength: 1, maxLength: 20 })], {
|
|
1007
1009
|
numRuns
|
|
@@ -1028,7 +1030,8 @@ var runStorePropertyTck = (options) => {
|
|
|
1028
1030
|
).rejects.toThrow();
|
|
1029
1031
|
const after = await collect(store, { stream, stream_exact: true });
|
|
1030
1032
|
(0, import_vitest8.expect)(after.length).toBe(before.length);
|
|
1031
|
-
}
|
|
1033
|
+
},
|
|
1034
|
+
timeout
|
|
1032
1035
|
);
|
|
1033
1036
|
});
|
|
1034
1037
|
(0, import_vitest8.describe)("claim/lease lifecycle invariants", () => {
|
|
@@ -1075,7 +1078,8 @@ var runStorePropertyTck = (options) => {
|
|
|
1075
1078
|
}
|
|
1076
1079
|
}
|
|
1077
1080
|
(0, import_vitest8.expect)(totalResolved + pending.length).toBe(totalClaims);
|
|
1078
|
-
}
|
|
1081
|
+
},
|
|
1082
|
+
timeout
|
|
1079
1083
|
);
|
|
1080
1084
|
import_vitest7.test.prop(
|
|
1081
1085
|
[
|
|
@@ -1118,35 +1122,40 @@ var runStorePropertyTck = (options) => {
|
|
|
1118
1122
|
watermark1.get(lease.stream)
|
|
1119
1123
|
);
|
|
1120
1124
|
}
|
|
1121
|
-
}
|
|
1125
|
+
},
|
|
1126
|
+
timeout
|
|
1122
1127
|
);
|
|
1123
1128
|
import_vitest7.test.prop([import_vitest7.fc.array(claimStreamArb, { minLength: 1, maxLength: 5 })], {
|
|
1124
1129
|
numRuns
|
|
1125
|
-
})(
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
+
})(
|
|
1131
|
+
"blocked streams cannot be claimed again",
|
|
1132
|
+
async (commits) => {
|
|
1133
|
+
await reset2();
|
|
1134
|
+
const streams = [...new Set(commits)];
|
|
1135
|
+
await store.subscribe(streams.map((stream) => ({ stream })));
|
|
1136
|
+
for (const stream of commits) {
|
|
1137
|
+
await store.commit(
|
|
1138
|
+
stream,
|
|
1139
|
+
[inc(1)],
|
|
1140
|
+
make_meta({ stream })
|
|
1141
|
+
);
|
|
1142
|
+
}
|
|
1143
|
+
await mark_all2(store);
|
|
1144
|
+
const claimed = await store.claim(10, 10, "worker", 6e4);
|
|
1145
|
+
await store.block(claimed.map((l) => ({ ...l, error: "test" })));
|
|
1146
|
+
const blockedSet = new Set(claimed.map((l) => l.stream));
|
|
1147
|
+
await store.subscribe([{ stream: "ctrl" }]);
|
|
1130
1148
|
await store.commit(
|
|
1131
|
-
|
|
1149
|
+
"ctrl",
|
|
1132
1150
|
[inc(1)],
|
|
1133
|
-
make_meta({ stream })
|
|
1151
|
+
make_meta({ stream: "ctrl" })
|
|
1134
1152
|
);
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
await store.commit(
|
|
1142
|
-
"ctrl",
|
|
1143
|
-
[inc(1)],
|
|
1144
|
-
make_meta({ stream: "ctrl" })
|
|
1145
|
-
);
|
|
1146
|
-
await mark_all2(store);
|
|
1147
|
-
const reclaim = await store.claim(10, 10, "worker2", 6e4);
|
|
1148
|
-
for (const l of reclaim) (0, import_vitest8.expect)(blockedSet.has(l.stream)).toBe(false);
|
|
1149
|
-
});
|
|
1153
|
+
await mark_all2(store);
|
|
1154
|
+
const reclaim = await store.claim(10, 10, "worker2", 6e4);
|
|
1155
|
+
for (const l of reclaim) (0, import_vitest8.expect)(blockedSet.has(l.stream)).toBe(false);
|
|
1156
|
+
},
|
|
1157
|
+
timeout
|
|
1158
|
+
);
|
|
1150
1159
|
});
|
|
1151
1160
|
});
|
|
1152
1161
|
};
|
|
@@ -4196,6 +4205,103 @@ var runStoreTck = (options) => {
|
|
|
4196
4205
|
}
|
|
4197
4206
|
});
|
|
4198
4207
|
});
|
|
4208
|
+
import_vitest9.describe.skipIf(!caps.lease_correlation)(
|
|
4209
|
+
"correlation lease via subscribe (capability)",
|
|
4210
|
+
() => {
|
|
4211
|
+
const by = () => `corr-${uid()}`;
|
|
4212
|
+
const key = () => `key-${uid()}`;
|
|
4213
|
+
const take = (k, who, millis = 1e4) => store.subscribe([], void 0, { key: k, by: who, millis });
|
|
4214
|
+
const release = async (k, who) => {
|
|
4215
|
+
await take(k, who, 1);
|
|
4216
|
+
await new Promise((r) => setTimeout(r, 20));
|
|
4217
|
+
};
|
|
4218
|
+
(0, import_vitest9.it)("grants the lease to the first caller", async () => {
|
|
4219
|
+
const k = key();
|
|
4220
|
+
const who = by();
|
|
4221
|
+
(0, import_vitest9.expect)((await take(k, who)).correlating).toBe(true);
|
|
4222
|
+
await release(k, who);
|
|
4223
|
+
});
|
|
4224
|
+
(0, import_vitest9.it)("answers undefined when no correlator is supplied", async () => {
|
|
4225
|
+
(0, import_vitest9.expect)(await store.subscribe([])).not.toHaveProperty("correlating");
|
|
4226
|
+
});
|
|
4227
|
+
(0, import_vitest9.it)("refuses a second holder while the lease is live", async () => {
|
|
4228
|
+
const k = key();
|
|
4229
|
+
const who = by();
|
|
4230
|
+
(0, import_vitest9.expect)((await take(k, who)).correlating).toBe(true);
|
|
4231
|
+
(0, import_vitest9.expect)((await take(k, by())).correlating).toBe(false);
|
|
4232
|
+
await release(k, who);
|
|
4233
|
+
});
|
|
4234
|
+
(0, import_vitest9.it)("lets the same holder renew rather than failing", async () => {
|
|
4235
|
+
const k = key();
|
|
4236
|
+
const who = by();
|
|
4237
|
+
(0, import_vitest9.expect)((await take(k, who)).correlating).toBe(true);
|
|
4238
|
+
(0, import_vitest9.expect)((await take(k, who)).correlating).toBe(true);
|
|
4239
|
+
await release(k, who);
|
|
4240
|
+
});
|
|
4241
|
+
(0, import_vitest9.it)("becomes available again once the lease expires", async () => {
|
|
4242
|
+
const k = key();
|
|
4243
|
+
(0, import_vitest9.expect)((await take(k, by(), 1)).correlating).toBe(true);
|
|
4244
|
+
await new Promise((r) => setTimeout(r, 30));
|
|
4245
|
+
const next = by();
|
|
4246
|
+
(0, import_vitest9.expect)((await take(k, next)).correlating).toBe(true);
|
|
4247
|
+
await release(k, next);
|
|
4248
|
+
});
|
|
4249
|
+
(0, import_vitest9.it)("keys leases independently, so one correlator cannot starve another", async () => {
|
|
4250
|
+
const a = key();
|
|
4251
|
+
const b = key();
|
|
4252
|
+
const holder_a = by();
|
|
4253
|
+
const holder_b = by();
|
|
4254
|
+
(0, import_vitest9.expect)((await take(a, holder_a)).correlating).toBe(true);
|
|
4255
|
+
(0, import_vitest9.expect)((await take(b, holder_b)).correlating).toBe(true);
|
|
4256
|
+
await release(a, holder_a);
|
|
4257
|
+
await release(b, holder_b);
|
|
4258
|
+
});
|
|
4259
|
+
(0, import_vitest9.it)("still advances the checkpoint for a caller that loses the lease", async () => {
|
|
4260
|
+
const k = key();
|
|
4261
|
+
const holder = by();
|
|
4262
|
+
(0, import_vitest9.expect)((await take(k, holder)).correlating).toBe(true);
|
|
4263
|
+
const loser = await store.subscribe([], 7777, {
|
|
4264
|
+
key: k,
|
|
4265
|
+
by: by(),
|
|
4266
|
+
millis: 1e4
|
|
4267
|
+
});
|
|
4268
|
+
(0, import_vitest9.expect)(loser.correlating).toBe(false);
|
|
4269
|
+
(0, import_vitest9.expect)(loser.correlated_at).toBeGreaterThanOrEqual(7777);
|
|
4270
|
+
await release(k, holder);
|
|
4271
|
+
});
|
|
4272
|
+
(0, import_vitest9.it)("seeds a new key from the shared floor, then lets it diverge", async () => {
|
|
4273
|
+
const a = key();
|
|
4274
|
+
const holder_a = by();
|
|
4275
|
+
const first = await store.subscribe([], 4100, {
|
|
4276
|
+
key: a,
|
|
4277
|
+
by: holder_a,
|
|
4278
|
+
millis: 1e4
|
|
4279
|
+
});
|
|
4280
|
+
(0, import_vitest9.expect)(first.correlated_at).toBeGreaterThanOrEqual(4100);
|
|
4281
|
+
const b = key();
|
|
4282
|
+
const holder_b = by();
|
|
4283
|
+
const second = await store.subscribe([], void 0, {
|
|
4284
|
+
key: b,
|
|
4285
|
+
by: holder_b,
|
|
4286
|
+
millis: 1e4
|
|
4287
|
+
});
|
|
4288
|
+
(0, import_vitest9.expect)(second.correlated_at).toBeGreaterThanOrEqual(4100);
|
|
4289
|
+
await store.subscribe([], 9e3, {
|
|
4290
|
+
key: a,
|
|
4291
|
+
by: holder_a,
|
|
4292
|
+
millis: 1e4
|
|
4293
|
+
});
|
|
4294
|
+
const b_again = await store.subscribe([], void 0, {
|
|
4295
|
+
key: b,
|
|
4296
|
+
by: holder_b,
|
|
4297
|
+
millis: 1e4
|
|
4298
|
+
});
|
|
4299
|
+
(0, import_vitest9.expect)(b_again.correlated_at).toBe(second.correlated_at);
|
|
4300
|
+
await release(a, holder_a);
|
|
4301
|
+
await release(b, holder_b);
|
|
4302
|
+
});
|
|
4303
|
+
}
|
|
4304
|
+
);
|
|
4199
4305
|
import_vitest9.describe.skipIf(!caps.restore)("restore (capability)", () => {
|
|
4200
4306
|
beforeEach(async () => {
|
|
4201
4307
|
await store.drop();
|