rivetkit 2.1.2 → 2.1.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/browser/client.d.ts +11 -0
- package/dist/browser/client.js +1 -1
- package/dist/browser/client.js.map +1 -1
- package/dist/browser/inspector/client.js +1 -1
- package/dist/browser/inspector/client.js.map +1 -1
- package/dist/inspector.tar.gz +0 -0
- package/dist/tsup/{chunk-MNS5LY6M.cjs → chunk-3B6PCYJB.cjs} +280 -115
- package/dist/tsup/chunk-3B6PCYJB.cjs.map +1 -0
- package/dist/tsup/{chunk-YQ5P6KMN.js → chunk-3GTO6H3E.js} +12 -5
- package/dist/tsup/chunk-3GTO6H3E.js.map +1 -0
- package/dist/tsup/{chunk-RMJJE43B.cjs → chunk-4KSHPFXF.cjs} +2 -2
- package/dist/tsup/{chunk-RMJJE43B.cjs.map → chunk-4KSHPFXF.cjs.map} +1 -1
- package/dist/tsup/{chunk-PW3YONDJ.js → chunk-5UEFNG7P.js} +2 -2
- package/dist/tsup/{chunk-PSUVV4HM.js → chunk-ANKZ2FS6.js} +2 -4
- package/dist/tsup/chunk-ANKZ2FS6.js.map +1 -0
- package/dist/tsup/{chunk-GVQAVU7R.cjs → chunk-AQD4CBZ2.cjs} +4 -4
- package/dist/tsup/{chunk-GVQAVU7R.cjs.map → chunk-AQD4CBZ2.cjs.map} +1 -1
- package/dist/tsup/{chunk-WUXR722E.js → chunk-DZXDUGLL.js} +2 -2
- package/dist/tsup/{chunk-WUXR722E.js.map → chunk-DZXDUGLL.js.map} +1 -1
- package/dist/tsup/{chunk-NXEHFUDB.cjs → chunk-GXRVSSVD.cjs} +28 -21
- package/dist/tsup/chunk-GXRVSSVD.cjs.map +1 -0
- package/dist/tsup/{chunk-UZV7NXC6.cjs → chunk-H5TSEPN4.cjs} +30 -30
- package/dist/tsup/{chunk-UZV7NXC6.cjs.map → chunk-H5TSEPN4.cjs.map} +1 -1
- package/dist/tsup/{chunk-TDFDR7AO.js → chunk-HBYEYBIC.js} +2 -2
- package/dist/tsup/{chunk-772NPMTY.cjs → chunk-HKOSZKKZ.cjs} +263 -299
- package/dist/tsup/chunk-HKOSZKKZ.cjs.map +1 -0
- package/dist/tsup/{chunk-HB4RGGMC.js → chunk-I6PL6QIY.js} +5 -5
- package/dist/tsup/{chunk-RHUII57M.js → chunk-KTWY3K6Z.js} +23 -12
- package/dist/tsup/chunk-KTWY3K6Z.js.map +1 -0
- package/dist/tsup/{chunk-HFWRHT5T.cjs → chunk-LK36OGGO.cjs} +3 -5
- package/dist/tsup/chunk-LK36OGGO.cjs.map +1 -0
- package/dist/tsup/{chunk-BSIJG3LG.js → chunk-M6H4XIF4.js} +179 -215
- package/dist/tsup/chunk-M6H4XIF4.js.map +1 -0
- package/dist/tsup/{chunk-ZHQDRRMY.cjs → chunk-QPADHLDU.cjs} +3 -3
- package/dist/tsup/{chunk-ZHQDRRMY.cjs.map → chunk-QPADHLDU.cjs.map} +1 -1
- package/dist/tsup/{chunk-BFI4LYS2.js → chunk-TEFYRRAK.js} +4 -4
- package/dist/tsup/{chunk-PZAV6PP2.cjs → chunk-TEUL4UYN.cjs} +152 -152
- package/dist/tsup/{chunk-PZAV6PP2.cjs.map → chunk-TEUL4UYN.cjs.map} +1 -1
- package/dist/tsup/{chunk-VMX4I4MP.js → chunk-UDMRZR6A.js} +212 -47
- package/dist/tsup/chunk-UDMRZR6A.js.map +1 -0
- package/dist/tsup/{chunk-QABDKI3W.cjs → chunk-UWAGLDT6.cjs} +263 -252
- package/dist/tsup/chunk-UWAGLDT6.cjs.map +1 -0
- package/dist/tsup/client/mod.cjs +6 -6
- package/dist/tsup/client/mod.d.cts +2 -2
- package/dist/tsup/client/mod.d.ts +2 -2
- package/dist/tsup/client/mod.js +5 -5
- package/dist/tsup/common/log.cjs +2 -2
- package/dist/tsup/common/log.js +1 -1
- package/dist/tsup/common/websocket.cjs +3 -3
- package/dist/tsup/common/websocket.js +2 -2
- package/dist/tsup/{config-P3XujgRr.d.ts → config-Qj-zLJPc.d.ts} +11 -0
- package/dist/tsup/{config-_gfywqqI.d.cts → config-iPj5l1bL.d.cts} +11 -0
- package/dist/tsup/{context-uNA4TRn3.d.ts → context-CQCMuHND.d.ts} +1 -1
- package/dist/tsup/{context-Bxd8Cx4H.d.cts → context-DzvH1PBK.d.cts} +1 -1
- package/dist/tsup/{driver-CPGHKXyh.d.ts → driver-Jo8v-kbU.d.ts} +1 -1
- package/dist/tsup/driver-helpers/mod.cjs +4 -4
- package/dist/tsup/driver-helpers/mod.d.cts +4 -4
- package/dist/tsup/driver-helpers/mod.d.ts +4 -4
- package/dist/tsup/driver-helpers/mod.js +3 -3
- package/dist/tsup/{driver-BcLvZcKl.d.cts → driver-iV8J-WMv.d.cts} +1 -1
- package/dist/tsup/driver-test-suite/mod.cjs +556 -333
- package/dist/tsup/driver-test-suite/mod.cjs.map +1 -1
- package/dist/tsup/driver-test-suite/mod.d.cts +2 -2
- package/dist/tsup/driver-test-suite/mod.d.ts +2 -2
- package/dist/tsup/driver-test-suite/mod.js +1332 -1109
- package/dist/tsup/driver-test-suite/mod.js.map +1 -1
- package/dist/tsup/inspector/mod.cjs +3 -3
- package/dist/tsup/inspector/mod.js +2 -2
- package/dist/tsup/mod.cjs +8 -8
- package/dist/tsup/mod.d.cts +5 -5
- package/dist/tsup/mod.d.ts +5 -5
- package/dist/tsup/mod.js +7 -7
- package/dist/tsup/serve-test-suite/mod.cjs +194 -100
- package/dist/tsup/serve-test-suite/mod.cjs.map +1 -1
- package/dist/tsup/serve-test-suite/mod.js +105 -11
- package/dist/tsup/serve-test-suite/mod.js.map +1 -1
- package/dist/tsup/test/mod.cjs +10 -10
- package/dist/tsup/test/mod.d.cts +1 -1
- package/dist/tsup/test/mod.d.ts +1 -1
- package/dist/tsup/test/mod.js +6 -6
- package/dist/tsup/utils.cjs +2 -2
- package/dist/tsup/utils.js +1 -1
- package/dist/tsup/workflow/mod.cjs +5 -5
- package/dist/tsup/workflow/mod.d.cts +3 -3
- package/dist/tsup/workflow/mod.d.ts +3 -3
- package/dist/tsup/workflow/mod.js +4 -4
- package/package.json +5 -5
- package/src/actor/config.ts +0 -2
- package/src/actor/instance/mod.ts +30 -6
- package/src/actor/router.ts +9 -6
- package/src/driver-test-suite/mod.ts +3 -0
- package/src/driver-test-suite/tests/actor-db.ts +299 -216
- package/src/driver-test-suite/tests/actor-driver.ts +4 -0
- package/src/driver-test-suite/tests/actor-lifecycle.ts +157 -0
- package/src/driver-test-suite/tests/actor-queue.ts +10 -9
- package/src/driver-test-suite/tests/actor-workflow.ts +12 -2
- package/src/driver-test-suite/tests/conn-error-serialization.ts +64 -0
- package/src/driver-test-suite/utils.ts +8 -8
- package/src/drivers/engine/actor-driver.ts +113 -11
- package/src/manager/router.ts +20 -6
- package/src/{registry → utils}/serve.ts +38 -4
- package/src/workflow/context.ts +4 -0
- package/src/workflow/driver.ts +4 -1
- package/dist/tsup/chunk-772NPMTY.cjs.map +0 -1
- package/dist/tsup/chunk-BSIJG3LG.js.map +0 -1
- package/dist/tsup/chunk-HFWRHT5T.cjs.map +0 -1
- package/dist/tsup/chunk-MNS5LY6M.cjs.map +0 -1
- package/dist/tsup/chunk-NXEHFUDB.cjs.map +0 -1
- package/dist/tsup/chunk-PSUVV4HM.js.map +0 -1
- package/dist/tsup/chunk-QABDKI3W.cjs.map +0 -1
- package/dist/tsup/chunk-RHUII57M.js.map +0 -1
- package/dist/tsup/chunk-VMX4I4MP.js.map +0 -1
- package/dist/tsup/chunk-YQ5P6KMN.js.map +0 -1
- /package/dist/tsup/{chunk-PW3YONDJ.js.map → chunk-5UEFNG7P.js.map} +0 -0
- /package/dist/tsup/{chunk-TDFDR7AO.js.map → chunk-HBYEYBIC.js.map} +0 -0
- /package/dist/tsup/{chunk-HB4RGGMC.js.map → chunk-I6PL6QIY.js.map} +0 -0
- /package/dist/tsup/{chunk-BFI4LYS2.js.map → chunk-TEFYRRAK.js.map} +0 -0
|
@@ -4,20 +4,20 @@ import {
|
|
|
4
4
|
SLEEP_TIMEOUT,
|
|
5
5
|
WORKFLOW_QUEUE_NAME,
|
|
6
6
|
logger
|
|
7
|
-
} from "../chunk-
|
|
8
|
-
import "../chunk-
|
|
9
|
-
import "../chunk-
|
|
10
|
-
import "../chunk-
|
|
11
|
-
import "../chunk-
|
|
7
|
+
} from "../chunk-TEFYRRAK.js";
|
|
8
|
+
import "../chunk-3GTO6H3E.js";
|
|
9
|
+
import "../chunk-HBYEYBIC.js";
|
|
10
|
+
import "../chunk-M6H4XIF4.js";
|
|
11
|
+
import "../chunk-KTWY3K6Z.js";
|
|
12
12
|
import {
|
|
13
13
|
ActorError,
|
|
14
14
|
ClientConfigSchema,
|
|
15
15
|
createClient,
|
|
16
16
|
createClientWithDriver
|
|
17
|
-
} from "../chunk-
|
|
17
|
+
} from "../chunk-I6PL6QIY.js";
|
|
18
18
|
import {
|
|
19
19
|
importWebSocket
|
|
20
|
-
} from "../chunk-
|
|
20
|
+
} from "../chunk-5UEFNG7P.js";
|
|
21
21
|
import "../chunk-KJSYAUOM.js";
|
|
22
22
|
import "../chunk-N4KRDJ56.js";
|
|
23
23
|
import {
|
|
@@ -29,14 +29,14 @@ import {
|
|
|
29
29
|
WS_PROTOCOL_TARGET,
|
|
30
30
|
WS_TEST_PROTOCOL_PATH,
|
|
31
31
|
buildManagerRouter
|
|
32
|
-
} from "../chunk-
|
|
32
|
+
} from "../chunk-UDMRZR6A.js";
|
|
33
33
|
import "../chunk-LXUQ667X.js";
|
|
34
34
|
import {
|
|
35
35
|
assertUnreachable
|
|
36
|
-
} from "../chunk-
|
|
36
|
+
} from "../chunk-ANKZ2FS6.js";
|
|
37
37
|
import {
|
|
38
38
|
noopNext
|
|
39
|
-
} from "../chunk-
|
|
39
|
+
} from "../chunk-DZXDUGLL.js";
|
|
40
40
|
import {
|
|
41
41
|
INTERNAL_ERROR_CODE,
|
|
42
42
|
INTERNAL_ERROR_DESCRIPTION
|
|
@@ -47,7 +47,7 @@ import "../chunk-424PT5DM.js";
|
|
|
47
47
|
import { serve as honoServe } from "@hono/node-server";
|
|
48
48
|
import { createNodeWebSocket } from "@hono/node-ws";
|
|
49
49
|
import invariant2 from "invariant";
|
|
50
|
-
import { describe as
|
|
50
|
+
import { describe as describe31 } from "vitest";
|
|
51
51
|
|
|
52
52
|
// src/driver-test-suite/tests/action-features.ts
|
|
53
53
|
import { describe, expect, test } from "vitest";
|
|
@@ -243,10 +243,6 @@ async function setupDriverTest(c, driverTestConfig) {
|
|
|
243
243
|
vi.setSystemTime(FAKE_TIME);
|
|
244
244
|
}
|
|
245
245
|
const { endpoint, namespace, runnerName, cleanup } = await driverTestConfig.start();
|
|
246
|
-
c.onTestFinished(() => {
|
|
247
|
-
logger().info("cleaning up test");
|
|
248
|
-
cleanup();
|
|
249
|
-
});
|
|
250
246
|
let client;
|
|
251
247
|
if (driverTestConfig.clientType === "http") {
|
|
252
248
|
client = createClient({
|
|
@@ -269,9 +265,13 @@ async function setupDriverTest(c, driverTestConfig) {
|
|
|
269
265
|
} else {
|
|
270
266
|
assertUnreachable(driverTestConfig.clientType);
|
|
271
267
|
}
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
268
|
+
c.onTestFinished(async () => {
|
|
269
|
+
if (!driverTestConfig.HACK_skipCleanupNet) {
|
|
270
|
+
await client.dispose();
|
|
271
|
+
}
|
|
272
|
+
logger().info("cleaning up test");
|
|
273
|
+
await cleanup();
|
|
274
|
+
});
|
|
275
275
|
return {
|
|
276
276
|
client,
|
|
277
277
|
endpoint
|
|
@@ -1247,6 +1247,7 @@ var HIGH_VOLUME_COUNT = 1e3;
|
|
|
1247
1247
|
var SLEEP_WAIT_MS = 150;
|
|
1248
1248
|
var LIFECYCLE_POLL_INTERVAL_MS = 25;
|
|
1249
1249
|
var LIFECYCLE_POLL_ATTEMPTS = 40;
|
|
1250
|
+
var REAL_TIMER_DB_TIMEOUT_MS = 18e4;
|
|
1250
1251
|
var CHUNK_BOUNDARY_SIZES = [
|
|
1251
1252
|
CHUNK_SIZE - 1,
|
|
1252
1253
|
CHUNK_SIZE,
|
|
@@ -1271,302 +1272,419 @@ function getDbActor(client, variant) {
|
|
|
1271
1272
|
}
|
|
1272
1273
|
function runActorDbTests(driverTestConfig) {
|
|
1273
1274
|
const variants = ["raw", "drizzle"];
|
|
1275
|
+
const dbTestTimeout = driverTestConfig.useRealTimers ? REAL_TIMER_DB_TIMEOUT_MS : void 0;
|
|
1276
|
+
const lifecycleTestTimeout = driverTestConfig.useRealTimers ? REAL_TIMER_DB_TIMEOUT_MS : void 0;
|
|
1274
1277
|
for (const variant of variants) {
|
|
1275
1278
|
describe6(`Actor Database (${variant}) Tests`, () => {
|
|
1276
|
-
test6(
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1279
|
+
test6(
|
|
1280
|
+
"bootstraps schema on startup",
|
|
1281
|
+
async (c) => {
|
|
1282
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1283
|
+
const actor = getDbActor(client, variant).getOrCreate([
|
|
1284
|
+
`db-${variant}-bootstrap-${crypto.randomUUID()}`
|
|
1285
|
+
]);
|
|
1286
|
+
const count = await actor.getCount();
|
|
1287
|
+
expect6(count).toBe(0);
|
|
1288
|
+
},
|
|
1289
|
+
dbTestTimeout
|
|
1290
|
+
);
|
|
1291
|
+
test6(
|
|
1292
|
+
"supports CRUD, raw SQL, and multi-statement exec",
|
|
1293
|
+
async (c) => {
|
|
1294
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1295
|
+
const actor = getDbActor(client, variant).getOrCreate([
|
|
1296
|
+
`db-${variant}-crud-${crypto.randomUUID()}`
|
|
1297
|
+
]);
|
|
1298
|
+
await actor.reset();
|
|
1299
|
+
const first = await actor.insertValue("alpha");
|
|
1300
|
+
const second = await actor.insertValue("beta");
|
|
1301
|
+
const values = await actor.getValues();
|
|
1302
|
+
expect6(values.length).toBeGreaterThanOrEqual(2);
|
|
1303
|
+
expect6(values.some((row) => row.value === "alpha")).toBeTruthy();
|
|
1304
|
+
expect6(values.some((row) => row.value === "beta")).toBeTruthy();
|
|
1305
|
+
await actor.updateValue(first.id, "alpha-updated");
|
|
1306
|
+
const updated = await actor.getValue(first.id);
|
|
1307
|
+
expect6(updated).toBe("alpha-updated");
|
|
1308
|
+
await actor.deleteValue(second.id);
|
|
1309
|
+
const count = await actor.getCount();
|
|
1310
|
+
if (driverTestConfig.useRealTimers) {
|
|
1311
|
+
expect6(count).toBeGreaterThanOrEqual(1);
|
|
1312
|
+
} else {
|
|
1313
|
+
expect6(count).toBe(1);
|
|
1314
|
+
}
|
|
1315
|
+
const rawCount = await actor.rawSelectCount();
|
|
1316
|
+
if (driverTestConfig.useRealTimers) {
|
|
1317
|
+
expect6(rawCount).toBeGreaterThanOrEqual(1);
|
|
1318
|
+
} else {
|
|
1319
|
+
expect6(rawCount).toBe(1);
|
|
1320
|
+
}
|
|
1321
|
+
const multiValue = await actor.multiStatementInsert("gamma");
|
|
1322
|
+
expect6(multiValue).toBe("gamma-updated");
|
|
1323
|
+
},
|
|
1324
|
+
dbTestTimeout
|
|
1325
|
+
);
|
|
1326
|
+
test6(
|
|
1327
|
+
"handles transactions",
|
|
1328
|
+
async (c) => {
|
|
1329
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1330
|
+
const actor = getDbActor(client, variant).getOrCreate([
|
|
1331
|
+
`db-${variant}-tx-${crypto.randomUUID()}`
|
|
1332
|
+
]);
|
|
1333
|
+
await actor.reset();
|
|
1334
|
+
await actor.transactionCommit("commit");
|
|
1329
1335
|
expect6(await actor.getCount()).toBe(1);
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1336
|
+
await actor.transactionRollback("rollback");
|
|
1337
|
+
expect6(await actor.getCount()).toBe(1);
|
|
1338
|
+
},
|
|
1339
|
+
dbTestTimeout
|
|
1340
|
+
);
|
|
1341
|
+
test6(
|
|
1342
|
+
"persists across sleep and wake cycles",
|
|
1343
|
+
async (c) => {
|
|
1344
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1345
|
+
const actor = getDbActor(client, variant).getOrCreate([
|
|
1346
|
+
`db-${variant}-sleep-${crypto.randomUUID()}`
|
|
1347
|
+
]);
|
|
1348
|
+
await actor.reset();
|
|
1349
|
+
await actor.insertValue("sleepy");
|
|
1350
|
+
const baselineCount = await actor.getCount();
|
|
1351
|
+
expect6(baselineCount).toBeGreaterThan(0);
|
|
1352
|
+
for (let i = 0; i < 3; i++) {
|
|
1353
|
+
await actor.triggerSleep();
|
|
1354
|
+
await waitFor(driverTestConfig, SLEEP_WAIT_MS);
|
|
1355
|
+
expect6(await actor.getCount()).toBe(baselineCount);
|
|
1356
|
+
}
|
|
1357
|
+
},
|
|
1358
|
+
dbTestTimeout
|
|
1359
|
+
);
|
|
1360
|
+
test6(
|
|
1361
|
+
"completes onDisconnect DB writes before sleeping",
|
|
1362
|
+
async (c) => {
|
|
1363
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1364
|
+
const key = `db-${variant}-disconnect-${crypto.randomUUID()}`;
|
|
1365
|
+
const actor = getDbActor(client, variant).getOrCreate([key]);
|
|
1366
|
+
await actor.reset();
|
|
1367
|
+
await actor.configureDisconnectInsert(true, 250);
|
|
1368
|
+
await waitFor(driverTestConfig, SLEEP_WAIT_MS + 250);
|
|
1369
|
+
await actor.configureDisconnectInsert(false, 0);
|
|
1370
|
+
expect6(await actor.getDisconnectInsertCount()).toBe(1);
|
|
1371
|
+
},
|
|
1372
|
+
dbTestTimeout
|
|
1373
|
+
);
|
|
1374
|
+
test6(
|
|
1375
|
+
"handles high-volume inserts",
|
|
1376
|
+
async (c) => {
|
|
1377
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1378
|
+
const actor = getDbActor(client, variant).getOrCreate([
|
|
1379
|
+
`db-${variant}-high-volume-${crypto.randomUUID()}`
|
|
1380
|
+
]);
|
|
1381
|
+
await actor.reset();
|
|
1382
|
+
await actor.insertMany(HIGH_VOLUME_COUNT);
|
|
1383
|
+
const count = await actor.getCount();
|
|
1384
|
+
if (driverTestConfig.useRealTimers) {
|
|
1385
|
+
expect6(count).toBeGreaterThanOrEqual(HIGH_VOLUME_COUNT);
|
|
1386
|
+
} else {
|
|
1387
|
+
expect6(count).toBe(HIGH_VOLUME_COUNT);
|
|
1388
|
+
}
|
|
1389
|
+
},
|
|
1390
|
+
dbTestTimeout
|
|
1391
|
+
);
|
|
1392
|
+
test6(
|
|
1393
|
+
"handles payloads across chunk boundaries",
|
|
1394
|
+
async (c) => {
|
|
1395
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1396
|
+
const actor = getDbActor(client, variant).getOrCreate([
|
|
1397
|
+
`db-${variant}-chunk-${crypto.randomUUID()}`
|
|
1398
|
+
]);
|
|
1399
|
+
await actor.reset();
|
|
1400
|
+
for (const size of CHUNK_BOUNDARY_SIZES) {
|
|
1401
|
+
const { id } = await actor.insertPayloadOfSize(size);
|
|
1402
|
+
const storedSize = await actor.getPayloadSize(id);
|
|
1403
|
+
expect6(storedSize).toBe(size);
|
|
1404
|
+
}
|
|
1405
|
+
},
|
|
1406
|
+
dbTestTimeout
|
|
1407
|
+
);
|
|
1408
|
+
test6(
|
|
1409
|
+
"handles large payloads",
|
|
1410
|
+
async (c) => {
|
|
1411
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1412
|
+
const actor = getDbActor(client, variant).getOrCreate([
|
|
1413
|
+
`db-${variant}-large-${crypto.randomUUID()}`
|
|
1414
|
+
]);
|
|
1415
|
+
await actor.reset();
|
|
1416
|
+
const { id } = await actor.insertPayloadOfSize(LARGE_PAYLOAD_SIZE);
|
|
1417
|
+
const storedSize = await actor.getPayloadSize(id);
|
|
1418
|
+
expect6(storedSize).toBe(LARGE_PAYLOAD_SIZE);
|
|
1419
|
+
},
|
|
1420
|
+
dbTestTimeout
|
|
1421
|
+
);
|
|
1422
|
+
test6(
|
|
1423
|
+
"supports shrink and regrow workloads with vacuum",
|
|
1424
|
+
async (c) => {
|
|
1425
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1426
|
+
const actor = getDbActor(client, variant).getOrCreate([
|
|
1427
|
+
`db-${variant}-shrink-regrow-${crypto.randomUUID()}`
|
|
1428
|
+
]);
|
|
1429
|
+
await actor.reset();
|
|
1430
|
+
await actor.vacuum();
|
|
1431
|
+
const baselinePages = await actor.getPageCount();
|
|
1432
|
+
await actor.insertPayloadRows(
|
|
1433
|
+
SHRINK_GROW_INITIAL_ROWS,
|
|
1434
|
+
SHRINK_GROW_INITIAL_PAYLOAD
|
|
1435
|
+
);
|
|
1436
|
+
const grownPages = await actor.getPageCount();
|
|
1437
|
+
await actor.reset();
|
|
1438
|
+
await actor.vacuum();
|
|
1439
|
+
const shrunkPages = await actor.getPageCount();
|
|
1440
|
+
await actor.insertPayloadRows(
|
|
1441
|
+
SHRINK_GROW_REGROW_ROWS,
|
|
1442
|
+
SHRINK_GROW_REGROW_PAYLOAD
|
|
1443
|
+
);
|
|
1444
|
+
const regrownPages = await actor.getPageCount();
|
|
1445
|
+
expect6(grownPages).toBeGreaterThanOrEqual(baselinePages);
|
|
1446
|
+
expect6(shrunkPages).toBeLessThanOrEqual(grownPages);
|
|
1447
|
+
expect6(regrownPages).toBeGreaterThan(shrunkPages);
|
|
1448
|
+
},
|
|
1449
|
+
dbTestTimeout
|
|
1450
|
+
);
|
|
1451
|
+
test6(
|
|
1452
|
+
"handles repeated updates to the same row",
|
|
1453
|
+
async (c) => {
|
|
1454
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1455
|
+
const actor = getDbActor(client, variant).getOrCreate([
|
|
1456
|
+
`db-${variant}-updates-${crypto.randomUUID()}`
|
|
1457
|
+
]);
|
|
1458
|
+
await actor.reset();
|
|
1459
|
+
const { id } = await actor.insertValue("base");
|
|
1460
|
+
const result = await actor.repeatUpdate(id, 50);
|
|
1461
|
+
expect6(result.value).toBe("Updated 49");
|
|
1462
|
+
const value = await actor.getValue(id);
|
|
1463
|
+
expect6(value).toBe("Updated 49");
|
|
1464
|
+
const hotRowIds = [];
|
|
1465
|
+
for (let i = 0; i < HOT_ROW_COUNT; i++) {
|
|
1466
|
+
const row = await actor.insertValue(`init-${i}`);
|
|
1467
|
+
hotRowIds.push(row.id);
|
|
1468
|
+
}
|
|
1469
|
+
const updatedRows = await actor.roundRobinUpdateValues(
|
|
1470
|
+
hotRowIds,
|
|
1471
|
+
HOT_ROW_UPDATES
|
|
1472
|
+
);
|
|
1473
|
+
expect6(updatedRows).toHaveLength(HOT_ROW_COUNT);
|
|
1474
|
+
for (const row of updatedRows) {
|
|
1475
|
+
expect6(row.value).toMatch(/^v-\d+$/);
|
|
1476
|
+
}
|
|
1477
|
+
},
|
|
1478
|
+
dbTestTimeout
|
|
1479
|
+
);
|
|
1480
|
+
test6(
|
|
1481
|
+
"passes integrity checks after mixed workload and sleep",
|
|
1482
|
+
async (c) => {
|
|
1483
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1484
|
+
const actor = getDbActor(client, variant).getOrCreate([
|
|
1485
|
+
`db-${variant}-integrity-${crypto.randomUUID()}`
|
|
1486
|
+
]);
|
|
1487
|
+
await actor.reset();
|
|
1488
|
+
await actor.runMixedWorkload(
|
|
1489
|
+
INTEGRITY_SEED_COUNT,
|
|
1490
|
+
INTEGRITY_CHURN_COUNT
|
|
1491
|
+
);
|
|
1492
|
+
expect6((await actor.integrityCheck()).toLowerCase()).toBe("ok");
|
|
1493
|
+
await actor.triggerSleep();
|
|
1494
|
+
await waitFor(driverTestConfig, SLEEP_WAIT_MS + 100);
|
|
1495
|
+
expect6((await actor.integrityCheck()).toLowerCase()).toBe("ok");
|
|
1496
|
+
},
|
|
1497
|
+
dbTestTimeout
|
|
1498
|
+
);
|
|
1499
|
+
});
|
|
1500
|
+
}
|
|
1501
|
+
describe6("Actor Database Lifecycle Cleanup Tests", () => {
|
|
1502
|
+
test6(
|
|
1503
|
+
"runs db provider cleanup on sleep",
|
|
1504
|
+
async (c) => {
|
|
1343
1505
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1344
|
-
const
|
|
1345
|
-
|
|
1506
|
+
const observer = client.dbLifecycleObserver.getOrCreate(["observer"]);
|
|
1507
|
+
const lifecycle = client.dbLifecycle.getOrCreate([
|
|
1508
|
+
`db-lifecycle-sleep-${crypto.randomUUID()}`
|
|
1346
1509
|
]);
|
|
1347
|
-
await
|
|
1348
|
-
await
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1510
|
+
const actorId = await lifecycle.getActorId();
|
|
1511
|
+
const before = await observer.getCounts(actorId);
|
|
1512
|
+
await lifecycle.insertValue("before-sleep");
|
|
1513
|
+
await lifecycle.triggerSleep();
|
|
1514
|
+
await waitFor(driverTestConfig, SLEEP_WAIT_MS + 100);
|
|
1515
|
+
await lifecycle.ping();
|
|
1516
|
+
let after = before;
|
|
1517
|
+
for (let i = 0; i < LIFECYCLE_POLL_ATTEMPTS; i++) {
|
|
1518
|
+
after = await observer.getCounts(actorId);
|
|
1519
|
+
if (after.cleanup >= before.cleanup + 1) {
|
|
1520
|
+
break;
|
|
1521
|
+
}
|
|
1522
|
+
await waitFor(driverTestConfig, LIFECYCLE_POLL_INTERVAL_MS);
|
|
1523
|
+
}
|
|
1524
|
+
expect6(after.create).toBeGreaterThanOrEqual(before.create);
|
|
1525
|
+
expect6(after.migrate).toBeGreaterThanOrEqual(before.migrate);
|
|
1526
|
+
expect6(after.cleanup).toBeGreaterThanOrEqual(before.cleanup + 1);
|
|
1527
|
+
},
|
|
1528
|
+
lifecycleTestTimeout
|
|
1529
|
+
);
|
|
1530
|
+
test6(
|
|
1531
|
+
"runs db provider cleanup on destroy",
|
|
1532
|
+
async (c) => {
|
|
1352
1533
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1353
|
-
const
|
|
1354
|
-
|
|
1534
|
+
const observer = client.dbLifecycleObserver.getOrCreate(["observer"]);
|
|
1535
|
+
const lifecycle = client.dbLifecycle.getOrCreate([
|
|
1536
|
+
`db-lifecycle-destroy-${crypto.randomUUID()}`
|
|
1355
1537
|
]);
|
|
1356
|
-
await
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1538
|
+
const actorId = await lifecycle.getActorId();
|
|
1539
|
+
const before = await observer.getCounts(actorId);
|
|
1540
|
+
await lifecycle.insertValue("before-destroy");
|
|
1541
|
+
await lifecycle.triggerDestroy();
|
|
1542
|
+
await waitFor(driverTestConfig, SLEEP_WAIT_MS + 100);
|
|
1543
|
+
let cleanupCount = before.cleanup;
|
|
1544
|
+
for (let i = 0; i < LIFECYCLE_POLL_ATTEMPTS; i++) {
|
|
1545
|
+
const counts = await observer.getCounts(actorId);
|
|
1546
|
+
cleanupCount = counts.cleanup;
|
|
1547
|
+
if (cleanupCount >= before.cleanup + 1) {
|
|
1548
|
+
break;
|
|
1549
|
+
}
|
|
1550
|
+
await waitFor(driverTestConfig, LIFECYCLE_POLL_INTERVAL_MS);
|
|
1361
1551
|
}
|
|
1362
|
-
|
|
1363
|
-
|
|
1552
|
+
expect6(cleanupCount).toBeGreaterThanOrEqual(before.cleanup + 1);
|
|
1553
|
+
},
|
|
1554
|
+
lifecycleTestTimeout
|
|
1555
|
+
);
|
|
1556
|
+
test6(
|
|
1557
|
+
"runs db provider cleanup when migration fails",
|
|
1558
|
+
async (c) => {
|
|
1364
1559
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1365
|
-
const
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1560
|
+
const observer = client.dbLifecycleObserver.getOrCreate(["observer"]);
|
|
1561
|
+
const beforeTotalCleanup = await observer.getTotalCleanupCount();
|
|
1562
|
+
const key = `db-lifecycle-migrate-failure-${crypto.randomUUID()}`;
|
|
1563
|
+
const lifecycle = client.dbLifecycleFailing.getOrCreate([key]);
|
|
1564
|
+
let threw = false;
|
|
1565
|
+
try {
|
|
1566
|
+
await lifecycle.ping();
|
|
1567
|
+
} catch {
|
|
1568
|
+
threw = true;
|
|
1569
|
+
}
|
|
1570
|
+
expect6(threw).toBeTruthy();
|
|
1571
|
+
let cleanupCount = beforeTotalCleanup;
|
|
1572
|
+
for (let i = 0; i < LIFECYCLE_POLL_ATTEMPTS; i++) {
|
|
1573
|
+
cleanupCount = await observer.getTotalCleanupCount();
|
|
1574
|
+
if (cleanupCount >= beforeTotalCleanup + 1) {
|
|
1575
|
+
break;
|
|
1576
|
+
}
|
|
1577
|
+
await waitFor(driverTestConfig, LIFECYCLE_POLL_INTERVAL_MS);
|
|
1578
|
+
}
|
|
1579
|
+
expect6(cleanupCount).toBeGreaterThanOrEqual(beforeTotalCleanup + 1);
|
|
1580
|
+
},
|
|
1581
|
+
lifecycleTestTimeout
|
|
1582
|
+
);
|
|
1583
|
+
test6(
|
|
1584
|
+
"handles parallel actor lifecycle churn",
|
|
1585
|
+
async (c) => {
|
|
1374
1586
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1375
|
-
const
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
await actor.insertPayloadRows(
|
|
1382
|
-
SHRINK_GROW_INITIAL_ROWS,
|
|
1383
|
-
SHRINK_GROW_INITIAL_PAYLOAD
|
|
1587
|
+
const observer = client.dbLifecycleObserver.getOrCreate(["observer"]);
|
|
1588
|
+
const actorHandles = Array.from(
|
|
1589
|
+
{ length: 12 },
|
|
1590
|
+
(_, i) => client.dbLifecycle.getOrCreate([
|
|
1591
|
+
`db-lifecycle-stress-${i}-${crypto.randomUUID()}`
|
|
1592
|
+
])
|
|
1384
1593
|
);
|
|
1385
|
-
const
|
|
1386
|
-
|
|
1387
|
-
await actor.vacuum();
|
|
1388
|
-
const shrunkPages = await actor.getPageCount();
|
|
1389
|
-
await actor.insertPayloadRows(
|
|
1390
|
-
SHRINK_GROW_REGROW_ROWS,
|
|
1391
|
-
SHRINK_GROW_REGROW_PAYLOAD
|
|
1594
|
+
const actorIds = await Promise.all(
|
|
1595
|
+
actorHandles.map((handle) => handle.getActorId())
|
|
1392
1596
|
);
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
expect6(shrunkPages).toBeLessThanOrEqual(grownPages);
|
|
1396
|
-
expect6(regrownPages).toBeGreaterThan(shrunkPages);
|
|
1397
|
-
});
|
|
1398
|
-
test6("handles repeated updates to the same row", async (c) => {
|
|
1399
|
-
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1400
|
-
const actor = getDbActor(client, variant).getOrCreate([
|
|
1401
|
-
`db-${variant}-updates-${crypto.randomUUID()}`
|
|
1402
|
-
]);
|
|
1403
|
-
await actor.reset();
|
|
1404
|
-
const { id } = await actor.insertValue("base");
|
|
1405
|
-
const result = await actor.repeatUpdate(id, 50);
|
|
1406
|
-
expect6(result.value).toBe("Updated 49");
|
|
1407
|
-
const value = await actor.getValue(id);
|
|
1408
|
-
expect6(value).toBe("Updated 49");
|
|
1409
|
-
const hotRowIds = [];
|
|
1410
|
-
for (let i = 0; i < HOT_ROW_COUNT; i++) {
|
|
1411
|
-
const row = await actor.insertValue(`init-${i}`);
|
|
1412
|
-
hotRowIds.push(row.id);
|
|
1413
|
-
}
|
|
1414
|
-
const updatedRows = await actor.roundRobinUpdateValues(
|
|
1415
|
-
hotRowIds,
|
|
1416
|
-
HOT_ROW_UPDATES
|
|
1597
|
+
await Promise.all(
|
|
1598
|
+
actorHandles.map((handle, i) => handle.insertValue(`phase-1-${i}`))
|
|
1417
1599
|
);
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
});
|
|
1423
|
-
test6("passes integrity checks after mixed workload and sleep", async (c) => {
|
|
1424
|
-
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1425
|
-
const actor = getDbActor(client, variant).getOrCreate([
|
|
1426
|
-
`db-${variant}-integrity-${crypto.randomUUID()}`
|
|
1427
|
-
]);
|
|
1428
|
-
await actor.reset();
|
|
1429
|
-
await actor.runMixedWorkload(
|
|
1430
|
-
INTEGRITY_SEED_COUNT,
|
|
1431
|
-
INTEGRITY_CHURN_COUNT
|
|
1600
|
+
await Promise.all(actorHandles.map((handle) => handle.triggerSleep()));
|
|
1601
|
+
await waitFor(driverTestConfig, SLEEP_WAIT_MS + 100);
|
|
1602
|
+
await Promise.all(
|
|
1603
|
+
actorHandles.map((handle, i) => handle.insertValue(`phase-2-${i}`))
|
|
1432
1604
|
);
|
|
1433
|
-
|
|
1434
|
-
|
|
1605
|
+
const survivors = actorHandles.slice(0, 6);
|
|
1606
|
+
const destroyed = actorHandles.slice(6);
|
|
1607
|
+
await Promise.all(destroyed.map((handle) => handle.triggerDestroy()));
|
|
1608
|
+
await Promise.all(survivors.map((handle) => handle.triggerSleep()));
|
|
1435
1609
|
await waitFor(driverTestConfig, SLEEP_WAIT_MS + 100);
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
]);
|
|
1447
|
-
const actorId = await lifecycle.getActorId();
|
|
1448
|
-
const before = await observer.getCounts(actorId);
|
|
1449
|
-
await lifecycle.insertValue("before-sleep");
|
|
1450
|
-
await lifecycle.triggerSleep();
|
|
1451
|
-
await waitFor(driverTestConfig, SLEEP_WAIT_MS + 100);
|
|
1452
|
-
await lifecycle.ping();
|
|
1453
|
-
let after = before;
|
|
1454
|
-
for (let i = 0; i < LIFECYCLE_POLL_ATTEMPTS; i++) {
|
|
1455
|
-
after = await observer.getCounts(actorId);
|
|
1456
|
-
if (after.cleanup >= before.cleanup + 1) {
|
|
1457
|
-
break;
|
|
1610
|
+
await Promise.all(survivors.map((handle) => handle.ping()));
|
|
1611
|
+
const survivorCounts = await Promise.all(
|
|
1612
|
+
survivors.map((handle) => handle.getCount())
|
|
1613
|
+
);
|
|
1614
|
+
for (const count of survivorCounts) {
|
|
1615
|
+
if (driverTestConfig.useRealTimers) {
|
|
1616
|
+
expect6(count).toBeGreaterThanOrEqual(2);
|
|
1617
|
+
} else {
|
|
1618
|
+
expect6(count).toBe(2);
|
|
1619
|
+
}
|
|
1458
1620
|
}
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
await lifecycle.insertValue("before-destroy");
|
|
1474
|
-
await lifecycle.triggerDestroy();
|
|
1475
|
-
await waitFor(driverTestConfig, SLEEP_WAIT_MS + 100);
|
|
1476
|
-
let cleanupCount = before.cleanup;
|
|
1477
|
-
for (let i = 0; i < LIFECYCLE_POLL_ATTEMPTS; i++) {
|
|
1478
|
-
const counts = await observer.getCounts(actorId);
|
|
1479
|
-
cleanupCount = counts.cleanup;
|
|
1480
|
-
if (cleanupCount >= before.cleanup + 1) {
|
|
1481
|
-
break;
|
|
1621
|
+
const lifecycleCleanup = /* @__PURE__ */ new Map();
|
|
1622
|
+
for (let i = 0; i < LIFECYCLE_POLL_ATTEMPTS; i++) {
|
|
1623
|
+
let allCleaned = true;
|
|
1624
|
+
for (const actorId of actorIds) {
|
|
1625
|
+
const counts = await observer.getCounts(actorId);
|
|
1626
|
+
lifecycleCleanup.set(actorId, counts.cleanup);
|
|
1627
|
+
if (counts.cleanup < 1) {
|
|
1628
|
+
allCleaned = false;
|
|
1629
|
+
}
|
|
1630
|
+
}
|
|
1631
|
+
if (allCleaned) {
|
|
1632
|
+
break;
|
|
1633
|
+
}
|
|
1634
|
+
await waitFor(driverTestConfig, LIFECYCLE_POLL_INTERVAL_MS);
|
|
1482
1635
|
}
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1636
|
+
for (const actorId of actorIds) {
|
|
1637
|
+
expect6(lifecycleCleanup.get(actorId) ?? 0).toBeGreaterThanOrEqual(1);
|
|
1638
|
+
}
|
|
1639
|
+
},
|
|
1640
|
+
lifecycleTestTimeout
|
|
1641
|
+
);
|
|
1642
|
+
});
|
|
1643
|
+
}
|
|
1644
|
+
|
|
1645
|
+
// src/driver-test-suite/tests/conn-error-serialization.ts
|
|
1646
|
+
import { describe as describe7, expect as expect7, test as test7 } from "vitest";
|
|
1647
|
+
function runConnErrorSerializationTests(driverTestConfig) {
|
|
1648
|
+
describe7("Connection Error Serialization Tests", () => {
|
|
1649
|
+
test7("error thrown in createConnState preserves group and code through WebSocket serialization", async (c) => {
|
|
1488
1650
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1489
|
-
const
|
|
1490
|
-
const
|
|
1491
|
-
|
|
1492
|
-
|
|
1651
|
+
const actorKey = `test-error-serialization-${Date.now()}`;
|
|
1652
|
+
const actor = client.connErrorSerializationActor.getOrCreate(
|
|
1653
|
+
[actorKey],
|
|
1654
|
+
{ params: { shouldThrow: true } }
|
|
1655
|
+
);
|
|
1656
|
+
const conn = actor.connect();
|
|
1657
|
+
let caughtError;
|
|
1493
1658
|
try {
|
|
1494
|
-
await
|
|
1495
|
-
} catch {
|
|
1496
|
-
|
|
1497
|
-
}
|
|
1498
|
-
expect6(threw).toBeTruthy();
|
|
1499
|
-
const actorId = await client.dbLifecycleFailing.get([key]).resolve();
|
|
1500
|
-
let cleanupCount = 0;
|
|
1501
|
-
for (let i = 0; i < LIFECYCLE_POLL_ATTEMPTS; i++) {
|
|
1502
|
-
const counts = await observer.getCounts(actorId);
|
|
1503
|
-
cleanupCount = counts.cleanup;
|
|
1504
|
-
if (cleanupCount >= 1) {
|
|
1505
|
-
break;
|
|
1506
|
-
}
|
|
1507
|
-
await waitFor(driverTestConfig, LIFECYCLE_POLL_INTERVAL_MS);
|
|
1659
|
+
await conn.getValue();
|
|
1660
|
+
} catch (err) {
|
|
1661
|
+
caughtError = err;
|
|
1508
1662
|
}
|
|
1509
|
-
|
|
1663
|
+
expect7(caughtError).toBeDefined();
|
|
1664
|
+
expect7(caughtError.group).toBe("connection");
|
|
1665
|
+
expect7(caughtError.code).toBe("custom_error");
|
|
1666
|
+
await conn.dispose();
|
|
1510
1667
|
});
|
|
1511
|
-
|
|
1668
|
+
test7("successful createConnState does not throw error", async (c) => {
|
|
1512
1669
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1513
|
-
const
|
|
1514
|
-
const
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
`db-lifecycle-stress-${i}-${crypto.randomUUID()}`
|
|
1518
|
-
])
|
|
1519
|
-
);
|
|
1520
|
-
const actorIds = await Promise.all(
|
|
1521
|
-
actorHandles.map((handle) => handle.getActorId())
|
|
1522
|
-
);
|
|
1523
|
-
await Promise.all(
|
|
1524
|
-
actorHandles.map((handle, i) => handle.insertValue(`phase-1-${i}`))
|
|
1670
|
+
const actorKey = `test-no-error-${Date.now()}`;
|
|
1671
|
+
const actor = client.connErrorSerializationActor.getOrCreate(
|
|
1672
|
+
[actorKey],
|
|
1673
|
+
{ params: { shouldThrow: false } }
|
|
1525
1674
|
);
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
);
|
|
1531
|
-
const survivors = actorHandles.slice(0, 6);
|
|
1532
|
-
const destroyed = actorHandles.slice(6);
|
|
1533
|
-
await Promise.all(destroyed.map((handle) => handle.triggerDestroy()));
|
|
1534
|
-
await Promise.all(survivors.map((handle) => handle.triggerSleep()));
|
|
1535
|
-
await waitFor(driverTestConfig, SLEEP_WAIT_MS + 100);
|
|
1536
|
-
await Promise.all(survivors.map((handle) => handle.ping()));
|
|
1537
|
-
const survivorCounts = await Promise.all(
|
|
1538
|
-
survivors.map((handle) => handle.getCount())
|
|
1539
|
-
);
|
|
1540
|
-
for (const count of survivorCounts) {
|
|
1541
|
-
expect6(count).toBe(2);
|
|
1542
|
-
}
|
|
1543
|
-
const lifecycleCleanup = /* @__PURE__ */ new Map();
|
|
1544
|
-
for (let i = 0; i < LIFECYCLE_POLL_ATTEMPTS; i++) {
|
|
1545
|
-
let allCleaned = true;
|
|
1546
|
-
for (const actorId of actorIds) {
|
|
1547
|
-
const counts = await observer.getCounts(actorId);
|
|
1548
|
-
lifecycleCleanup.set(actorId, counts.cleanup);
|
|
1549
|
-
if (counts.cleanup < 1) {
|
|
1550
|
-
allCleaned = false;
|
|
1551
|
-
}
|
|
1552
|
-
}
|
|
1553
|
-
if (allCleaned) {
|
|
1554
|
-
break;
|
|
1555
|
-
}
|
|
1556
|
-
await waitFor(driverTestConfig, LIFECYCLE_POLL_INTERVAL_MS);
|
|
1557
|
-
}
|
|
1558
|
-
for (const actorId of actorIds) {
|
|
1559
|
-
expect6(lifecycleCleanup.get(actorId) ?? 0).toBeGreaterThanOrEqual(1);
|
|
1560
|
-
}
|
|
1675
|
+
const conn = actor.connect();
|
|
1676
|
+
const value = await conn.getValue();
|
|
1677
|
+
expect7(value).toBe(0);
|
|
1678
|
+
await conn.dispose();
|
|
1561
1679
|
});
|
|
1562
1680
|
});
|
|
1563
1681
|
}
|
|
1564
1682
|
|
|
1565
1683
|
// src/driver-test-suite/tests/actor-destroy.ts
|
|
1566
|
-
import { describe as
|
|
1684
|
+
import { describe as describe8, expect as expect8, test as test8, vi as vi5 } from "vitest";
|
|
1567
1685
|
function runActorDestroyTests(driverTestConfig) {
|
|
1568
|
-
|
|
1569
|
-
|
|
1686
|
+
describe8("Actor Destroy Tests", () => {
|
|
1687
|
+
test8("actor destroy clears state (without connect)", async (c) => {
|
|
1570
1688
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1571
1689
|
const actorKey = "test-destroy-without-connect";
|
|
1572
1690
|
const observer = client.destroyObserver.getOrCreate(["observer"]);
|
|
@@ -1574,12 +1692,12 @@ function runActorDestroyTests(driverTestConfig) {
|
|
|
1574
1692
|
const destroyActor = client.destroyActor.getOrCreate([actorKey]);
|
|
1575
1693
|
await destroyActor.setValue(42);
|
|
1576
1694
|
const value = await destroyActor.getValue();
|
|
1577
|
-
|
|
1695
|
+
expect8(value).toBe(42);
|
|
1578
1696
|
const actorId = await destroyActor.resolve();
|
|
1579
1697
|
await destroyActor.destroy();
|
|
1580
1698
|
await vi5.waitFor(async () => {
|
|
1581
1699
|
const wasDestroyed = await observer.wasDestroyed(actorKey);
|
|
1582
|
-
|
|
1700
|
+
expect8(wasDestroyed, "actor onDestroy not called").toBeTruthy();
|
|
1583
1701
|
});
|
|
1584
1702
|
await vi5.waitFor(async () => {
|
|
1585
1703
|
let actorRunning = false;
|
|
@@ -1587,20 +1705,20 @@ function runActorDestroyTests(driverTestConfig) {
|
|
|
1587
1705
|
await client.destroyActor.getForId(actorId).getValue();
|
|
1588
1706
|
actorRunning = true;
|
|
1589
1707
|
} catch (err) {
|
|
1590
|
-
|
|
1591
|
-
|
|
1708
|
+
expect8(err.group).toBe("actor");
|
|
1709
|
+
expect8(err.code).toBe("not_found");
|
|
1592
1710
|
}
|
|
1593
|
-
|
|
1711
|
+
expect8(actorRunning, "actor still running").toBeFalsy();
|
|
1594
1712
|
});
|
|
1595
1713
|
let existsById = false;
|
|
1596
1714
|
try {
|
|
1597
1715
|
await client.destroyActor.getForId(actorId).getValue();
|
|
1598
1716
|
existsById = true;
|
|
1599
1717
|
} catch (err) {
|
|
1600
|
-
|
|
1601
|
-
|
|
1718
|
+
expect8(err.group).toBe("actor");
|
|
1719
|
+
expect8(err.code).toBe("not_found");
|
|
1602
1720
|
}
|
|
1603
|
-
|
|
1721
|
+
expect8(
|
|
1604
1722
|
existsById,
|
|
1605
1723
|
"actor should not exist after destroy"
|
|
1606
1724
|
).toBeFalsy();
|
|
@@ -1609,10 +1727,10 @@ function runActorDestroyTests(driverTestConfig) {
|
|
|
1609
1727
|
await client.destroyActor.get(["test-destroy-without-connect"]).resolve();
|
|
1610
1728
|
existsByKey = true;
|
|
1611
1729
|
} catch (err) {
|
|
1612
|
-
|
|
1613
|
-
|
|
1730
|
+
expect8(err.group).toBe("actor");
|
|
1731
|
+
expect8(err.code).toBe("not_found");
|
|
1614
1732
|
}
|
|
1615
|
-
|
|
1733
|
+
expect8(
|
|
1616
1734
|
existsByKey,
|
|
1617
1735
|
"actor should not exist after destroy"
|
|
1618
1736
|
).toBeFalsy();
|
|
@@ -1620,9 +1738,9 @@ function runActorDestroyTests(driverTestConfig) {
|
|
|
1620
1738
|
"test-destroy-without-connect"
|
|
1621
1739
|
]);
|
|
1622
1740
|
const newValue = await newActor.getValue();
|
|
1623
|
-
|
|
1741
|
+
expect8(newValue).toBe(0);
|
|
1624
1742
|
});
|
|
1625
|
-
|
|
1743
|
+
test8("actor destroy clears state (with connect)", async (c) => {
|
|
1626
1744
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1627
1745
|
const actorKey = "test-destroy-with-connect";
|
|
1628
1746
|
const observer = client.destroyObserver.getOrCreate(["observer"]);
|
|
@@ -1634,12 +1752,12 @@ function runActorDestroyTests(driverTestConfig) {
|
|
|
1634
1752
|
const destroyActor = destroyActorHandle.connect();
|
|
1635
1753
|
await destroyActor.setValue(99);
|
|
1636
1754
|
const value = await destroyActor.getValue();
|
|
1637
|
-
|
|
1755
|
+
expect8(value).toBe(99);
|
|
1638
1756
|
await destroyActor.destroy();
|
|
1639
1757
|
await destroyActor.dispose();
|
|
1640
1758
|
await vi5.waitFor(async () => {
|
|
1641
1759
|
const wasDestroyed = await observer.wasDestroyed(actorKey);
|
|
1642
|
-
|
|
1760
|
+
expect8(wasDestroyed, "actor onDestroy not called").toBeTruthy();
|
|
1643
1761
|
});
|
|
1644
1762
|
await vi5.waitFor(async () => {
|
|
1645
1763
|
let actorRunning = false;
|
|
@@ -1647,20 +1765,20 @@ function runActorDestroyTests(driverTestConfig) {
|
|
|
1647
1765
|
await client.destroyActor.getForId(actorId).getValue();
|
|
1648
1766
|
actorRunning = true;
|
|
1649
1767
|
} catch (err) {
|
|
1650
|
-
|
|
1651
|
-
|
|
1768
|
+
expect8(err.group).toBe("actor");
|
|
1769
|
+
expect8(err.code).toBe("not_found");
|
|
1652
1770
|
}
|
|
1653
|
-
|
|
1771
|
+
expect8(actorRunning, "actor still running").toBeFalsy();
|
|
1654
1772
|
});
|
|
1655
1773
|
let existsById = false;
|
|
1656
1774
|
try {
|
|
1657
1775
|
await client.destroyActor.getForId(actorId).getValue();
|
|
1658
1776
|
existsById = true;
|
|
1659
1777
|
} catch (err) {
|
|
1660
|
-
|
|
1661
|
-
|
|
1778
|
+
expect8(err.group).toBe("actor");
|
|
1779
|
+
expect8(err.code).toBe("not_found");
|
|
1662
1780
|
}
|
|
1663
|
-
|
|
1781
|
+
expect8(
|
|
1664
1782
|
existsById,
|
|
1665
1783
|
"actor should not exist after destroy"
|
|
1666
1784
|
).toBeFalsy();
|
|
@@ -1669,10 +1787,10 @@ function runActorDestroyTests(driverTestConfig) {
|
|
|
1669
1787
|
await client.destroyActor.get(["test-destroy-with-connect"]).resolve();
|
|
1670
1788
|
existsByKey = true;
|
|
1671
1789
|
} catch (err) {
|
|
1672
|
-
|
|
1673
|
-
|
|
1790
|
+
expect8(err.group).toBe("actor");
|
|
1791
|
+
expect8(err.code).toBe("not_found");
|
|
1674
1792
|
}
|
|
1675
|
-
|
|
1793
|
+
expect8(
|
|
1676
1794
|
existsByKey,
|
|
1677
1795
|
"actor should not exist after destroy"
|
|
1678
1796
|
).toBeFalsy();
|
|
@@ -1680,9 +1798,9 @@ function runActorDestroyTests(driverTestConfig) {
|
|
|
1680
1798
|
"test-destroy-with-connect"
|
|
1681
1799
|
]);
|
|
1682
1800
|
const newValue = await newActor.getValue();
|
|
1683
|
-
|
|
1801
|
+
expect8(newValue).toBe(0);
|
|
1684
1802
|
});
|
|
1685
|
-
|
|
1803
|
+
test8("actor destroy allows recreation via getOrCreate with resolve", async (c) => {
|
|
1686
1804
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1687
1805
|
const actorKey = "test-destroy-getorcreate-resolve";
|
|
1688
1806
|
const observer = client.destroyObserver.getOrCreate(["observer"]);
|
|
@@ -1690,12 +1808,12 @@ function runActorDestroyTests(driverTestConfig) {
|
|
|
1690
1808
|
const destroyActor = client.destroyActor.getOrCreate([actorKey]);
|
|
1691
1809
|
await destroyActor.setValue(123);
|
|
1692
1810
|
const value = await destroyActor.getValue();
|
|
1693
|
-
|
|
1811
|
+
expect8(value).toBe(123);
|
|
1694
1812
|
const actorId = await destroyActor.resolve();
|
|
1695
1813
|
await destroyActor.destroy();
|
|
1696
1814
|
await vi5.waitFor(async () => {
|
|
1697
1815
|
const wasDestroyed = await observer.wasDestroyed(actorKey);
|
|
1698
|
-
|
|
1816
|
+
expect8(wasDestroyed, "actor onDestroy not called").toBeTruthy();
|
|
1699
1817
|
});
|
|
1700
1818
|
await vi5.waitFor(async () => {
|
|
1701
1819
|
let actorRunning = false;
|
|
@@ -1703,17 +1821,17 @@ function runActorDestroyTests(driverTestConfig) {
|
|
|
1703
1821
|
await client.destroyActor.getForId(actorId).getValue();
|
|
1704
1822
|
actorRunning = true;
|
|
1705
1823
|
} catch (err) {
|
|
1706
|
-
|
|
1707
|
-
|
|
1824
|
+
expect8(err.group).toBe("actor");
|
|
1825
|
+
expect8(err.code).toBe("not_found");
|
|
1708
1826
|
}
|
|
1709
|
-
|
|
1827
|
+
expect8(actorRunning, "actor still running").toBeFalsy();
|
|
1710
1828
|
});
|
|
1711
1829
|
const newHandle = client.destroyActor.getOrCreate([actorKey]);
|
|
1712
1830
|
const newActorId = await newHandle.resolve();
|
|
1713
1831
|
const newValue = await newHandle.getValue();
|
|
1714
|
-
|
|
1832
|
+
expect8(newValue).toBe(0);
|
|
1715
1833
|
});
|
|
1716
|
-
|
|
1834
|
+
test8("actor destroy allows recreation via create", async (c) => {
|
|
1717
1835
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1718
1836
|
const actorKey = "test-destroy-create";
|
|
1719
1837
|
const observer = client.destroyObserver.getOrCreate(["observer"]);
|
|
@@ -1721,12 +1839,12 @@ function runActorDestroyTests(driverTestConfig) {
|
|
|
1721
1839
|
const initialHandle = await client.destroyActor.create([actorKey]);
|
|
1722
1840
|
await initialHandle.setValue(456);
|
|
1723
1841
|
const value = await initialHandle.getValue();
|
|
1724
|
-
|
|
1842
|
+
expect8(value).toBe(456);
|
|
1725
1843
|
const actorId = await initialHandle.resolve();
|
|
1726
1844
|
await initialHandle.destroy();
|
|
1727
1845
|
await vi5.waitFor(async () => {
|
|
1728
1846
|
const wasDestroyed = await observer.wasDestroyed(actorKey);
|
|
1729
|
-
|
|
1847
|
+
expect8(wasDestroyed, "actor onDestroy not called").toBeTruthy();
|
|
1730
1848
|
});
|
|
1731
1849
|
await vi5.waitFor(async () => {
|
|
1732
1850
|
let actorRunning = false;
|
|
@@ -1734,31 +1852,127 @@ function runActorDestroyTests(driverTestConfig) {
|
|
|
1734
1852
|
await client.destroyActor.getForId(actorId).getValue();
|
|
1735
1853
|
actorRunning = true;
|
|
1736
1854
|
} catch (err) {
|
|
1737
|
-
|
|
1738
|
-
|
|
1855
|
+
expect8(err.group).toBe("actor");
|
|
1856
|
+
expect8(err.code).toBe("not_found");
|
|
1739
1857
|
}
|
|
1740
|
-
|
|
1858
|
+
expect8(actorRunning, "actor still running").toBeFalsy();
|
|
1741
1859
|
});
|
|
1742
1860
|
const newHandle = await client.destroyActor.create([actorKey]);
|
|
1743
1861
|
const newActorId = await newHandle.resolve();
|
|
1744
1862
|
const newValue = await newHandle.getValue();
|
|
1745
|
-
|
|
1863
|
+
expect8(newValue).toBe(0);
|
|
1746
1864
|
});
|
|
1747
1865
|
});
|
|
1748
1866
|
}
|
|
1749
1867
|
|
|
1750
1868
|
// src/driver-test-suite/tests/actor-driver.ts
|
|
1751
|
-
import { describe as
|
|
1869
|
+
import { describe as describe13 } from "vitest";
|
|
1870
|
+
|
|
1871
|
+
// src/driver-test-suite/tests/actor-lifecycle.ts
|
|
1872
|
+
import { describe as describe9, expect as expect9, test as test9 } from "vitest";
|
|
1873
|
+
function runActorLifecycleTests(driverTestConfig) {
|
|
1874
|
+
describe9("Actor Lifecycle Tests", () => {
|
|
1875
|
+
test9("actor stop during start waits for start to complete", async (c) => {
|
|
1876
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1877
|
+
const actorKey = `test-stop-during-start-${Date.now()}`;
|
|
1878
|
+
const actor = client.startStopRaceActor.getOrCreate([actorKey]);
|
|
1879
|
+
const pingPromise = actor.ping();
|
|
1880
|
+
const actorId = await actor.resolve();
|
|
1881
|
+
await actor.destroy();
|
|
1882
|
+
const result = await pingPromise;
|
|
1883
|
+
expect9(result).toBe("pong");
|
|
1884
|
+
let destroyed = false;
|
|
1885
|
+
try {
|
|
1886
|
+
await client.startStopRaceActor.getForId(actorId).ping();
|
|
1887
|
+
} catch (err) {
|
|
1888
|
+
destroyed = true;
|
|
1889
|
+
expect9(err.group).toBe("actor");
|
|
1890
|
+
expect9(err.code).toBe("not_found");
|
|
1891
|
+
}
|
|
1892
|
+
expect9(destroyed).toBe(true);
|
|
1893
|
+
});
|
|
1894
|
+
test9("actor stop before actor instantiation completes cleans up handler", async (c) => {
|
|
1895
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1896
|
+
const actorKey = `test-stop-before-instantiation-${Date.now()}`;
|
|
1897
|
+
const actors = Array.from(
|
|
1898
|
+
{ length: 5 },
|
|
1899
|
+
(_, i) => client.startStopRaceActor.getOrCreate([
|
|
1900
|
+
`${actorKey}-${i}`
|
|
1901
|
+
])
|
|
1902
|
+
);
|
|
1903
|
+
const ids = await Promise.all(actors.map((a) => a.resolve()));
|
|
1904
|
+
await Promise.all(actors.map((a) => a.destroy()));
|
|
1905
|
+
for (const id of ids) {
|
|
1906
|
+
let destroyed = false;
|
|
1907
|
+
try {
|
|
1908
|
+
await client.startStopRaceActor.getForId(id).ping();
|
|
1909
|
+
} catch (err) {
|
|
1910
|
+
destroyed = true;
|
|
1911
|
+
expect9(err.group).toBe("actor");
|
|
1912
|
+
expect9(err.code).toBe("not_found");
|
|
1913
|
+
}
|
|
1914
|
+
expect9(destroyed, `actor ${id} should be destroyed`).toBe(
|
|
1915
|
+
true
|
|
1916
|
+
);
|
|
1917
|
+
}
|
|
1918
|
+
});
|
|
1919
|
+
test9("onBeforeActorStart completes before stop proceeds", async (c) => {
|
|
1920
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1921
|
+
const actorKey = `test-before-actor-start-${Date.now()}`;
|
|
1922
|
+
const actor = client.startStopRaceActor.getOrCreate([actorKey]);
|
|
1923
|
+
const statePromise = actor.getState();
|
|
1924
|
+
await actor.destroy();
|
|
1925
|
+
const state = await statePromise;
|
|
1926
|
+
expect9(state.initialized).toBe(true);
|
|
1927
|
+
expect9(state.startCompleted).toBe(true);
|
|
1928
|
+
});
|
|
1929
|
+
test9("multiple rapid create/destroy cycles handle race correctly", async (c) => {
|
|
1930
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1931
|
+
for (let i = 0; i < 10; i++) {
|
|
1932
|
+
const actorKey = `test-rapid-cycle-${Date.now()}-${i}`;
|
|
1933
|
+
const actor = client.startStopRaceActor.getOrCreate([
|
|
1934
|
+
actorKey
|
|
1935
|
+
]);
|
|
1936
|
+
const resolvePromise = actor.resolve();
|
|
1937
|
+
const destroyPromise = actor.destroy();
|
|
1938
|
+
await Promise.all([resolvePromise, destroyPromise]);
|
|
1939
|
+
}
|
|
1940
|
+
expect9(true).toBe(true);
|
|
1941
|
+
});
|
|
1942
|
+
test9("actor stop called with no actor instance cleans up handler", async (c) => {
|
|
1943
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1944
|
+
const actorKey = `test-cleanup-no-instance-${Date.now()}`;
|
|
1945
|
+
const actor = client.startStopRaceActor.getOrCreate([actorKey]);
|
|
1946
|
+
const id = await actor.resolve();
|
|
1947
|
+
await actor.destroy();
|
|
1948
|
+
const newActor = client.startStopRaceActor.getOrCreate([
|
|
1949
|
+
actorKey
|
|
1950
|
+
]);
|
|
1951
|
+
const result = await newActor.ping();
|
|
1952
|
+
expect9(result).toBe("pong");
|
|
1953
|
+
await newActor.destroy();
|
|
1954
|
+
});
|
|
1955
|
+
test9("onDestroy is called even when actor is destroyed during start", async (c) => {
|
|
1956
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1957
|
+
const actorKey = `test-ondestroy-during-start-${Date.now()}`;
|
|
1958
|
+
const actor = client.startStopRaceActor.getOrCreate([actorKey]);
|
|
1959
|
+
const statePromise = actor.getState();
|
|
1960
|
+
await actor.destroy();
|
|
1961
|
+
const state = await statePromise;
|
|
1962
|
+
expect9(state.destroyCalled).toBe(true);
|
|
1963
|
+
});
|
|
1964
|
+
});
|
|
1965
|
+
}
|
|
1752
1966
|
|
|
1753
1967
|
// src/driver-test-suite/tests/actor-schedule.ts
|
|
1754
|
-
import { describe as
|
|
1968
|
+
import { describe as describe10, expect as expect10, test as test10 } from "vitest";
|
|
1755
1969
|
function runActorScheduleTests(driverTestConfig) {
|
|
1756
1970
|
var _a;
|
|
1757
|
-
|
|
1971
|
+
describe10.skipIf((_a = driverTestConfig.skip) == null ? void 0 : _a.schedule)(
|
|
1758
1972
|
"Actor Schedule Tests",
|
|
1759
1973
|
() => {
|
|
1760
|
-
|
|
1761
|
-
|
|
1974
|
+
describe10("Scheduled Alarms", () => {
|
|
1975
|
+
test10("executes c.schedule.at() with specific timestamp", async (c) => {
|
|
1762
1976
|
const { client } = await setupDriverTest(
|
|
1763
1977
|
c,
|
|
1764
1978
|
driverTestConfig
|
|
@@ -1769,10 +1983,10 @@ function runActorScheduleTests(driverTestConfig) {
|
|
|
1769
1983
|
await waitFor(driverTestConfig, 500);
|
|
1770
1984
|
const lastRun = await scheduled.getLastRun();
|
|
1771
1985
|
const scheduledCount = await scheduled.getScheduledCount();
|
|
1772
|
-
|
|
1773
|
-
|
|
1986
|
+
expect10(lastRun).toBeGreaterThan(0);
|
|
1987
|
+
expect10(scheduledCount).toBe(1);
|
|
1774
1988
|
});
|
|
1775
|
-
|
|
1989
|
+
test10("executes c.schedule.after() with delay", async (c) => {
|
|
1776
1990
|
const { client } = await setupDriverTest(
|
|
1777
1991
|
c,
|
|
1778
1992
|
driverTestConfig
|
|
@@ -1782,10 +1996,10 @@ function runActorScheduleTests(driverTestConfig) {
|
|
|
1782
1996
|
await waitFor(driverTestConfig, 500);
|
|
1783
1997
|
const lastRun = await scheduled.getLastRun();
|
|
1784
1998
|
const scheduledCount = await scheduled.getScheduledCount();
|
|
1785
|
-
|
|
1786
|
-
|
|
1999
|
+
expect10(lastRun).toBeGreaterThan(0);
|
|
2000
|
+
expect10(scheduledCount).toBe(1);
|
|
1787
2001
|
});
|
|
1788
|
-
|
|
2002
|
+
test10("multiple scheduled tasks execute in order", async (c) => {
|
|
1789
2003
|
const { client } = await setupDriverTest(
|
|
1790
2004
|
c,
|
|
1791
2005
|
driverTestConfig
|
|
@@ -1797,16 +2011,16 @@ function runActorScheduleTests(driverTestConfig) {
|
|
|
1797
2011
|
await scheduled.scheduleTaskAfterWithId("third", 1250);
|
|
1798
2012
|
await waitFor(driverTestConfig, 500);
|
|
1799
2013
|
const history1 = await scheduled.getTaskHistory();
|
|
1800
|
-
|
|
2014
|
+
expect10(history1[0]).toBe("first");
|
|
1801
2015
|
await waitFor(driverTestConfig, 500);
|
|
1802
2016
|
const history2 = await scheduled.getTaskHistory();
|
|
1803
|
-
|
|
2017
|
+
expect10(history2.slice(0, 2)).toEqual([
|
|
1804
2018
|
"first",
|
|
1805
2019
|
"second"
|
|
1806
2020
|
]);
|
|
1807
2021
|
await waitFor(driverTestConfig, 500);
|
|
1808
2022
|
const history3 = await scheduled.getTaskHistory();
|
|
1809
|
-
|
|
2023
|
+
expect10(history3).toEqual(["first", "second", "third"]);
|
|
1810
2024
|
});
|
|
1811
2025
|
});
|
|
1812
2026
|
}
|
|
@@ -1814,33 +2028,33 @@ function runActorScheduleTests(driverTestConfig) {
|
|
|
1814
2028
|
}
|
|
1815
2029
|
|
|
1816
2030
|
// src/driver-test-suite/tests/actor-sleep.ts
|
|
1817
|
-
import { describe as
|
|
2031
|
+
import { describe as describe11, expect as expect11, test as test11 } from "vitest";
|
|
1818
2032
|
function runActorSleepTests(driverTestConfig) {
|
|
1819
2033
|
var _a;
|
|
1820
|
-
|
|
1821
|
-
|
|
2034
|
+
describe11.skipIf((_a = driverTestConfig.skip) == null ? void 0 : _a.sleep)("Actor Sleep Tests", () => {
|
|
2035
|
+
test11("actor sleep persists state", async (c) => {
|
|
1822
2036
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1823
2037
|
const sleepActor = client.sleep.getOrCreate();
|
|
1824
2038
|
{
|
|
1825
2039
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1826
|
-
|
|
1827
|
-
|
|
2040
|
+
expect11(sleepCount).toBe(0);
|
|
2041
|
+
expect11(startCount).toBe(1);
|
|
1828
2042
|
}
|
|
1829
2043
|
await sleepActor.triggerSleep();
|
|
1830
2044
|
await waitFor(driverTestConfig, 250);
|
|
1831
2045
|
{
|
|
1832
2046
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1833
|
-
|
|
1834
|
-
|
|
2047
|
+
expect11(sleepCount).toBe(1);
|
|
2048
|
+
expect11(startCount).toBe(2);
|
|
1835
2049
|
}
|
|
1836
2050
|
});
|
|
1837
|
-
|
|
2051
|
+
test11("actor sleep persists state with connect", async (c) => {
|
|
1838
2052
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1839
2053
|
const sleepActor = client.sleep.getOrCreate().connect();
|
|
1840
2054
|
{
|
|
1841
2055
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1842
|
-
|
|
1843
|
-
|
|
2056
|
+
expect11(sleepCount).toBe(0);
|
|
2057
|
+
expect11(startCount).toBe(1);
|
|
1844
2058
|
}
|
|
1845
2059
|
await sleepActor.triggerSleep();
|
|
1846
2060
|
await sleepActor.dispose();
|
|
@@ -1848,108 +2062,108 @@ function runActorSleepTests(driverTestConfig) {
|
|
|
1848
2062
|
const sleepActor2 = client.sleep.getOrCreate();
|
|
1849
2063
|
{
|
|
1850
2064
|
const { startCount, sleepCount } = await sleepActor2.getCounts();
|
|
1851
|
-
|
|
1852
|
-
|
|
2065
|
+
expect11(sleepCount).toBe(1);
|
|
2066
|
+
expect11(startCount).toBe(2);
|
|
1853
2067
|
}
|
|
1854
2068
|
});
|
|
1855
|
-
|
|
2069
|
+
test11("actor automatically sleeps after timeout", async (c) => {
|
|
1856
2070
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1857
2071
|
const sleepActor = client.sleep.getOrCreate();
|
|
1858
2072
|
{
|
|
1859
2073
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1860
|
-
|
|
1861
|
-
|
|
2074
|
+
expect11(sleepCount).toBe(0);
|
|
2075
|
+
expect11(startCount).toBe(1);
|
|
1862
2076
|
}
|
|
1863
2077
|
await waitFor(driverTestConfig, SLEEP_TIMEOUT + 250);
|
|
1864
2078
|
{
|
|
1865
2079
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1866
|
-
|
|
1867
|
-
|
|
2080
|
+
expect11(sleepCount).toBe(1);
|
|
2081
|
+
expect11(startCount).toBe(2);
|
|
1868
2082
|
}
|
|
1869
2083
|
});
|
|
1870
|
-
|
|
2084
|
+
test11("actor automatically sleeps after timeout with connect", async (c) => {
|
|
1871
2085
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1872
2086
|
const sleepActor = client.sleep.getOrCreate().connect();
|
|
1873
2087
|
{
|
|
1874
2088
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1875
|
-
|
|
1876
|
-
|
|
2089
|
+
expect11(sleepCount).toBe(0);
|
|
2090
|
+
expect11(startCount).toBe(1);
|
|
1877
2091
|
}
|
|
1878
2092
|
await sleepActor.dispose();
|
|
1879
2093
|
await waitFor(driverTestConfig, SLEEP_TIMEOUT + 250);
|
|
1880
2094
|
const sleepActor2 = client.sleep.getOrCreate();
|
|
1881
2095
|
{
|
|
1882
2096
|
const { startCount, sleepCount } = await sleepActor2.getCounts();
|
|
1883
|
-
|
|
1884
|
-
|
|
2097
|
+
expect11(sleepCount).toBe(1);
|
|
2098
|
+
expect11(startCount).toBe(2);
|
|
1885
2099
|
}
|
|
1886
2100
|
});
|
|
1887
|
-
|
|
2101
|
+
test11("rpc calls keep actor awake", async (c) => {
|
|
1888
2102
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1889
2103
|
const sleepActor = client.sleep.getOrCreate();
|
|
1890
2104
|
{
|
|
1891
2105
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1892
|
-
|
|
1893
|
-
|
|
2106
|
+
expect11(sleepCount).toBe(0);
|
|
2107
|
+
expect11(startCount).toBe(1);
|
|
1894
2108
|
}
|
|
1895
2109
|
await waitFor(driverTestConfig, SLEEP_TIMEOUT - 250);
|
|
1896
2110
|
{
|
|
1897
2111
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1898
|
-
|
|
1899
|
-
|
|
2112
|
+
expect11(sleepCount).toBe(0);
|
|
2113
|
+
expect11(startCount).toBe(1);
|
|
1900
2114
|
}
|
|
1901
2115
|
await waitFor(driverTestConfig, SLEEP_TIMEOUT - 250);
|
|
1902
2116
|
{
|
|
1903
2117
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1904
|
-
|
|
1905
|
-
|
|
2118
|
+
expect11(sleepCount).toBe(0);
|
|
2119
|
+
expect11(startCount).toBe(1);
|
|
1906
2120
|
}
|
|
1907
2121
|
await waitFor(driverTestConfig, SLEEP_TIMEOUT + 250);
|
|
1908
2122
|
{
|
|
1909
2123
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1910
|
-
|
|
1911
|
-
|
|
2124
|
+
expect11(sleepCount).toBe(1);
|
|
2125
|
+
expect11(startCount).toBe(2);
|
|
1912
2126
|
}
|
|
1913
2127
|
});
|
|
1914
|
-
|
|
2128
|
+
test11("alarms keep actor awake", async (c) => {
|
|
1915
2129
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1916
2130
|
const sleepActor = client.sleep.getOrCreate();
|
|
1917
2131
|
{
|
|
1918
2132
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1919
|
-
|
|
1920
|
-
|
|
2133
|
+
expect11(sleepCount).toBe(0);
|
|
2134
|
+
expect11(startCount).toBe(1);
|
|
1921
2135
|
}
|
|
1922
2136
|
await sleepActor.setAlarm(SLEEP_TIMEOUT - 250);
|
|
1923
2137
|
await waitFor(driverTestConfig, SLEEP_TIMEOUT + 250);
|
|
1924
2138
|
{
|
|
1925
2139
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1926
|
-
|
|
1927
|
-
|
|
2140
|
+
expect11(sleepCount).toBe(0);
|
|
2141
|
+
expect11(startCount).toBe(1);
|
|
1928
2142
|
}
|
|
1929
2143
|
});
|
|
1930
|
-
|
|
2144
|
+
test11("alarms wake actors", async (c) => {
|
|
1931
2145
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1932
2146
|
const sleepActor = client.sleep.getOrCreate();
|
|
1933
2147
|
{
|
|
1934
2148
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1935
|
-
|
|
1936
|
-
|
|
2149
|
+
expect11(sleepCount).toBe(0);
|
|
2150
|
+
expect11(startCount).toBe(1);
|
|
1937
2151
|
}
|
|
1938
2152
|
await sleepActor.setAlarm(SLEEP_TIMEOUT + 250);
|
|
1939
2153
|
await waitFor(driverTestConfig, SLEEP_TIMEOUT + 200);
|
|
1940
2154
|
{
|
|
1941
2155
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1942
|
-
|
|
1943
|
-
|
|
2156
|
+
expect11(sleepCount).toBe(1);
|
|
2157
|
+
expect11(startCount).toBe(2);
|
|
1944
2158
|
}
|
|
1945
2159
|
});
|
|
1946
|
-
|
|
2160
|
+
test11("long running rpcs keep actor awake", async (c) => {
|
|
1947
2161
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1948
2162
|
const sleepActor = client.sleepWithLongRpc.getOrCreate().connect();
|
|
1949
2163
|
{
|
|
1950
2164
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1951
|
-
|
|
1952
|
-
|
|
2165
|
+
expect11(sleepCount).toBe(0);
|
|
2166
|
+
expect11(startCount).toBe(1);
|
|
1953
2167
|
}
|
|
1954
2168
|
const waitPromise = new Promise(
|
|
1955
2169
|
(resolve) => sleepActor.once("waiting", resolve)
|
|
@@ -1961,19 +2175,19 @@ function runActorSleepTests(driverTestConfig) {
|
|
|
1961
2175
|
await longRunningPromise;
|
|
1962
2176
|
{
|
|
1963
2177
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1964
|
-
|
|
1965
|
-
|
|
2178
|
+
expect11(sleepCount).toBe(0);
|
|
2179
|
+
expect11(startCount).toBe(1);
|
|
1966
2180
|
}
|
|
1967
2181
|
await sleepActor.dispose();
|
|
1968
2182
|
await waitFor(driverTestConfig, SLEEP_TIMEOUT + 250);
|
|
1969
2183
|
const sleepActor2 = client.sleepWithLongRpc.getOrCreate();
|
|
1970
2184
|
{
|
|
1971
2185
|
const { startCount, sleepCount } = await sleepActor2.getCounts();
|
|
1972
|
-
|
|
1973
|
-
|
|
2186
|
+
expect11(sleepCount).toBe(1);
|
|
2187
|
+
expect11(startCount).toBe(2);
|
|
1974
2188
|
}
|
|
1975
2189
|
});
|
|
1976
|
-
|
|
2190
|
+
test11("active raw websockets keep actor awake", async (c) => {
|
|
1977
2191
|
const { client, endpoint: baseUrl } = await setupDriverTest(
|
|
1978
2192
|
c,
|
|
1979
2193
|
driverTestConfig
|
|
@@ -1981,8 +2195,8 @@ function runActorSleepTests(driverTestConfig) {
|
|
|
1981
2195
|
const sleepActor = client.sleepWithRawWebSocket.getOrCreate();
|
|
1982
2196
|
{
|
|
1983
2197
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1984
|
-
|
|
1985
|
-
|
|
2198
|
+
expect11(sleepCount).toBe(0);
|
|
2199
|
+
expect11(startCount).toBe(1);
|
|
1986
2200
|
}
|
|
1987
2201
|
const ws = await sleepActor.webSocket();
|
|
1988
2202
|
await new Promise((resolve, reject) => {
|
|
@@ -2007,17 +2221,17 @@ function runActorSleepTests(driverTestConfig) {
|
|
|
2007
2221
|
}
|
|
2008
2222
|
};
|
|
2009
2223
|
});
|
|
2010
|
-
|
|
2011
|
-
|
|
2224
|
+
expect11(counts.sleepCount).toBe(0);
|
|
2225
|
+
expect11(counts.startCount).toBe(1);
|
|
2012
2226
|
ws.close();
|
|
2013
2227
|
await waitFor(driverTestConfig, SLEEP_TIMEOUT + 250);
|
|
2014
2228
|
{
|
|
2015
2229
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
2016
|
-
|
|
2017
|
-
|
|
2230
|
+
expect11(sleepCount).toBe(1);
|
|
2231
|
+
expect11(startCount).toBe(2);
|
|
2018
2232
|
}
|
|
2019
2233
|
});
|
|
2020
|
-
|
|
2234
|
+
test11("active raw fetch requests keep actor awake", async (c) => {
|
|
2021
2235
|
const { client, endpoint: baseUrl } = await setupDriverTest(
|
|
2022
2236
|
c,
|
|
2023
2237
|
driverTestConfig
|
|
@@ -2025,8 +2239,8 @@ function runActorSleepTests(driverTestConfig) {
|
|
|
2025
2239
|
const sleepActor = client.sleepWithRawHttp.getOrCreate();
|
|
2026
2240
|
{
|
|
2027
2241
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
2028
|
-
|
|
2029
|
-
|
|
2242
|
+
expect11(sleepCount).toBe(0);
|
|
2243
|
+
expect11(startCount).toBe(1);
|
|
2030
2244
|
}
|
|
2031
2245
|
const fetchDuration = SLEEP_TIMEOUT + 250;
|
|
2032
2246
|
const fetchPromise = sleepActor.fetch(
|
|
@@ -2034,67 +2248,67 @@ function runActorSleepTests(driverTestConfig) {
|
|
|
2034
2248
|
);
|
|
2035
2249
|
const response = await fetchPromise;
|
|
2036
2250
|
const result = await response.json();
|
|
2037
|
-
|
|
2251
|
+
expect11(result.completed).toBe(true);
|
|
2038
2252
|
{
|
|
2039
2253
|
const { startCount, sleepCount, requestCount } = await sleepActor.getCounts();
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2254
|
+
expect11(sleepCount).toBe(0);
|
|
2255
|
+
expect11(startCount).toBe(1);
|
|
2256
|
+
expect11(requestCount).toBe(1);
|
|
2043
2257
|
}
|
|
2044
2258
|
await waitFor(driverTestConfig, SLEEP_TIMEOUT + 250);
|
|
2045
2259
|
{
|
|
2046
2260
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
2047
|
-
|
|
2048
|
-
|
|
2261
|
+
expect11(sleepCount).toBe(1);
|
|
2262
|
+
expect11(startCount).toBe(2);
|
|
2049
2263
|
}
|
|
2050
2264
|
});
|
|
2051
|
-
|
|
2265
|
+
test11("noSleep option disables sleeping", async (c) => {
|
|
2052
2266
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2053
2267
|
const sleepActor = client.sleepWithNoSleepOption.getOrCreate();
|
|
2054
2268
|
{
|
|
2055
2269
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
2056
|
-
|
|
2057
|
-
|
|
2270
|
+
expect11(sleepCount).toBe(0);
|
|
2271
|
+
expect11(startCount).toBe(1);
|
|
2058
2272
|
}
|
|
2059
2273
|
await waitFor(driverTestConfig, SLEEP_TIMEOUT + 250);
|
|
2060
2274
|
{
|
|
2061
2275
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
2062
|
-
|
|
2063
|
-
|
|
2276
|
+
expect11(sleepCount).toBe(0);
|
|
2277
|
+
expect11(startCount).toBe(1);
|
|
2064
2278
|
}
|
|
2065
2279
|
await waitFor(driverTestConfig, SLEEP_TIMEOUT + 250);
|
|
2066
2280
|
{
|
|
2067
2281
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
2068
|
-
|
|
2069
|
-
|
|
2282
|
+
expect11(sleepCount).toBe(0);
|
|
2283
|
+
expect11(startCount).toBe(1);
|
|
2070
2284
|
}
|
|
2071
2285
|
});
|
|
2072
2286
|
});
|
|
2073
2287
|
}
|
|
2074
2288
|
|
|
2075
2289
|
// src/driver-test-suite/tests/actor-state.ts
|
|
2076
|
-
import { describe as
|
|
2290
|
+
import { describe as describe12, expect as expect12, test as test12 } from "vitest";
|
|
2077
2291
|
function runActorStateTests(driverTestConfig) {
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2292
|
+
describe12("Actor State Tests", () => {
|
|
2293
|
+
describe12("State Persistence", () => {
|
|
2294
|
+
test12("persists state between actor instances", async (c) => {
|
|
2081
2295
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2082
2296
|
const counterInstance = client.counter.getOrCreate();
|
|
2083
2297
|
const initialCount = await counterInstance.increment(5);
|
|
2084
|
-
|
|
2298
|
+
expect12(initialCount).toBe(5);
|
|
2085
2299
|
const sameInstance = client.counter.getOrCreate();
|
|
2086
2300
|
const persistedCount = await sameInstance.increment(3);
|
|
2087
|
-
|
|
2301
|
+
expect12(persistedCount).toBe(8);
|
|
2088
2302
|
});
|
|
2089
|
-
|
|
2303
|
+
test12("restores state after actor disconnect/reconnect", async (c) => {
|
|
2090
2304
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2091
2305
|
const counterInstance = client.counter.getOrCreate();
|
|
2092
2306
|
await counterInstance.increment(5);
|
|
2093
2307
|
const reconnectedInstance = client.counter.getOrCreate();
|
|
2094
2308
|
const persistedCount = await reconnectedInstance.increment(0);
|
|
2095
|
-
|
|
2309
|
+
expect12(persistedCount).toBe(5);
|
|
2096
2310
|
});
|
|
2097
|
-
|
|
2311
|
+
test12("maintains separate state for different actors", async (c) => {
|
|
2098
2312
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2099
2313
|
const counterA = client.counter.getOrCreate(["counter-a"]);
|
|
2100
2314
|
await counterA.increment(5);
|
|
@@ -2102,8 +2316,8 @@ function runActorStateTests(driverTestConfig) {
|
|
|
2102
2316
|
await counterB.increment(10);
|
|
2103
2317
|
const countA = await counterA.increment(0);
|
|
2104
2318
|
const countB = await counterB.increment(0);
|
|
2105
|
-
|
|
2106
|
-
|
|
2319
|
+
expect12(countA).toBe(5);
|
|
2320
|
+
expect12(countB).toBe(10);
|
|
2107
2321
|
});
|
|
2108
2322
|
});
|
|
2109
2323
|
});
|
|
@@ -2111,90 +2325,91 @@ function runActorStateTests(driverTestConfig) {
|
|
|
2111
2325
|
|
|
2112
2326
|
// src/driver-test-suite/tests/actor-driver.ts
|
|
2113
2327
|
function runActorDriverTests(driverTestConfig) {
|
|
2114
|
-
|
|
2328
|
+
describe13("Actor Driver Tests", () => {
|
|
2115
2329
|
runActorStateTests(driverTestConfig);
|
|
2116
2330
|
runActorScheduleTests(driverTestConfig);
|
|
2117
2331
|
runActorSleepTests(driverTestConfig);
|
|
2332
|
+
runActorLifecycleTests(driverTestConfig);
|
|
2118
2333
|
});
|
|
2119
2334
|
}
|
|
2120
2335
|
|
|
2121
2336
|
// src/driver-test-suite/tests/actor-error-handling.ts
|
|
2122
|
-
import { describe as
|
|
2337
|
+
import { describe as describe14, expect as expect13, test as test13 } from "vitest";
|
|
2123
2338
|
function runActorErrorHandlingTests(driverTestConfig) {
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2339
|
+
describe14("Actor Error Handling Tests", () => {
|
|
2340
|
+
describe14("UserError Handling", () => {
|
|
2341
|
+
test13("should handle simple UserError with message", async (c) => {
|
|
2127
2342
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2128
2343
|
const handle = client.errorHandlingActor.getOrCreate();
|
|
2129
2344
|
try {
|
|
2130
2345
|
await handle.throwSimpleError();
|
|
2131
|
-
|
|
2346
|
+
expect13(true).toBe(false);
|
|
2132
2347
|
} catch (error) {
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2348
|
+
expect13(error.message).toBe("Simple error message");
|
|
2349
|
+
expect13(error.code).toBe("user_error");
|
|
2350
|
+
expect13(error.metadata).toBeUndefined();
|
|
2136
2351
|
}
|
|
2137
2352
|
});
|
|
2138
|
-
|
|
2353
|
+
test13("should handle detailed UserError with code and metadata", async (c) => {
|
|
2139
2354
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2140
2355
|
const handle = client.errorHandlingActor.getOrCreate();
|
|
2141
2356
|
try {
|
|
2142
2357
|
await handle.throwDetailedError();
|
|
2143
|
-
|
|
2358
|
+
expect13(true).toBe(false);
|
|
2144
2359
|
} catch (error) {
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2360
|
+
expect13(error.message).toBe("Detailed error message");
|
|
2361
|
+
expect13(error.code).toBe("detailed_error");
|
|
2362
|
+
expect13(error.metadata).toBeDefined();
|
|
2363
|
+
expect13(error.metadata.reason).toBe("test");
|
|
2364
|
+
expect13(error.metadata.timestamp).toBeDefined();
|
|
2150
2365
|
}
|
|
2151
2366
|
});
|
|
2152
2367
|
});
|
|
2153
|
-
|
|
2154
|
-
|
|
2368
|
+
describe14("Internal Error Handling", () => {
|
|
2369
|
+
test13("should convert internal errors to safe format", async (c) => {
|
|
2155
2370
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2156
2371
|
const handle = client.errorHandlingActor.getOrCreate();
|
|
2157
2372
|
try {
|
|
2158
2373
|
await handle.throwInternalError();
|
|
2159
|
-
|
|
2374
|
+
expect13(true).toBe(false);
|
|
2160
2375
|
} catch (error) {
|
|
2161
|
-
|
|
2162
|
-
|
|
2376
|
+
expect13(error.code).toBe(INTERNAL_ERROR_CODE);
|
|
2377
|
+
expect13(error.message).toBe(INTERNAL_ERROR_DESCRIPTION);
|
|
2163
2378
|
}
|
|
2164
2379
|
});
|
|
2165
2380
|
});
|
|
2166
|
-
|
|
2167
|
-
|
|
2381
|
+
describe14.skip("Action Timeout", () => {
|
|
2382
|
+
test13("should handle action timeouts with custom duration", async (c) => {
|
|
2168
2383
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2169
2384
|
const handle = client.errorHandlingActor.getOrCreate();
|
|
2170
2385
|
const timeoutPromise = handle.timeoutAction();
|
|
2171
2386
|
try {
|
|
2172
2387
|
await timeoutPromise;
|
|
2173
|
-
|
|
2388
|
+
expect13(true).toBe(false);
|
|
2174
2389
|
} catch (error) {
|
|
2175
|
-
|
|
2390
|
+
expect13(error.message).toMatch(/timed out/i);
|
|
2176
2391
|
}
|
|
2177
2392
|
});
|
|
2178
|
-
|
|
2393
|
+
test13("should successfully run actions within timeout", async (c) => {
|
|
2179
2394
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2180
2395
|
const handle = client.errorHandlingActor.getOrCreate();
|
|
2181
2396
|
const result = await handle.delayedAction(200);
|
|
2182
|
-
|
|
2397
|
+
expect13(result).toBe("Completed after 200ms");
|
|
2183
2398
|
});
|
|
2184
|
-
|
|
2399
|
+
test13("should respect different timeouts for different actors", async (c) => {
|
|
2185
2400
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2186
2401
|
try {
|
|
2187
2402
|
await client.customTimeoutActor.getOrCreate().slowAction();
|
|
2188
|
-
|
|
2403
|
+
expect13(true).toBe(false);
|
|
2189
2404
|
} catch (error) {
|
|
2190
|
-
|
|
2405
|
+
expect13(error.message).toMatch(/timed out/i);
|
|
2191
2406
|
}
|
|
2192
2407
|
const quickResult = await client.customTimeoutActor.getOrCreate().quickAction();
|
|
2193
|
-
|
|
2408
|
+
expect13(quickResult).toBe("Quick action completed");
|
|
2194
2409
|
});
|
|
2195
2410
|
});
|
|
2196
|
-
|
|
2197
|
-
|
|
2411
|
+
describe14("Error Recovery", () => {
|
|
2412
|
+
test13("should continue working after errors", async (c) => {
|
|
2198
2413
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2199
2414
|
const handle = client.errorHandlingActor.getOrCreate();
|
|
2200
2415
|
try {
|
|
@@ -2202,27 +2417,27 @@ function runActorErrorHandlingTests(driverTestConfig) {
|
|
|
2202
2417
|
} catch (error) {
|
|
2203
2418
|
}
|
|
2204
2419
|
const result = await handle.successfulAction();
|
|
2205
|
-
|
|
2420
|
+
expect13(result).toBe("success");
|
|
2206
2421
|
});
|
|
2207
2422
|
});
|
|
2208
2423
|
});
|
|
2209
2424
|
}
|
|
2210
2425
|
|
|
2211
2426
|
// src/driver-test-suite/tests/actor-handle.ts
|
|
2212
|
-
import { describe as
|
|
2427
|
+
import { describe as describe15, expect as expect14, test as test14 } from "vitest";
|
|
2213
2428
|
function runActorHandleTests(driverTestConfig) {
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2429
|
+
describe15("Actor Handle Tests", () => {
|
|
2430
|
+
describe15("Access Methods", () => {
|
|
2431
|
+
test14("should use .get() to access a actor", async (c) => {
|
|
2217
2432
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2218
2433
|
await client.counter.create(["test-get-handle"]);
|
|
2219
2434
|
const handle = client.counter.get(["test-get-handle"]);
|
|
2220
2435
|
const count = await handle.increment(5);
|
|
2221
|
-
|
|
2436
|
+
expect14(count).toBe(5);
|
|
2222
2437
|
const retrievedCount = await handle.getCount();
|
|
2223
|
-
|
|
2438
|
+
expect14(retrievedCount).toBe(5);
|
|
2224
2439
|
});
|
|
2225
|
-
|
|
2440
|
+
test14("should use .getForId() to access a actor by ID", async (c) => {
|
|
2226
2441
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2227
2442
|
const handle = client.counter.getOrCreate([
|
|
2228
2443
|
"test-get-for-id-handle"
|
|
@@ -2231,73 +2446,73 @@ function runActorHandleTests(driverTestConfig) {
|
|
|
2231
2446
|
const actorId = await handle.resolve();
|
|
2232
2447
|
const idHandle = client.counter.getForId(actorId);
|
|
2233
2448
|
const count = await idHandle.getCount();
|
|
2234
|
-
|
|
2449
|
+
expect14(count).toBe(3);
|
|
2235
2450
|
const newCount = await idHandle.increment(4);
|
|
2236
|
-
|
|
2451
|
+
expect14(newCount).toBe(7);
|
|
2237
2452
|
});
|
|
2238
|
-
|
|
2453
|
+
test14("should use .getOrCreate() to access or create a actor", async (c) => {
|
|
2239
2454
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2240
2455
|
const handle = client.counter.getOrCreate([
|
|
2241
2456
|
"test-get-or-create-handle"
|
|
2242
2457
|
]);
|
|
2243
2458
|
const count = await handle.increment(7);
|
|
2244
|
-
|
|
2459
|
+
expect14(count).toBe(7);
|
|
2245
2460
|
const sameHandle = client.counter.getOrCreate([
|
|
2246
2461
|
"test-get-or-create-handle"
|
|
2247
2462
|
]);
|
|
2248
2463
|
const retrievedCount = await sameHandle.getCount();
|
|
2249
|
-
|
|
2464
|
+
expect14(retrievedCount).toBe(7);
|
|
2250
2465
|
});
|
|
2251
|
-
|
|
2466
|
+
test14("should use (await create()) to create and return a handle", async (c) => {
|
|
2252
2467
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2253
2468
|
const handle = await client.counter.create([
|
|
2254
2469
|
"test-create-handle"
|
|
2255
2470
|
]);
|
|
2256
2471
|
const count = await handle.increment(9);
|
|
2257
|
-
|
|
2472
|
+
expect14(count).toBe(9);
|
|
2258
2473
|
const retrievedCount = await handle.getCount();
|
|
2259
|
-
|
|
2474
|
+
expect14(retrievedCount).toBe(9);
|
|
2260
2475
|
});
|
|
2261
|
-
|
|
2476
|
+
test14("errors when calling create twice with the same key", async (c) => {
|
|
2262
2477
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2263
2478
|
const key = ["duplicate-create-handle", crypto.randomUUID()];
|
|
2264
2479
|
await client.counter.create(key);
|
|
2265
2480
|
try {
|
|
2266
2481
|
await client.counter.create(key);
|
|
2267
|
-
|
|
2482
|
+
expect14.fail("did not error on duplicate create");
|
|
2268
2483
|
} catch (err) {
|
|
2269
|
-
|
|
2270
|
-
|
|
2484
|
+
expect14(err.group).toBe("actor");
|
|
2485
|
+
expect14(err.code).toBe("duplicate_key");
|
|
2271
2486
|
}
|
|
2272
2487
|
});
|
|
2273
|
-
|
|
2488
|
+
test14(".get().resolve() errors for non-existent actor", async (c) => {
|
|
2274
2489
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2275
2490
|
const missingId = `nonexistent-${crypto.randomUUID()}`;
|
|
2276
2491
|
try {
|
|
2277
2492
|
await client.counter.get([missingId]).resolve();
|
|
2278
|
-
|
|
2493
|
+
expect14.fail(
|
|
2279
2494
|
"did not error for get().resolve() on missing actor"
|
|
2280
2495
|
);
|
|
2281
2496
|
} catch (err) {
|
|
2282
|
-
|
|
2283
|
-
|
|
2497
|
+
expect14(err.group).toBe("actor");
|
|
2498
|
+
expect14(err.code).toBe("not_found");
|
|
2284
2499
|
}
|
|
2285
2500
|
});
|
|
2286
2501
|
});
|
|
2287
|
-
|
|
2288
|
-
|
|
2502
|
+
describe15("Action Functionality", () => {
|
|
2503
|
+
test14("should call actions directly on the handle", async (c) => {
|
|
2289
2504
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2290
2505
|
const handle = client.counter.getOrCreate([
|
|
2291
2506
|
"test-action-handle"
|
|
2292
2507
|
]);
|
|
2293
2508
|
const count1 = await handle.increment(3);
|
|
2294
|
-
|
|
2509
|
+
expect14(count1).toBe(3);
|
|
2295
2510
|
const count2 = await handle.increment(5);
|
|
2296
|
-
|
|
2511
|
+
expect14(count2).toBe(8);
|
|
2297
2512
|
const retrievedCount = await handle.getCount();
|
|
2298
|
-
|
|
2513
|
+
expect14(retrievedCount).toBe(8);
|
|
2299
2514
|
});
|
|
2300
|
-
|
|
2515
|
+
test14("should handle independent handles to the same actor", async (c) => {
|
|
2301
2516
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2302
2517
|
const handle1 = client.counter.getOrCreate([
|
|
2303
2518
|
"test-multiple-handles"
|
|
@@ -2305,82 +2520,82 @@ function runActorHandleTests(driverTestConfig) {
|
|
|
2305
2520
|
const handle2 = client.counter.get(["test-multiple-handles"]);
|
|
2306
2521
|
await handle1.increment(3);
|
|
2307
2522
|
const count = await handle2.getCount();
|
|
2308
|
-
|
|
2523
|
+
expect14(count).toBe(3);
|
|
2309
2524
|
const finalCount = await handle2.increment(4);
|
|
2310
|
-
|
|
2525
|
+
expect14(finalCount).toBe(7);
|
|
2311
2526
|
const checkCount = await handle1.getCount();
|
|
2312
|
-
|
|
2527
|
+
expect14(checkCount).toBe(7);
|
|
2313
2528
|
});
|
|
2314
|
-
|
|
2529
|
+
test14("should resolve a actor's ID", async (c) => {
|
|
2315
2530
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2316
2531
|
const handle = client.counter.getOrCreate(["test-resolve-id"]);
|
|
2317
2532
|
await handle.increment(1);
|
|
2318
2533
|
const actorId = await handle.resolve();
|
|
2319
|
-
|
|
2320
|
-
|
|
2534
|
+
expect14(typeof actorId).toBe("string");
|
|
2535
|
+
expect14(actorId).not.toBe("");
|
|
2321
2536
|
const idHandle = client.counter.getForId(actorId);
|
|
2322
2537
|
const count = await idHandle.getCount();
|
|
2323
|
-
|
|
2538
|
+
expect14(count).toBe(1);
|
|
2324
2539
|
});
|
|
2325
2540
|
});
|
|
2326
|
-
|
|
2327
|
-
|
|
2541
|
+
describe15("Lifecycle Hooks", () => {
|
|
2542
|
+
test14("should trigger lifecycle hooks on actor creation", async (c) => {
|
|
2328
2543
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2329
2544
|
const handle = client.counterWithLifecycle.getOrCreate([
|
|
2330
2545
|
"test-lifecycle-handle"
|
|
2331
2546
|
]);
|
|
2332
2547
|
const initialEvents = await handle.getEvents();
|
|
2333
|
-
|
|
2548
|
+
expect14(initialEvents).toContain("onWake");
|
|
2334
2549
|
const sameHandle = client.counterWithLifecycle.getOrCreate([
|
|
2335
2550
|
"test-lifecycle-handle"
|
|
2336
2551
|
]);
|
|
2337
2552
|
const events = await sameHandle.getEvents();
|
|
2338
|
-
|
|
2339
|
-
|
|
2553
|
+
expect14(events).toContain("onWake");
|
|
2554
|
+
expect14(events.filter((e) => e === "onWake").length).toBe(1);
|
|
2340
2555
|
});
|
|
2341
|
-
|
|
2556
|
+
test14("should trigger lifecycle hooks for each Action call", async (c) => {
|
|
2342
2557
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2343
2558
|
const viewHandle = client.counterWithLifecycle.getOrCreate([
|
|
2344
2559
|
"test-lifecycle-action"
|
|
2345
2560
|
]);
|
|
2346
2561
|
const initialEvents = await viewHandle.getEvents();
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2562
|
+
expect14(initialEvents).toContain("onWake");
|
|
2563
|
+
expect14(initialEvents).not.toContain("onBeforeConnect");
|
|
2564
|
+
expect14(initialEvents).not.toContain("onConnect");
|
|
2565
|
+
expect14(initialEvents).not.toContain("onDisconnect");
|
|
2351
2566
|
const trackingHandle = client.counterWithLifecycle.getOrCreate(
|
|
2352
2567
|
["test-lifecycle-action"],
|
|
2353
2568
|
{ params: { trackLifecycle: true } }
|
|
2354
2569
|
);
|
|
2355
2570
|
await trackingHandle.increment(5);
|
|
2356
2571
|
const eventsAfterAction = await viewHandle.getEvents();
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2572
|
+
expect14(eventsAfterAction).toContain("onBeforeConnect");
|
|
2573
|
+
expect14(eventsAfterAction).toContain("onConnect");
|
|
2574
|
+
expect14(eventsAfterAction).toContain("onDisconnect");
|
|
2575
|
+
expect14(
|
|
2361
2576
|
eventsAfterAction.filter((e) => e === "onBeforeConnect").length
|
|
2362
2577
|
).toBe(1);
|
|
2363
|
-
|
|
2578
|
+
expect14(
|
|
2364
2579
|
eventsAfterAction.filter((e) => e === "onConnect").length
|
|
2365
2580
|
).toBe(1);
|
|
2366
|
-
|
|
2581
|
+
expect14(
|
|
2367
2582
|
eventsAfterAction.filter((e) => e === "onDisconnect").length
|
|
2368
2583
|
).toBe(1);
|
|
2369
2584
|
await trackingHandle.increment(10);
|
|
2370
2585
|
const eventsAfterSecondAction = await viewHandle.getEvents();
|
|
2371
|
-
|
|
2586
|
+
expect14(
|
|
2372
2587
|
eventsAfterSecondAction.filter(
|
|
2373
2588
|
(e) => e === "onBeforeConnect"
|
|
2374
2589
|
).length
|
|
2375
2590
|
).toBe(2);
|
|
2376
|
-
|
|
2591
|
+
expect14(
|
|
2377
2592
|
eventsAfterSecondAction.filter((e) => e === "onConnect").length
|
|
2378
2593
|
).toBe(2);
|
|
2379
|
-
|
|
2594
|
+
expect14(
|
|
2380
2595
|
eventsAfterSecondAction.filter((e) => e === "onDisconnect").length
|
|
2381
2596
|
).toBe(2);
|
|
2382
2597
|
});
|
|
2383
|
-
|
|
2598
|
+
test14("should trigger lifecycle hooks for each Action call across multiple handles", async (c) => {
|
|
2384
2599
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2385
2600
|
const viewHandle = client.counterWithLifecycle.getOrCreate([
|
|
2386
2601
|
"test-lifecycle-multi-handle"
|
|
@@ -2396,12 +2611,12 @@ function runActorHandleTests(driverTestConfig) {
|
|
|
2396
2611
|
await trackingHandle1.increment(5);
|
|
2397
2612
|
await trackingHandle2.increment(10);
|
|
2398
2613
|
const events = await viewHandle.getEvents();
|
|
2399
|
-
|
|
2400
|
-
|
|
2614
|
+
expect14(events.filter((e) => e === "onWake").length).toBe(1);
|
|
2615
|
+
expect14(
|
|
2401
2616
|
events.filter((e) => e === "onBeforeConnect").length
|
|
2402
2617
|
).toBe(2);
|
|
2403
|
-
|
|
2404
|
-
|
|
2618
|
+
expect14(events.filter((e) => e === "onConnect").length).toBe(2);
|
|
2619
|
+
expect14(events.filter((e) => e === "onDisconnect").length).toBe(
|
|
2405
2620
|
2
|
|
2406
2621
|
);
|
|
2407
2622
|
});
|
|
@@ -2410,27 +2625,27 @@ function runActorHandleTests(driverTestConfig) {
|
|
|
2410
2625
|
}
|
|
2411
2626
|
|
|
2412
2627
|
// src/driver-test-suite/tests/actor-inline-client.ts
|
|
2413
|
-
import { describe as
|
|
2628
|
+
import { describe as describe16, expect as expect15, test as test15 } from "vitest";
|
|
2414
2629
|
function runActorInlineClientTests(driverTestConfig) {
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2630
|
+
describe16("Actor Inline Client Tests", () => {
|
|
2631
|
+
describe16("Stateless Client Calls", () => {
|
|
2632
|
+
test15("should make stateless calls to other actors", async (c) => {
|
|
2418
2633
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2419
2634
|
const inlineClientHandle = client.inlineClientActor.getOrCreate(
|
|
2420
2635
|
["inline-client-test"]
|
|
2421
2636
|
);
|
|
2422
2637
|
const result = await inlineClientHandle.callCounterIncrement(5);
|
|
2423
|
-
|
|
2638
|
+
expect15(result).toBe(5);
|
|
2424
2639
|
const counterState = await inlineClientHandle.getCounterState();
|
|
2425
|
-
|
|
2640
|
+
expect15(counterState).toBe(5);
|
|
2426
2641
|
const messages = await inlineClientHandle.getMessages();
|
|
2427
|
-
|
|
2428
|
-
|
|
2642
|
+
expect15(messages).toHaveLength(2);
|
|
2643
|
+
expect15(messages[0]).toContain(
|
|
2429
2644
|
"Called counter.increment(5), result: 5"
|
|
2430
2645
|
);
|
|
2431
|
-
|
|
2646
|
+
expect15(messages[1]).toContain("Got counter state: 5");
|
|
2432
2647
|
});
|
|
2433
|
-
|
|
2648
|
+
test15("should handle multiple stateless calls", async (c) => {
|
|
2434
2649
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2435
2650
|
const inlineClientHandle = client.inlineClientActor.getOrCreate(
|
|
2436
2651
|
["inline-client-multi"]
|
|
@@ -2439,58 +2654,58 @@ function runActorInlineClientTests(driverTestConfig) {
|
|
|
2439
2654
|
const result1 = await inlineClientHandle.callCounterIncrement(3);
|
|
2440
2655
|
const result2 = await inlineClientHandle.callCounterIncrement(7);
|
|
2441
2656
|
const finalState = await inlineClientHandle.getCounterState();
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2657
|
+
expect15(result1).toBe(3);
|
|
2658
|
+
expect15(result2).toBe(10);
|
|
2659
|
+
expect15(finalState).toBe(10);
|
|
2445
2660
|
const messages = await inlineClientHandle.getMessages();
|
|
2446
|
-
|
|
2447
|
-
|
|
2661
|
+
expect15(messages).toHaveLength(3);
|
|
2662
|
+
expect15(messages[0]).toContain(
|
|
2448
2663
|
"Called counter.increment(3), result: 3"
|
|
2449
2664
|
);
|
|
2450
|
-
|
|
2665
|
+
expect15(messages[1]).toContain(
|
|
2451
2666
|
"Called counter.increment(7), result: 10"
|
|
2452
2667
|
);
|
|
2453
|
-
|
|
2668
|
+
expect15(messages[2]).toContain("Got counter state: 10");
|
|
2454
2669
|
});
|
|
2455
2670
|
});
|
|
2456
|
-
|
|
2457
|
-
|
|
2671
|
+
describe16("Stateful Client Calls", () => {
|
|
2672
|
+
test15("should connect to other actors and receive events", async (c) => {
|
|
2458
2673
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2459
2674
|
const inlineClientHandle = client.inlineClientActor.getOrCreate(
|
|
2460
2675
|
["inline-client-stateful"]
|
|
2461
2676
|
);
|
|
2462
2677
|
await inlineClientHandle.clearMessages();
|
|
2463
2678
|
const result = await inlineClientHandle.connectToCounterAndIncrement(4);
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2679
|
+
expect15(result.result1).toBe(4);
|
|
2680
|
+
expect15(result.result2).toBe(12);
|
|
2681
|
+
expect15(result.events).toEqual([4, 12]);
|
|
2467
2682
|
const messages = await inlineClientHandle.getMessages();
|
|
2468
|
-
|
|
2469
|
-
|
|
2683
|
+
expect15(messages).toHaveLength(1);
|
|
2684
|
+
expect15(messages[0]).toContain(
|
|
2470
2685
|
"Connected to counter, incremented by 4 and 8"
|
|
2471
2686
|
);
|
|
2472
|
-
|
|
2473
|
-
|
|
2687
|
+
expect15(messages[0]).toContain("results: 4, 12");
|
|
2688
|
+
expect15(messages[0]).toContain("events: [4,12]");
|
|
2474
2689
|
});
|
|
2475
|
-
|
|
2690
|
+
test15("should handle stateful connection independently", async (c) => {
|
|
2476
2691
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2477
2692
|
const inlineClientHandle = client.inlineClientActor.getOrCreate(
|
|
2478
2693
|
["inline-client-independent"]
|
|
2479
2694
|
);
|
|
2480
2695
|
await inlineClientHandle.clearMessages();
|
|
2481
2696
|
const result = await inlineClientHandle.connectToCounterAndIncrement(2);
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2697
|
+
expect15(result.result1).toBe(2);
|
|
2698
|
+
expect15(result.result2).toBe(6);
|
|
2699
|
+
expect15(result.events).toEqual([2, 6]);
|
|
2485
2700
|
const messages = await inlineClientHandle.getMessages();
|
|
2486
|
-
|
|
2487
|
-
|
|
2701
|
+
expect15(messages).toHaveLength(1);
|
|
2702
|
+
expect15(messages[0]).toContain(
|
|
2488
2703
|
"Connected to counter, incremented by 2 and 4"
|
|
2489
2704
|
);
|
|
2490
2705
|
});
|
|
2491
2706
|
});
|
|
2492
|
-
|
|
2493
|
-
|
|
2707
|
+
describe16("Mixed Client Usage", () => {
|
|
2708
|
+
test15("should handle both stateless and stateful calls", async (c) => {
|
|
2494
2709
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2495
2710
|
const inlineClientHandle = client.inlineClientActor.getOrCreate(
|
|
2496
2711
|
["inline-client-mixed"]
|
|
@@ -2498,17 +2713,17 @@ function runActorInlineClientTests(driverTestConfig) {
|
|
|
2498
2713
|
await inlineClientHandle.clearMessages();
|
|
2499
2714
|
await inlineClientHandle.callCounterIncrement(1);
|
|
2500
2715
|
const statelessResult = await inlineClientHandle.getCounterState();
|
|
2501
|
-
|
|
2716
|
+
expect15(statelessResult).toBe(1);
|
|
2502
2717
|
const statefulResult = await inlineClientHandle.connectToCounterAndIncrement(3);
|
|
2503
|
-
|
|
2504
|
-
|
|
2718
|
+
expect15(statefulResult.result1).toBe(3);
|
|
2719
|
+
expect15(statefulResult.result2).toBe(9);
|
|
2505
2720
|
const messages = await inlineClientHandle.getMessages();
|
|
2506
|
-
|
|
2507
|
-
|
|
2721
|
+
expect15(messages).toHaveLength(3);
|
|
2722
|
+
expect15(messages[0]).toContain(
|
|
2508
2723
|
"Called counter.increment(1), result: 1"
|
|
2509
2724
|
);
|
|
2510
|
-
|
|
2511
|
-
|
|
2725
|
+
expect15(messages[1]).toContain("Got counter state: 1");
|
|
2726
|
+
expect15(messages[2]).toContain(
|
|
2512
2727
|
"Connected to counter, incremented by 3 and 6"
|
|
2513
2728
|
);
|
|
2514
2729
|
});
|
|
@@ -2517,10 +2732,10 @@ function runActorInlineClientTests(driverTestConfig) {
|
|
|
2517
2732
|
}
|
|
2518
2733
|
|
|
2519
2734
|
// src/driver-test-suite/tests/actor-inspector.ts
|
|
2520
|
-
import { describe as
|
|
2735
|
+
import { describe as describe17, expect as expect16, test as test16 } from "vitest";
|
|
2521
2736
|
function runActorInspectorTests(driverTestConfig) {
|
|
2522
|
-
|
|
2523
|
-
|
|
2737
|
+
describe17("Actor Inspector HTTP API", () => {
|
|
2738
|
+
test16("GET /inspector/state returns actor state", async (c) => {
|
|
2524
2739
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2525
2740
|
const handle = client.counter.getOrCreate(["inspector-state"]);
|
|
2526
2741
|
await handle.increment(5);
|
|
@@ -2528,11 +2743,11 @@ function runActorInspectorTests(driverTestConfig) {
|
|
|
2528
2743
|
const response = await fetch(`${gatewayUrl}/inspector/state`, {
|
|
2529
2744
|
headers: { Authorization: "Bearer token" }
|
|
2530
2745
|
});
|
|
2531
|
-
|
|
2746
|
+
expect16(response.status).toBe(200);
|
|
2532
2747
|
const data = await response.json();
|
|
2533
|
-
|
|
2748
|
+
expect16(data).toEqual({ state: { count: 5 } });
|
|
2534
2749
|
});
|
|
2535
|
-
|
|
2750
|
+
test16("PATCH /inspector/state updates actor state", async (c) => {
|
|
2536
2751
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2537
2752
|
const handle = client.counter.getOrCreate([
|
|
2538
2753
|
"inspector-set-state"
|
|
@@ -2550,13 +2765,13 @@ function runActorInspectorTests(driverTestConfig) {
|
|
|
2550
2765
|
body: JSON.stringify({ state: { count: 42 } })
|
|
2551
2766
|
}
|
|
2552
2767
|
);
|
|
2553
|
-
|
|
2768
|
+
expect16(patchResponse.status).toBe(200);
|
|
2554
2769
|
const patchData = await patchResponse.json();
|
|
2555
|
-
|
|
2770
|
+
expect16(patchData).toEqual({ ok: true });
|
|
2556
2771
|
const count = await handle.getCount();
|
|
2557
|
-
|
|
2772
|
+
expect16(count).toBe(42);
|
|
2558
2773
|
});
|
|
2559
|
-
|
|
2774
|
+
test16("GET /inspector/connections returns connections list", async (c) => {
|
|
2560
2775
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2561
2776
|
const handle = client.counter.getOrCreate([
|
|
2562
2777
|
"inspector-connections"
|
|
@@ -2569,12 +2784,12 @@ function runActorInspectorTests(driverTestConfig) {
|
|
|
2569
2784
|
headers: { Authorization: "Bearer token" }
|
|
2570
2785
|
}
|
|
2571
2786
|
);
|
|
2572
|
-
|
|
2787
|
+
expect16(response.status).toBe(200);
|
|
2573
2788
|
const data = await response.json();
|
|
2574
|
-
|
|
2575
|
-
|
|
2789
|
+
expect16(data).toHaveProperty("connections");
|
|
2790
|
+
expect16(Array.isArray(data.connections)).toBe(true);
|
|
2576
2791
|
});
|
|
2577
|
-
|
|
2792
|
+
test16("GET /inspector/rpcs returns available actions", async (c) => {
|
|
2578
2793
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2579
2794
|
const handle = client.counter.getOrCreate(["inspector-rpcs"]);
|
|
2580
2795
|
await handle.increment(0);
|
|
@@ -2582,14 +2797,14 @@ function runActorInspectorTests(driverTestConfig) {
|
|
|
2582
2797
|
const response = await fetch(`${gatewayUrl}/inspector/rpcs`, {
|
|
2583
2798
|
headers: { Authorization: "Bearer token" }
|
|
2584
2799
|
});
|
|
2585
|
-
|
|
2800
|
+
expect16(response.status).toBe(200);
|
|
2586
2801
|
const data = await response.json();
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2802
|
+
expect16(data).toHaveProperty("rpcs");
|
|
2803
|
+
expect16(data.rpcs).toContain("increment");
|
|
2804
|
+
expect16(data.rpcs).toContain("getCount");
|
|
2805
|
+
expect16(data.rpcs).toContain("setCount");
|
|
2591
2806
|
});
|
|
2592
|
-
|
|
2807
|
+
test16("POST /inspector/action/:name executes an action", async (c) => {
|
|
2593
2808
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2594
2809
|
const handle = client.counter.getOrCreate([
|
|
2595
2810
|
"inspector-action"
|
|
@@ -2607,13 +2822,13 @@ function runActorInspectorTests(driverTestConfig) {
|
|
|
2607
2822
|
body: JSON.stringify({ args: [5] })
|
|
2608
2823
|
}
|
|
2609
2824
|
);
|
|
2610
|
-
|
|
2825
|
+
expect16(response.status).toBe(200);
|
|
2611
2826
|
const data = await response.json();
|
|
2612
|
-
|
|
2827
|
+
expect16(data.output).toBe(15);
|
|
2613
2828
|
const count = await handle.getCount();
|
|
2614
|
-
|
|
2829
|
+
expect16(count).toBe(15);
|
|
2615
2830
|
});
|
|
2616
|
-
|
|
2831
|
+
test16("GET /inspector/queue returns queue status", async (c) => {
|
|
2617
2832
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2618
2833
|
const handle = client.counter.getOrCreate(["inspector-queue"]);
|
|
2619
2834
|
await handle.increment(0);
|
|
@@ -2624,18 +2839,18 @@ function runActorInspectorTests(driverTestConfig) {
|
|
|
2624
2839
|
headers: { Authorization: "Bearer token" }
|
|
2625
2840
|
}
|
|
2626
2841
|
);
|
|
2627
|
-
|
|
2842
|
+
expect16(response.status).toBe(200);
|
|
2628
2843
|
const data = await response.json();
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
});
|
|
2638
|
-
|
|
2844
|
+
expect16(data).toHaveProperty("size");
|
|
2845
|
+
expect16(data).toHaveProperty("maxSize");
|
|
2846
|
+
expect16(data).toHaveProperty("truncated");
|
|
2847
|
+
expect16(data).toHaveProperty("messages");
|
|
2848
|
+
expect16(typeof data.size).toBe("number");
|
|
2849
|
+
expect16(typeof data.maxSize).toBe("number");
|
|
2850
|
+
expect16(typeof data.truncated).toBe("boolean");
|
|
2851
|
+
expect16(Array.isArray(data.messages)).toBe(true);
|
|
2852
|
+
});
|
|
2853
|
+
test16("GET /inspector/traces returns trace data", async (c) => {
|
|
2639
2854
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2640
2855
|
const handle = client.counter.getOrCreate([
|
|
2641
2856
|
"inspector-traces"
|
|
@@ -2648,13 +2863,13 @@ function runActorInspectorTests(driverTestConfig) {
|
|
|
2648
2863
|
headers: { Authorization: "Bearer token" }
|
|
2649
2864
|
}
|
|
2650
2865
|
);
|
|
2651
|
-
|
|
2866
|
+
expect16(response.status).toBe(200);
|
|
2652
2867
|
const data = await response.json();
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2868
|
+
expect16(data).toHaveProperty("otlp");
|
|
2869
|
+
expect16(data).toHaveProperty("clamped");
|
|
2870
|
+
expect16(typeof data.clamped).toBe("boolean");
|
|
2656
2871
|
});
|
|
2657
|
-
|
|
2872
|
+
test16("GET /inspector/workflow-history returns workflow status", async (c) => {
|
|
2658
2873
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2659
2874
|
const handle = client.counter.getOrCreate([
|
|
2660
2875
|
"inspector-workflow"
|
|
@@ -2667,14 +2882,14 @@ function runActorInspectorTests(driverTestConfig) {
|
|
|
2667
2882
|
headers: { Authorization: "Bearer token" }
|
|
2668
2883
|
}
|
|
2669
2884
|
);
|
|
2670
|
-
|
|
2885
|
+
expect16(response.status).toBe(200);
|
|
2671
2886
|
const data = await response.json();
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2887
|
+
expect16(data).toHaveProperty("history");
|
|
2888
|
+
expect16(data).toHaveProperty("isWorkflowEnabled");
|
|
2889
|
+
expect16(data.isWorkflowEnabled).toBe(false);
|
|
2890
|
+
expect16(data.history).toBeNull();
|
|
2676
2891
|
});
|
|
2677
|
-
|
|
2892
|
+
test16("GET /inspector/summary returns full actor snapshot", async (c) => {
|
|
2678
2893
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2679
2894
|
const handle = client.counter.getOrCreate([
|
|
2680
2895
|
"inspector-summary"
|
|
@@ -2687,18 +2902,18 @@ function runActorInspectorTests(driverTestConfig) {
|
|
|
2687
2902
|
headers: { Authorization: "Bearer token" }
|
|
2688
2903
|
}
|
|
2689
2904
|
);
|
|
2690
|
-
|
|
2905
|
+
expect16(response.status).toBe(200);
|
|
2691
2906
|
const data = await response.json();
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
});
|
|
2701
|
-
|
|
2907
|
+
expect16(data.state).toEqual({ count: 7 });
|
|
2908
|
+
expect16(Array.isArray(data.connections)).toBe(true);
|
|
2909
|
+
expect16(data.rpcs).toContain("increment");
|
|
2910
|
+
expect16(typeof data.queueSize).toBe("number");
|
|
2911
|
+
expect16(data.isStateEnabled).toBe(true);
|
|
2912
|
+
expect16(typeof data.isDatabaseEnabled).toBe("boolean");
|
|
2913
|
+
expect16(data.isWorkflowEnabled).toBe(false);
|
|
2914
|
+
expect16(data.workflowHistory).toBeNull();
|
|
2915
|
+
});
|
|
2916
|
+
test16("inspector endpoints require auth in non-dev mode", async (c) => {
|
|
2702
2917
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2703
2918
|
const handle = client.counter.getOrCreate([
|
|
2704
2919
|
"inspector-auth"
|
|
@@ -2708,16 +2923,16 @@ function runActorInspectorTests(driverTestConfig) {
|
|
|
2708
2923
|
const response = await fetch(`${gatewayUrl}/inspector/state`, {
|
|
2709
2924
|
headers: { Authorization: "Bearer wrong-token" }
|
|
2710
2925
|
});
|
|
2711
|
-
|
|
2926
|
+
expect16(response.status).toBe(401);
|
|
2712
2927
|
});
|
|
2713
2928
|
});
|
|
2714
2929
|
}
|
|
2715
2930
|
|
|
2716
2931
|
// src/driver-test-suite/tests/actor-kv.ts
|
|
2717
|
-
import { describe as
|
|
2932
|
+
import { describe as describe18, expect as expect17, test as test17 } from "vitest";
|
|
2718
2933
|
function runActorKvTests(driverTestConfig) {
|
|
2719
|
-
|
|
2720
|
-
|
|
2934
|
+
describe18("Actor KV Tests", () => {
|
|
2935
|
+
test17("supports text encoding and decoding", async (c) => {
|
|
2721
2936
|
const { client: rawClient } = await setupDriverTest(
|
|
2722
2937
|
c,
|
|
2723
2938
|
driverTestConfig
|
|
@@ -2726,17 +2941,17 @@ function runActorKvTests(driverTestConfig) {
|
|
|
2726
2941
|
const kvHandle = client.kvActor.getOrCreate(["kv-text"]);
|
|
2727
2942
|
await kvHandle.putText("greeting", "hello");
|
|
2728
2943
|
const value = await kvHandle.getText("greeting");
|
|
2729
|
-
|
|
2944
|
+
expect17(value).toBe("hello");
|
|
2730
2945
|
await kvHandle.putText("prefix-a", "alpha");
|
|
2731
2946
|
await kvHandle.putText("prefix-b", "beta");
|
|
2732
2947
|
const results = await kvHandle.listText("prefix-");
|
|
2733
2948
|
const sorted = results.sort((a, b) => a.key.localeCompare(b.key));
|
|
2734
|
-
|
|
2949
|
+
expect17(sorted).toEqual([
|
|
2735
2950
|
{ key: "prefix-a", value: "alpha" },
|
|
2736
2951
|
{ key: "prefix-b", value: "beta" }
|
|
2737
2952
|
]);
|
|
2738
2953
|
});
|
|
2739
|
-
|
|
2954
|
+
test17(
|
|
2740
2955
|
"supports arrayBuffer encoding and decoding",
|
|
2741
2956
|
async (c) => {
|
|
2742
2957
|
const { client: rawClient } = await setupDriverTest(
|
|
@@ -2755,32 +2970,32 @@ function runActorKvTests(driverTestConfig) {
|
|
|
2755
2970
|
23,
|
|
2756
2971
|
42
|
|
2757
2972
|
]);
|
|
2758
|
-
|
|
2973
|
+
expect17(values).toEqual([4, 8, 15, 16, 23, 42]);
|
|
2759
2974
|
}
|
|
2760
2975
|
);
|
|
2761
2976
|
});
|
|
2762
2977
|
}
|
|
2763
2978
|
|
|
2764
2979
|
// src/driver-test-suite/tests/actor-metadata.ts
|
|
2765
|
-
import { describe as
|
|
2980
|
+
import { describe as describe19, expect as expect18, test as test18 } from "vitest";
|
|
2766
2981
|
function runActorMetadataTests(driverTestConfig) {
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2982
|
+
describe19("Actor Metadata Tests", () => {
|
|
2983
|
+
describe19("Actor Name", () => {
|
|
2984
|
+
test18("should provide access to actor name", async (c) => {
|
|
2770
2985
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2771
2986
|
const handle = client.metadataActor.getOrCreate();
|
|
2772
2987
|
const actorName = await handle.getActorName();
|
|
2773
|
-
|
|
2988
|
+
expect18(actorName).toBe("metadataActor");
|
|
2774
2989
|
});
|
|
2775
|
-
|
|
2990
|
+
test18("should preserve actor name in state during onWake", async (c) => {
|
|
2776
2991
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2777
2992
|
const handle = client.metadataActor.getOrCreate();
|
|
2778
2993
|
const storedName = await handle.getStoredActorName();
|
|
2779
|
-
|
|
2994
|
+
expect18(storedName).toBe("metadataActor");
|
|
2780
2995
|
});
|
|
2781
2996
|
});
|
|
2782
|
-
|
|
2783
|
-
|
|
2997
|
+
describe19("Actor Tags", () => {
|
|
2998
|
+
test18("should provide access to tags", async (c) => {
|
|
2784
2999
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2785
3000
|
const handle = client.metadataActor.getOrCreate();
|
|
2786
3001
|
await handle.setupTestTags({
|
|
@@ -2788,12 +3003,12 @@ function runActorMetadataTests(driverTestConfig) {
|
|
|
2788
3003
|
purpose: "metadata-test"
|
|
2789
3004
|
});
|
|
2790
3005
|
const tags = await handle.getTags();
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
3006
|
+
expect18(tags).toHaveProperty("env");
|
|
3007
|
+
expect18(tags.env).toBe("test");
|
|
3008
|
+
expect18(tags).toHaveProperty("purpose");
|
|
3009
|
+
expect18(tags.purpose).toBe("metadata-test");
|
|
2795
3010
|
});
|
|
2796
|
-
|
|
3011
|
+
test18("should allow accessing individual tags", async (c) => {
|
|
2797
3012
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2798
3013
|
const handle = client.metadataActor.getOrCreate();
|
|
2799
3014
|
await handle.setupTestTags({
|
|
@@ -2803,128 +3018,128 @@ function runActorMetadataTests(driverTestConfig) {
|
|
|
2803
3018
|
const category = await handle.getTag("category");
|
|
2804
3019
|
const version = await handle.getTag("version");
|
|
2805
3020
|
const nonexistent = await handle.getTag("nonexistent");
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
3021
|
+
expect18(category).toBe("test-actor");
|
|
3022
|
+
expect18(version).toBe("1.0");
|
|
3023
|
+
expect18(nonexistent).toBeNull();
|
|
2809
3024
|
});
|
|
2810
3025
|
});
|
|
2811
|
-
|
|
2812
|
-
|
|
3026
|
+
describe19("Metadata Structure", () => {
|
|
3027
|
+
test18("should provide complete metadata object", async (c) => {
|
|
2813
3028
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2814
3029
|
const handle = client.metadataActor.getOrCreate();
|
|
2815
3030
|
await handle.setupTestTags({ type: "metadata-test" });
|
|
2816
3031
|
await handle.setupTestRegion("us-west-1");
|
|
2817
3032
|
const metadata = await handle.getMetadata();
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
3033
|
+
expect18(metadata).toHaveProperty("name");
|
|
3034
|
+
expect18(metadata.name).toBe("metadataActor");
|
|
3035
|
+
expect18(metadata).toHaveProperty("tags");
|
|
3036
|
+
expect18(metadata.tags).toHaveProperty("type");
|
|
3037
|
+
expect18(metadata.tags.type).toBe("metadata-test");
|
|
3038
|
+
expect18(metadata).toHaveProperty("region");
|
|
3039
|
+
expect18(metadata.region).toBe("us-west-1");
|
|
2825
3040
|
});
|
|
2826
3041
|
});
|
|
2827
|
-
|
|
2828
|
-
|
|
3042
|
+
describe19("Region Information", () => {
|
|
3043
|
+
test18("should retrieve region information", async (c) => {
|
|
2829
3044
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2830
3045
|
const handle = client.metadataActor.getOrCreate();
|
|
2831
3046
|
await handle.setupTestRegion("eu-central-1");
|
|
2832
3047
|
const region = await handle.getRegion();
|
|
2833
|
-
|
|
3048
|
+
expect18(region).toBe("eu-central-1");
|
|
2834
3049
|
});
|
|
2835
3050
|
});
|
|
2836
3051
|
});
|
|
2837
3052
|
}
|
|
2838
3053
|
|
|
2839
3054
|
// src/driver-test-suite/tests/actor-onstatechange.ts
|
|
2840
|
-
import { describe as
|
|
3055
|
+
import { describe as describe20, expect as expect19, test as test19 } from "vitest";
|
|
2841
3056
|
function runActorOnStateChangeTests(driverTestConfig) {
|
|
2842
|
-
|
|
2843
|
-
|
|
3057
|
+
describe20("Actor onStateChange Tests", () => {
|
|
3058
|
+
test19("triggers onStateChange when state is modified", async (c) => {
|
|
2844
3059
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2845
3060
|
const actor = client.onStateChangeActor.getOrCreate();
|
|
2846
3061
|
await actor.setValue(10);
|
|
2847
3062
|
const changeCount = await actor.getChangeCount();
|
|
2848
|
-
|
|
3063
|
+
expect19(changeCount).toBe(1);
|
|
2849
3064
|
});
|
|
2850
|
-
|
|
3065
|
+
test19("triggers onChange multiple times for multiple state changes", async (c) => {
|
|
2851
3066
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2852
3067
|
const actor = client.onStateChangeActor.getOrCreate();
|
|
2853
3068
|
await actor.incrementMultiple(3);
|
|
2854
3069
|
const changeCount = await actor.getChangeCount();
|
|
2855
|
-
|
|
3070
|
+
expect19(changeCount).toBe(3);
|
|
2856
3071
|
});
|
|
2857
|
-
|
|
3072
|
+
test19("does NOT trigger onChange for read-only actions", async (c) => {
|
|
2858
3073
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2859
3074
|
const actor = client.onStateChangeActor.getOrCreate();
|
|
2860
3075
|
await actor.setValue(5);
|
|
2861
3076
|
const value = await actor.getValue();
|
|
2862
|
-
|
|
3077
|
+
expect19(value).toBe(5);
|
|
2863
3078
|
const changeCount = await actor.getChangeCount();
|
|
2864
|
-
|
|
3079
|
+
expect19(changeCount).toBe(1);
|
|
2865
3080
|
});
|
|
2866
|
-
|
|
3081
|
+
test19("does NOT trigger onChange for computed values", async (c) => {
|
|
2867
3082
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2868
3083
|
const actor = client.onStateChangeActor.getOrCreate();
|
|
2869
3084
|
await actor.setValue(3);
|
|
2870
3085
|
{
|
|
2871
3086
|
const changeCount = await actor.getChangeCount();
|
|
2872
|
-
|
|
3087
|
+
expect19(changeCount).toBe(1);
|
|
2873
3088
|
}
|
|
2874
3089
|
const doubled = await actor.getDoubled();
|
|
2875
|
-
|
|
3090
|
+
expect19(doubled).toBe(6);
|
|
2876
3091
|
{
|
|
2877
3092
|
const changeCount = await actor.getChangeCount();
|
|
2878
|
-
|
|
3093
|
+
expect19(changeCount).toBe(1);
|
|
2879
3094
|
}
|
|
2880
3095
|
});
|
|
2881
|
-
|
|
3096
|
+
test19("simple: connect, call action, dispose does NOT trigger onChange", async (c) => {
|
|
2882
3097
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2883
3098
|
const actor = client.onStateChangeActor.getOrCreate();
|
|
2884
3099
|
const connection = await actor.connect();
|
|
2885
3100
|
const value = await connection.getValue();
|
|
2886
|
-
|
|
3101
|
+
expect19(value).toBe(0);
|
|
2887
3102
|
await connection.dispose();
|
|
2888
3103
|
const changeCount = await actor.getChangeCount();
|
|
2889
|
-
|
|
3104
|
+
expect19(changeCount).toBe(0);
|
|
2890
3105
|
});
|
|
2891
3106
|
});
|
|
2892
3107
|
}
|
|
2893
3108
|
|
|
2894
3109
|
// src/driver-test-suite/tests/actor-queue.ts
|
|
2895
|
-
import { describe as
|
|
3110
|
+
import { describe as describe21, expect as expect20, test as test20 } from "vitest";
|
|
2896
3111
|
function runActorQueueTests(driverTestConfig) {
|
|
2897
|
-
|
|
2898
|
-
|
|
3112
|
+
describe21("Actor Queue Tests", () => {
|
|
3113
|
+
test20("client can send to actor queue", async (c) => {
|
|
2899
3114
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2900
3115
|
const handle = client.queueActor.getOrCreate(["client-send"]);
|
|
2901
3116
|
await handle.send("greeting", { hello: "world" });
|
|
2902
3117
|
const message = await handle.receiveOne("greeting");
|
|
2903
|
-
|
|
3118
|
+
expect20(message).toEqual({
|
|
2904
3119
|
name: "greeting",
|
|
2905
3120
|
body: { hello: "world" }
|
|
2906
3121
|
});
|
|
2907
3122
|
});
|
|
2908
|
-
|
|
3123
|
+
test20("actor can send to its own queue", async (c) => {
|
|
2909
3124
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2910
3125
|
const handle = client.queueActor.getOrCreate(["self-send"]);
|
|
2911
3126
|
await handle.sendToSelf("self", { value: 42 });
|
|
2912
3127
|
const message = await handle.receiveOne("self");
|
|
2913
|
-
|
|
3128
|
+
expect20(message).toEqual({ name: "self", body: { value: 42 } });
|
|
2914
3129
|
});
|
|
2915
|
-
|
|
3130
|
+
test20("nextBatch supports name arrays and counts", async (c) => {
|
|
2916
3131
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2917
3132
|
const handle = client.queueActor.getOrCreate(["receive-array"]);
|
|
2918
3133
|
await handle.send("a", 1);
|
|
2919
3134
|
await handle.send("b", 2);
|
|
2920
3135
|
await handle.send("c", 3);
|
|
2921
3136
|
const messages = await handle.receiveMany(["a", "b"], { count: 2 });
|
|
2922
|
-
|
|
3137
|
+
expect20(messages).toEqual([
|
|
2923
3138
|
{ name: "a", body: 1 },
|
|
2924
3139
|
{ name: "b", body: 2 }
|
|
2925
3140
|
]);
|
|
2926
3141
|
});
|
|
2927
|
-
|
|
3142
|
+
test20("nextBatch supports request objects", async (c) => {
|
|
2928
3143
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2929
3144
|
const handle = client.queueActor.getOrCreate(["receive-request"]);
|
|
2930
3145
|
await handle.send("one", "first");
|
|
@@ -2933,12 +3148,12 @@ function runActorQueueTests(driverTestConfig) {
|
|
|
2933
3148
|
names: ["one", "two"],
|
|
2934
3149
|
count: 2
|
|
2935
3150
|
});
|
|
2936
|
-
|
|
3151
|
+
expect20(messages).toEqual([
|
|
2937
3152
|
{ name: "one", body: "first" },
|
|
2938
3153
|
{ name: "two", body: "second" }
|
|
2939
3154
|
]);
|
|
2940
3155
|
});
|
|
2941
|
-
|
|
3156
|
+
test20("nextBatch defaults to all names when names is omitted", async (c) => {
|
|
2942
3157
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2943
3158
|
const handle = client.queueActor.getOrCreate([
|
|
2944
3159
|
"receive-request-all"
|
|
@@ -2946,66 +3161,66 @@ function runActorQueueTests(driverTestConfig) {
|
|
|
2946
3161
|
await handle.send("one", "first");
|
|
2947
3162
|
await handle.send("two", "second");
|
|
2948
3163
|
const messages = await handle.receiveRequest({ count: 2 });
|
|
2949
|
-
|
|
3164
|
+
expect20(messages).toEqual([
|
|
2950
3165
|
{ name: "one", body: "first" },
|
|
2951
3166
|
{ name: "two", body: "second" }
|
|
2952
3167
|
]);
|
|
2953
3168
|
});
|
|
2954
|
-
|
|
3169
|
+
test20("next timeout returns empty array", async (c) => {
|
|
2955
3170
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2956
3171
|
const handle = client.queueActor.getOrCreate(["receive-timeout"]);
|
|
2957
3172
|
const promise = handle.receiveMany(["missing"], { timeout: 50 });
|
|
2958
3173
|
await waitFor(driverTestConfig, 60);
|
|
2959
3174
|
const messages = await promise;
|
|
2960
|
-
|
|
3175
|
+
expect20(messages).toEqual([]);
|
|
2961
3176
|
});
|
|
2962
|
-
|
|
3177
|
+
test20("tryNextBatch does not wait and returns empty array", async (c) => {
|
|
2963
3178
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2964
3179
|
const handle = client.queueActor.getOrCreate(["try-next-empty"]);
|
|
2965
3180
|
const messages = await handle.tryReceiveMany({
|
|
2966
3181
|
names: ["missing"],
|
|
2967
3182
|
count: 1
|
|
2968
3183
|
});
|
|
2969
|
-
|
|
3184
|
+
expect20(messages).toEqual([]);
|
|
2970
3185
|
});
|
|
2971
|
-
|
|
3186
|
+
test20("abort throws ActorAborted", async (c) => {
|
|
2972
3187
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2973
3188
|
const handle = client.queueActor.getOrCreate(["abort-test"]);
|
|
2974
3189
|
try {
|
|
2975
3190
|
await handle.waitForAbort();
|
|
2976
|
-
|
|
3191
|
+
expect20.fail("expected ActorAborted error");
|
|
2977
3192
|
} catch (error) {
|
|
2978
|
-
|
|
2979
|
-
|
|
3193
|
+
expect20(error.group).toBe("actor");
|
|
3194
|
+
expect20(error.code).toBe("aborted");
|
|
2980
3195
|
}
|
|
2981
3196
|
});
|
|
2982
|
-
|
|
3197
|
+
test20("next supports signal abort", async (c) => {
|
|
2983
3198
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2984
3199
|
const handle = client.queueActor.getOrCreate(["signal-abort-next"]);
|
|
2985
3200
|
const result = await handle.waitForSignalAbort();
|
|
2986
|
-
|
|
3201
|
+
expect20(result).toEqual({
|
|
2987
3202
|
group: "actor",
|
|
2988
3203
|
code: "aborted"
|
|
2989
3204
|
});
|
|
2990
3205
|
});
|
|
2991
|
-
|
|
3206
|
+
test20("next supports actor abort when signal is provided", async (c) => {
|
|
2992
3207
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2993
3208
|
const handle = client.queueActor.getOrCreate([
|
|
2994
3209
|
"actor-abort-with-signal-next"
|
|
2995
3210
|
]);
|
|
2996
3211
|
const result = await handle.waitForActorAbortWithSignal();
|
|
2997
|
-
|
|
3212
|
+
expect20(result).toEqual({
|
|
2998
3213
|
group: "actor",
|
|
2999
3214
|
code: "aborted"
|
|
3000
3215
|
});
|
|
3001
3216
|
});
|
|
3002
|
-
|
|
3217
|
+
test20("iter supports signal abort", async (c) => {
|
|
3003
3218
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3004
3219
|
const handle = client.queueActor.getOrCreate(["signal-abort-iter"]);
|
|
3005
3220
|
const result = await handle.iterWithSignalAbort();
|
|
3006
|
-
|
|
3221
|
+
expect20(result).toEqual({ ok: true });
|
|
3007
3222
|
});
|
|
3008
|
-
|
|
3223
|
+
test20("enforces queue size limit", async (c) => {
|
|
3009
3224
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3010
3225
|
const key = `size-limit-${Date.now()}-${Math.random().toString(16).slice(2)}`;
|
|
3011
3226
|
const handle = client.queueLimitedActor.getOrCreate([key]);
|
|
@@ -3013,19 +3228,19 @@ function runActorQueueTests(driverTestConfig) {
|
|
|
3013
3228
|
await waitFor(driverTestConfig, 10);
|
|
3014
3229
|
try {
|
|
3015
3230
|
await handle.send("message", 2);
|
|
3016
|
-
|
|
3231
|
+
expect20.fail("expected queue full error");
|
|
3017
3232
|
} catch (error) {
|
|
3018
|
-
|
|
3019
|
-
|
|
3233
|
+
expect20(error).toBeInstanceOf(Error);
|
|
3234
|
+
expect20(error.message).toContain(
|
|
3020
3235
|
"Queue is full. Limit is"
|
|
3021
3236
|
);
|
|
3022
3237
|
if (driverTestConfig.clientType !== "http") {
|
|
3023
|
-
|
|
3024
|
-
|
|
3238
|
+
expect20(error.group).toBe("queue");
|
|
3239
|
+
expect20(error.code).toBe("full");
|
|
3025
3240
|
}
|
|
3026
3241
|
}
|
|
3027
3242
|
});
|
|
3028
|
-
|
|
3243
|
+
test20("enforces message size limit", async (c) => {
|
|
3029
3244
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3030
3245
|
const handle = client.queueLimitedActor.getOrCreate([
|
|
3031
3246
|
"message-limit"
|
|
@@ -3033,28 +3248,29 @@ function runActorQueueTests(driverTestConfig) {
|
|
|
3033
3248
|
const largePayload = "a".repeat(200);
|
|
3034
3249
|
try {
|
|
3035
3250
|
await handle.send("oversize", largePayload);
|
|
3036
|
-
|
|
3251
|
+
expect20.fail("expected message_too_large error");
|
|
3037
3252
|
} catch (error) {
|
|
3038
|
-
|
|
3039
|
-
|
|
3253
|
+
expect20(error.group).toBe("queue");
|
|
3254
|
+
expect20(error.code).toBe("message_too_large");
|
|
3040
3255
|
}
|
|
3041
3256
|
});
|
|
3042
|
-
|
|
3257
|
+
test20("wait send returns completion response", async (c) => {
|
|
3043
3258
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3044
3259
|
const handle = client.queueActor.getOrCreate(["wait-complete"]);
|
|
3260
|
+
const waitTimeout = driverTestConfig.useRealTimers ? 5e3 : 1e3;
|
|
3045
3261
|
const actionPromise = handle.receiveAndComplete("tasks");
|
|
3046
3262
|
const result = await handle.send(
|
|
3047
3263
|
"tasks",
|
|
3048
3264
|
{ value: 123 },
|
|
3049
|
-
{ wait: true, timeout:
|
|
3265
|
+
{ wait: true, timeout: waitTimeout }
|
|
3050
3266
|
);
|
|
3051
3267
|
await actionPromise;
|
|
3052
|
-
|
|
3268
|
+
expect20(result).toEqual({
|
|
3053
3269
|
status: "completed",
|
|
3054
3270
|
response: { echo: { value: 123 } }
|
|
3055
3271
|
});
|
|
3056
3272
|
});
|
|
3057
|
-
|
|
3273
|
+
test20("wait send times out", async (c) => {
|
|
3058
3274
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3059
3275
|
const handle = client.queueActor.getOrCreate(["wait-timeout"]);
|
|
3060
3276
|
const resultPromise = handle.send(
|
|
@@ -3064,20 +3280,20 @@ function runActorQueueTests(driverTestConfig) {
|
|
|
3064
3280
|
);
|
|
3065
3281
|
await waitFor(driverTestConfig, 60);
|
|
3066
3282
|
const result = await resultPromise;
|
|
3067
|
-
|
|
3283
|
+
expect20(result.status).toBe("timedOut");
|
|
3068
3284
|
});
|
|
3069
|
-
|
|
3285
|
+
test20("manual receive retries message when not completed", async (c) => {
|
|
3070
3286
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3071
3287
|
const handle = client.queueActor.getOrCreate([
|
|
3072
3288
|
"manual-retry-uncompleted"
|
|
3073
3289
|
]);
|
|
3074
3290
|
await handle.send("tasks", { value: 789 });
|
|
3075
3291
|
const first = await handle.receiveWithoutComplete("tasks");
|
|
3076
|
-
|
|
3292
|
+
expect20(first).toEqual({ name: "tasks", body: { value: 789 } });
|
|
3077
3293
|
const retried = await handle.receiveOne("tasks", { timeout: 1e3 });
|
|
3078
|
-
|
|
3294
|
+
expect20(retried).toEqual({ name: "tasks", body: { value: 789 } });
|
|
3079
3295
|
});
|
|
3080
|
-
|
|
3296
|
+
test20("next throws when previous manual message is not completed", async (c) => {
|
|
3081
3297
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3082
3298
|
const handle = client.queueActor.getOrCreate([
|
|
3083
3299
|
"manual-next-requires-complete"
|
|
@@ -3086,46 +3302,46 @@ function runActorQueueTests(driverTestConfig) {
|
|
|
3086
3302
|
const result = await handle.receiveManualThenNextWithoutComplete(
|
|
3087
3303
|
"tasks"
|
|
3088
3304
|
);
|
|
3089
|
-
|
|
3305
|
+
expect20(result).toEqual({
|
|
3090
3306
|
group: "queue",
|
|
3091
3307
|
code: "previous_message_not_completed"
|
|
3092
3308
|
});
|
|
3093
3309
|
});
|
|
3094
|
-
|
|
3310
|
+
test20("manual receive includes complete even without completion schema", async (c) => {
|
|
3095
3311
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3096
3312
|
const handle = client.queueActor.getOrCreate([
|
|
3097
3313
|
"complete-not-allowed"
|
|
3098
3314
|
]);
|
|
3099
3315
|
await handle.send("nowait", { value: "test" });
|
|
3100
3316
|
const result = await handle.receiveWithoutCompleteMethod("nowait");
|
|
3101
|
-
|
|
3317
|
+
expect20(result).toEqual({
|
|
3102
3318
|
hasComplete: true
|
|
3103
3319
|
});
|
|
3104
3320
|
});
|
|
3105
|
-
|
|
3321
|
+
test20("manual receive retries queues without completion schema until completed", async (c) => {
|
|
3106
3322
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3107
3323
|
const handle = client.queueActor.getOrCreate([
|
|
3108
3324
|
"complete-not-allowed-consume"
|
|
3109
3325
|
]);
|
|
3110
3326
|
await handle.send("nowait", { value: "test" });
|
|
3111
3327
|
const result = await handle.receiveWithoutCompleteMethod("nowait");
|
|
3112
|
-
|
|
3328
|
+
expect20(result).toEqual({ hasComplete: true });
|
|
3113
3329
|
const next = await handle.receiveOne("nowait", { timeout: 1e3 });
|
|
3114
|
-
|
|
3330
|
+
expect20(next).toEqual({ name: "nowait", body: { value: "test" } });
|
|
3115
3331
|
});
|
|
3116
|
-
|
|
3332
|
+
test20("complete throws when called twice", async (c) => {
|
|
3117
3333
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3118
3334
|
const handle = client.queueActor.getOrCreate([
|
|
3119
3335
|
"complete-twice"
|
|
3120
3336
|
]);
|
|
3121
3337
|
await handle.send("twice", { value: "test" });
|
|
3122
3338
|
const result = await handle.receiveAndCompleteTwice("twice");
|
|
3123
|
-
|
|
3339
|
+
expect20(result).toEqual({
|
|
3124
3340
|
group: "queue",
|
|
3125
3341
|
code: "already_completed"
|
|
3126
3342
|
});
|
|
3127
3343
|
});
|
|
3128
|
-
|
|
3344
|
+
test20("wait send no longer requires queue completion schema", async (c) => {
|
|
3129
3345
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3130
3346
|
const handle = client.queueActor.getOrCreate([
|
|
3131
3347
|
"missing-completion-schema"
|
|
@@ -3135,78 +3351,78 @@ function runActorQueueTests(driverTestConfig) {
|
|
|
3135
3351
|
{ value: "test" },
|
|
3136
3352
|
{ wait: true, timeout: 50 }
|
|
3137
3353
|
);
|
|
3138
|
-
|
|
3354
|
+
expect20(result).toEqual({ status: "timedOut" });
|
|
3139
3355
|
});
|
|
3140
|
-
|
|
3356
|
+
test20("iter can consume queued messages", async (c) => {
|
|
3141
3357
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3142
3358
|
const handle = client.queueActor.getOrCreate(["iter-consume"]);
|
|
3143
3359
|
await handle.send("one", "first");
|
|
3144
3360
|
const message = await handle.receiveWithIterator("one");
|
|
3145
|
-
|
|
3361
|
+
expect20(message).toEqual({ name: "one", body: "first" });
|
|
3146
3362
|
});
|
|
3147
|
-
|
|
3363
|
+
test20("queue async iterator can consume queued messages", async (c) => {
|
|
3148
3364
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3149
3365
|
const handle = client.queueActor.getOrCreate([
|
|
3150
3366
|
"async-iter-consume"
|
|
3151
3367
|
]);
|
|
3152
3368
|
await handle.send("two", "second");
|
|
3153
3369
|
const message = await handle.receiveWithAsyncIterator();
|
|
3154
|
-
|
|
3370
|
+
expect20(message).toEqual({ name: "two", body: "second" });
|
|
3155
3371
|
});
|
|
3156
3372
|
});
|
|
3157
3373
|
}
|
|
3158
3374
|
|
|
3159
3375
|
// src/driver-test-suite/tests/actor-run.ts
|
|
3160
|
-
import { describe as
|
|
3376
|
+
import { describe as describe22, expect as expect21, test as test21 } from "vitest";
|
|
3161
3377
|
function runActorRunTests(driverTestConfig) {
|
|
3162
3378
|
var _a;
|
|
3163
|
-
|
|
3164
|
-
|
|
3379
|
+
describe22.skipIf((_a = driverTestConfig.skip) == null ? void 0 : _a.sleep)("Actor Run Tests", () => {
|
|
3380
|
+
test21("run handler starts after actor startup", async (c) => {
|
|
3165
3381
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3166
3382
|
const actor = client.runWithTicks.getOrCreate(["run-starts"]);
|
|
3167
3383
|
await waitFor(driverTestConfig, 100);
|
|
3168
3384
|
const state = await actor.getState();
|
|
3169
|
-
|
|
3170
|
-
|
|
3385
|
+
expect21(state.runStarted).toBe(true);
|
|
3386
|
+
expect21(state.tickCount).toBeGreaterThan(0);
|
|
3171
3387
|
});
|
|
3172
|
-
|
|
3388
|
+
test21("run handler ticks continuously", async (c) => {
|
|
3173
3389
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3174
3390
|
const actor = client.runWithTicks.getOrCreate(["run-ticks"]);
|
|
3175
3391
|
await waitFor(driverTestConfig, 200);
|
|
3176
3392
|
const state1 = await actor.getState();
|
|
3177
|
-
|
|
3393
|
+
expect21(state1.tickCount).toBeGreaterThan(0);
|
|
3178
3394
|
const count1 = state1.tickCount;
|
|
3179
3395
|
await waitFor(driverTestConfig, 200);
|
|
3180
3396
|
const state2 = await actor.getState();
|
|
3181
|
-
|
|
3397
|
+
expect21(state2.tickCount).toBeGreaterThan(count1);
|
|
3182
3398
|
});
|
|
3183
|
-
|
|
3399
|
+
test21("active run handler keeps actor awake past sleep timeout", async (c) => {
|
|
3184
3400
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3185
3401
|
const actor = client.runWithTicks.getOrCreate([
|
|
3186
3402
|
"run-stays-awake"
|
|
3187
3403
|
]);
|
|
3188
3404
|
await waitFor(driverTestConfig, 100);
|
|
3189
3405
|
const state1 = await actor.getState();
|
|
3190
|
-
|
|
3406
|
+
expect21(state1.runStarted).toBe(true);
|
|
3191
3407
|
const tickCount1 = state1.tickCount;
|
|
3192
3408
|
await waitFor(driverTestConfig, RUN_SLEEP_TIMEOUT + 300);
|
|
3193
3409
|
const state2 = await actor.getState();
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
3410
|
+
expect21(state2.runStarted).toBe(true);
|
|
3411
|
+
expect21(state2.runExited).toBe(false);
|
|
3412
|
+
expect21(state2.tickCount).toBeGreaterThan(tickCount1);
|
|
3197
3413
|
});
|
|
3198
|
-
|
|
3414
|
+
test21("actor without run handler works normally", async (c) => {
|
|
3199
3415
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3200
3416
|
const actor = client.runWithoutHandler.getOrCreate([
|
|
3201
3417
|
"no-run-handler"
|
|
3202
3418
|
]);
|
|
3203
3419
|
const state = await actor.getState();
|
|
3204
|
-
|
|
3420
|
+
expect21(state.wakeCount).toBe(1);
|
|
3205
3421
|
await waitFor(driverTestConfig, RUN_SLEEP_TIMEOUT + 300);
|
|
3206
3422
|
const state2 = await actor.getState();
|
|
3207
|
-
|
|
3423
|
+
expect21(state2.wakeCount).toBe(2);
|
|
3208
3424
|
});
|
|
3209
|
-
|
|
3425
|
+
test21("run handler can consume from queue", async (c) => {
|
|
3210
3426
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3211
3427
|
const actor = client.runWithQueueConsumer.getOrCreate([
|
|
3212
3428
|
"queue-consumer"
|
|
@@ -3217,127 +3433,127 @@ function runActorRunTests(driverTestConfig) {
|
|
|
3217
3433
|
await actor.sendMessage({ type: "test", value: 3 });
|
|
3218
3434
|
await waitFor(driverTestConfig, 1200);
|
|
3219
3435
|
const state = await actor.getState();
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3436
|
+
expect21(state.runStarted).toBe(true);
|
|
3437
|
+
expect21(state.messagesReceived.length).toBe(3);
|
|
3438
|
+
expect21(state.messagesReceived[0].body).toEqual({
|
|
3223
3439
|
type: "test",
|
|
3224
3440
|
value: 1
|
|
3225
3441
|
});
|
|
3226
|
-
|
|
3442
|
+
expect21(state.messagesReceived[1].body).toEqual({
|
|
3227
3443
|
type: "test",
|
|
3228
3444
|
value: 2
|
|
3229
3445
|
});
|
|
3230
|
-
|
|
3446
|
+
expect21(state.messagesReceived[2].body).toEqual({
|
|
3231
3447
|
type: "test",
|
|
3232
3448
|
value: 3
|
|
3233
3449
|
});
|
|
3234
3450
|
});
|
|
3235
|
-
|
|
3451
|
+
test21("queue-waiting run handler can sleep and resume", async (c) => {
|
|
3236
3452
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3237
3453
|
const actor = client.runWithQueueConsumer.getOrCreate([
|
|
3238
3454
|
"queue-consumer-sleep"
|
|
3239
3455
|
]);
|
|
3240
3456
|
await waitFor(driverTestConfig, 100);
|
|
3241
3457
|
const state1 = await actor.getState();
|
|
3242
|
-
|
|
3458
|
+
expect21(state1.runStarted).toBe(true);
|
|
3243
3459
|
await waitFor(driverTestConfig, RUN_SLEEP_TIMEOUT + 500);
|
|
3244
3460
|
const state2 = await actor.getState();
|
|
3245
|
-
|
|
3461
|
+
expect21(state2.wakeCount).toBeGreaterThan(state1.wakeCount);
|
|
3246
3462
|
});
|
|
3247
|
-
|
|
3463
|
+
test21("run handler that exits early triggers destroy", async (c) => {
|
|
3248
3464
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3249
3465
|
const actor = client.runWithEarlyExit.getOrCreate(["early-exit"]);
|
|
3250
3466
|
await waitFor(driverTestConfig, 100);
|
|
3251
3467
|
const state1 = await actor.getState();
|
|
3252
|
-
|
|
3468
|
+
expect21(state1.runStarted).toBe(true);
|
|
3253
3469
|
await waitFor(driverTestConfig, 300);
|
|
3254
3470
|
const actor2 = client.runWithEarlyExit.getOrCreate([
|
|
3255
3471
|
"early-exit-fresh"
|
|
3256
3472
|
]);
|
|
3257
3473
|
const state2 = await actor2.getState();
|
|
3258
|
-
|
|
3474
|
+
expect21(state2.runStarted).toBe(true);
|
|
3259
3475
|
});
|
|
3260
|
-
|
|
3476
|
+
test21("run handler that throws error triggers destroy", async (c) => {
|
|
3261
3477
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3262
3478
|
const actor = client.runWithError.getOrCreate(["run-error"]);
|
|
3263
3479
|
await waitFor(driverTestConfig, 100);
|
|
3264
3480
|
const state1 = await actor.getState();
|
|
3265
|
-
|
|
3481
|
+
expect21(state1.runStarted).toBe(true);
|
|
3266
3482
|
await waitFor(driverTestConfig, 300);
|
|
3267
3483
|
const actor2 = client.runWithError.getOrCreate(["run-error-fresh"]);
|
|
3268
3484
|
const state2 = await actor2.getState();
|
|
3269
|
-
|
|
3485
|
+
expect21(state2.runStarted).toBe(true);
|
|
3270
3486
|
});
|
|
3271
3487
|
});
|
|
3272
3488
|
}
|
|
3273
3489
|
|
|
3274
3490
|
// src/driver-test-suite/tests/actor-stateless.ts
|
|
3275
|
-
import { describe as
|
|
3491
|
+
import { describe as describe23, expect as expect22, test as test22 } from "vitest";
|
|
3276
3492
|
function runActorStatelessTests(driverTestConfig) {
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3493
|
+
describe23("Actor Stateless Tests", () => {
|
|
3494
|
+
describe23("Stateless Actor Operations", () => {
|
|
3495
|
+
test22("can call actions on stateless actor", async (c) => {
|
|
3280
3496
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3281
3497
|
const instance = client.statelessActor.getOrCreate();
|
|
3282
3498
|
const result = await instance.ping();
|
|
3283
|
-
|
|
3499
|
+
expect22(result).toBe("pong");
|
|
3284
3500
|
});
|
|
3285
|
-
|
|
3501
|
+
test22("can echo messages", async (c) => {
|
|
3286
3502
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3287
3503
|
const instance = client.statelessActor.getOrCreate();
|
|
3288
3504
|
const message = "Hello, World!";
|
|
3289
3505
|
const result = await instance.echo(message);
|
|
3290
|
-
|
|
3506
|
+
expect22(result).toBe(message);
|
|
3291
3507
|
});
|
|
3292
|
-
|
|
3508
|
+
test22("can access actorId", async (c) => {
|
|
3293
3509
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3294
3510
|
const instance = client.statelessActor.getOrCreate(["test-id"]);
|
|
3295
3511
|
const actorId = await instance.getActorId();
|
|
3296
|
-
|
|
3297
|
-
|
|
3512
|
+
expect22(actorId).toBeDefined();
|
|
3513
|
+
expect22(typeof actorId).toBe("string");
|
|
3298
3514
|
});
|
|
3299
|
-
|
|
3515
|
+
test22("accessing state throws StateNotEnabled", async (c) => {
|
|
3300
3516
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3301
3517
|
const instance = client.statelessActor.getOrCreate();
|
|
3302
3518
|
const result = await instance.tryGetState();
|
|
3303
|
-
|
|
3304
|
-
|
|
3519
|
+
expect22(result.success).toBe(false);
|
|
3520
|
+
expect22(result.error).toContain("state");
|
|
3305
3521
|
});
|
|
3306
|
-
|
|
3522
|
+
test22("accessing db throws DatabaseNotEnabled", async (c) => {
|
|
3307
3523
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3308
3524
|
const instance = client.statelessActor.getOrCreate();
|
|
3309
3525
|
const result = await instance.tryGetDb();
|
|
3310
|
-
|
|
3311
|
-
|
|
3526
|
+
expect22(result.success).toBe(false);
|
|
3527
|
+
expect22(result.error).toContain("database");
|
|
3312
3528
|
});
|
|
3313
|
-
|
|
3529
|
+
test22("multiple stateless actors can exist independently", async (c) => {
|
|
3314
3530
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3315
3531
|
const actor1 = client.statelessActor.getOrCreate(["actor-1"]);
|
|
3316
3532
|
const actor2 = client.statelessActor.getOrCreate(["actor-2"]);
|
|
3317
3533
|
const id1 = await actor1.getActorId();
|
|
3318
3534
|
const id2 = await actor2.getActorId();
|
|
3319
|
-
|
|
3535
|
+
expect22(id1).not.toBe(id2);
|
|
3320
3536
|
});
|
|
3321
3537
|
});
|
|
3322
3538
|
});
|
|
3323
3539
|
}
|
|
3324
3540
|
|
|
3325
3541
|
// src/driver-test-suite/tests/actor-vars.ts
|
|
3326
|
-
import { describe as
|
|
3542
|
+
import { describe as describe24, expect as expect23, test as test23 } from "vitest";
|
|
3327
3543
|
function runActorVarsTests(driverTestConfig) {
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
|
|
3544
|
+
describe24("Actor Variables", () => {
|
|
3545
|
+
describe24("Static vars", () => {
|
|
3546
|
+
test23("should provide access to static vars", async (c) => {
|
|
3331
3547
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3332
3548
|
const instance = client.staticVarActor.getOrCreate();
|
|
3333
3549
|
const result = await instance.getVars();
|
|
3334
|
-
|
|
3550
|
+
expect23(result).toEqual({ counter: 42, name: "test-actor" });
|
|
3335
3551
|
const name = await instance.getName();
|
|
3336
|
-
|
|
3552
|
+
expect23(name).toBe("test-actor");
|
|
3337
3553
|
});
|
|
3338
3554
|
});
|
|
3339
|
-
|
|
3340
|
-
|
|
3555
|
+
describe24("Deep cloning of static vars", () => {
|
|
3556
|
+
test23("should deep clone static vars between actor instances", async (c) => {
|
|
3341
3557
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3342
3558
|
const instance1 = client.nestedVarActor.getOrCreate([
|
|
3343
3559
|
"instance1"
|
|
@@ -3346,63 +3562,69 @@ function runActorVarsTests(driverTestConfig) {
|
|
|
3346
3562
|
"instance2"
|
|
3347
3563
|
]);
|
|
3348
3564
|
const modifiedVars = await instance1.modifyNested();
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3565
|
+
expect23(modifiedVars.nested.value).toBe("modified");
|
|
3566
|
+
expect23(modifiedVars.nested.array).toContain(4);
|
|
3567
|
+
expect23(modifiedVars.nested.obj.key).toBe("new-value");
|
|
3352
3568
|
const instance2Vars = await instance2.getVars();
|
|
3353
|
-
|
|
3354
|
-
|
|
3355
|
-
|
|
3569
|
+
expect23(instance2Vars.nested.value).toBe("original");
|
|
3570
|
+
expect23(instance2Vars.nested.array).toEqual([1, 2, 3]);
|
|
3571
|
+
expect23(instance2Vars.nested.obj.key).toBe("value");
|
|
3356
3572
|
});
|
|
3357
3573
|
});
|
|
3358
|
-
|
|
3359
|
-
|
|
3574
|
+
describe24("createVars", () => {
|
|
3575
|
+
test23("should support dynamic vars creation", async (c) => {
|
|
3360
3576
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3361
3577
|
const instance = client.dynamicVarActor.getOrCreate();
|
|
3362
3578
|
const vars = await instance.getVars();
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3579
|
+
expect23(vars).toHaveProperty("random");
|
|
3580
|
+
expect23(vars).toHaveProperty("computed");
|
|
3581
|
+
expect23(typeof vars.random).toBe("number");
|
|
3582
|
+
expect23(typeof vars.computed).toBe("string");
|
|
3583
|
+
expect23(vars.computed).toMatch(/^Actor-\d+$/);
|
|
3368
3584
|
});
|
|
3369
|
-
|
|
3585
|
+
test23("should create different vars for different instances", async (c) => {
|
|
3370
3586
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3371
3587
|
const instance1 = client.uniqueVarActor.getOrCreate(["test1"]);
|
|
3372
3588
|
const instance2 = client.uniqueVarActor.getOrCreate(["test2"]);
|
|
3373
3589
|
const vars1 = await instance1.getVars();
|
|
3374
3590
|
const vars2 = await instance2.getVars();
|
|
3375
|
-
|
|
3591
|
+
expect23(vars1.id).not.toBe(vars2.id);
|
|
3376
3592
|
});
|
|
3377
3593
|
});
|
|
3378
|
-
|
|
3379
|
-
|
|
3594
|
+
describe24("Driver Context", () => {
|
|
3595
|
+
test23("should provide access to driver context", async (c) => {
|
|
3380
3596
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3381
3597
|
const instance = client.driverCtxActor.getOrCreate();
|
|
3382
3598
|
const vars = await instance.getVars();
|
|
3383
|
-
|
|
3599
|
+
expect23(vars).toHaveProperty("hasDriverCtx");
|
|
3384
3600
|
});
|
|
3385
3601
|
});
|
|
3386
3602
|
});
|
|
3387
3603
|
}
|
|
3388
3604
|
|
|
3389
3605
|
// src/driver-test-suite/tests/actor-workflow.ts
|
|
3390
|
-
import { describe as
|
|
3606
|
+
import { describe as describe25, expect as expect24, test as test24 } from "vitest";
|
|
3391
3607
|
function runActorWorkflowTests(driverTestConfig) {
|
|
3392
|
-
|
|
3608
|
+
describe25("Actor Workflow Tests", () => {
|
|
3393
3609
|
var _a;
|
|
3394
|
-
|
|
3610
|
+
test24("replays steps and guards state access", async (c) => {
|
|
3395
3611
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3396
3612
|
const actor = client.workflowCounterActor.getOrCreate([
|
|
3397
3613
|
"workflow-basic"
|
|
3398
3614
|
]);
|
|
3399
|
-
await
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3615
|
+
let state = await actor.getState();
|
|
3616
|
+
for (let i = 0; i < 50; i++) {
|
|
3617
|
+
if (state.runCount > 0 && state.history.length > 0 && state.guardTriggered) {
|
|
3618
|
+
break;
|
|
3619
|
+
}
|
|
3620
|
+
await waitFor(driverTestConfig, 100);
|
|
3621
|
+
state = await actor.getState();
|
|
3622
|
+
}
|
|
3623
|
+
expect24(state.runCount).toBeGreaterThan(0);
|
|
3624
|
+
expect24(state.history.length).toBeGreaterThan(0);
|
|
3625
|
+
expect24(state.guardTriggered).toBe(true);
|
|
3404
3626
|
});
|
|
3405
|
-
|
|
3627
|
+
test24("consumes queue messages via workflow queue.next", async (c) => {
|
|
3406
3628
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3407
3629
|
const actor = client.workflowQueueActor.getOrCreate(["workflow-queue"]);
|
|
3408
3630
|
await actor.send(WORKFLOW_QUEUE_NAME, {
|
|
@@ -3410,20 +3632,20 @@ function runActorWorkflowTests(driverTestConfig) {
|
|
|
3410
3632
|
});
|
|
3411
3633
|
await waitFor(driverTestConfig, 200);
|
|
3412
3634
|
const messages = await actor.getMessages();
|
|
3413
|
-
|
|
3635
|
+
expect24(messages).toEqual([{ hello: "world" }]);
|
|
3414
3636
|
});
|
|
3415
|
-
|
|
3637
|
+
test24("workflow queue.next supports completing wait sends", async (c) => {
|
|
3416
3638
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3417
3639
|
const actor = client.workflowQueueActor.getOrCreate([
|
|
3418
3640
|
"workflow-queue-wait"
|
|
3419
3641
|
]);
|
|
3420
3642
|
const result = await actor.sendAndWait({ value: 123 });
|
|
3421
|
-
|
|
3643
|
+
expect24(result).toEqual({
|
|
3422
3644
|
status: "completed",
|
|
3423
3645
|
response: { echo: { value: 123 } }
|
|
3424
3646
|
});
|
|
3425
3647
|
});
|
|
3426
|
-
|
|
3648
|
+
test24("db and client are step-only in workflow context", async (c) => {
|
|
3427
3649
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3428
3650
|
const actor = client.workflowAccessActor.getOrCreate([
|
|
3429
3651
|
"workflow-access"
|
|
@@ -3433,24 +3655,24 @@ function runActorWorkflowTests(driverTestConfig) {
|
|
|
3433
3655
|
await waitFor(driverTestConfig, 50);
|
|
3434
3656
|
state = await actor.getState();
|
|
3435
3657
|
}
|
|
3436
|
-
|
|
3658
|
+
expect24(state.outsideDbError).toBe(
|
|
3437
3659
|
"db is only available inside workflow steps"
|
|
3438
3660
|
);
|
|
3439
|
-
|
|
3661
|
+
expect24(state.outsideClientError).toBe(
|
|
3440
3662
|
"client is only available inside workflow steps"
|
|
3441
3663
|
);
|
|
3442
|
-
|
|
3443
|
-
|
|
3664
|
+
expect24(state.insideDbCount).toBeGreaterThan(0);
|
|
3665
|
+
expect24(state.insideClientAvailable).toBe(true);
|
|
3444
3666
|
});
|
|
3445
|
-
|
|
3667
|
+
test24("sleeps and resumes between ticks", async (c) => {
|
|
3446
3668
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3447
3669
|
const actor = client.workflowSleepActor.getOrCreate(["workflow-sleep"]);
|
|
3448
3670
|
const initial = await actor.getState();
|
|
3449
3671
|
await waitFor(driverTestConfig, 200);
|
|
3450
3672
|
const next = await actor.getState();
|
|
3451
|
-
|
|
3673
|
+
expect24(next.ticks).toBeGreaterThan(initial.ticks);
|
|
3452
3674
|
});
|
|
3453
|
-
|
|
3675
|
+
test24.skipIf((_a = driverTestConfig.skip) == null ? void 0 : _a.sleep)(
|
|
3454
3676
|
"workflow run teardown does not wait for runStopTimeout",
|
|
3455
3677
|
async (c) => {
|
|
3456
3678
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
@@ -3460,69 +3682,69 @@ function runActorWorkflowTests(driverTestConfig) {
|
|
|
3460
3682
|
await actor.getTimeline();
|
|
3461
3683
|
await waitFor(driverTestConfig, 1200);
|
|
3462
3684
|
const timeline = await actor.getTimeline();
|
|
3463
|
-
|
|
3464
|
-
|
|
3685
|
+
expect24(timeline.wakeAts.length).toBeGreaterThanOrEqual(2);
|
|
3686
|
+
expect24(timeline.sleepAts.length).toBeGreaterThanOrEqual(1);
|
|
3465
3687
|
const firstSleepDelayMs = timeline.sleepAts[0] - timeline.wakeAts[0];
|
|
3466
|
-
|
|
3688
|
+
expect24(firstSleepDelayMs).toBeLessThan(1800);
|
|
3467
3689
|
}
|
|
3468
3690
|
);
|
|
3469
3691
|
});
|
|
3470
3692
|
}
|
|
3471
3693
|
|
|
3472
3694
|
// src/driver-test-suite/tests/manager-driver.ts
|
|
3473
|
-
import { describe as
|
|
3695
|
+
import { describe as describe26, expect as expect25, test as test25 } from "vitest";
|
|
3474
3696
|
function runManagerDriverTests(driverTestConfig) {
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3697
|
+
describe26("Manager Driver Tests", () => {
|
|
3698
|
+
describe26("Client Connection Methods", () => {
|
|
3699
|
+
test25("connect() - finds or creates a actor", async (c) => {
|
|
3478
3700
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3479
3701
|
const counterA = client.counter.getOrCreate();
|
|
3480
3702
|
await counterA.increment(5);
|
|
3481
3703
|
const counterAAgain = client.counter.getOrCreate();
|
|
3482
3704
|
const count = await counterAAgain.increment(0);
|
|
3483
|
-
|
|
3705
|
+
expect25(count).toBe(5);
|
|
3484
3706
|
const counterB = client.counter.getOrCreate([
|
|
3485
3707
|
"counter-b",
|
|
3486
3708
|
"testing"
|
|
3487
3709
|
]);
|
|
3488
3710
|
await counterB.increment(10);
|
|
3489
3711
|
const countB = await counterB.increment(0);
|
|
3490
|
-
|
|
3712
|
+
expect25(countB).toBe(10);
|
|
3491
3713
|
});
|
|
3492
|
-
|
|
3714
|
+
test25("throws ActorAlreadyExists when creating duplicate actors", async (c) => {
|
|
3493
3715
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3494
3716
|
const uniqueKey = ["duplicate-actor-test", crypto.randomUUID()];
|
|
3495
3717
|
const counter = client.counter.getOrCreate(uniqueKey);
|
|
3496
3718
|
await counter.increment(5);
|
|
3497
3719
|
try {
|
|
3498
3720
|
await client.counter.create(uniqueKey);
|
|
3499
|
-
|
|
3721
|
+
expect25.fail("did not error on duplicate create");
|
|
3500
3722
|
} catch (err) {
|
|
3501
|
-
|
|
3502
|
-
|
|
3723
|
+
expect25(err.group).toBe("actor");
|
|
3724
|
+
expect25(err.code).toBe("duplicate_key");
|
|
3503
3725
|
}
|
|
3504
3726
|
const count = await counter.increment(0);
|
|
3505
|
-
|
|
3727
|
+
expect25(count).toBe(5);
|
|
3506
3728
|
});
|
|
3507
3729
|
});
|
|
3508
|
-
|
|
3509
|
-
|
|
3730
|
+
describe26("Connection Options", () => {
|
|
3731
|
+
test25("get without create prevents actor creation", async (c) => {
|
|
3510
3732
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3511
3733
|
const nonexistentId = `nonexistent-${crypto.randomUUID()}`;
|
|
3512
3734
|
try {
|
|
3513
3735
|
await client.counter.get([nonexistentId]).resolve();
|
|
3514
|
-
|
|
3736
|
+
expect25.fail("did not error for get");
|
|
3515
3737
|
} catch (err) {
|
|
3516
|
-
|
|
3517
|
-
|
|
3738
|
+
expect25(err.group).toBe("actor");
|
|
3739
|
+
expect25(err.code).toBe("not_found");
|
|
3518
3740
|
}
|
|
3519
3741
|
const createdCounter = client.counter.getOrCreate(nonexistentId);
|
|
3520
3742
|
await createdCounter.increment(3);
|
|
3521
3743
|
const retrievedCounter = client.counter.get(nonexistentId);
|
|
3522
3744
|
const count = await retrievedCounter.increment(0);
|
|
3523
|
-
|
|
3745
|
+
expect25(count).toBe(3);
|
|
3524
3746
|
});
|
|
3525
|
-
|
|
3747
|
+
test25("connection params are passed to actors", async (c) => {
|
|
3526
3748
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3527
3749
|
const counter = client.counter.getOrCreate(void 0, {
|
|
3528
3750
|
params: {
|
|
@@ -3533,20 +3755,20 @@ function runManagerDriverTests(driverTestConfig) {
|
|
|
3533
3755
|
});
|
|
3534
3756
|
await counter.increment(1);
|
|
3535
3757
|
const count = await counter.increment(0);
|
|
3536
|
-
|
|
3758
|
+
expect25(count).toBe(1);
|
|
3537
3759
|
});
|
|
3538
3760
|
});
|
|
3539
|
-
|
|
3540
|
-
|
|
3761
|
+
describe26("Actor Creation & Retrieval", () => {
|
|
3762
|
+
test25("creates and retrieves actors by ID", async (c) => {
|
|
3541
3763
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3542
3764
|
const uniqueId = `test-counter-${crypto.randomUUID()}`;
|
|
3543
3765
|
const counter = client.counter.getOrCreate([uniqueId]);
|
|
3544
3766
|
await counter.increment(10);
|
|
3545
3767
|
const retrievedCounter = client.counter.getOrCreate([uniqueId]);
|
|
3546
3768
|
const count = await retrievedCounter.increment(0);
|
|
3547
|
-
|
|
3769
|
+
expect25(count).toBe(10);
|
|
3548
3770
|
});
|
|
3549
|
-
|
|
3771
|
+
test25("passes input to actor during creation", async (c) => {
|
|
3550
3772
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3551
3773
|
const testInput = {
|
|
3552
3774
|
name: "test-actor",
|
|
@@ -3557,17 +3779,17 @@ function runManagerDriverTests(driverTestConfig) {
|
|
|
3557
3779
|
input: testInput
|
|
3558
3780
|
});
|
|
3559
3781
|
const inputs = await actor.getInputs();
|
|
3560
|
-
|
|
3561
|
-
|
|
3782
|
+
expect25(inputs.initialInput).toEqual(testInput);
|
|
3783
|
+
expect25(inputs.onCreateInput).toEqual(testInput);
|
|
3562
3784
|
});
|
|
3563
|
-
|
|
3785
|
+
test25("input is undefined when not provided", async (c) => {
|
|
3564
3786
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3565
3787
|
const actor = await client.inputActor.create();
|
|
3566
3788
|
const inputs = await actor.getInputs();
|
|
3567
|
-
|
|
3568
|
-
|
|
3789
|
+
expect25(inputs.initialInput).toBeUndefined();
|
|
3790
|
+
expect25(inputs.onCreateInput).toBeUndefined();
|
|
3569
3791
|
});
|
|
3570
|
-
|
|
3792
|
+
test25("getOrCreate passes input to actor during creation", async (c) => {
|
|
3571
3793
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3572
3794
|
const uniqueKey = [`input-test-${crypto.randomUUID()}`];
|
|
3573
3795
|
const testInput = {
|
|
@@ -3579,22 +3801,22 @@ function runManagerDriverTests(driverTestConfig) {
|
|
|
3579
3801
|
createWithInput: testInput
|
|
3580
3802
|
});
|
|
3581
3803
|
const inputs = await actor.getInputs();
|
|
3582
|
-
|
|
3583
|
-
|
|
3804
|
+
expect25(inputs.initialInput).toEqual(testInput);
|
|
3805
|
+
expect25(inputs.onCreateInput).toEqual(testInput);
|
|
3584
3806
|
const existingActor = client.inputActor.getOrCreate(uniqueKey);
|
|
3585
3807
|
const existingInputs = await existingActor.getInputs();
|
|
3586
|
-
|
|
3587
|
-
|
|
3808
|
+
expect25(existingInputs.initialInput).toEqual(testInput);
|
|
3809
|
+
expect25(existingInputs.onCreateInput).toEqual(testInput);
|
|
3588
3810
|
});
|
|
3589
3811
|
});
|
|
3590
|
-
|
|
3591
|
-
|
|
3812
|
+
describe26("Key Matching", () => {
|
|
3813
|
+
test25("multi-part actor keys are passed through correctly", async (c) => {
|
|
3592
3814
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3593
3815
|
const multiPartKey = ["tenant/with/slash", "room"];
|
|
3594
3816
|
const counter = client.counter.getOrCreate(multiPartKey);
|
|
3595
|
-
|
|
3817
|
+
expect25(await counter.getKey()).toEqual(multiPartKey);
|
|
3596
3818
|
});
|
|
3597
|
-
|
|
3819
|
+
test25("matches actors only with exactly the same keys", async (c) => {
|
|
3598
3820
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3599
3821
|
const originalCounter = client.counter.getOrCreate([
|
|
3600
3822
|
"counter-match",
|
|
@@ -3608,20 +3830,20 @@ function runManagerDriverTests(driverTestConfig) {
|
|
|
3608
3830
|
"us-east"
|
|
3609
3831
|
]);
|
|
3610
3832
|
const exactMatchCount = await exactMatchCounter.increment(0);
|
|
3611
|
-
|
|
3833
|
+
expect25(exactMatchCount).toBe(10);
|
|
3612
3834
|
const subsetMatchCounter = client.counter.getOrCreate([
|
|
3613
3835
|
"counter-match",
|
|
3614
3836
|
"test"
|
|
3615
3837
|
]);
|
|
3616
3838
|
const subsetMatchCount = await subsetMatchCounter.increment(0);
|
|
3617
|
-
|
|
3839
|
+
expect25(subsetMatchCount).toBe(0);
|
|
3618
3840
|
const singleKeyCounter = client.counter.getOrCreate([
|
|
3619
3841
|
"counter-match"
|
|
3620
3842
|
]);
|
|
3621
3843
|
const singleKeyCount = await singleKeyCounter.increment(0);
|
|
3622
|
-
|
|
3844
|
+
expect25(singleKeyCount).toBe(0);
|
|
3623
3845
|
});
|
|
3624
|
-
|
|
3846
|
+
test25("string key matches array with single string key", async (c) => {
|
|
3625
3847
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3626
3848
|
const stringKeyCounter = client.counter.getOrCreate("string-key-test");
|
|
3627
3849
|
await stringKeyCounter.increment(7);
|
|
@@ -3629,20 +3851,20 @@ function runManagerDriverTests(driverTestConfig) {
|
|
|
3629
3851
|
"string-key-test"
|
|
3630
3852
|
]);
|
|
3631
3853
|
const count = await arrayKeyCounter.increment(0);
|
|
3632
|
-
|
|
3854
|
+
expect25(count).toBe(7);
|
|
3633
3855
|
});
|
|
3634
|
-
|
|
3856
|
+
test25("undefined key matches empty array key and no key", async (c) => {
|
|
3635
3857
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3636
3858
|
const undefinedKeyCounter = client.counter.getOrCreate(void 0);
|
|
3637
3859
|
await undefinedKeyCounter.increment(12);
|
|
3638
3860
|
const emptyArrayKeyCounter = client.counter.getOrCreate([]);
|
|
3639
3861
|
const emptyArrayCount = await emptyArrayKeyCounter.increment(0);
|
|
3640
|
-
|
|
3862
|
+
expect25(emptyArrayCount).toBe(12);
|
|
3641
3863
|
const noKeyCounter = client.counter.getOrCreate();
|
|
3642
3864
|
const noKeyCount = await noKeyCounter.increment(0);
|
|
3643
|
-
|
|
3865
|
+
expect25(noKeyCount).toBe(12);
|
|
3644
3866
|
});
|
|
3645
|
-
|
|
3867
|
+
test25("no keys does not match actors with keys", async (c) => {
|
|
3646
3868
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3647
3869
|
const keyedCounter = client.counter.getOrCreate([
|
|
3648
3870
|
"counter-with-keys",
|
|
@@ -3651,9 +3873,9 @@ function runManagerDriverTests(driverTestConfig) {
|
|
|
3651
3873
|
await keyedCounter.increment(15);
|
|
3652
3874
|
const noKeysCounter = client.counter.getOrCreate();
|
|
3653
3875
|
const count = await noKeysCounter.increment(10);
|
|
3654
|
-
|
|
3876
|
+
expect25(count).toBe(10);
|
|
3655
3877
|
});
|
|
3656
|
-
|
|
3878
|
+
test25("actors with keys match actors with no keys", async (c) => {
|
|
3657
3879
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3658
3880
|
const noKeysCounter = client.counter.getOrCreate();
|
|
3659
3881
|
await noKeysCounter.increment(25);
|
|
@@ -3662,11 +3884,11 @@ function runManagerDriverTests(driverTestConfig) {
|
|
|
3662
3884
|
"prod"
|
|
3663
3885
|
]);
|
|
3664
3886
|
const keyedCount = await keyedCounter.increment(0);
|
|
3665
|
-
|
|
3887
|
+
expect25(keyedCount).toBe(0);
|
|
3666
3888
|
});
|
|
3667
3889
|
});
|
|
3668
|
-
|
|
3669
|
-
|
|
3890
|
+
describe26("Multiple Actor Instances", () => {
|
|
3891
|
+
test25("creates multiple actor instances of the same type", async (c) => {
|
|
3670
3892
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3671
3893
|
const instance1 = client.counter.getOrCreate(["multi-1"]);
|
|
3672
3894
|
const instance2 = client.counter.getOrCreate(["multi-2"]);
|
|
@@ -3677,35 +3899,35 @@ function runManagerDriverTests(driverTestConfig) {
|
|
|
3677
3899
|
const retrieved1 = client.counter.getOrCreate(["multi-1"]);
|
|
3678
3900
|
const retrieved2 = client.counter.getOrCreate(["multi-2"]);
|
|
3679
3901
|
const retrieved3 = client.counter.getOrCreate(["multi-3"]);
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
|
|
3902
|
+
expect25(await retrieved1.increment(0)).toBe(1);
|
|
3903
|
+
expect25(await retrieved2.increment(0)).toBe(2);
|
|
3904
|
+
expect25(await retrieved3.increment(0)).toBe(3);
|
|
3683
3905
|
});
|
|
3684
|
-
|
|
3906
|
+
test25("handles default instance with no explicit ID", async (c) => {
|
|
3685
3907
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3686
3908
|
const defaultCounter = client.counter.getOrCreate();
|
|
3687
3909
|
await defaultCounter.increment(5);
|
|
3688
3910
|
const sameDefaultCounter = client.counter.getOrCreate();
|
|
3689
3911
|
const count = await sameDefaultCounter.increment(0);
|
|
3690
|
-
|
|
3912
|
+
expect25(count).toBe(5);
|
|
3691
3913
|
});
|
|
3692
3914
|
});
|
|
3693
3915
|
});
|
|
3694
3916
|
}
|
|
3695
3917
|
|
|
3696
3918
|
// src/driver-test-suite/tests/raw-http.ts
|
|
3697
|
-
import { describe as
|
|
3919
|
+
import { describe as describe27, expect as expect26, test as test26 } from "vitest";
|
|
3698
3920
|
function runRawHttpTests(driverTestConfig) {
|
|
3699
|
-
|
|
3700
|
-
|
|
3921
|
+
describe27("raw http", () => {
|
|
3922
|
+
test26("should handle raw HTTP GET requests", async (c) => {
|
|
3701
3923
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3702
3924
|
const actor = client.rawHttpActor.getOrCreate(["test"]);
|
|
3703
3925
|
const helloResponse = await actor.fetch("api/hello");
|
|
3704
|
-
|
|
3926
|
+
expect26(helloResponse.ok).toBe(true);
|
|
3705
3927
|
const helloData = await helloResponse.json();
|
|
3706
|
-
|
|
3928
|
+
expect26(helloData).toEqual({ message: "Hello from actor!" });
|
|
3707
3929
|
});
|
|
3708
|
-
|
|
3930
|
+
test26("should handle raw HTTP POST requests with echo", async (c) => {
|
|
3709
3931
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3710
3932
|
const actor = client.rawHttpActor.getOrCreate(["test"]);
|
|
3711
3933
|
const testData = { test: "data", number: 123 };
|
|
@@ -3716,22 +3938,22 @@ function runRawHttpTests(driverTestConfig) {
|
|
|
3716
3938
|
},
|
|
3717
3939
|
body: JSON.stringify(testData)
|
|
3718
3940
|
});
|
|
3719
|
-
|
|
3941
|
+
expect26(echoResponse.ok).toBe(true);
|
|
3720
3942
|
const echoData = await echoResponse.json();
|
|
3721
|
-
|
|
3943
|
+
expect26(echoData).toEqual(testData);
|
|
3722
3944
|
});
|
|
3723
|
-
|
|
3945
|
+
test26("should track state across raw HTTP requests", async (c) => {
|
|
3724
3946
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3725
3947
|
const actor = client.rawHttpActor.getOrCreate(["state-test"]);
|
|
3726
3948
|
await actor.fetch("api/hello");
|
|
3727
3949
|
await actor.fetch("api/hello");
|
|
3728
3950
|
await actor.fetch("api/state");
|
|
3729
3951
|
const stateResponse = await actor.fetch("api/state");
|
|
3730
|
-
|
|
3952
|
+
expect26(stateResponse.ok).toBe(true);
|
|
3731
3953
|
const stateData = await stateResponse.json();
|
|
3732
|
-
|
|
3954
|
+
expect26(stateData.requestCount).toBe(4);
|
|
3733
3955
|
});
|
|
3734
|
-
|
|
3956
|
+
test26("should pass headers correctly", async (c) => {
|
|
3735
3957
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3736
3958
|
const actor = client.rawHttpActor.getOrCreate(["headers-test"]);
|
|
3737
3959
|
const customHeaders = {
|
|
@@ -3741,44 +3963,44 @@ function runRawHttpTests(driverTestConfig) {
|
|
|
3741
3963
|
const response = await actor.fetch("api/headers", {
|
|
3742
3964
|
headers: customHeaders
|
|
3743
3965
|
});
|
|
3744
|
-
|
|
3966
|
+
expect26(response.ok).toBe(true);
|
|
3745
3967
|
const headers = await response.json();
|
|
3746
|
-
|
|
3747
|
-
|
|
3968
|
+
expect26(headers["x-custom-header"]).toBe("test-value");
|
|
3969
|
+
expect26(headers["x-another-header"]).toBe("another-value");
|
|
3748
3970
|
});
|
|
3749
|
-
|
|
3971
|
+
test26("should return 404 for unhandled paths", async (c) => {
|
|
3750
3972
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3751
3973
|
const actor = client.rawHttpActor.getOrCreate(["404-test"]);
|
|
3752
3974
|
const response = await actor.fetch("api/nonexistent");
|
|
3753
|
-
|
|
3754
|
-
|
|
3975
|
+
expect26(response.ok).toBe(false);
|
|
3976
|
+
expect26(response.status).toBe(404);
|
|
3755
3977
|
});
|
|
3756
|
-
|
|
3978
|
+
test26("should return 404 when no onRequest handler defined", async (c) => {
|
|
3757
3979
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3758
3980
|
const actor = client.rawHttpNoHandlerActor.getOrCreate([
|
|
3759
3981
|
"no-handler"
|
|
3760
3982
|
]);
|
|
3761
3983
|
const response = await actor.fetch("api/anything");
|
|
3762
|
-
|
|
3763
|
-
|
|
3984
|
+
expect26(response.ok).toBe(false);
|
|
3985
|
+
expect26(response.status).toBe(404);
|
|
3764
3986
|
});
|
|
3765
|
-
|
|
3987
|
+
test26("should return 500 error when onRequest returns void", async (c) => {
|
|
3766
3988
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3767
3989
|
const actor = client.rawHttpVoidReturnActor.getOrCreate([
|
|
3768
3990
|
"void-return"
|
|
3769
3991
|
]);
|
|
3770
3992
|
const response = await actor.fetch("api/anything");
|
|
3771
|
-
|
|
3772
|
-
|
|
3993
|
+
expect26(response.ok).toBe(false);
|
|
3994
|
+
expect26(response.status).toBe(500);
|
|
3773
3995
|
try {
|
|
3774
3996
|
const errorData = await response.json();
|
|
3775
|
-
|
|
3997
|
+
expect26(errorData.message).toContain(
|
|
3776
3998
|
"onRequest handler must return a Response"
|
|
3777
3999
|
);
|
|
3778
4000
|
} catch {
|
|
3779
4001
|
}
|
|
3780
4002
|
});
|
|
3781
|
-
|
|
4003
|
+
test26("should handle different HTTP methods", async (c) => {
|
|
3782
4004
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3783
4005
|
const actor = client.rawHttpActor.getOrCreate(["methods-test"]);
|
|
3784
4006
|
const methods = ["GET", "POST", "PUT", "DELETE", "PATCH"];
|
|
@@ -3788,17 +4010,17 @@ function runRawHttpTests(driverTestConfig) {
|
|
|
3788
4010
|
body: ["POST", "PUT", "PATCH"].includes(method) ? JSON.stringify({ method }) : void 0
|
|
3789
4011
|
});
|
|
3790
4012
|
if (method === "POST") {
|
|
3791
|
-
|
|
4013
|
+
expect26(response.ok).toBe(true);
|
|
3792
4014
|
const data = await response.json();
|
|
3793
|
-
|
|
4015
|
+
expect26(data).toEqual({ method });
|
|
3794
4016
|
} else if (method === "GET") {
|
|
3795
|
-
|
|
4017
|
+
expect26(response.status).toBe(404);
|
|
3796
4018
|
} else {
|
|
3797
|
-
|
|
4019
|
+
expect26(response.status).toBe(404);
|
|
3798
4020
|
}
|
|
3799
4021
|
}
|
|
3800
4022
|
});
|
|
3801
|
-
|
|
4023
|
+
test26("should handle binary data", async (c) => {
|
|
3802
4024
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3803
4025
|
const actor = client.rawHttpActor.getOrCreate(["binary-test"]);
|
|
3804
4026
|
const binaryData = new Uint8Array([1, 2, 3, 4, 5]);
|
|
@@ -3809,82 +4031,82 @@ function runRawHttpTests(driverTestConfig) {
|
|
|
3809
4031
|
},
|
|
3810
4032
|
body: binaryData
|
|
3811
4033
|
});
|
|
3812
|
-
|
|
4034
|
+
expect26(response.ok).toBe(true);
|
|
3813
4035
|
const responseBuffer = await response.arrayBuffer();
|
|
3814
4036
|
const responseArray = new Uint8Array(responseBuffer);
|
|
3815
|
-
|
|
4037
|
+
expect26(Array.from(responseArray)).toEqual([1, 2, 3, 4, 5]);
|
|
3816
4038
|
});
|
|
3817
|
-
|
|
4039
|
+
test26("should work with Hono router using createVars", async (c) => {
|
|
3818
4040
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3819
4041
|
const actor = client.rawHttpHonoActor.getOrCreate(["hono-test"]);
|
|
3820
4042
|
const rootResponse = await actor.fetch("/");
|
|
3821
|
-
|
|
4043
|
+
expect26(rootResponse.ok).toBe(true);
|
|
3822
4044
|
const rootData = await rootResponse.json();
|
|
3823
|
-
|
|
4045
|
+
expect26(rootData).toEqual({ message: "Welcome to Hono actor!" });
|
|
3824
4046
|
const usersResponse = await actor.fetch("/users");
|
|
3825
|
-
|
|
4047
|
+
expect26(usersResponse.ok).toBe(true);
|
|
3826
4048
|
const users = await usersResponse.json();
|
|
3827
|
-
|
|
4049
|
+
expect26(users).toEqual([
|
|
3828
4050
|
{ id: 1, name: "Alice" },
|
|
3829
4051
|
{ id: 2, name: "Bob" }
|
|
3830
4052
|
]);
|
|
3831
4053
|
const userResponse = await actor.fetch("/users/1");
|
|
3832
|
-
|
|
4054
|
+
expect26(userResponse.ok).toBe(true);
|
|
3833
4055
|
const user = await userResponse.json();
|
|
3834
|
-
|
|
4056
|
+
expect26(user).toEqual({ id: 1, name: "Alice" });
|
|
3835
4057
|
const newUser = { name: "Charlie" };
|
|
3836
4058
|
const createResponse = await actor.fetch("/users", {
|
|
3837
4059
|
method: "POST",
|
|
3838
4060
|
headers: { "Content-Type": "application/json" },
|
|
3839
4061
|
body: JSON.stringify(newUser)
|
|
3840
4062
|
});
|
|
3841
|
-
|
|
3842
|
-
|
|
4063
|
+
expect26(createResponse.ok).toBe(true);
|
|
4064
|
+
expect26(createResponse.status).toBe(201);
|
|
3843
4065
|
const createdUser = await createResponse.json();
|
|
3844
|
-
|
|
4066
|
+
expect26(createdUser).toEqual({ id: 3, name: "Charlie" });
|
|
3845
4067
|
const updateData = { name: "Alice Updated" };
|
|
3846
4068
|
const updateResponse = await actor.fetch("/users/1", {
|
|
3847
4069
|
method: "PUT",
|
|
3848
4070
|
headers: { "Content-Type": "application/json" },
|
|
3849
4071
|
body: JSON.stringify(updateData)
|
|
3850
4072
|
});
|
|
3851
|
-
|
|
4073
|
+
expect26(updateResponse.ok).toBe(true);
|
|
3852
4074
|
const updatedUser = await updateResponse.json();
|
|
3853
|
-
|
|
4075
|
+
expect26(updatedUser).toEqual({ id: 1, name: "Alice Updated" });
|
|
3854
4076
|
const deleteResponse = await actor.fetch("/users/2", {
|
|
3855
4077
|
method: "DELETE"
|
|
3856
4078
|
});
|
|
3857
|
-
|
|
4079
|
+
expect26(deleteResponse.ok).toBe(true);
|
|
3858
4080
|
const deleteResult = await deleteResponse.json();
|
|
3859
|
-
|
|
4081
|
+
expect26(deleteResult).toEqual({ message: "User 2 deleted" });
|
|
3860
4082
|
const notFoundResponse = await actor.fetch("/api/unknown");
|
|
3861
|
-
|
|
3862
|
-
|
|
4083
|
+
expect26(notFoundResponse.ok).toBe(false);
|
|
4084
|
+
expect26(notFoundResponse.status).toBe(404);
|
|
3863
4085
|
});
|
|
3864
|
-
|
|
4086
|
+
test26("should handle paths with and without leading slashes", async (c) => {
|
|
3865
4087
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3866
4088
|
const actor = client.rawHttpActor.getOrCreate(["path-test"]);
|
|
3867
4089
|
const responseWithoutSlash = await actor.fetch("api/hello");
|
|
3868
|
-
|
|
4090
|
+
expect26(responseWithoutSlash.ok).toBe(true);
|
|
3869
4091
|
const dataWithoutSlash = await responseWithoutSlash.json();
|
|
3870
|
-
|
|
4092
|
+
expect26(dataWithoutSlash).toEqual({ message: "Hello from actor!" });
|
|
3871
4093
|
const responseWithSlash = await actor.fetch("/api/hello");
|
|
3872
|
-
|
|
4094
|
+
expect26(responseWithSlash.ok).toBe(true);
|
|
3873
4095
|
const dataWithSlash = await responseWithSlash.json();
|
|
3874
|
-
|
|
4096
|
+
expect26(dataWithSlash).toEqual({ message: "Hello from actor!" });
|
|
3875
4097
|
});
|
|
3876
|
-
|
|
4098
|
+
test26("should not create double slashes in request URLs", async (c) => {
|
|
3877
4099
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3878
4100
|
const actor = client.rawHttpHonoActor.getOrCreate(["url-test"]);
|
|
3879
4101
|
const response = await actor.fetch("/users");
|
|
3880
|
-
|
|
4102
|
+
expect26(response.ok).toBe(true);
|
|
3881
4103
|
const data = await response.json();
|
|
3882
|
-
|
|
4104
|
+
expect26(data).toEqual([
|
|
3883
4105
|
{ id: 1, name: "Alice" },
|
|
3884
4106
|
{ id: 2, name: "Bob" }
|
|
3885
4107
|
]);
|
|
3886
4108
|
});
|
|
3887
|
-
|
|
4109
|
+
test26("should handle forwarded requests correctly without double slashes", async (c) => {
|
|
3888
4110
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3889
4111
|
const actor = client.rawHttpHonoActor.getOrCreate(["forward-test"]);
|
|
3890
4112
|
const truncatedPath = "/users";
|
|
@@ -3896,14 +4118,14 @@ function runRawHttpTests(driverTestConfig) {
|
|
|
3896
4118
|
truncatedPath,
|
|
3897
4119
|
newRequest
|
|
3898
4120
|
);
|
|
3899
|
-
|
|
4121
|
+
expect26(response.ok).toBe(true);
|
|
3900
4122
|
const users = await response.json();
|
|
3901
|
-
|
|
4123
|
+
expect26(users).toEqual([
|
|
3902
4124
|
{ id: 1, name: "Alice" },
|
|
3903
4125
|
{ id: 2, name: "Bob" }
|
|
3904
4126
|
]);
|
|
3905
4127
|
});
|
|
3906
|
-
|
|
4128
|
+
test26("example fix: should properly forward requests using just Request object", async (c) => {
|
|
3907
4129
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3908
4130
|
const actor = client.rawHttpHonoActor.getOrCreate(["forward-fix"]);
|
|
3909
4131
|
const truncatedPath = "/users/1";
|
|
@@ -3912,11 +4134,11 @@ function runRawHttpTests(driverTestConfig) {
|
|
|
3912
4134
|
method: "GET"
|
|
3913
4135
|
});
|
|
3914
4136
|
const response = await actor.fetch(newRequest);
|
|
3915
|
-
|
|
4137
|
+
expect26(response.ok).toBe(true);
|
|
3916
4138
|
const user = await response.json();
|
|
3917
|
-
|
|
4139
|
+
expect26(user).toEqual({ id: 1, name: "Alice" });
|
|
3918
4140
|
});
|
|
3919
|
-
|
|
4141
|
+
test26("should support standard fetch API with URL and Request objects", async (c) => {
|
|
3920
4142
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3921
4143
|
const actor = client.rawHttpActor.getOrCreate(["fetch-api-test"]);
|
|
3922
4144
|
const url = new URL("/api/echo", "http://example.com");
|
|
@@ -3925,18 +4147,18 @@ function runRawHttpTests(driverTestConfig) {
|
|
|
3925
4147
|
headers: { "Content-Type": "application/json" },
|
|
3926
4148
|
body: JSON.stringify({ from: "URL object" })
|
|
3927
4149
|
});
|
|
3928
|
-
|
|
4150
|
+
expect26(urlResponse.ok).toBe(true);
|
|
3929
4151
|
const urlData = await urlResponse.json();
|
|
3930
|
-
|
|
4152
|
+
expect26(urlData).toEqual({ from: "URL object" });
|
|
3931
4153
|
const request = new Request("http://example.com/api/echo", {
|
|
3932
4154
|
method: "POST",
|
|
3933
4155
|
headers: { "Content-Type": "application/json" },
|
|
3934
4156
|
body: JSON.stringify({ from: "Request object" })
|
|
3935
4157
|
});
|
|
3936
4158
|
const requestResponse = await actor.fetch(request);
|
|
3937
|
-
|
|
4159
|
+
expect26(requestResponse.ok).toBe(true);
|
|
3938
4160
|
const requestData = await requestResponse.json();
|
|
3939
|
-
|
|
4161
|
+
expect26(requestData).toEqual({ from: "Request object" });
|
|
3940
4162
|
const request2 = new Request("http://example.com/api/headers", {
|
|
3941
4163
|
method: "GET",
|
|
3942
4164
|
headers: { "X-Original": "request-header" }
|
|
@@ -3944,19 +4166,19 @@ function runRawHttpTests(driverTestConfig) {
|
|
|
3944
4166
|
const overrideResponse = await actor.fetch(request2, {
|
|
3945
4167
|
headers: { "X-Override": "init-header" }
|
|
3946
4168
|
});
|
|
3947
|
-
|
|
4169
|
+
expect26(overrideResponse.ok).toBe(true);
|
|
3948
4170
|
const headers = await overrideResponse.json();
|
|
3949
|
-
|
|
3950
|
-
|
|
4171
|
+
expect26(headers["x-override"]).toBe("init-header");
|
|
4172
|
+
expect26(headers["x-original"]).toBe("request-header");
|
|
3951
4173
|
});
|
|
3952
4174
|
});
|
|
3953
4175
|
}
|
|
3954
4176
|
|
|
3955
4177
|
// src/driver-test-suite/tests/raw-http-request-properties.ts
|
|
3956
|
-
import { describe as
|
|
4178
|
+
import { describe as describe28, expect as expect27, test as test27 } from "vitest";
|
|
3957
4179
|
function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
3958
|
-
|
|
3959
|
-
|
|
4180
|
+
describe28("raw http request properties", () => {
|
|
4181
|
+
test27("should pass all Request properties correctly to onRequest", async (c) => {
|
|
3960
4182
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3961
4183
|
const actor = client.rawHttpRequestPropertiesActor.getOrCreate([
|
|
3962
4184
|
"test"
|
|
@@ -3970,22 +4192,22 @@ function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
|
3970
4192
|
},
|
|
3971
4193
|
body: JSON.stringify({ test: "data" })
|
|
3972
4194
|
});
|
|
3973
|
-
|
|
4195
|
+
expect27(response.ok).toBe(true);
|
|
3974
4196
|
const data = await response.json();
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
|
|
3978
|
-
|
|
4197
|
+
expect27(data.url).toContain("/test/path?foo=bar&baz=qux");
|
|
4198
|
+
expect27(data.pathname).toBe("/test/path");
|
|
4199
|
+
expect27(data.search).toBe("?foo=bar&baz=qux");
|
|
4200
|
+
expect27(data.searchParams).toEqual({
|
|
3979
4201
|
foo: "bar",
|
|
3980
4202
|
baz: "qux"
|
|
3981
4203
|
});
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
|
|
3985
|
-
|
|
3986
|
-
|
|
4204
|
+
expect27(data.method).toBe("POST");
|
|
4205
|
+
expect27(data.headers["content-type"]).toBe("application/json");
|
|
4206
|
+
expect27(data.headers["x-custom-header"]).toBe("custom-value");
|
|
4207
|
+
expect27(data.headers["authorization"]).toBe("Bearer test-token");
|
|
4208
|
+
expect27(data.body).toEqual({ test: "data" });
|
|
3987
4209
|
});
|
|
3988
|
-
|
|
4210
|
+
test27("should handle GET requests with no body", async (c) => {
|
|
3989
4211
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3990
4212
|
const actor = client.rawHttpRequestPropertiesActor.getOrCreate([
|
|
3991
4213
|
"test"
|
|
@@ -3993,12 +4215,12 @@ function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
|
3993
4215
|
const response = await actor.fetch("test/get", {
|
|
3994
4216
|
method: "GET"
|
|
3995
4217
|
});
|
|
3996
|
-
|
|
4218
|
+
expect27(response.ok).toBe(true);
|
|
3997
4219
|
const data = await response.json();
|
|
3998
|
-
|
|
3999
|
-
|
|
4220
|
+
expect27(data.method).toBe("GET");
|
|
4221
|
+
expect27(data.body).toBeNull();
|
|
4000
4222
|
});
|
|
4001
|
-
|
|
4223
|
+
test27("should handle different content types", async (c) => {
|
|
4002
4224
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
4003
4225
|
const actor = client.rawHttpRequestPropertiesActor.getOrCreate([
|
|
4004
4226
|
"test"
|
|
@@ -4013,12 +4235,12 @@ function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
|
4013
4235
|
},
|
|
4014
4236
|
body: formData.toString()
|
|
4015
4237
|
});
|
|
4016
|
-
|
|
4238
|
+
expect27(formResponse.ok).toBe(true);
|
|
4017
4239
|
const formResult = await formResponse.json();
|
|
4018
|
-
|
|
4240
|
+
expect27(formResult.headers["content-type"]).toBe(
|
|
4019
4241
|
"application/x-www-form-urlencoded"
|
|
4020
4242
|
);
|
|
4021
|
-
|
|
4243
|
+
expect27(formResult.bodyText).toBe("field1=value1&field2=value2");
|
|
4022
4244
|
const textResponse = await actor.fetch("test/text", {
|
|
4023
4245
|
method: "POST",
|
|
4024
4246
|
headers: {
|
|
@@ -4026,12 +4248,12 @@ function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
|
4026
4248
|
},
|
|
4027
4249
|
body: "Hello, World!"
|
|
4028
4250
|
});
|
|
4029
|
-
|
|
4251
|
+
expect27(textResponse.ok).toBe(true);
|
|
4030
4252
|
const textResult = await textResponse.json();
|
|
4031
|
-
|
|
4032
|
-
|
|
4253
|
+
expect27(textResult.headers["content-type"]).toBe("text/plain");
|
|
4254
|
+
expect27(textResult.bodyText).toBe("Hello, World!");
|
|
4033
4255
|
});
|
|
4034
|
-
|
|
4256
|
+
test27("should preserve all header casing and values", async (c) => {
|
|
4035
4257
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
4036
4258
|
const actor = client.rawHttpRequestPropertiesActor.getOrCreate([
|
|
4037
4259
|
"test"
|
|
@@ -4045,38 +4267,38 @@ function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
|
4045
4267
|
"X-Request-ID": "12345"
|
|
4046
4268
|
}
|
|
4047
4269
|
});
|
|
4048
|
-
|
|
4270
|
+
expect27(response.ok).toBe(true);
|
|
4049
4271
|
const data = await response.json();
|
|
4050
|
-
|
|
4051
|
-
|
|
4052
|
-
|
|
4053
|
-
|
|
4054
|
-
|
|
4272
|
+
expect27(data.headers["accept"]).toBe("application/json");
|
|
4273
|
+
expect27(data.headers["accept-language"]).toBe("en-US,en;q=0.9");
|
|
4274
|
+
expect27(data.headers["cache-control"]).toBe("no-cache");
|
|
4275
|
+
expect27(data.headers["user-agent"]).toBeTruthy();
|
|
4276
|
+
expect27(data.headers["x-request-id"]).toBe("12345");
|
|
4055
4277
|
});
|
|
4056
|
-
|
|
4278
|
+
test27("should handle empty and special URL paths", async (c) => {
|
|
4057
4279
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
4058
4280
|
const actor = client.rawHttpRequestPropertiesActor.getOrCreate([
|
|
4059
4281
|
"test"
|
|
4060
4282
|
]);
|
|
4061
4283
|
const rootResponse = await actor.fetch("");
|
|
4062
|
-
|
|
4284
|
+
expect27(rootResponse.ok).toBe(true);
|
|
4063
4285
|
const rootData = await rootResponse.json();
|
|
4064
|
-
|
|
4286
|
+
expect27(rootData.pathname).toBe("/");
|
|
4065
4287
|
const specialResponse = await actor.fetch(
|
|
4066
4288
|
"test/path%20with%20spaces/and%2Fslashes"
|
|
4067
4289
|
);
|
|
4068
|
-
|
|
4290
|
+
expect27(specialResponse.ok).toBe(true);
|
|
4069
4291
|
const specialData = await specialResponse.json();
|
|
4070
|
-
|
|
4292
|
+
expect27(specialData.pathname).toMatch(
|
|
4071
4293
|
/path.*with.*spaces.*and.*slashes/
|
|
4072
4294
|
);
|
|
4073
4295
|
const fragmentResponse = await actor.fetch("test/path#fragment");
|
|
4074
|
-
|
|
4296
|
+
expect27(fragmentResponse.ok).toBe(true);
|
|
4075
4297
|
const fragmentData = await fragmentResponse.json();
|
|
4076
|
-
|
|
4077
|
-
|
|
4298
|
+
expect27(fragmentData.pathname).toBe("/test/path");
|
|
4299
|
+
expect27(fragmentData.hash).toBe("");
|
|
4078
4300
|
});
|
|
4079
|
-
|
|
4301
|
+
test27("should handle request properties for all HTTP methods", async (c) => {
|
|
4080
4302
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
4081
4303
|
const actor = client.rawHttpRequestPropertiesActor.getOrCreate([
|
|
4082
4304
|
"test"
|
|
@@ -4100,21 +4322,21 @@ function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
|
4100
4322
|
}
|
|
4101
4323
|
);
|
|
4102
4324
|
if (method === "HEAD") {
|
|
4103
|
-
|
|
4325
|
+
expect27(response.status).toBe(200);
|
|
4104
4326
|
const text = await response.text();
|
|
4105
|
-
|
|
4327
|
+
expect27(text).toBe("");
|
|
4106
4328
|
} else if (method === "OPTIONS") {
|
|
4107
|
-
|
|
4329
|
+
expect27(response.status).toBe(204);
|
|
4108
4330
|
const text = await response.text();
|
|
4109
|
-
|
|
4331
|
+
expect27(text).toBe("");
|
|
4110
4332
|
} else {
|
|
4111
|
-
|
|
4333
|
+
expect27(response.ok).toBe(true);
|
|
4112
4334
|
const data = await response.json();
|
|
4113
|
-
|
|
4335
|
+
expect27(data.method).toBe(method);
|
|
4114
4336
|
}
|
|
4115
4337
|
}
|
|
4116
4338
|
});
|
|
4117
|
-
|
|
4339
|
+
test27("should handle complex query parameters", async (c) => {
|
|
4118
4340
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
4119
4341
|
const actor = client.rawHttpRequestPropertiesActor.getOrCreate([
|
|
4120
4342
|
"test"
|
|
@@ -4122,13 +4344,13 @@ function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
|
4122
4344
|
const response = await actor.fetch(
|
|
4123
4345
|
"test?key=value1&key=value2&array[]=1&array[]=2&nested[prop]=val"
|
|
4124
4346
|
);
|
|
4125
|
-
|
|
4347
|
+
expect27(response.ok).toBe(true);
|
|
4126
4348
|
const data = await response.json();
|
|
4127
|
-
|
|
4128
|
-
|
|
4129
|
-
|
|
4349
|
+
expect27(data.searchParams.key).toBe("value2");
|
|
4350
|
+
expect27(data.searchParams["array[]"]).toBe("2");
|
|
4351
|
+
expect27(data.searchParams["nested[prop]"]).toBe("val");
|
|
4130
4352
|
});
|
|
4131
|
-
|
|
4353
|
+
test27("should handle multipart form data", async (c) => {
|
|
4132
4354
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
4133
4355
|
const actor = client.rawHttpRequestPropertiesActor.getOrCreate([
|
|
4134
4356
|
"test"
|
|
@@ -4152,27 +4374,27 @@ function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
|
4152
4374
|
},
|
|
4153
4375
|
body
|
|
4154
4376
|
});
|
|
4155
|
-
|
|
4377
|
+
expect27(response.ok).toBe(true);
|
|
4156
4378
|
const data = await response.json();
|
|
4157
|
-
|
|
4379
|
+
expect27(data.headers["content-type"]).toContain(
|
|
4158
4380
|
"multipart/form-data"
|
|
4159
4381
|
);
|
|
4160
|
-
|
|
4161
|
-
|
|
4382
|
+
expect27(data.bodyText).toContain("field1");
|
|
4383
|
+
expect27(data.bodyText).toContain("value1");
|
|
4162
4384
|
});
|
|
4163
|
-
|
|
4385
|
+
test27("should handle very long URLs", async (c) => {
|
|
4164
4386
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
4165
4387
|
const actor = client.rawHttpRequestPropertiesActor.getOrCreate([
|
|
4166
4388
|
"test"
|
|
4167
4389
|
]);
|
|
4168
4390
|
const longValue = "x".repeat(1e3);
|
|
4169
4391
|
const response = await actor.fetch(`test/long?param=${longValue}`);
|
|
4170
|
-
|
|
4392
|
+
expect27(response.ok).toBe(true);
|
|
4171
4393
|
const data = await response.json();
|
|
4172
|
-
|
|
4173
|
-
|
|
4394
|
+
expect27(data.searchParams.param).toBe(longValue);
|
|
4395
|
+
expect27(data.search.length).toBeGreaterThan(1e3);
|
|
4174
4396
|
});
|
|
4175
|
-
|
|
4397
|
+
test27.skip("should handle large request bodies", async (c) => {
|
|
4176
4398
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
4177
4399
|
const actor = client.rawHttpRequestPropertiesActor.getOrCreate([
|
|
4178
4400
|
"test"
|
|
@@ -4189,11 +4411,11 @@ function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
|
4189
4411
|
},
|
|
4190
4412
|
body: JSON.stringify(largeArray)
|
|
4191
4413
|
});
|
|
4192
|
-
|
|
4414
|
+
expect27(response.ok).toBe(true);
|
|
4193
4415
|
const data = await response.json();
|
|
4194
|
-
|
|
4416
|
+
expect27(data.body).toHaveLength(1e4);
|
|
4195
4417
|
});
|
|
4196
|
-
|
|
4418
|
+
test27("should handle missing content-type header", async (c) => {
|
|
4197
4419
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
4198
4420
|
const actor = client.rawHttpRequestPropertiesActor.getOrCreate([
|
|
4199
4421
|
"test"
|
|
@@ -4202,11 +4424,11 @@ function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
|
4202
4424
|
method: "POST",
|
|
4203
4425
|
body: "plain text without content-type"
|
|
4204
4426
|
});
|
|
4205
|
-
|
|
4427
|
+
expect27(response.ok).toBe(true);
|
|
4206
4428
|
const data = await response.json();
|
|
4207
|
-
|
|
4429
|
+
expect27(data.bodyText).toBe("plain text without content-type");
|
|
4208
4430
|
});
|
|
4209
|
-
|
|
4431
|
+
test27("should handle empty request body", async (c) => {
|
|
4210
4432
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
4211
4433
|
const actor = client.rawHttpRequestPropertiesActor.getOrCreate([
|
|
4212
4434
|
"test"
|
|
@@ -4218,9 +4440,9 @@ function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
|
4218
4440
|
},
|
|
4219
4441
|
body: ""
|
|
4220
4442
|
});
|
|
4221
|
-
|
|
4443
|
+
expect27(response.ok).toBe(true);
|
|
4222
4444
|
});
|
|
4223
|
-
|
|
4445
|
+
test27("should handle custom HTTP methods", async (c) => {
|
|
4224
4446
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
4225
4447
|
const actor = client.rawHttpRequestPropertiesActor.getOrCreate([
|
|
4226
4448
|
"test"
|
|
@@ -4231,12 +4453,12 @@ function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
|
4231
4453
|
});
|
|
4232
4454
|
if (response.ok) {
|
|
4233
4455
|
const data = await response.json();
|
|
4234
|
-
|
|
4456
|
+
expect27(data.method).toBe("CUSTOM");
|
|
4235
4457
|
}
|
|
4236
4458
|
} catch (error) {
|
|
4237
4459
|
}
|
|
4238
4460
|
});
|
|
4239
|
-
|
|
4461
|
+
test27("should handle cookies in headers", async (c) => {
|
|
4240
4462
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
4241
4463
|
const actor = client.rawHttpRequestPropertiesActor.getOrCreate([
|
|
4242
4464
|
"test"
|
|
@@ -4246,13 +4468,13 @@ function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
|
4246
4468
|
Cookie: "session=abc123; user=test; preferences=dark_mode"
|
|
4247
4469
|
}
|
|
4248
4470
|
});
|
|
4249
|
-
|
|
4471
|
+
expect27(response.ok).toBe(true);
|
|
4250
4472
|
const data = await response.json();
|
|
4251
|
-
|
|
4473
|
+
expect27(data.headers.cookie).toBe(
|
|
4252
4474
|
"session=abc123; user=test; preferences=dark_mode"
|
|
4253
4475
|
);
|
|
4254
4476
|
});
|
|
4255
|
-
|
|
4477
|
+
test27("should handle URL encoding properly", async (c) => {
|
|
4256
4478
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
4257
4479
|
const actor = client.rawHttpRequestPropertiesActor.getOrCreate([
|
|
4258
4480
|
"test"
|
|
@@ -4260,13 +4482,13 @@ function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
|
4260
4482
|
const response = await actor.fetch(
|
|
4261
4483
|
"test/encoded?special=%20%21%40%23%24%25%5E%26&unicode=%E2%9C%93&email=test%40example.com"
|
|
4262
4484
|
);
|
|
4263
|
-
|
|
4485
|
+
expect27(response.ok).toBe(true);
|
|
4264
4486
|
const data = await response.json();
|
|
4265
|
-
|
|
4266
|
-
|
|
4267
|
-
|
|
4487
|
+
expect27(data.searchParams.special).toBe(" !@#$%^&");
|
|
4488
|
+
expect27(data.searchParams.unicode).toBe("\u2713");
|
|
4489
|
+
expect27(data.searchParams.email).toBe("test@example.com");
|
|
4268
4490
|
});
|
|
4269
|
-
|
|
4491
|
+
test27("should handle concurrent requests maintaining separate contexts", async (c) => {
|
|
4270
4492
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
4271
4493
|
const actor = client.rawHttpRequestPropertiesActor.getOrCreate([
|
|
4272
4494
|
"test"
|
|
@@ -4290,24 +4512,24 @@ function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
|
4290
4512
|
const results = await Promise.all(
|
|
4291
4513
|
responses.map((r) => r.json())
|
|
4292
4514
|
);
|
|
4293
|
-
|
|
4294
|
-
|
|
4295
|
-
|
|
4296
|
-
|
|
4297
|
-
|
|
4298
|
-
|
|
4299
|
-
|
|
4300
|
-
|
|
4301
|
-
|
|
4515
|
+
expect27(results[0].searchParams.id).toBe("1");
|
|
4516
|
+
expect27(results[0].method).toBe("POST");
|
|
4517
|
+
expect27(results[0].body).toEqual({ request: 1 });
|
|
4518
|
+
expect27(results[1].searchParams.id).toBe("2");
|
|
4519
|
+
expect27(results[1].method).toBe("PUT");
|
|
4520
|
+
expect27(results[1].body).toEqual({ request: 2 });
|
|
4521
|
+
expect27(results[2].searchParams.id).toBe("3");
|
|
4522
|
+
expect27(results[2].method).toBe("DELETE");
|
|
4523
|
+
expect27(results[2].body).toBeNull();
|
|
4302
4524
|
});
|
|
4303
4525
|
});
|
|
4304
4526
|
}
|
|
4305
4527
|
|
|
4306
4528
|
// src/driver-test-suite/tests/raw-websocket.ts
|
|
4307
|
-
import { describe as
|
|
4529
|
+
import { describe as describe29, expect as expect28, test as test28 } from "vitest";
|
|
4308
4530
|
function runRawWebSocketTests(driverTestConfig) {
|
|
4309
|
-
|
|
4310
|
-
|
|
4531
|
+
describe29("raw websocket", () => {
|
|
4532
|
+
test28("should establish raw WebSocket connection", async (c) => {
|
|
4311
4533
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
4312
4534
|
const actor = client.rawWebSocketActor.getOrCreate(["basic"]);
|
|
4313
4535
|
const ws = await actor.webSocket();
|
|
@@ -4334,11 +4556,11 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
4334
4556
|
);
|
|
4335
4557
|
ws.addEventListener("close", reject);
|
|
4336
4558
|
});
|
|
4337
|
-
|
|
4338
|
-
|
|
4559
|
+
expect28(welcomeMessage.type).toBe("welcome");
|
|
4560
|
+
expect28(welcomeMessage.connectionCount).toBe(1);
|
|
4339
4561
|
ws.close();
|
|
4340
4562
|
});
|
|
4341
|
-
|
|
4563
|
+
test28("should echo messages", async (c) => {
|
|
4342
4564
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
4343
4565
|
const actor = client.rawWebSocketActor.getOrCreate(["echo"]);
|
|
4344
4566
|
const ws = await actor.webSocket();
|
|
@@ -4366,10 +4588,10 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
4366
4588
|
);
|
|
4367
4589
|
ws.addEventListener("close", reject);
|
|
4368
4590
|
});
|
|
4369
|
-
|
|
4591
|
+
expect28(echoMessage).toEqual(testMessage);
|
|
4370
4592
|
ws.close();
|
|
4371
4593
|
});
|
|
4372
|
-
|
|
4594
|
+
test28("should handle ping/pong protocol", async (c) => {
|
|
4373
4595
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
4374
4596
|
const actor = client.rawWebSocketActor.getOrCreate(["ping"]);
|
|
4375
4597
|
const ws = await actor.webSocket();
|
|
@@ -4395,11 +4617,11 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
4395
4617
|
});
|
|
4396
4618
|
ws.addEventListener("close", reject);
|
|
4397
4619
|
});
|
|
4398
|
-
|
|
4399
|
-
|
|
4620
|
+
expect28(pongMessage.type).toBe("pong");
|
|
4621
|
+
expect28(pongMessage.timestamp).toBeDefined();
|
|
4400
4622
|
ws.close();
|
|
4401
4623
|
});
|
|
4402
|
-
|
|
4624
|
+
test28("should track stats across connections", async (c) => {
|
|
4403
4625
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
4404
4626
|
const actor1 = client.rawWebSocketActor.getOrCreate(["stats"]);
|
|
4405
4627
|
const ws1 = await actor1.webSocket();
|
|
@@ -4443,15 +4665,15 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
4443
4665
|
});
|
|
4444
4666
|
ws1.send(JSON.stringify({ type: "getStats" }));
|
|
4445
4667
|
const stats = await statsPromise;
|
|
4446
|
-
|
|
4447
|
-
|
|
4668
|
+
expect28(stats.connectionCount).toBe(2);
|
|
4669
|
+
expect28(stats.messageCount).toBe(4);
|
|
4448
4670
|
const actionStats = await actor1.getStats();
|
|
4449
|
-
|
|
4450
|
-
|
|
4671
|
+
expect28(actionStats.connectionCount).toBe(2);
|
|
4672
|
+
expect28(actionStats.messageCount).toBe(4);
|
|
4451
4673
|
ws1.close();
|
|
4452
4674
|
ws2.close();
|
|
4453
4675
|
});
|
|
4454
|
-
|
|
4676
|
+
test28("should handle binary data", async (c) => {
|
|
4455
4677
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
4456
4678
|
const actor = client.rawWebSocketBinaryActor.getOrCreate([
|
|
4457
4679
|
"binary"
|
|
@@ -4484,7 +4706,7 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
4484
4706
|
const smallData = new Uint8Array([1, 2, 3, 4, 5]);
|
|
4485
4707
|
ws.send(smallData);
|
|
4486
4708
|
const smallReversed = await receiveBinaryMessage();
|
|
4487
|
-
|
|
4709
|
+
expect28(Array.from(smallReversed)).toEqual([5, 4, 3, 2, 1]);
|
|
4488
4710
|
const largeData = new Uint8Array(1024);
|
|
4489
4711
|
for (let i = 0; i < largeData.length; i++) {
|
|
4490
4712
|
largeData[i] = i % 256;
|
|
@@ -4492,13 +4714,13 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
4492
4714
|
ws.send(largeData);
|
|
4493
4715
|
const largeReversed = await receiveBinaryMessage();
|
|
4494
4716
|
for (let i = 0; i < largeData.length; i++) {
|
|
4495
|
-
|
|
4717
|
+
expect28(largeReversed[i]).toBe(
|
|
4496
4718
|
largeData[largeData.length - 1 - i]
|
|
4497
4719
|
);
|
|
4498
4720
|
}
|
|
4499
4721
|
ws.close();
|
|
4500
4722
|
});
|
|
4501
|
-
|
|
4723
|
+
test28("should work with custom paths", async (c) => {
|
|
4502
4724
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
4503
4725
|
const actor = client.rawWebSocketActor.getOrCreate(["paths"]);
|
|
4504
4726
|
const ws = await actor.webSocket("custom/path");
|
|
@@ -4518,10 +4740,10 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
4518
4740
|
{ once: true }
|
|
4519
4741
|
);
|
|
4520
4742
|
});
|
|
4521
|
-
|
|
4743
|
+
expect28(welcomeMessage.type).toBe("welcome");
|
|
4522
4744
|
ws.close();
|
|
4523
4745
|
});
|
|
4524
|
-
|
|
4746
|
+
test28("should handle connection close properly", async (c) => {
|
|
4525
4747
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
4526
4748
|
const actor = client.rawWebSocketActor.getOrCreate(["close-test"]);
|
|
4527
4749
|
const ws = await actor.webSocket();
|
|
@@ -4534,7 +4756,7 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
4534
4756
|
});
|
|
4535
4757
|
}
|
|
4536
4758
|
const initialStats = await actor.getStats();
|
|
4537
|
-
|
|
4759
|
+
expect28(initialStats.connectionCount).toBe(1);
|
|
4538
4760
|
const closePromise = new Promise((resolve) => {
|
|
4539
4761
|
ws.addEventListener("close", () => resolve(), { once: true });
|
|
4540
4762
|
});
|
|
@@ -4548,9 +4770,9 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
4548
4770
|
}
|
|
4549
4771
|
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
4550
4772
|
}
|
|
4551
|
-
|
|
4773
|
+
expect28(finalStats == null ? void 0 : finalStats.connectionCount).toBe(0);
|
|
4552
4774
|
});
|
|
4553
|
-
|
|
4775
|
+
test28("should properly handle onWebSocket open and close events", async (c) => {
|
|
4554
4776
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
4555
4777
|
const actor = client.rawWebSocketActor.getOrCreate([
|
|
4556
4778
|
"open-close-test"
|
|
@@ -4570,8 +4792,8 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
4570
4792
|
);
|
|
4571
4793
|
ws1.addEventListener("close", reject);
|
|
4572
4794
|
});
|
|
4573
|
-
|
|
4574
|
-
|
|
4795
|
+
expect28(welcome1.type).toBe("welcome");
|
|
4796
|
+
expect28(welcome1.connectionCount).toBe(1);
|
|
4575
4797
|
const ws2 = await actor.webSocket();
|
|
4576
4798
|
await new Promise((resolve, reject) => {
|
|
4577
4799
|
ws2.addEventListener("open", () => resolve(), { once: true });
|
|
@@ -4587,10 +4809,10 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
4587
4809
|
);
|
|
4588
4810
|
ws2.addEventListener("close", reject);
|
|
4589
4811
|
});
|
|
4590
|
-
|
|
4591
|
-
|
|
4812
|
+
expect28(welcome2.type).toBe("welcome");
|
|
4813
|
+
expect28(welcome2.connectionCount).toBe(2);
|
|
4592
4814
|
const midStats = await actor.getStats();
|
|
4593
|
-
|
|
4815
|
+
expect28(midStats.connectionCount).toBe(2);
|
|
4594
4816
|
ws1.close();
|
|
4595
4817
|
await new Promise((resolve) => {
|
|
4596
4818
|
ws1.addEventListener("close", () => resolve(), { once: true });
|
|
@@ -4603,7 +4825,7 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
4603
4825
|
}
|
|
4604
4826
|
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
4605
4827
|
}
|
|
4606
|
-
|
|
4828
|
+
expect28(afterFirstClose == null ? void 0 : afterFirstClose.connectionCount).toBe(1);
|
|
4607
4829
|
ws2.close();
|
|
4608
4830
|
await new Promise((resolve) => {
|
|
4609
4831
|
ws2.addEventListener("close", () => resolve(), { once: true });
|
|
@@ -4616,9 +4838,9 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
4616
4838
|
}
|
|
4617
4839
|
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
4618
4840
|
}
|
|
4619
|
-
|
|
4841
|
+
expect28(finalStats == null ? void 0 : finalStats.connectionCount).toBe(0);
|
|
4620
4842
|
});
|
|
4621
|
-
|
|
4843
|
+
test28("should handle query parameters in websocket paths", async (c) => {
|
|
4622
4844
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
4623
4845
|
const actor = client.rawWebSocketActor.getOrCreate([
|
|
4624
4846
|
"query-params"
|
|
@@ -4641,12 +4863,12 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
4641
4863
|
});
|
|
4642
4864
|
ws.send(JSON.stringify({ type: "getRequestInfo" }));
|
|
4643
4865
|
const requestInfo = await requestInfoPromise;
|
|
4644
|
-
|
|
4645
|
-
|
|
4646
|
-
|
|
4866
|
+
expect28(requestInfo.url).toContain("api/v1/stream");
|
|
4867
|
+
expect28(requestInfo.url).toContain("token=abc123");
|
|
4868
|
+
expect28(requestInfo.url).toContain("user=test");
|
|
4647
4869
|
ws.close();
|
|
4648
4870
|
});
|
|
4649
|
-
|
|
4871
|
+
test28("should handle query parameters on base websocket path (no subpath)", async (c) => {
|
|
4650
4872
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
4651
4873
|
const actor = client.rawWebSocketActor.getOrCreate([
|
|
4652
4874
|
"base-path-query-params"
|
|
@@ -4670,18 +4892,18 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
4670
4892
|
});
|
|
4671
4893
|
ws.send(JSON.stringify({ type: "getRequestInfo" }));
|
|
4672
4894
|
const requestInfo = await requestInfoPromise;
|
|
4673
|
-
|
|
4674
|
-
|
|
4895
|
+
expect28(requestInfo.url).toContain("token=secret");
|
|
4896
|
+
expect28(requestInfo.url).toContain("session=123");
|
|
4675
4897
|
ws.close();
|
|
4676
4898
|
});
|
|
4677
4899
|
});
|
|
4678
4900
|
}
|
|
4679
4901
|
|
|
4680
4902
|
// src/driver-test-suite/tests/request-access.ts
|
|
4681
|
-
import { describe as
|
|
4903
|
+
import { describe as describe30, expect as expect29, test as test29 } from "vitest";
|
|
4682
4904
|
function runRequestAccessTests(driverTestConfig) {
|
|
4683
|
-
|
|
4684
|
-
|
|
4905
|
+
describe30("Request Access in Lifecycle Hooks", () => {
|
|
4906
|
+
test29("should have access to request object in onBeforeConnect and createConnState", async (c) => {
|
|
4685
4907
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
4686
4908
|
const handle = client.requestAccessActor.getOrCreate(
|
|
4687
4909
|
["test-request"],
|
|
@@ -4692,23 +4914,23 @@ function runRequestAccessTests(driverTestConfig) {
|
|
|
4692
4914
|
const connection = handle.connect();
|
|
4693
4915
|
const requestInfo = await connection.getRequestInfo();
|
|
4694
4916
|
if (driverTestConfig.clientType === "http") {
|
|
4695
|
-
|
|
4696
|
-
|
|
4697
|
-
|
|
4698
|
-
|
|
4917
|
+
expect29(requestInfo.onBeforeConnect.hasRequest).toBe(true);
|
|
4918
|
+
expect29(requestInfo.onBeforeConnect.requestUrl).toBeDefined();
|
|
4919
|
+
expect29(requestInfo.onBeforeConnect.requestMethod).toBeDefined();
|
|
4920
|
+
expect29(
|
|
4699
4921
|
requestInfo.onBeforeConnect.requestHeaders
|
|
4700
4922
|
).toBeDefined();
|
|
4701
|
-
|
|
4702
|
-
|
|
4703
|
-
|
|
4704
|
-
|
|
4923
|
+
expect29(requestInfo.createConnState.hasRequest).toBe(true);
|
|
4924
|
+
expect29(requestInfo.createConnState.requestUrl).toBeDefined();
|
|
4925
|
+
expect29(requestInfo.createConnState.requestMethod).toBeDefined();
|
|
4926
|
+
expect29(
|
|
4705
4927
|
requestInfo.createConnState.requestHeaders
|
|
4706
4928
|
).toBeDefined();
|
|
4707
4929
|
} else {
|
|
4708
4930
|
}
|
|
4709
4931
|
await connection.dispose();
|
|
4710
4932
|
});
|
|
4711
|
-
|
|
4933
|
+
test29("should not have request when trackRequest is false", async (c) => {
|
|
4712
4934
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
4713
4935
|
const handle = client.requestAccessActor.getOrCreate(
|
|
4714
4936
|
["test-no-request"],
|
|
@@ -4718,21 +4940,21 @@ function runRequestAccessTests(driverTestConfig) {
|
|
|
4718
4940
|
);
|
|
4719
4941
|
const connection = handle.connect();
|
|
4720
4942
|
const requestInfo = await connection.getRequestInfo();
|
|
4721
|
-
|
|
4722
|
-
|
|
4723
|
-
|
|
4724
|
-
|
|
4943
|
+
expect29(requestInfo.onBeforeConnect.hasRequest).toBe(false);
|
|
4944
|
+
expect29(requestInfo.onBeforeConnect.requestUrl).toBeNull();
|
|
4945
|
+
expect29(requestInfo.onBeforeConnect.requestMethod).toBeNull();
|
|
4946
|
+
expect29(
|
|
4725
4947
|
Object.keys(requestInfo.onBeforeConnect.requestHeaders)
|
|
4726
4948
|
).toHaveLength(0);
|
|
4727
|
-
|
|
4728
|
-
|
|
4729
|
-
|
|
4730
|
-
|
|
4949
|
+
expect29(requestInfo.createConnState.hasRequest).toBe(false);
|
|
4950
|
+
expect29(requestInfo.createConnState.requestUrl).toBeNull();
|
|
4951
|
+
expect29(requestInfo.createConnState.requestMethod).toBeNull();
|
|
4952
|
+
expect29(
|
|
4731
4953
|
Object.keys(requestInfo.createConnState.requestHeaders)
|
|
4732
4954
|
).toHaveLength(0);
|
|
4733
4955
|
await connection.dispose();
|
|
4734
4956
|
});
|
|
4735
|
-
|
|
4957
|
+
test29("should capture request headers and method", async (c) => {
|
|
4736
4958
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
4737
4959
|
const handle = client.requestAccessActor.getOrCreate(
|
|
4738
4960
|
["test-headers"],
|
|
@@ -4743,18 +4965,18 @@ function runRequestAccessTests(driverTestConfig) {
|
|
|
4743
4965
|
const connection = handle.connect();
|
|
4744
4966
|
const requestInfo = await connection.getRequestInfo();
|
|
4745
4967
|
if (driverTestConfig.clientType === "http") {
|
|
4746
|
-
|
|
4747
|
-
|
|
4748
|
-
|
|
4749
|
-
|
|
4750
|
-
|
|
4968
|
+
expect29(requestInfo.onBeforeConnect.hasRequest).toBe(true);
|
|
4969
|
+
expect29(requestInfo.onBeforeConnect.requestMethod).toBeTruthy();
|
|
4970
|
+
expect29(requestInfo.onBeforeConnect.requestUrl).toBeTruthy();
|
|
4971
|
+
expect29(requestInfo.onBeforeConnect.requestHeaders).toBeTruthy();
|
|
4972
|
+
expect29(typeof requestInfo.onBeforeConnect.requestHeaders).toBe(
|
|
4751
4973
|
"object"
|
|
4752
4974
|
);
|
|
4753
|
-
|
|
4754
|
-
|
|
4755
|
-
|
|
4756
|
-
|
|
4757
|
-
|
|
4975
|
+
expect29(requestInfo.createConnState.hasRequest).toBe(true);
|
|
4976
|
+
expect29(requestInfo.createConnState.requestMethod).toBeTruthy();
|
|
4977
|
+
expect29(requestInfo.createConnState.requestUrl).toBeTruthy();
|
|
4978
|
+
expect29(requestInfo.createConnState.requestHeaders).toBeTruthy();
|
|
4979
|
+
expect29(typeof requestInfo.createConnState.requestHeaders).toBe(
|
|
4758
4980
|
"object"
|
|
4759
4981
|
);
|
|
4760
4982
|
} else {
|
|
@@ -4766,14 +4988,14 @@ function runRequestAccessTests(driverTestConfig) {
|
|
|
4766
4988
|
|
|
4767
4989
|
// src/driver-test-suite/mod.ts
|
|
4768
4990
|
function runDriverTests(driverTestConfigPartial) {
|
|
4769
|
-
|
|
4991
|
+
describe31("Driver Tests", () => {
|
|
4770
4992
|
var _a;
|
|
4771
4993
|
const clientTypes = ((_a = driverTestConfigPartial.skip) == null ? void 0 : _a.inline) ? ["http"] : ["http", "inline"];
|
|
4772
4994
|
for (const clientType of clientTypes) {
|
|
4773
|
-
|
|
4995
|
+
describe31(`client type (${clientType})`, () => {
|
|
4774
4996
|
const encodings = ["bare", "cbor", "json"];
|
|
4775
4997
|
for (const encoding of encodings) {
|
|
4776
|
-
|
|
4998
|
+
describe31(`encoding (${encoding})`, () => {
|
|
4777
4999
|
const driverTestConfig = {
|
|
4778
5000
|
...driverTestConfigPartial,
|
|
4779
5001
|
clientType,
|
|
@@ -4784,6 +5006,7 @@ function runDriverTests(driverTestConfigPartial) {
|
|
|
4784
5006
|
runActorConnTests(driverTestConfig);
|
|
4785
5007
|
runActorConnStateTests(driverTestConfig);
|
|
4786
5008
|
runActorConnHibernationTests(driverTestConfig);
|
|
5009
|
+
runConnErrorSerializationTests(driverTestConfig);
|
|
4787
5010
|
runActorDbTests(driverTestConfig);
|
|
4788
5011
|
runActorDestroyTests(driverTestConfig);
|
|
4789
5012
|
runRequestAccessTests(driverTestConfig);
|