rivetkit 2.0.42 → 2.1.0-rc.1
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/{tsup/config-CLnylLYY.d.ts → browser/client.d.ts} +2127 -1910
- package/dist/browser/client.js +5182 -0
- package/dist/browser/client.js.map +1 -0
- package/dist/browser/inspector/client.d.ts +130 -0
- package/dist/browser/inspector/client.js +2854 -0
- package/dist/browser/inspector/client.js.map +1 -0
- package/dist/browser/v3-DnYObHH3.d.ts +279 -0
- package/dist/schemas/actor-inspector/v2.ts +796 -0
- package/dist/schemas/actor-inspector/v3.ts +899 -0
- package/dist/schemas/actor-persist/v4.ts +406 -0
- package/dist/schemas/client-protocol/v3.ts +554 -0
- package/dist/schemas/persist/v1.ts +781 -0
- package/dist/schemas/transport/v1.ts +697 -0
- package/dist/tsup/actor/errors.cjs +27 -3
- package/dist/tsup/actor/errors.cjs.map +1 -1
- package/dist/tsup/actor/errors.d.cts +37 -1
- package/dist/tsup/actor/errors.d.ts +37 -1
- package/dist/tsup/actor/errors.js +26 -1
- package/dist/tsup/{actor-router-consts-DzI2szci.d.cts → actor-router-consts-D29T1Z-K.d.cts} +1 -1
- package/dist/tsup/{actor-router-consts-DzI2szci.d.ts → actor-router-consts-D29T1Z-K.d.ts} +1 -1
- package/dist/tsup/chunk-424PT5DM.js +23 -0
- package/dist/tsup/chunk-424PT5DM.js.map +1 -0
- package/dist/tsup/{chunk-JDAD2YFA.js → chunk-5ESWDTHJ.js} +148 -273
- package/dist/tsup/chunk-5ESWDTHJ.js.map +1 -0
- package/dist/tsup/{chunk-FJ3KTN4V.js → chunk-6LIBPELE.js} +119 -11
- package/dist/tsup/chunk-6LIBPELE.js.map +1 -0
- package/dist/tsup/chunk-6LJAZ5R4.cjs +96 -0
- package/dist/tsup/chunk-6LJAZ5R4.cjs.map +1 -0
- package/dist/tsup/{chunk-LFVF5SCU.js → chunk-7HTNH26M.js} +126 -1
- package/dist/tsup/chunk-7HTNH26M.js.map +1 -0
- package/dist/tsup/chunk-7K4CYDGD.js +630 -0
- package/dist/tsup/chunk-7K4CYDGD.js.map +1 -0
- package/dist/tsup/{chunk-XXGJCOL6.js → chunk-A6YIZWTK.js} +2 -2
- package/dist/tsup/chunk-AIYEYMX5.cjs +630 -0
- package/dist/tsup/chunk-AIYEYMX5.cjs.map +1 -0
- package/dist/tsup/{chunk-Q6W7RJJP.js → chunk-DIGBC2VI.js} +211 -2316
- package/dist/tsup/chunk-DIGBC2VI.js.map +1 -0
- package/dist/tsup/{chunk-RZW2DNND.cjs → chunk-F6JYU5IK.cjs} +1957 -1039
- package/dist/tsup/chunk-F6JYU5IK.cjs.map +1 -0
- package/dist/tsup/chunk-HAZL2EPK.cjs +534 -0
- package/dist/tsup/chunk-HAZL2EPK.cjs.map +1 -0
- package/dist/tsup/chunk-HDQ2JUQT.cjs +23 -0
- package/dist/tsup/chunk-HDQ2JUQT.cjs.map +1 -0
- package/dist/tsup/chunk-HIDX4C5Y.cjs +1036 -0
- package/dist/tsup/chunk-HIDX4C5Y.cjs.map +1 -0
- package/dist/tsup/chunk-IVG73YCW.js +534 -0
- package/dist/tsup/chunk-IVG73YCW.js.map +1 -0
- package/dist/tsup/chunk-KJSYAUOM.js +96 -0
- package/dist/tsup/chunk-KJSYAUOM.js.map +1 -0
- package/dist/tsup/{chunk-2XQS746M.cjs → chunk-L47L3ZWJ.cjs} +127 -2
- package/dist/tsup/chunk-L47L3ZWJ.cjs.map +1 -0
- package/dist/tsup/{chunk-H4TB4X25.cjs → chunk-LW6KLR7A.cjs} +126 -18
- package/dist/tsup/chunk-LW6KLR7A.cjs.map +1 -0
- package/dist/tsup/chunk-LXUQ667X.js +2006 -0
- package/dist/tsup/chunk-LXUQ667X.js.map +1 -0
- package/dist/tsup/{chunk-GMAVRZSF.js → chunk-M2T62AZQ.js} +1790 -872
- package/dist/tsup/chunk-M2T62AZQ.js.map +1 -0
- package/dist/tsup/chunk-MZ37VV3P.js +5974 -0
- package/dist/tsup/chunk-MZ37VV3P.js.map +1 -0
- package/dist/tsup/chunk-N4KRDJ56.js +72 -0
- package/dist/tsup/chunk-N4KRDJ56.js.map +1 -0
- package/dist/tsup/chunk-NIYZDWMW.cjs +2006 -0
- package/dist/tsup/chunk-NIYZDWMW.cjs.map +1 -0
- package/dist/tsup/chunk-OMEPCQK2.js +649 -0
- package/dist/tsup/chunk-OMEPCQK2.js.map +1 -0
- package/dist/tsup/chunk-SR3KQE7Q.cjs +72 -0
- package/dist/tsup/chunk-SR3KQE7Q.cjs.map +1 -0
- package/dist/tsup/chunk-SSEP6DHP.cjs +2657 -0
- package/dist/tsup/chunk-SSEP6DHP.cjs.map +1 -0
- package/dist/tsup/chunk-T5YCUGVS.js +1036 -0
- package/dist/tsup/chunk-T5YCUGVS.js.map +1 -0
- package/dist/tsup/{chunk-EJVBH5VF.cjs → chunk-TPGXWFQT.cjs} +3 -3
- package/dist/tsup/{chunk-EJVBH5VF.cjs.map → chunk-TPGXWFQT.cjs.map} +1 -1
- package/dist/tsup/{chunk-X35U3YNX.cjs → chunk-TYLXNCA5.cjs} +214 -339
- package/dist/tsup/chunk-TYLXNCA5.cjs.map +1 -0
- package/dist/tsup/chunk-VKVNIQRQ.js +257 -0
- package/dist/tsup/chunk-VKVNIQRQ.js.map +1 -0
- package/dist/tsup/chunk-XWBAQO5H.cjs +649 -0
- package/dist/tsup/chunk-XWBAQO5H.cjs.map +1 -0
- package/dist/tsup/chunk-YQ4LDVD6.cjs +5974 -0
- package/dist/tsup/chunk-YQ4LDVD6.cjs.map +1 -0
- package/dist/tsup/chunk-ZFY5J2EP.cjs +257 -0
- package/dist/tsup/chunk-ZFY5J2EP.cjs.map +1 -0
- package/dist/tsup/client/mod.cjs +9 -10
- package/dist/tsup/client/mod.cjs.map +1 -1
- package/dist/tsup/client/mod.d.cts +11 -5
- package/dist/tsup/client/mod.d.ts +11 -5
- package/dist/tsup/client/mod.js +8 -8
- package/dist/tsup/common/log.cjs +4 -4
- package/dist/tsup/common/log.d.cts +2 -2
- package/dist/tsup/common/log.d.ts +2 -2
- package/dist/tsup/common/log.js +3 -2
- package/dist/tsup/common/websocket.cjs +5 -5
- package/dist/tsup/common/websocket.js +4 -3
- package/dist/tsup/config-BFqid9Gr.d.ts +2574 -0
- package/dist/tsup/config-BiNoIHRs.d.cts +80 -0
- package/dist/tsup/config-BiNoIHRs.d.ts +80 -0
- package/dist/tsup/{config-CZB2-W8x.d.cts → config-CAZphOS1.d.cts} +681 -355
- package/dist/tsup/db/drizzle/mod.cjs +49 -0
- package/dist/tsup/db/drizzle/mod.cjs.map +1 -0
- package/dist/tsup/db/drizzle/mod.d.cts +17 -0
- package/dist/tsup/db/drizzle/mod.d.ts +17 -0
- package/dist/tsup/db/drizzle/mod.js +49 -0
- package/dist/tsup/db/drizzle/mod.js.map +1 -0
- package/dist/tsup/db/mod.cjs +9 -0
- package/dist/tsup/db/mod.cjs.map +1 -0
- package/dist/tsup/db/mod.d.cts +9 -0
- package/dist/tsup/db/mod.d.ts +9 -0
- package/dist/tsup/db/mod.js +9 -0
- package/dist/tsup/db/mod.js.map +1 -0
- package/dist/tsup/{driver-D0QX9M11.d.ts → driver-Bxv62E2p.d.ts} +2 -2
- package/dist/tsup/{driver-q-zqG7fc.d.cts → driver-DYXwJR5D.d.cts} +2 -2
- package/dist/tsup/driver-helpers/mod.cjs +12 -6
- package/dist/tsup/driver-helpers/mod.cjs.map +1 -1
- package/dist/tsup/driver-helpers/mod.d.cts +12 -5
- package/dist/tsup/driver-helpers/mod.d.ts +12 -5
- package/dist/tsup/driver-helpers/mod.js +12 -5
- package/dist/tsup/driver-test-suite/mod.cjs +1370 -116
- package/dist/tsup/driver-test-suite/mod.cjs.map +1 -1
- package/dist/tsup/driver-test-suite/mod.d.cts +10 -4
- package/dist/tsup/driver-test-suite/mod.d.ts +10 -4
- package/dist/tsup/driver-test-suite/mod.js +2093 -838
- package/dist/tsup/driver-test-suite/mod.js.map +1 -1
- package/dist/tsup/inspector/mod.cjs +29 -3
- package/dist/tsup/inspector/mod.cjs.map +1 -1
- package/dist/tsup/inspector/mod.d.cts +124 -3
- package/dist/tsup/inspector/mod.d.ts +124 -3
- package/dist/tsup/inspector/mod.js +72 -45
- package/dist/tsup/keys-CydblqMh.d.cts +13 -0
- package/dist/tsup/keys-CydblqMh.d.ts +13 -0
- package/dist/tsup/mod.cjs +16 -10
- package/dist/tsup/mod.cjs.map +1 -1
- package/dist/tsup/mod.d.cts +26 -14
- package/dist/tsup/mod.d.ts +26 -14
- package/dist/tsup/mod.js +20 -13
- package/dist/tsup/serve-test-suite/mod.cjs +1165 -83
- package/dist/tsup/serve-test-suite/mod.cjs.map +1 -1
- package/dist/tsup/serve-test-suite/mod.js +1114 -29
- package/dist/tsup/serve-test-suite/mod.js.map +1 -1
- package/dist/tsup/test/mod.cjs +84 -11
- package/dist/tsup/test/mod.cjs.map +1 -1
- package/dist/tsup/test/mod.d.cts +10 -5
- package/dist/tsup/test/mod.d.ts +10 -5
- package/dist/tsup/test/mod.js +85 -11
- package/dist/tsup/test/mod.js.map +1 -1
- package/dist/tsup/utils.cjs +10 -4
- package/dist/tsup/utils.cjs.map +1 -1
- package/dist/tsup/utils.d.cts +72 -2
- package/dist/tsup/utils.d.ts +72 -2
- package/dist/tsup/utils.js +9 -2
- package/dist/tsup/v3-DnYObHH3.d.cts +279 -0
- package/dist/tsup/v3-DnYObHH3.d.ts +279 -0
- package/dist/tsup/workflow/mod.cjs +16 -0
- package/dist/tsup/workflow/mod.cjs.map +1 -0
- package/dist/tsup/workflow/mod.d.cts +83 -0
- package/dist/tsup/workflow/mod.d.ts +83 -0
- package/dist/tsup/workflow/mod.js +16 -0
- package/dist/tsup/workflow/mod.js.map +1 -0
- package/package.json +62 -5
- package/src/actor/config.ts +478 -68
- package/src/actor/conn/mod.ts +68 -16
- package/src/actor/conn/state-manager.ts +2 -2
- package/src/actor/contexts/action.ts +20 -12
- package/src/actor/contexts/base/actor.ts +137 -7
- package/src/actor/contexts/base/conn-init.ts +27 -7
- package/src/actor/contexts/base/conn.ts +27 -18
- package/src/actor/contexts/before-action-response.ts +9 -2
- package/src/actor/contexts/before-connect.ts +7 -2
- package/src/actor/contexts/connect.ts +9 -2
- package/src/actor/contexts/create-conn-state.ts +7 -2
- package/src/actor/contexts/create-vars.ts +16 -3
- package/src/actor/contexts/create.ts +16 -3
- package/src/actor/contexts/destroy.ts +9 -3
- package/src/actor/contexts/disconnect.ts +10 -4
- package/src/actor/contexts/index.ts +4 -3
- package/src/actor/contexts/request.ts +23 -6
- package/src/actor/contexts/run.ts +47 -0
- package/src/actor/contexts/sleep.ts +9 -3
- package/src/actor/contexts/state-change.ts +9 -3
- package/src/actor/contexts/wake.ts +9 -3
- package/src/actor/contexts/websocket.ts +23 -6
- package/src/actor/database.ts +8 -18
- package/src/actor/definition.ts +20 -6
- package/src/actor/driver.ts +32 -3
- package/src/actor/errors.ts +127 -0
- package/src/actor/instance/connection-manager.ts +183 -80
- package/src/actor/instance/event-manager.ts +26 -15
- package/src/actor/instance/keys.ts +117 -0
- package/src/actor/instance/mod.ts +784 -174
- package/src/actor/instance/queue-manager.ts +603 -0
- package/src/actor/instance/queue.ts +287 -0
- package/src/actor/instance/schedule-manager.ts +49 -7
- package/src/actor/instance/state-manager.ts +35 -11
- package/src/actor/instance/traces-driver.ts +128 -0
- package/src/actor/mod.ts +26 -2
- package/src/actor/protocol/old.ts +28 -13
- package/src/actor/protocol/serde.ts +1 -1
- package/src/actor/router-endpoints.ts +177 -21
- package/src/actor/router-websocket-endpoints.ts +18 -29
- package/src/actor/router.ts +177 -0
- package/src/actor/schema.ts +291 -0
- package/src/actor/utils.ts +40 -0
- package/src/client/actor-common.ts +1 -1
- package/src/client/actor-conn.ts +100 -33
- package/src/client/actor-handle.ts +61 -33
- package/src/client/client.ts +2 -4
- package/src/client/config.ts +1 -1
- package/src/client/mod.browser.ts +2 -0
- package/src/client/mod.ts +1 -4
- package/src/client/queue.ts +146 -0
- package/src/client/utils.ts +1 -1
- package/src/common/log.ts +1 -1
- package/src/common/utils.ts +3 -3
- package/src/db/config.ts +100 -0
- package/src/db/drizzle/mod.ts +226 -0
- package/src/db/drizzle/sqlite-core.ts +22 -0
- package/src/db/mod.ts +125 -0
- package/src/db/shared.ts +92 -0
- package/src/db/sqlite-vfs.ts +12 -0
- package/src/driver-helpers/mod.ts +1 -0
- package/src/driver-test-suite/mod.ts +69 -43
- package/src/driver-test-suite/tests/access-control.ts +218 -0
- package/src/driver-test-suite/tests/actor-db-raw.ts +73 -0
- package/src/driver-test-suite/tests/actor-db.ts +394 -0
- package/src/driver-test-suite/tests/actor-inspector.ts +259 -358
- package/src/driver-test-suite/tests/actor-kv.ts +41 -20
- package/src/driver-test-suite/tests/actor-queue.ts +324 -0
- package/src/driver-test-suite/tests/actor-run.ts +181 -0
- package/src/driver-test-suite/tests/actor-schedule.ts +5 -2
- package/src/driver-test-suite/tests/actor-sleep.ts +3 -3
- package/src/driver-test-suite/tests/actor-stateless.ts +70 -0
- package/src/driver-test-suite/tests/actor-workflow.ts +108 -0
- package/src/driver-test-suite/tests/manager-driver.ts +11 -0
- package/src/driver-test-suite/tests/raw-http-request-properties.ts +1 -1
- package/src/driver-test-suite/tests/raw-websocket.ts +12 -12
- package/src/drivers/default.ts +7 -2
- package/src/drivers/engine/actor-driver.ts +45 -37
- package/src/drivers/engine/config.ts +1 -1
- package/src/drivers/file-system/actor.ts +20 -2
- package/src/drivers/file-system/global-state.ts +569 -258
- package/src/drivers/file-system/kv-limits.ts +70 -0
- package/src/drivers/file-system/manager.ts +22 -6
- package/src/drivers/file-system/mod.ts +39 -16
- package/src/drivers/file-system/sqlite-runtime.ts +210 -0
- package/src/inspector/actor-inspector.ts +224 -102
- package/src/inspector/config.ts +1 -1
- package/src/inspector/handler.ts +102 -20
- package/src/inspector/mod.browser.ts +8 -0
- package/src/inspector/mod.ts +2 -0
- package/src/inspector/serve-ui.ts +40 -0
- package/src/inspector/transport.ts +18 -0
- package/src/inspector/utils.ts +5 -39
- package/src/manager/gateway.ts +1 -1
- package/src/manager/protocol/mod.ts +1 -1
- package/src/manager/protocol/query.ts +1 -1
- package/src/manager/router-schema.ts +1 -1
- package/src/manager/router.ts +38 -12
- package/src/manager-api/actors.ts +1 -1
- package/src/manager-api/common.ts +1 -1
- package/src/registry/config/driver.ts +1 -1
- package/src/registry/config/index.ts +212 -43
- package/src/registry/config/legacy-runner.ts +1 -1
- package/src/registry/config/runner.ts +1 -1
- package/src/registry/config/serverless.ts +1 -1
- package/src/registry/index.ts +7 -5
- package/src/remote-manager-driver/api-utils.ts +1 -1
- package/src/schemas/actor-inspector/mod.ts +1 -1
- package/src/schemas/actor-inspector/versioned.ts +195 -8
- package/src/schemas/actor-persist/versioned.ts +87 -7
- package/src/schemas/client-protocol/mod.ts +1 -1
- package/src/schemas/client-protocol/versioned.ts +127 -11
- package/src/schemas/client-protocol-zod/mod.ts +16 -1
- package/src/schemas/persist/mod.ts +1 -0
- package/src/schemas/transport/mod.ts +1 -0
- package/src/serde.ts +1 -1
- package/src/serve-test-suite/mod.ts +10 -9
- package/src/test/mod.ts +15 -56
- package/src/utils/endpoint-parser.test.ts +1 -1
- package/src/utils/endpoint-parser.ts +1 -1
- package/src/utils/env-vars.ts +12 -1
- package/src/utils/node.ts +15 -2
- package/src/utils.test.ts +34 -0
- package/src/utils.ts +140 -6
- package/src/workflow/constants.ts +2 -0
- package/src/workflow/context.ts +532 -0
- package/src/workflow/driver.ts +191 -0
- package/src/workflow/inspector.ts +268 -0
- package/src/workflow/mod.ts +122 -0
- package/dist/tsup/chunk-2IJTYN6K.cjs +0 -278
- package/dist/tsup/chunk-2IJTYN6K.cjs.map +0 -1
- package/dist/tsup/chunk-2XQS746M.cjs.map +0 -1
- package/dist/tsup/chunk-3VP5CSHV.cjs +0 -114
- package/dist/tsup/chunk-3VP5CSHV.cjs.map +0 -1
- package/dist/tsup/chunk-AQFSQMBG.js +0 -114
- package/dist/tsup/chunk-AQFSQMBG.js.map +0 -1
- package/dist/tsup/chunk-E6ZE2YEA.js +0 -664
- package/dist/tsup/chunk-E6ZE2YEA.js.map +0 -1
- package/dist/tsup/chunk-FJ3KTN4V.js.map +0 -1
- package/dist/tsup/chunk-GBENOENJ.cjs +0 -8
- package/dist/tsup/chunk-GBENOENJ.cjs.map +0 -1
- package/dist/tsup/chunk-GD7UXGOE.cjs +0 -4762
- package/dist/tsup/chunk-GD7UXGOE.cjs.map +0 -1
- package/dist/tsup/chunk-GMAVRZSF.js.map +0 -1
- package/dist/tsup/chunk-H4TB4X25.cjs.map +0 -1
- package/dist/tsup/chunk-JDAD2YFA.js.map +0 -1
- package/dist/tsup/chunk-KCOVZOPS.js +0 -1946
- package/dist/tsup/chunk-KCOVZOPS.js.map +0 -1
- package/dist/tsup/chunk-KDFWJKMJ.cjs +0 -664
- package/dist/tsup/chunk-KDFWJKMJ.cjs.map +0 -1
- package/dist/tsup/chunk-LFVF5SCU.js.map +0 -1
- package/dist/tsup/chunk-Q6W7RJJP.js.map +0 -1
- package/dist/tsup/chunk-RUW5CZ5Z.cjs +0 -1949
- package/dist/tsup/chunk-RUW5CZ5Z.cjs.map +0 -1
- package/dist/tsup/chunk-RZW2DNND.cjs.map +0 -1
- package/dist/tsup/chunk-TCOEBUUE.js +0 -278
- package/dist/tsup/chunk-TCOEBUUE.js.map +0 -1
- package/dist/tsup/chunk-X35U3YNX.cjs.map +0 -1
- package/dist/tsup/keys-Chhy4ylv.d.cts +0 -8
- package/dist/tsup/keys-Chhy4ylv.d.ts +0 -8
- package/dist/tsup/v1-Gq4avTK3.d.cts +0 -240
- package/dist/tsup/v1-Gq4avTK3.d.ts +0 -240
- /package/dist/tsup/{chunk-XXGJCOL6.js.map → chunk-A6YIZWTK.js.map} +0 -0
|
@@ -1,22 +1,25 @@
|
|
|
1
1
|
import {
|
|
2
2
|
HIBERNATION_SLEEP_TIMEOUT,
|
|
3
|
+
RUN_SLEEP_TIMEOUT,
|
|
3
4
|
SLEEP_TIMEOUT,
|
|
5
|
+
WORKFLOW_QUEUE_NAME,
|
|
4
6
|
logger
|
|
5
|
-
} from "../chunk-
|
|
6
|
-
import
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
import "../chunk-
|
|
10
|
-
import "../chunk-KCOVZOPS.js";
|
|
7
|
+
} from "../chunk-OMEPCQK2.js";
|
|
8
|
+
import "../chunk-7K4CYDGD.js";
|
|
9
|
+
import "../chunk-IVG73YCW.js";
|
|
10
|
+
import "../chunk-5ESWDTHJ.js";
|
|
11
|
+
import "../chunk-MZ37VV3P.js";
|
|
11
12
|
import {
|
|
12
13
|
ActorError,
|
|
13
14
|
ClientConfigSchema,
|
|
14
15
|
createClient,
|
|
15
16
|
createClientWithDriver
|
|
16
|
-
} from "../chunk-
|
|
17
|
+
} from "../chunk-DIGBC2VI.js";
|
|
17
18
|
import {
|
|
18
19
|
importWebSocket
|
|
19
|
-
} from "../chunk-
|
|
20
|
+
} from "../chunk-A6YIZWTK.js";
|
|
21
|
+
import "../chunk-KJSYAUOM.js";
|
|
22
|
+
import "../chunk-N4KRDJ56.js";
|
|
20
23
|
import {
|
|
21
24
|
HEADER_ACTOR_ID,
|
|
22
25
|
WS_PROTOCOL_ACTOR,
|
|
@@ -25,23 +28,26 @@ import {
|
|
|
25
28
|
WS_PROTOCOL_STANDARD,
|
|
26
29
|
WS_PROTOCOL_TARGET,
|
|
27
30
|
WS_TEST_PROTOCOL_PATH,
|
|
28
|
-
assertUnreachable,
|
|
29
31
|
buildManagerRouter
|
|
30
|
-
} from "../chunk-
|
|
31
|
-
import "../chunk-
|
|
32
|
+
} from "../chunk-M2T62AZQ.js";
|
|
33
|
+
import "../chunk-LXUQ667X.js";
|
|
34
|
+
import {
|
|
35
|
+
assertUnreachable
|
|
36
|
+
} from "../chunk-T5YCUGVS.js";
|
|
32
37
|
import {
|
|
33
38
|
noopNext
|
|
34
|
-
} from "../chunk-
|
|
39
|
+
} from "../chunk-6LIBPELE.js";
|
|
35
40
|
import {
|
|
36
41
|
INTERNAL_ERROR_CODE,
|
|
37
42
|
INTERNAL_ERROR_DESCRIPTION
|
|
38
|
-
} from "../chunk-
|
|
43
|
+
} from "../chunk-7HTNH26M.js";
|
|
44
|
+
import "../chunk-424PT5DM.js";
|
|
39
45
|
|
|
40
46
|
// src/driver-test-suite/mod.ts
|
|
41
47
|
import { serve as honoServe } from "@hono/node-server";
|
|
42
48
|
import { createNodeWebSocket } from "@hono/node-ws";
|
|
43
49
|
import invariant2 from "invariant";
|
|
44
|
-
import { describe as
|
|
50
|
+
import { describe as describe29 } from "vitest";
|
|
45
51
|
|
|
46
52
|
// src/driver-test-suite/tests/action-features.ts
|
|
47
53
|
import { describe, expect, test } from "vitest";
|
|
@@ -403,21 +409,209 @@ function runActionFeaturesTests(driverTestConfig) {
|
|
|
403
409
|
});
|
|
404
410
|
}
|
|
405
411
|
|
|
412
|
+
// src/driver-test-suite/tests/access-control.ts
|
|
413
|
+
import { describe as describe2, expect as expect2, test as test2 } from "vitest";
|
|
414
|
+
function runAccessControlTests(driverTestConfig) {
|
|
415
|
+
describe2("access control", () => {
|
|
416
|
+
test2("actions run without entrypoint auth gating", async (c) => {
|
|
417
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
418
|
+
const handle = client.accessControlActor.getOrCreate(["actions"]);
|
|
419
|
+
const allowed = await handle.allowedAction("ok");
|
|
420
|
+
expect2(allowed).toBe("allowed:ok");
|
|
421
|
+
});
|
|
422
|
+
test2("passes connection id into canPublish context", async (c) => {
|
|
423
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
424
|
+
const handle = client.accessControlActor.getOrCreate(["publish-ctx"]);
|
|
425
|
+
await handle.send("allowedQueue", { value: "one" });
|
|
426
|
+
const connId = await handle.allowedGetLastCanPublishConnId();
|
|
427
|
+
expect2(typeof connId).toBe("string");
|
|
428
|
+
expect2(connId.length).toBeGreaterThan(0);
|
|
429
|
+
});
|
|
430
|
+
test2("allows and denies queue sends, and ignores undefined queues", async (c) => {
|
|
431
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
432
|
+
const handle = client.accessControlActor.getOrCreate(["queue"]);
|
|
433
|
+
await handle.send("allowedQueue", { value: "one" });
|
|
434
|
+
await expect2(
|
|
435
|
+
handle.send("blockedQueue", { value: "two" })
|
|
436
|
+
).rejects.toMatchObject({
|
|
437
|
+
code: "forbidden"
|
|
438
|
+
});
|
|
439
|
+
await expect2(
|
|
440
|
+
handle.send("missingQueue", { value: "three" })
|
|
441
|
+
).resolves.toBeUndefined();
|
|
442
|
+
await expect2(
|
|
443
|
+
handle.send(
|
|
444
|
+
"missingQueue",
|
|
445
|
+
{ value: "four" },
|
|
446
|
+
{ wait: true, timeout: 50 }
|
|
447
|
+
)
|
|
448
|
+
).resolves.toMatchObject({ status: "completed" });
|
|
449
|
+
const allowedMessage = await handle.allowedReceiveQueue();
|
|
450
|
+
expect2(allowedMessage).toEqual({ value: "one" });
|
|
451
|
+
const remainingMessage = await handle.allowedReceiveAnyQueue();
|
|
452
|
+
expect2(remainingMessage).toBeNull();
|
|
453
|
+
});
|
|
454
|
+
test2("ignores incoming queue sends when actor has no queues config", async (c) => {
|
|
455
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
456
|
+
const handle = client.accessControlNoQueuesActor.getOrCreate([
|
|
457
|
+
"no-queues"
|
|
458
|
+
]);
|
|
459
|
+
await expect2(
|
|
460
|
+
handle.send("anyQueue", { value: "ignored" })
|
|
461
|
+
).resolves.toBeUndefined();
|
|
462
|
+
await expect2(
|
|
463
|
+
handle.send(
|
|
464
|
+
"anyQueue",
|
|
465
|
+
{ value: "ignored-wait" },
|
|
466
|
+
{ wait: true, timeout: 50 }
|
|
467
|
+
)
|
|
468
|
+
).resolves.toMatchObject({ status: "completed" });
|
|
469
|
+
expect2(await handle.readAnyQueue()).toBeNull();
|
|
470
|
+
});
|
|
471
|
+
test2("allows and denies subscriptions with canSubscribe", async (c) => {
|
|
472
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
473
|
+
const handle = client.accessControlActor.getOrCreate([
|
|
474
|
+
"subscription"
|
|
475
|
+
]);
|
|
476
|
+
const conn = handle.connect();
|
|
477
|
+
const allowedEventPromise = new Promise(
|
|
478
|
+
(resolve, reject) => {
|
|
479
|
+
const unsubscribeError = conn.onError((error) => {
|
|
480
|
+
reject(error);
|
|
481
|
+
});
|
|
482
|
+
const unsubscribeEvent = conn.on(
|
|
483
|
+
"allowedEvent",
|
|
484
|
+
(payload) => {
|
|
485
|
+
unsubscribeError();
|
|
486
|
+
unsubscribeEvent();
|
|
487
|
+
resolve(payload);
|
|
488
|
+
}
|
|
489
|
+
);
|
|
490
|
+
}
|
|
491
|
+
);
|
|
492
|
+
await conn.allowedAction("subscribe-ready");
|
|
493
|
+
await conn.allowedBroadcastAllowedEvent("hello");
|
|
494
|
+
expect2(await allowedEventPromise).toEqual({ value: "hello" });
|
|
495
|
+
const connId = await conn.allowedGetLastCanSubscribeConnId();
|
|
496
|
+
expect2(typeof connId).toBe("string");
|
|
497
|
+
expect2(connId.length).toBeGreaterThan(0);
|
|
498
|
+
await conn.dispose();
|
|
499
|
+
const blockedConn = handle.connect();
|
|
500
|
+
blockedConn.on("blockedEvent", () => {
|
|
501
|
+
});
|
|
502
|
+
await expect2(
|
|
503
|
+
blockedConn.allowedAction("blocked-subscribe-ready")
|
|
504
|
+
).rejects.toMatchObject({
|
|
505
|
+
code: "forbidden"
|
|
506
|
+
});
|
|
507
|
+
await blockedConn.dispose();
|
|
508
|
+
});
|
|
509
|
+
test2("broadcasts undefined events without failing subscriptions", async (c) => {
|
|
510
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
511
|
+
const handle = client.accessControlActor.getOrCreate([
|
|
512
|
+
"undefined-event"
|
|
513
|
+
]);
|
|
514
|
+
const conn = handle.connect();
|
|
515
|
+
const eventPromise = new Promise((resolve, reject) => {
|
|
516
|
+
const unsubscribeError = conn.onError((error) => {
|
|
517
|
+
reject(error);
|
|
518
|
+
});
|
|
519
|
+
const unsubscribeEvent = conn.on("undefinedEvent", (payload) => {
|
|
520
|
+
unsubscribeError();
|
|
521
|
+
unsubscribeEvent();
|
|
522
|
+
resolve(payload);
|
|
523
|
+
});
|
|
524
|
+
});
|
|
525
|
+
await conn.allowedAction("undefined-subscribe-ready");
|
|
526
|
+
await conn.allowedBroadcastUndefinedEvent("wildcard");
|
|
527
|
+
expect2(await eventPromise).toEqual({ value: "wildcard" });
|
|
528
|
+
await conn.dispose();
|
|
529
|
+
});
|
|
530
|
+
test2("allows and denies raw request handlers", async (c) => {
|
|
531
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
532
|
+
const allowedHandle = client.accessControlActor.getOrCreate(
|
|
533
|
+
["raw-request-allow"],
|
|
534
|
+
{
|
|
535
|
+
params: { allowRequest: true }
|
|
536
|
+
}
|
|
537
|
+
);
|
|
538
|
+
const deniedHandle = client.accessControlActor.getOrCreate(
|
|
539
|
+
["raw-request-deny"],
|
|
540
|
+
{
|
|
541
|
+
params: { allowRequest: false }
|
|
542
|
+
}
|
|
543
|
+
);
|
|
544
|
+
const allowedResponse = await allowedHandle.fetch("/status");
|
|
545
|
+
expect2(allowedResponse.status).toBe(200);
|
|
546
|
+
expect2(await allowedResponse.json()).toEqual({ ok: true });
|
|
547
|
+
const deniedResponse = await deniedHandle.fetch("/status");
|
|
548
|
+
expect2(deniedResponse.status).toBe(403);
|
|
549
|
+
});
|
|
550
|
+
test2("allows and denies raw websocket handlers", async (c) => {
|
|
551
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
552
|
+
const allowedHandle = client.accessControlActor.getOrCreate(
|
|
553
|
+
["raw-websocket-allow"],
|
|
554
|
+
{
|
|
555
|
+
params: { allowWebSocket: true }
|
|
556
|
+
}
|
|
557
|
+
);
|
|
558
|
+
const ws = await allowedHandle.webSocket();
|
|
559
|
+
const welcome = await new Promise((resolve) => {
|
|
560
|
+
ws.addEventListener(
|
|
561
|
+
"message",
|
|
562
|
+
(event) => {
|
|
563
|
+
resolve(
|
|
564
|
+
JSON.parse(event.data)
|
|
565
|
+
);
|
|
566
|
+
},
|
|
567
|
+
{ once: true }
|
|
568
|
+
);
|
|
569
|
+
});
|
|
570
|
+
expect2(welcome.type).toBe("welcome");
|
|
571
|
+
ws.close();
|
|
572
|
+
const deniedHandle = client.accessControlActor.getOrCreate(
|
|
573
|
+
["raw-websocket-deny"],
|
|
574
|
+
{
|
|
575
|
+
params: { allowWebSocket: false }
|
|
576
|
+
}
|
|
577
|
+
);
|
|
578
|
+
let denied = false;
|
|
579
|
+
try {
|
|
580
|
+
const deniedWs = await deniedHandle.webSocket();
|
|
581
|
+
const closeEvent = await new Promise((resolve) => {
|
|
582
|
+
deniedWs.addEventListener(
|
|
583
|
+
"close",
|
|
584
|
+
(event) => {
|
|
585
|
+
resolve(event);
|
|
586
|
+
},
|
|
587
|
+
{ once: true }
|
|
588
|
+
);
|
|
589
|
+
});
|
|
590
|
+
expect2(closeEvent.code).toBe(1011);
|
|
591
|
+
denied = true;
|
|
592
|
+
} catch {
|
|
593
|
+
denied = true;
|
|
594
|
+
}
|
|
595
|
+
expect2(denied).toBe(true);
|
|
596
|
+
});
|
|
597
|
+
});
|
|
598
|
+
}
|
|
599
|
+
|
|
406
600
|
// src/driver-test-suite/tests/actor-conn.ts
|
|
407
|
-
import { describe as
|
|
601
|
+
import { describe as describe3, expect as expect3, test as test3, vi as vi2 } from "vitest";
|
|
408
602
|
function runActorConnTests(driverTestConfig) {
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
603
|
+
describe3("Actor Connection Tests", () => {
|
|
604
|
+
describe3("Connection Methods", () => {
|
|
605
|
+
test3("should connect using .get().connect()", async (c) => {
|
|
412
606
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
413
607
|
await client.counter.create(["test-get"]);
|
|
414
608
|
const handle = client.counter.get(["test-get"]);
|
|
415
609
|
const connection = handle.connect();
|
|
416
610
|
const count = await connection.increment(5);
|
|
417
|
-
|
|
611
|
+
expect3(count).toBe(5);
|
|
418
612
|
await connection.dispose();
|
|
419
613
|
});
|
|
420
|
-
|
|
614
|
+
test3("should connect using .getForId().connect()", async (c) => {
|
|
421
615
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
422
616
|
const handle = client.counter.getOrCreate(["test-get-for-id"]);
|
|
423
617
|
await handle.increment(3);
|
|
@@ -425,30 +619,30 @@ function runActorConnTests(driverTestConfig) {
|
|
|
425
619
|
const idHandle = client.counter.getForId(actorId);
|
|
426
620
|
const connection = idHandle.connect();
|
|
427
621
|
const count = await connection.getCount();
|
|
428
|
-
|
|
622
|
+
expect3(count).toBe(3);
|
|
429
623
|
await connection.dispose();
|
|
430
624
|
});
|
|
431
|
-
|
|
625
|
+
test3("should connect using .getOrCreate().connect()", async (c) => {
|
|
432
626
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
433
627
|
const handle = client.counter.getOrCreate([
|
|
434
628
|
"test-get-or-create"
|
|
435
629
|
]);
|
|
436
630
|
const connection = handle.connect();
|
|
437
631
|
const count = await connection.increment(7);
|
|
438
|
-
|
|
632
|
+
expect3(count).toBe(7);
|
|
439
633
|
await connection.dispose();
|
|
440
634
|
});
|
|
441
|
-
|
|
635
|
+
test3("should connect using (await create()).connect()", async (c) => {
|
|
442
636
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
443
637
|
const handle = await client.counter.create(["test-create"]);
|
|
444
638
|
const connection = handle.connect();
|
|
445
639
|
const count = await connection.increment(9);
|
|
446
|
-
|
|
640
|
+
expect3(count).toBe(9);
|
|
447
641
|
await connection.dispose();
|
|
448
642
|
});
|
|
449
643
|
});
|
|
450
|
-
|
|
451
|
-
|
|
644
|
+
describe3("Event Communication", () => {
|
|
645
|
+
test3("should mix RPC calls and WebSocket events", async (c) => {
|
|
452
646
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
453
647
|
const handle = client.counter.getOrCreate([
|
|
454
648
|
"test-mixed-rpc-ws"
|
|
@@ -460,17 +654,17 @@ function runActorConnTests(driverTestConfig) {
|
|
|
460
654
|
});
|
|
461
655
|
await vi2.waitFor(async () => {
|
|
462
656
|
await connection.setCount(1);
|
|
463
|
-
|
|
657
|
+
expect3(receivedEvents).includes(1);
|
|
464
658
|
});
|
|
465
659
|
await handle.setCount(2);
|
|
466
660
|
await handle.setCount(3);
|
|
467
661
|
await vi2.waitFor(() => {
|
|
468
|
-
|
|
469
|
-
|
|
662
|
+
expect3(receivedEvents).includes(2);
|
|
663
|
+
expect3(receivedEvents).includes(3);
|
|
470
664
|
});
|
|
471
665
|
await connection.dispose();
|
|
472
666
|
});
|
|
473
|
-
|
|
667
|
+
test3("should receive events via broadcast", async (c) => {
|
|
474
668
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
475
669
|
const handle = client.counter.getOrCreate(["test-broadcast"]);
|
|
476
670
|
const connection = handle.connect();
|
|
@@ -482,14 +676,14 @@ function runActorConnTests(driverTestConfig) {
|
|
|
482
676
|
async () => {
|
|
483
677
|
await connection.setCount(5);
|
|
484
678
|
await connection.setCount(8);
|
|
485
|
-
|
|
486
|
-
|
|
679
|
+
expect3(receivedEvents).toContain(5);
|
|
680
|
+
expect3(receivedEvents).toContain(8);
|
|
487
681
|
},
|
|
488
682
|
{ timeout: 1e4 }
|
|
489
683
|
);
|
|
490
684
|
await connection.dispose();
|
|
491
685
|
});
|
|
492
|
-
|
|
686
|
+
test3("should handle one-time events with once()", async (c) => {
|
|
493
687
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
494
688
|
const handle = client.counter.getOrCreate(["test-once"]);
|
|
495
689
|
const connection = handle.connect();
|
|
@@ -500,12 +694,12 @@ function runActorConnTests(driverTestConfig) {
|
|
|
500
694
|
await connection.increment(5);
|
|
501
695
|
await connection.increment(3);
|
|
502
696
|
await vi2.waitFor(() => {
|
|
503
|
-
|
|
504
|
-
|
|
697
|
+
expect3(receivedEvents).toEqual([5]);
|
|
698
|
+
expect3(receivedEvents).not.toContain(8);
|
|
505
699
|
});
|
|
506
700
|
await connection.dispose();
|
|
507
701
|
});
|
|
508
|
-
|
|
702
|
+
test3("should unsubscribe from events", async (c) => {
|
|
509
703
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
510
704
|
const handle = client.counter.getOrCreate(["test-unsubscribe"]);
|
|
511
705
|
const connection = handle.connect();
|
|
@@ -518,16 +712,16 @@ function runActorConnTests(driverTestConfig) {
|
|
|
518
712
|
);
|
|
519
713
|
await vi2.waitFor(async () => {
|
|
520
714
|
await connection.setCount(5);
|
|
521
|
-
|
|
715
|
+
expect3(receivedEvents).toEqual([5]);
|
|
522
716
|
});
|
|
523
717
|
unsubscribe();
|
|
524
718
|
await connection.setCount(8);
|
|
525
|
-
|
|
719
|
+
expect3(receivedEvents).not.toContain(8);
|
|
526
720
|
await connection.dispose();
|
|
527
721
|
});
|
|
528
722
|
});
|
|
529
|
-
|
|
530
|
-
|
|
723
|
+
describe3("Connection Parameters", () => {
|
|
724
|
+
test3("should pass connection parameters", async (c) => {
|
|
531
725
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
532
726
|
const handle1 = client.counterWithParams.getOrCreate(
|
|
533
727
|
["test-params"],
|
|
@@ -546,14 +740,14 @@ function runActorConnTests(driverTestConfig) {
|
|
|
546
740
|
await conn1.getInitializers();
|
|
547
741
|
await conn2.getInitializers();
|
|
548
742
|
const initializers = await conn1.getInitializers();
|
|
549
|
-
|
|
550
|
-
|
|
743
|
+
expect3(initializers).toContain("user1");
|
|
744
|
+
expect3(initializers).toContain("user2");
|
|
551
745
|
await conn1.dispose();
|
|
552
746
|
await conn2.dispose();
|
|
553
747
|
});
|
|
554
748
|
});
|
|
555
|
-
|
|
556
|
-
|
|
749
|
+
describe3("Lifecycle Hooks", () => {
|
|
750
|
+
test3("should trigger lifecycle hooks", async (c) => {
|
|
557
751
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
558
752
|
const connHandle = client.counterWithLifecycle.getOrCreate(
|
|
559
753
|
["test-lifecycle"],
|
|
@@ -563,7 +757,7 @@ function runActorConnTests(driverTestConfig) {
|
|
|
563
757
|
);
|
|
564
758
|
const connection = connHandle.connect();
|
|
565
759
|
const events = await connection.getEvents();
|
|
566
|
-
|
|
760
|
+
expect3(events).toEqual([
|
|
567
761
|
"onWake",
|
|
568
762
|
"onBeforeConnect",
|
|
569
763
|
"onConnect"
|
|
@@ -575,7 +769,7 @@ function runActorConnTests(driverTestConfig) {
|
|
|
575
769
|
"test-lifecycle"
|
|
576
770
|
]);
|
|
577
771
|
const finalEvents = await handle.getEvents();
|
|
578
|
-
|
|
772
|
+
expect3(finalEvents).toBeOneOf([
|
|
579
773
|
// Still active
|
|
580
774
|
[
|
|
581
775
|
"onWake",
|
|
@@ -601,20 +795,20 @@ function runActorConnTests(driverTestConfig) {
|
|
|
601
795
|
);
|
|
602
796
|
});
|
|
603
797
|
});
|
|
604
|
-
|
|
605
|
-
|
|
798
|
+
describe3("Connection State", () => {
|
|
799
|
+
test3("isConnected should be false before connection opens", async (c) => {
|
|
606
800
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
607
801
|
const handle = client.counter.getOrCreate([
|
|
608
802
|
"test-isconnected-initial"
|
|
609
803
|
]);
|
|
610
804
|
const connection = handle.connect();
|
|
611
|
-
|
|
805
|
+
expect3(connection.isConnected).toBe(false);
|
|
612
806
|
await vi2.waitFor(() => {
|
|
613
|
-
|
|
807
|
+
expect3(connection.isConnected).toBe(true);
|
|
614
808
|
});
|
|
615
809
|
await connection.dispose();
|
|
616
810
|
});
|
|
617
|
-
|
|
811
|
+
test3("onOpen should be called when connection opens", async (c) => {
|
|
618
812
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
619
813
|
const handle = client.counter.getOrCreate(["test-onopen"]);
|
|
620
814
|
const connection = handle.connect();
|
|
@@ -623,12 +817,12 @@ function runActorConnTests(driverTestConfig) {
|
|
|
623
817
|
openCount++;
|
|
624
818
|
});
|
|
625
819
|
await vi2.waitFor(() => {
|
|
626
|
-
|
|
820
|
+
expect3(openCount).toBe(1);
|
|
627
821
|
});
|
|
628
|
-
|
|
822
|
+
expect3(connection.isConnected).toBe(true);
|
|
629
823
|
await connection.dispose();
|
|
630
824
|
});
|
|
631
|
-
|
|
825
|
+
test3("onClose should be called when connection closes via dispose", async (c) => {
|
|
632
826
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
633
827
|
const handle = client.counter.getOrCreate(["test-onclose"]);
|
|
634
828
|
const connection = handle.connect();
|
|
@@ -637,13 +831,13 @@ function runActorConnTests(driverTestConfig) {
|
|
|
637
831
|
closeCount++;
|
|
638
832
|
});
|
|
639
833
|
await vi2.waitFor(() => {
|
|
640
|
-
|
|
834
|
+
expect3(connection.isConnected).toBe(true);
|
|
641
835
|
});
|
|
642
836
|
await connection.dispose();
|
|
643
|
-
|
|
644
|
-
|
|
837
|
+
expect3(closeCount).toBe(1);
|
|
838
|
+
expect3(connection.isConnected).toBe(false);
|
|
645
839
|
});
|
|
646
|
-
|
|
840
|
+
test3("should be able to unsubscribe from onOpen", async (c) => {
|
|
647
841
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
648
842
|
const handle = client.counter.getOrCreate([
|
|
649
843
|
"test-onopen-unsub"
|
|
@@ -655,12 +849,12 @@ function runActorConnTests(driverTestConfig) {
|
|
|
655
849
|
});
|
|
656
850
|
unsubscribe();
|
|
657
851
|
await vi2.waitFor(() => {
|
|
658
|
-
|
|
852
|
+
expect3(connection.isConnected).toBe(true);
|
|
659
853
|
});
|
|
660
|
-
|
|
854
|
+
expect3(openCount).toBe(0);
|
|
661
855
|
await connection.dispose();
|
|
662
856
|
});
|
|
663
|
-
|
|
857
|
+
test3("should be able to unsubscribe from onClose", async (c) => {
|
|
664
858
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
665
859
|
const handle = client.counter.getOrCreate([
|
|
666
860
|
"test-onclose-unsub"
|
|
@@ -671,13 +865,13 @@ function runActorConnTests(driverTestConfig) {
|
|
|
671
865
|
closeCount++;
|
|
672
866
|
});
|
|
673
867
|
await vi2.waitFor(() => {
|
|
674
|
-
|
|
868
|
+
expect3(connection.isConnected).toBe(true);
|
|
675
869
|
});
|
|
676
870
|
unsubscribe();
|
|
677
871
|
await connection.dispose();
|
|
678
|
-
|
|
872
|
+
expect3(closeCount).toBe(0);
|
|
679
873
|
});
|
|
680
|
-
|
|
874
|
+
test3("multiple onOpen handlers should all be called", async (c) => {
|
|
681
875
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
682
876
|
const handle = client.counter.getOrCreate([
|
|
683
877
|
"test-multi-onopen"
|
|
@@ -692,12 +886,12 @@ function runActorConnTests(driverTestConfig) {
|
|
|
692
886
|
handler2Called = true;
|
|
693
887
|
});
|
|
694
888
|
await vi2.waitFor(() => {
|
|
695
|
-
|
|
696
|
-
|
|
889
|
+
expect3(handler1Called).toBe(true);
|
|
890
|
+
expect3(handler2Called).toBe(true);
|
|
697
891
|
});
|
|
698
892
|
await connection.dispose();
|
|
699
893
|
});
|
|
700
|
-
|
|
894
|
+
test3("multiple onClose handlers should all be called", async (c) => {
|
|
701
895
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
702
896
|
const handle = client.counter.getOrCreate([
|
|
703
897
|
"test-multi-onclose"
|
|
@@ -712,15 +906,15 @@ function runActorConnTests(driverTestConfig) {
|
|
|
712
906
|
handler2Called = true;
|
|
713
907
|
});
|
|
714
908
|
await vi2.waitFor(() => {
|
|
715
|
-
|
|
909
|
+
expect3(connection.isConnected).toBe(true);
|
|
716
910
|
});
|
|
717
911
|
await connection.dispose();
|
|
718
|
-
|
|
719
|
-
|
|
912
|
+
expect3(handler1Called).toBe(true);
|
|
913
|
+
expect3(handler2Called).toBe(true);
|
|
720
914
|
});
|
|
721
915
|
});
|
|
722
|
-
|
|
723
|
-
|
|
916
|
+
describe3("Large Payloads", () => {
|
|
917
|
+
test3("should handle large request within size limit", async (c) => {
|
|
724
918
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
725
919
|
const handle = client.largePayloadConnActor.getOrCreate([
|
|
726
920
|
"test-large-request"
|
|
@@ -731,14 +925,14 @@ function runActorConnTests(driverTestConfig) {
|
|
|
731
925
|
items.push(`Item ${i} with some additional text to increase size`);
|
|
732
926
|
}
|
|
733
927
|
const result = await connection.processLargeRequest({ items });
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
928
|
+
expect3(result.itemCount).toBe(800);
|
|
929
|
+
expect3(result.firstItem).toBe("Item 0 with some additional text to increase size");
|
|
930
|
+
expect3(result.lastItem).toBe("Item 799 with some additional text to increase size");
|
|
737
931
|
const lastRequestSize = await connection.getLastRequestSize();
|
|
738
|
-
|
|
932
|
+
expect3(lastRequestSize).toBe(800);
|
|
739
933
|
await connection.dispose();
|
|
740
934
|
});
|
|
741
|
-
|
|
935
|
+
test3("should reject request exceeding maxIncomingMessageSize", async (c) => {
|
|
742
936
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
743
937
|
const handle = client.largePayloadConnActor.getOrCreate([
|
|
744
938
|
"test-large-request-exceed"
|
|
@@ -748,30 +942,30 @@ function runActorConnTests(driverTestConfig) {
|
|
|
748
942
|
for (let i = 0; i < 1500; i++) {
|
|
749
943
|
items.push(`Item ${i} with some additional text to increase size`);
|
|
750
944
|
}
|
|
751
|
-
await
|
|
945
|
+
await expect3(
|
|
752
946
|
connection.processLargeRequest({ items })
|
|
753
947
|
).rejects.toThrow();
|
|
754
948
|
await connection.dispose();
|
|
755
949
|
});
|
|
756
|
-
|
|
950
|
+
test3("should handle large response", async (c) => {
|
|
757
951
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
758
952
|
const handle = client.largePayloadConnActor.getOrCreate([
|
|
759
953
|
"test-large-response"
|
|
760
954
|
]);
|
|
761
955
|
const connection = handle.connect();
|
|
762
956
|
const result = await connection.getLargeResponse(800);
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
957
|
+
expect3(result.items).toHaveLength(800);
|
|
958
|
+
expect3(result.items[0]).toBe("Item 0 with some additional text to increase size");
|
|
959
|
+
expect3(result.items[799]).toBe("Item 799 with some additional text to increase size");
|
|
766
960
|
await connection.dispose();
|
|
767
961
|
});
|
|
768
|
-
|
|
962
|
+
test3("should reject response exceeding maxOutgoingMessageSize", async (c) => {
|
|
769
963
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
770
964
|
const handle = client.largePayloadConnActor.getOrCreate([
|
|
771
965
|
"test-large-response-exceed"
|
|
772
966
|
]);
|
|
773
967
|
const connection = handle.connect();
|
|
774
|
-
await
|
|
968
|
+
await expect3(
|
|
775
969
|
connection.getLargeResponse(2e4)
|
|
776
970
|
).rejects.toThrow();
|
|
777
971
|
await connection.dispose();
|
|
@@ -781,60 +975,60 @@ function runActorConnTests(driverTestConfig) {
|
|
|
781
975
|
}
|
|
782
976
|
|
|
783
977
|
// src/driver-test-suite/tests/actor-conn-hibernation.ts
|
|
784
|
-
import { describe as
|
|
978
|
+
import { describe as describe4, expect as expect4, test as test4, vi as vi3 } from "vitest";
|
|
785
979
|
function runActorConnHibernationTests(driverTestConfig) {
|
|
786
980
|
var _a;
|
|
787
|
-
|
|
981
|
+
describe4.skipIf((_a = driverTestConfig.skip) == null ? void 0 : _a.hibernation)(
|
|
788
982
|
"Connection Hibernation",
|
|
789
983
|
() => {
|
|
790
|
-
|
|
984
|
+
test4("basic conn hibernation", async (c) => {
|
|
791
985
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
792
986
|
const hibernatingActor = client.hibernationActor.getOrCreate().connect();
|
|
793
987
|
const ping1 = await hibernatingActor.ping();
|
|
794
|
-
|
|
988
|
+
expect4(ping1).toBe("pong");
|
|
795
989
|
await hibernatingActor.triggerSleep();
|
|
796
990
|
await waitFor(
|
|
797
991
|
driverTestConfig,
|
|
798
992
|
HIBERNATION_SLEEP_TIMEOUT + 100
|
|
799
993
|
);
|
|
800
994
|
const ping2 = await hibernatingActor.ping();
|
|
801
|
-
|
|
995
|
+
expect4(ping2).toBe("pong");
|
|
802
996
|
await hibernatingActor.dispose();
|
|
803
997
|
});
|
|
804
|
-
|
|
998
|
+
test4("conn state persists through hibernation", async (c) => {
|
|
805
999
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
806
1000
|
const hibernatingActor = client.hibernationActor.getOrCreate().connect();
|
|
807
1001
|
const count1 = await hibernatingActor.connIncrement();
|
|
808
|
-
|
|
1002
|
+
expect4(count1).toBe(1);
|
|
809
1003
|
const count2 = await hibernatingActor.connIncrement();
|
|
810
|
-
|
|
1004
|
+
expect4(count2).toBe(2);
|
|
811
1005
|
const initialLifecycle = await hibernatingActor.getConnLifecycleCounts();
|
|
812
|
-
|
|
813
|
-
|
|
1006
|
+
expect4(initialLifecycle.connectCount).toBe(1);
|
|
1007
|
+
expect4(initialLifecycle.disconnectCount).toBe(0);
|
|
814
1008
|
const initialActorCounts = await hibernatingActor.getActorCounts();
|
|
815
|
-
|
|
816
|
-
|
|
1009
|
+
expect4(initialActorCounts.wakeCount).toBe(1);
|
|
1010
|
+
expect4(initialActorCounts.sleepCount).toBe(0);
|
|
817
1011
|
await hibernatingActor.triggerSleep();
|
|
818
1012
|
await waitFor(
|
|
819
1013
|
driverTestConfig,
|
|
820
1014
|
HIBERNATION_SLEEP_TIMEOUT + 100
|
|
821
1015
|
);
|
|
822
1016
|
const count3 = await hibernatingActor.getConnCount();
|
|
823
|
-
|
|
1017
|
+
expect4(count3).toBe(2);
|
|
824
1018
|
const finalLifecycle = await hibernatingActor.getConnLifecycleCounts();
|
|
825
|
-
|
|
826
|
-
|
|
1019
|
+
expect4(finalLifecycle.connectCount).toBe(1);
|
|
1020
|
+
expect4(finalLifecycle.disconnectCount).toBe(0);
|
|
827
1021
|
const finalActorCounts = await hibernatingActor.getActorCounts();
|
|
828
|
-
|
|
829
|
-
|
|
1022
|
+
expect4(finalActorCounts.wakeCount).toBe(2);
|
|
1023
|
+
expect4(finalActorCounts.sleepCount).toBe(1);
|
|
830
1024
|
await hibernatingActor.dispose();
|
|
831
1025
|
});
|
|
832
|
-
|
|
1026
|
+
test4("closing connection during hibernation", async (c) => {
|
|
833
1027
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
834
1028
|
const conn1 = client.hibernationActor.getOrCreate().connect();
|
|
835
1029
|
await conn1.ping();
|
|
836
1030
|
const connectionIds = await conn1.getConnectionIds();
|
|
837
|
-
|
|
1031
|
+
expect4(connectionIds.length).toBe(1);
|
|
838
1032
|
const conn1Id = connectionIds[0];
|
|
839
1033
|
await conn1.triggerSleep();
|
|
840
1034
|
await waitFor(
|
|
@@ -847,8 +1041,8 @@ function runActorConnHibernationTests(driverTestConfig) {
|
|
|
847
1041
|
await vi3.waitFor(
|
|
848
1042
|
async () => {
|
|
849
1043
|
const newConnectionIds = await conn2.getConnectionIds();
|
|
850
|
-
|
|
851
|
-
|
|
1044
|
+
expect4(newConnectionIds.length).toBe(1);
|
|
1045
|
+
expect4(newConnectionIds[0]).not.toBe(conn1Id);
|
|
852
1046
|
},
|
|
853
1047
|
{
|
|
854
1048
|
timeout: 5e3,
|
|
@@ -856,7 +1050,7 @@ function runActorConnHibernationTests(driverTestConfig) {
|
|
|
856
1050
|
}
|
|
857
1051
|
);
|
|
858
1052
|
const lifecycle = await conn2.getConnLifecycleCounts();
|
|
859
|
-
|
|
1053
|
+
expect4(lifecycle.disconnectCount).toBe(0);
|
|
860
1054
|
await conn2.dispose();
|
|
861
1055
|
});
|
|
862
1056
|
}
|
|
@@ -864,22 +1058,22 @@ function runActorConnHibernationTests(driverTestConfig) {
|
|
|
864
1058
|
}
|
|
865
1059
|
|
|
866
1060
|
// src/driver-test-suite/tests/actor-conn-state.ts
|
|
867
|
-
import { describe as
|
|
1061
|
+
import { describe as describe5, expect as expect5, test as test5, vi as vi4 } from "vitest";
|
|
868
1062
|
function runActorConnStateTests(driverTestConfig) {
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
1063
|
+
describe5("Actor Connection State Tests", () => {
|
|
1064
|
+
describe5("Connection State Initialization", () => {
|
|
1065
|
+
test5("should retrieve connection state", async (c) => {
|
|
872
1066
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
873
1067
|
const connection = client.connStateActor.getOrCreate().connect();
|
|
874
1068
|
const connState = await connection.getConnectionState();
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
1069
|
+
expect5(connState.id).toBeDefined();
|
|
1070
|
+
expect5(connState.username).toBeDefined();
|
|
1071
|
+
expect5(connState.role).toBeDefined();
|
|
1072
|
+
expect5(connState.counter).toBeDefined();
|
|
1073
|
+
expect5(connState.createdAt).toBeDefined();
|
|
880
1074
|
await connection.dispose();
|
|
881
1075
|
});
|
|
882
|
-
|
|
1076
|
+
test5("should initialize connection state with custom parameters", async (c) => {
|
|
883
1077
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
884
1078
|
const connection = client.connStateActor.getOrCreate([], {
|
|
885
1079
|
params: {
|
|
@@ -888,13 +1082,13 @@ function runActorConnStateTests(driverTestConfig) {
|
|
|
888
1082
|
}
|
|
889
1083
|
}).connect();
|
|
890
1084
|
const connState = await connection.getConnectionState();
|
|
891
|
-
|
|
892
|
-
|
|
1085
|
+
expect5(connState.username).toBe("testuser");
|
|
1086
|
+
expect5(connState.role).toBe("admin");
|
|
893
1087
|
await connection.dispose();
|
|
894
1088
|
});
|
|
895
1089
|
});
|
|
896
|
-
|
|
897
|
-
|
|
1090
|
+
describe5("Connection State Management", () => {
|
|
1091
|
+
test5("should maintain unique state for each connection", async (c) => {
|
|
898
1092
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
899
1093
|
const conn1 = client.connStateActor.getOrCreate([], {
|
|
900
1094
|
params: { username: "user1" }
|
|
@@ -906,14 +1100,14 @@ function runActorConnStateTests(driverTestConfig) {
|
|
|
906
1100
|
await conn2.incrementConnCounter(10);
|
|
907
1101
|
const state1 = await conn1.getConnectionState();
|
|
908
1102
|
const state2 = await conn2.getConnectionState();
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
1103
|
+
expect5(state1.counter).toBe(5);
|
|
1104
|
+
expect5(state2.counter).toBe(10);
|
|
1105
|
+
expect5(state1.username).toBe("user1");
|
|
1106
|
+
expect5(state2.username).toBe("user2");
|
|
913
1107
|
await conn1.dispose();
|
|
914
1108
|
await conn2.dispose();
|
|
915
1109
|
});
|
|
916
|
-
|
|
1110
|
+
test5("should track connections in shared state", async (c) => {
|
|
917
1111
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
918
1112
|
const handle = client.connStateActor.getOrCreate();
|
|
919
1113
|
const conn1 = handle.connect();
|
|
@@ -922,12 +1116,12 @@ function runActorConnStateTests(driverTestConfig) {
|
|
|
922
1116
|
await conn2.getConnectionState();
|
|
923
1117
|
const state1 = await conn1.getConnectionState();
|
|
924
1118
|
const connectionIds = await conn1.getConnectionIds();
|
|
925
|
-
|
|
926
|
-
|
|
1119
|
+
expect5(connectionIds.length).toBeGreaterThanOrEqual(2);
|
|
1120
|
+
expect5(connectionIds).toContain(state1.id);
|
|
927
1121
|
await conn1.dispose();
|
|
928
1122
|
await conn2.dispose();
|
|
929
1123
|
});
|
|
930
|
-
|
|
1124
|
+
test5("should identify different connections in the same actor", async (c) => {
|
|
931
1125
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
932
1126
|
const handle = client.connStateActor.getOrCreate();
|
|
933
1127
|
const conn1 = handle.connect();
|
|
@@ -935,16 +1129,16 @@ function runActorConnStateTests(driverTestConfig) {
|
|
|
935
1129
|
await conn1.getConnectionState();
|
|
936
1130
|
await conn2.getConnectionState();
|
|
937
1131
|
const allStates = await conn1.getAllConnectionStates();
|
|
938
|
-
|
|
1132
|
+
expect5(allStates.length).toBeGreaterThanOrEqual(2);
|
|
939
1133
|
const ids = allStates.map((state) => state.id);
|
|
940
1134
|
const uniqueIds = [...new Set(ids)];
|
|
941
|
-
|
|
1135
|
+
expect5(uniqueIds.length).toBe(ids.length);
|
|
942
1136
|
await conn1.dispose();
|
|
943
1137
|
await conn2.dispose();
|
|
944
1138
|
});
|
|
945
1139
|
});
|
|
946
|
-
|
|
947
|
-
|
|
1140
|
+
describe5("Connection Lifecycle", () => {
|
|
1141
|
+
test5("should track connection and disconnection events", async (c) => {
|
|
948
1142
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
949
1143
|
const debugHandle = client.connStateActor.getOrCreate(
|
|
950
1144
|
void 0,
|
|
@@ -956,11 +1150,11 @@ function runActorConnStateTests(driverTestConfig) {
|
|
|
956
1150
|
const connState = await conn.getConnectionState();
|
|
957
1151
|
await vi4.waitFor(async () => {
|
|
958
1152
|
const connectionIds = await debugHandle.getConnectionIds();
|
|
959
|
-
|
|
1153
|
+
expect5(connectionIds).toContain(connState.id);
|
|
960
1154
|
});
|
|
961
1155
|
await vi4.waitFor(async () => {
|
|
962
1156
|
const disconnects = await debugHandle.getDisconnectionCount();
|
|
963
|
-
|
|
1157
|
+
expect5(disconnects).toBe(0);
|
|
964
1158
|
});
|
|
965
1159
|
await conn.dispose();
|
|
966
1160
|
await vi4.waitFor(
|
|
@@ -968,7 +1162,7 @@ function runActorConnStateTests(driverTestConfig) {
|
|
|
968
1162
|
console.log("disconnects before");
|
|
969
1163
|
const disconnects = await debugHandle.getDisconnectionCount();
|
|
970
1164
|
console.log("disconnects", disconnects);
|
|
971
|
-
|
|
1165
|
+
expect5(disconnects).toBe(1);
|
|
972
1166
|
},
|
|
973
1167
|
// SSE takes a long time to disconnect on CF Workers
|
|
974
1168
|
{
|
|
@@ -980,7 +1174,7 @@ function runActorConnStateTests(driverTestConfig) {
|
|
|
980
1174
|
await vi4.waitFor(async () => {
|
|
981
1175
|
const connectionIds = await debugHandle.getConnectionIds();
|
|
982
1176
|
console.log("conn ids", connectionIds);
|
|
983
|
-
|
|
1177
|
+
expect5(connectionIds.length).toBe(1);
|
|
984
1178
|
});
|
|
985
1179
|
await newConn.dispose();
|
|
986
1180
|
await vi4.waitFor(
|
|
@@ -988,7 +1182,7 @@ function runActorConnStateTests(driverTestConfig) {
|
|
|
988
1182
|
console.log("A");
|
|
989
1183
|
const disconnects = await debugHandle.getDisconnectionCount();
|
|
990
1184
|
console.log(`B ${disconnects}`);
|
|
991
|
-
|
|
1185
|
+
expect5(disconnects).toBe(2);
|
|
992
1186
|
},
|
|
993
1187
|
// SSE takes a long time to disconnect on CF Workers
|
|
994
1188
|
{
|
|
@@ -997,25 +1191,25 @@ function runActorConnStateTests(driverTestConfig) {
|
|
|
997
1191
|
}
|
|
998
1192
|
);
|
|
999
1193
|
});
|
|
1000
|
-
|
|
1194
|
+
test5("should update connection state", async (c) => {
|
|
1001
1195
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1002
1196
|
const conn = client.connStateActor.getOrCreate().connect();
|
|
1003
1197
|
const initialState = await conn.getConnectionState();
|
|
1004
|
-
|
|
1198
|
+
expect5(initialState.username).toBe("anonymous");
|
|
1005
1199
|
const updatedState = await conn.updateConnection({
|
|
1006
1200
|
username: "newname",
|
|
1007
1201
|
role: "moderator"
|
|
1008
1202
|
});
|
|
1009
|
-
|
|
1010
|
-
|
|
1203
|
+
expect5(updatedState.username).toBe("newname");
|
|
1204
|
+
expect5(updatedState.role).toBe("moderator");
|
|
1011
1205
|
const latestState = await conn.getConnectionState();
|
|
1012
|
-
|
|
1013
|
-
|
|
1206
|
+
expect5(latestState.username).toBe("newname");
|
|
1207
|
+
expect5(latestState.role).toBe("moderator");
|
|
1014
1208
|
await conn.dispose();
|
|
1015
1209
|
});
|
|
1016
1210
|
});
|
|
1017
|
-
|
|
1018
|
-
|
|
1211
|
+
describe5("Connection Communication", () => {
|
|
1212
|
+
test5("should send messages to specific connections", async (c) => {
|
|
1019
1213
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1020
1214
|
const handle = client.connStateActor.getOrCreate();
|
|
1021
1215
|
const conn1 = handle.connect();
|
|
@@ -1031,10 +1225,10 @@ function runActorConnStateTests(driverTestConfig) {
|
|
|
1031
1225
|
state2.id,
|
|
1032
1226
|
"Hello from conn1"
|
|
1033
1227
|
);
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1228
|
+
expect5(success).toBe(true);
|
|
1229
|
+
expect5(receivedMessages.length).toBe(1);
|
|
1230
|
+
expect5(receivedMessages[0].from).toBe(state1.id);
|
|
1231
|
+
expect5(receivedMessages[0].message).toBe(
|
|
1038
1232
|
"Hello from conn1"
|
|
1039
1233
|
);
|
|
1040
1234
|
});
|
|
@@ -1045,11 +1239,334 @@ function runActorConnStateTests(driverTestConfig) {
|
|
|
1045
1239
|
});
|
|
1046
1240
|
}
|
|
1047
1241
|
|
|
1242
|
+
// src/driver-test-suite/tests/actor-db.ts
|
|
1243
|
+
import { describe as describe6, expect as expect6, test as test6 } from "vitest";
|
|
1244
|
+
var CHUNK_SIZE = 4096;
|
|
1245
|
+
var LARGE_PAYLOAD_SIZE = 32768;
|
|
1246
|
+
var HIGH_VOLUME_COUNT = 1e3;
|
|
1247
|
+
var SLEEP_WAIT_MS = 150;
|
|
1248
|
+
var LIFECYCLE_POLL_INTERVAL_MS = 25;
|
|
1249
|
+
var LIFECYCLE_POLL_ATTEMPTS = 40;
|
|
1250
|
+
var CHUNK_BOUNDARY_SIZES = [
|
|
1251
|
+
CHUNK_SIZE - 1,
|
|
1252
|
+
CHUNK_SIZE,
|
|
1253
|
+
CHUNK_SIZE + 1,
|
|
1254
|
+
2 * CHUNK_SIZE - 1,
|
|
1255
|
+
2 * CHUNK_SIZE,
|
|
1256
|
+
2 * CHUNK_SIZE + 1,
|
|
1257
|
+
4 * CHUNK_SIZE - 1,
|
|
1258
|
+
4 * CHUNK_SIZE,
|
|
1259
|
+
4 * CHUNK_SIZE + 1
|
|
1260
|
+
];
|
|
1261
|
+
var SHRINK_GROW_INITIAL_ROWS = 16;
|
|
1262
|
+
var SHRINK_GROW_REGROW_ROWS = 10;
|
|
1263
|
+
var SHRINK_GROW_INITIAL_PAYLOAD = 4096;
|
|
1264
|
+
var SHRINK_GROW_REGROW_PAYLOAD = 6144;
|
|
1265
|
+
var HOT_ROW_COUNT = 10;
|
|
1266
|
+
var HOT_ROW_UPDATES = 240;
|
|
1267
|
+
var INTEGRITY_SEED_COUNT = 64;
|
|
1268
|
+
var INTEGRITY_CHURN_COUNT = 120;
|
|
1269
|
+
function getDbActor(client, variant) {
|
|
1270
|
+
return variant === "raw" ? client.dbActorRaw : client.dbActorDrizzle;
|
|
1271
|
+
}
|
|
1272
|
+
function runActorDbTests(driverTestConfig) {
|
|
1273
|
+
const variants = ["raw", "drizzle"];
|
|
1274
|
+
for (const variant of variants) {
|
|
1275
|
+
describe6(`Actor Database (${variant}) Tests`, () => {
|
|
1276
|
+
test6("bootstraps schema on startup", async (c) => {
|
|
1277
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1278
|
+
const actor = getDbActor(client, variant).getOrCreate([
|
|
1279
|
+
`db-${variant}-bootstrap-${crypto.randomUUID()}`
|
|
1280
|
+
]);
|
|
1281
|
+
const count = await actor.getCount();
|
|
1282
|
+
expect6(count).toBe(0);
|
|
1283
|
+
});
|
|
1284
|
+
test6("supports CRUD, raw SQL, and multi-statement exec", async (c) => {
|
|
1285
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1286
|
+
const actor = getDbActor(client, variant).getOrCreate([
|
|
1287
|
+
`db-${variant}-crud-${crypto.randomUUID()}`
|
|
1288
|
+
]);
|
|
1289
|
+
await actor.reset();
|
|
1290
|
+
const first = await actor.insertValue("alpha");
|
|
1291
|
+
const second = await actor.insertValue("beta");
|
|
1292
|
+
const values = await actor.getValues();
|
|
1293
|
+
expect6(values).toHaveLength(2);
|
|
1294
|
+
expect6(values[0].value).toBe("alpha");
|
|
1295
|
+
expect6(values[1].value).toBe("beta");
|
|
1296
|
+
await actor.updateValue(first.id, "alpha-updated");
|
|
1297
|
+
const updated = await actor.getValue(first.id);
|
|
1298
|
+
expect6(updated).toBe("alpha-updated");
|
|
1299
|
+
await actor.deleteValue(second.id);
|
|
1300
|
+
const count = await actor.getCount();
|
|
1301
|
+
expect6(count).toBe(1);
|
|
1302
|
+
const rawCount = await actor.rawSelectCount();
|
|
1303
|
+
expect6(rawCount).toBe(1);
|
|
1304
|
+
const multiValue = await actor.multiStatementInsert("gamma");
|
|
1305
|
+
expect6(multiValue).toBe("gamma-updated");
|
|
1306
|
+
});
|
|
1307
|
+
test6("handles transactions", async (c) => {
|
|
1308
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1309
|
+
const actor = getDbActor(client, variant).getOrCreate([
|
|
1310
|
+
`db-${variant}-tx-${crypto.randomUUID()}`
|
|
1311
|
+
]);
|
|
1312
|
+
await actor.reset();
|
|
1313
|
+
await actor.transactionCommit("commit");
|
|
1314
|
+
expect6(await actor.getCount()).toBe(1);
|
|
1315
|
+
await actor.transactionRollback("rollback");
|
|
1316
|
+
expect6(await actor.getCount()).toBe(1);
|
|
1317
|
+
});
|
|
1318
|
+
test6("persists across sleep and wake cycles", async (c) => {
|
|
1319
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1320
|
+
const actor = getDbActor(client, variant).getOrCreate([
|
|
1321
|
+
`db-${variant}-sleep-${crypto.randomUUID()}`
|
|
1322
|
+
]);
|
|
1323
|
+
await actor.reset();
|
|
1324
|
+
await actor.insertValue("sleepy");
|
|
1325
|
+
expect6(await actor.getCount()).toBe(1);
|
|
1326
|
+
for (let i = 0; i < 3; i++) {
|
|
1327
|
+
await actor.triggerSleep();
|
|
1328
|
+
await waitFor(driverTestConfig, SLEEP_WAIT_MS);
|
|
1329
|
+
expect6(await actor.getCount()).toBe(1);
|
|
1330
|
+
}
|
|
1331
|
+
});
|
|
1332
|
+
test6("completes onDisconnect DB writes before sleeping", async (c) => {
|
|
1333
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1334
|
+
const key = `db-${variant}-disconnect-${crypto.randomUUID()}`;
|
|
1335
|
+
const actor = getDbActor(client, variant).getOrCreate([key]);
|
|
1336
|
+
await actor.reset();
|
|
1337
|
+
await actor.configureDisconnectInsert(true, 250);
|
|
1338
|
+
await waitFor(driverTestConfig, SLEEP_WAIT_MS + 250);
|
|
1339
|
+
await actor.configureDisconnectInsert(false, 0);
|
|
1340
|
+
expect6(await actor.getDisconnectInsertCount()).toBe(1);
|
|
1341
|
+
});
|
|
1342
|
+
test6("handles high-volume inserts", async (c) => {
|
|
1343
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1344
|
+
const actor = getDbActor(client, variant).getOrCreate([
|
|
1345
|
+
`db-${variant}-high-volume-${crypto.randomUUID()}`
|
|
1346
|
+
]);
|
|
1347
|
+
await actor.reset();
|
|
1348
|
+
await actor.insertMany(HIGH_VOLUME_COUNT);
|
|
1349
|
+
expect6(await actor.getCount()).toBe(HIGH_VOLUME_COUNT);
|
|
1350
|
+
});
|
|
1351
|
+
test6("handles payloads across chunk boundaries", async (c) => {
|
|
1352
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1353
|
+
const actor = getDbActor(client, variant).getOrCreate([
|
|
1354
|
+
`db-${variant}-chunk-${crypto.randomUUID()}`
|
|
1355
|
+
]);
|
|
1356
|
+
await actor.reset();
|
|
1357
|
+
for (const size of CHUNK_BOUNDARY_SIZES) {
|
|
1358
|
+
const { id } = await actor.insertPayloadOfSize(size);
|
|
1359
|
+
const storedSize = await actor.getPayloadSize(id);
|
|
1360
|
+
expect6(storedSize).toBe(size);
|
|
1361
|
+
}
|
|
1362
|
+
});
|
|
1363
|
+
test6("handles large payloads", async (c) => {
|
|
1364
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1365
|
+
const actor = getDbActor(client, variant).getOrCreate([
|
|
1366
|
+
`db-${variant}-large-${crypto.randomUUID()}`
|
|
1367
|
+
]);
|
|
1368
|
+
await actor.reset();
|
|
1369
|
+
const { id } = await actor.insertPayloadOfSize(LARGE_PAYLOAD_SIZE);
|
|
1370
|
+
const storedSize = await actor.getPayloadSize(id);
|
|
1371
|
+
expect6(storedSize).toBe(LARGE_PAYLOAD_SIZE);
|
|
1372
|
+
});
|
|
1373
|
+
test6("supports shrink and regrow workloads with vacuum", async (c) => {
|
|
1374
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1375
|
+
const actor = getDbActor(client, variant).getOrCreate([
|
|
1376
|
+
`db-${variant}-shrink-regrow-${crypto.randomUUID()}`
|
|
1377
|
+
]);
|
|
1378
|
+
await actor.reset();
|
|
1379
|
+
await actor.vacuum();
|
|
1380
|
+
const baselinePages = await actor.getPageCount();
|
|
1381
|
+
await actor.insertPayloadRows(
|
|
1382
|
+
SHRINK_GROW_INITIAL_ROWS,
|
|
1383
|
+
SHRINK_GROW_INITIAL_PAYLOAD
|
|
1384
|
+
);
|
|
1385
|
+
const grownPages = await actor.getPageCount();
|
|
1386
|
+
await actor.reset();
|
|
1387
|
+
await actor.vacuum();
|
|
1388
|
+
const shrunkPages = await actor.getPageCount();
|
|
1389
|
+
await actor.insertPayloadRows(
|
|
1390
|
+
SHRINK_GROW_REGROW_ROWS,
|
|
1391
|
+
SHRINK_GROW_REGROW_PAYLOAD
|
|
1392
|
+
);
|
|
1393
|
+
const regrownPages = await actor.getPageCount();
|
|
1394
|
+
expect6(grownPages).toBeGreaterThanOrEqual(baselinePages);
|
|
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
|
|
1417
|
+
);
|
|
1418
|
+
expect6(updatedRows).toHaveLength(HOT_ROW_COUNT);
|
|
1419
|
+
for (const row of updatedRows) {
|
|
1420
|
+
expect6(row.value).toMatch(/^v-\d+$/);
|
|
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
|
|
1432
|
+
);
|
|
1433
|
+
expect6((await actor.integrityCheck()).toLowerCase()).toBe("ok");
|
|
1434
|
+
await actor.triggerSleep();
|
|
1435
|
+
await waitFor(driverTestConfig, SLEEP_WAIT_MS + 100);
|
|
1436
|
+
expect6((await actor.integrityCheck()).toLowerCase()).toBe("ok");
|
|
1437
|
+
});
|
|
1438
|
+
});
|
|
1439
|
+
}
|
|
1440
|
+
describe6("Actor Database Lifecycle Cleanup Tests", () => {
|
|
1441
|
+
test6("runs db provider cleanup on sleep", async (c) => {
|
|
1442
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1443
|
+
const observer = client.dbLifecycleObserver.getOrCreate(["observer"]);
|
|
1444
|
+
const lifecycle = client.dbLifecycle.getOrCreate([
|
|
1445
|
+
`db-lifecycle-sleep-${crypto.randomUUID()}`
|
|
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;
|
|
1458
|
+
}
|
|
1459
|
+
await waitFor(driverTestConfig, LIFECYCLE_POLL_INTERVAL_MS);
|
|
1460
|
+
}
|
|
1461
|
+
expect6(after.create).toBeGreaterThanOrEqual(before.create);
|
|
1462
|
+
expect6(after.migrate).toBeGreaterThanOrEqual(before.migrate);
|
|
1463
|
+
expect6(after.cleanup).toBeGreaterThanOrEqual(before.cleanup + 1);
|
|
1464
|
+
});
|
|
1465
|
+
test6("runs db provider cleanup on destroy", async (c) => {
|
|
1466
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1467
|
+
const observer = client.dbLifecycleObserver.getOrCreate(["observer"]);
|
|
1468
|
+
const lifecycle = client.dbLifecycle.getOrCreate([
|
|
1469
|
+
`db-lifecycle-destroy-${crypto.randomUUID()}`
|
|
1470
|
+
]);
|
|
1471
|
+
const actorId = await lifecycle.getActorId();
|
|
1472
|
+
const before = await observer.getCounts(actorId);
|
|
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;
|
|
1482
|
+
}
|
|
1483
|
+
await waitFor(driverTestConfig, LIFECYCLE_POLL_INTERVAL_MS);
|
|
1484
|
+
}
|
|
1485
|
+
expect6(cleanupCount).toBeGreaterThanOrEqual(before.cleanup + 1);
|
|
1486
|
+
});
|
|
1487
|
+
test6("runs db provider cleanup when migration fails", async (c) => {
|
|
1488
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1489
|
+
const observer = client.dbLifecycleObserver.getOrCreate(["observer"]);
|
|
1490
|
+
const key = `db-lifecycle-migrate-failure-${crypto.randomUUID()}`;
|
|
1491
|
+
const lifecycle = client.dbLifecycleFailing.getOrCreate([key]);
|
|
1492
|
+
let threw = false;
|
|
1493
|
+
try {
|
|
1494
|
+
await lifecycle.ping();
|
|
1495
|
+
} catch {
|
|
1496
|
+
threw = true;
|
|
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);
|
|
1508
|
+
}
|
|
1509
|
+
expect6(cleanupCount).toBeGreaterThanOrEqual(1);
|
|
1510
|
+
});
|
|
1511
|
+
test6("handles parallel actor lifecycle churn", async (c) => {
|
|
1512
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1513
|
+
const observer = client.dbLifecycleObserver.getOrCreate(["observer"]);
|
|
1514
|
+
const actorHandles = Array.from(
|
|
1515
|
+
{ length: 12 },
|
|
1516
|
+
(_, i) => client.dbLifecycle.getOrCreate([
|
|
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}`))
|
|
1525
|
+
);
|
|
1526
|
+
await Promise.all(actorHandles.map((handle) => handle.triggerSleep()));
|
|
1527
|
+
await waitFor(driverTestConfig, SLEEP_WAIT_MS + 100);
|
|
1528
|
+
await Promise.all(
|
|
1529
|
+
actorHandles.map((handle, i) => handle.insertValue(`phase-2-${i}`))
|
|
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
|
+
}
|
|
1561
|
+
});
|
|
1562
|
+
});
|
|
1563
|
+
}
|
|
1564
|
+
|
|
1048
1565
|
// src/driver-test-suite/tests/actor-destroy.ts
|
|
1049
|
-
import { describe as
|
|
1566
|
+
import { describe as describe7, expect as expect7, test as test7, vi as vi5 } from "vitest";
|
|
1050
1567
|
function runActorDestroyTests(driverTestConfig) {
|
|
1051
|
-
|
|
1052
|
-
|
|
1568
|
+
describe7("Actor Destroy Tests", () => {
|
|
1569
|
+
test7("actor destroy clears state (without connect)", async (c) => {
|
|
1053
1570
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1054
1571
|
const actorKey = "test-destroy-without-connect";
|
|
1055
1572
|
const observer = client.destroyObserver.getOrCreate(["observer"]);
|
|
@@ -1057,12 +1574,12 @@ function runActorDestroyTests(driverTestConfig) {
|
|
|
1057
1574
|
const destroyActor = client.destroyActor.getOrCreate([actorKey]);
|
|
1058
1575
|
await destroyActor.setValue(42);
|
|
1059
1576
|
const value = await destroyActor.getValue();
|
|
1060
|
-
|
|
1577
|
+
expect7(value).toBe(42);
|
|
1061
1578
|
const actorId = await destroyActor.resolve();
|
|
1062
1579
|
await destroyActor.destroy();
|
|
1063
1580
|
await vi5.waitFor(async () => {
|
|
1064
1581
|
const wasDestroyed = await observer.wasDestroyed(actorKey);
|
|
1065
|
-
|
|
1582
|
+
expect7(wasDestroyed, "actor onDestroy not called").toBeTruthy();
|
|
1066
1583
|
});
|
|
1067
1584
|
await vi5.waitFor(async () => {
|
|
1068
1585
|
let actorRunning = false;
|
|
@@ -1070,20 +1587,20 @@ function runActorDestroyTests(driverTestConfig) {
|
|
|
1070
1587
|
await client.destroyActor.getForId(actorId).getValue();
|
|
1071
1588
|
actorRunning = true;
|
|
1072
1589
|
} catch (err) {
|
|
1073
|
-
|
|
1074
|
-
|
|
1590
|
+
expect7(err.group).toBe("actor");
|
|
1591
|
+
expect7(err.code).toBe("not_found");
|
|
1075
1592
|
}
|
|
1076
|
-
|
|
1593
|
+
expect7(actorRunning, "actor still running").toBeFalsy();
|
|
1077
1594
|
});
|
|
1078
1595
|
let existsById = false;
|
|
1079
1596
|
try {
|
|
1080
1597
|
await client.destroyActor.getForId(actorId).getValue();
|
|
1081
1598
|
existsById = true;
|
|
1082
1599
|
} catch (err) {
|
|
1083
|
-
|
|
1084
|
-
|
|
1600
|
+
expect7(err.group).toBe("actor");
|
|
1601
|
+
expect7(err.code).toBe("not_found");
|
|
1085
1602
|
}
|
|
1086
|
-
|
|
1603
|
+
expect7(
|
|
1087
1604
|
existsById,
|
|
1088
1605
|
"actor should not exist after destroy"
|
|
1089
1606
|
).toBeFalsy();
|
|
@@ -1092,10 +1609,10 @@ function runActorDestroyTests(driverTestConfig) {
|
|
|
1092
1609
|
await client.destroyActor.get(["test-destroy-without-connect"]).resolve();
|
|
1093
1610
|
existsByKey = true;
|
|
1094
1611
|
} catch (err) {
|
|
1095
|
-
|
|
1096
|
-
|
|
1612
|
+
expect7(err.group).toBe("actor");
|
|
1613
|
+
expect7(err.code).toBe("not_found");
|
|
1097
1614
|
}
|
|
1098
|
-
|
|
1615
|
+
expect7(
|
|
1099
1616
|
existsByKey,
|
|
1100
1617
|
"actor should not exist after destroy"
|
|
1101
1618
|
).toBeFalsy();
|
|
@@ -1103,9 +1620,9 @@ function runActorDestroyTests(driverTestConfig) {
|
|
|
1103
1620
|
"test-destroy-without-connect"
|
|
1104
1621
|
]);
|
|
1105
1622
|
const newValue = await newActor.getValue();
|
|
1106
|
-
|
|
1623
|
+
expect7(newValue).toBe(0);
|
|
1107
1624
|
});
|
|
1108
|
-
|
|
1625
|
+
test7("actor destroy clears state (with connect)", async (c) => {
|
|
1109
1626
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1110
1627
|
const actorKey = "test-destroy-with-connect";
|
|
1111
1628
|
const observer = client.destroyObserver.getOrCreate(["observer"]);
|
|
@@ -1117,12 +1634,12 @@ function runActorDestroyTests(driverTestConfig) {
|
|
|
1117
1634
|
const destroyActor = destroyActorHandle.connect();
|
|
1118
1635
|
await destroyActor.setValue(99);
|
|
1119
1636
|
const value = await destroyActor.getValue();
|
|
1120
|
-
|
|
1637
|
+
expect7(value).toBe(99);
|
|
1121
1638
|
await destroyActor.destroy();
|
|
1122
1639
|
await destroyActor.dispose();
|
|
1123
1640
|
await vi5.waitFor(async () => {
|
|
1124
1641
|
const wasDestroyed = await observer.wasDestroyed(actorKey);
|
|
1125
|
-
|
|
1642
|
+
expect7(wasDestroyed, "actor onDestroy not called").toBeTruthy();
|
|
1126
1643
|
});
|
|
1127
1644
|
await vi5.waitFor(async () => {
|
|
1128
1645
|
let actorRunning = false;
|
|
@@ -1130,20 +1647,20 @@ function runActorDestroyTests(driverTestConfig) {
|
|
|
1130
1647
|
await client.destroyActor.getForId(actorId).getValue();
|
|
1131
1648
|
actorRunning = true;
|
|
1132
1649
|
} catch (err) {
|
|
1133
|
-
|
|
1134
|
-
|
|
1650
|
+
expect7(err.group).toBe("actor");
|
|
1651
|
+
expect7(err.code).toBe("not_found");
|
|
1135
1652
|
}
|
|
1136
|
-
|
|
1653
|
+
expect7(actorRunning, "actor still running").toBeFalsy();
|
|
1137
1654
|
});
|
|
1138
1655
|
let existsById = false;
|
|
1139
1656
|
try {
|
|
1140
1657
|
await client.destroyActor.getForId(actorId).getValue();
|
|
1141
1658
|
existsById = true;
|
|
1142
1659
|
} catch (err) {
|
|
1143
|
-
|
|
1144
|
-
|
|
1660
|
+
expect7(err.group).toBe("actor");
|
|
1661
|
+
expect7(err.code).toBe("not_found");
|
|
1145
1662
|
}
|
|
1146
|
-
|
|
1663
|
+
expect7(
|
|
1147
1664
|
existsById,
|
|
1148
1665
|
"actor should not exist after destroy"
|
|
1149
1666
|
).toBeFalsy();
|
|
@@ -1152,10 +1669,10 @@ function runActorDestroyTests(driverTestConfig) {
|
|
|
1152
1669
|
await client.destroyActor.get(["test-destroy-with-connect"]).resolve();
|
|
1153
1670
|
existsByKey = true;
|
|
1154
1671
|
} catch (err) {
|
|
1155
|
-
|
|
1156
|
-
|
|
1672
|
+
expect7(err.group).toBe("actor");
|
|
1673
|
+
expect7(err.code).toBe("not_found");
|
|
1157
1674
|
}
|
|
1158
|
-
|
|
1675
|
+
expect7(
|
|
1159
1676
|
existsByKey,
|
|
1160
1677
|
"actor should not exist after destroy"
|
|
1161
1678
|
).toBeFalsy();
|
|
@@ -1163,9 +1680,9 @@ function runActorDestroyTests(driverTestConfig) {
|
|
|
1163
1680
|
"test-destroy-with-connect"
|
|
1164
1681
|
]);
|
|
1165
1682
|
const newValue = await newActor.getValue();
|
|
1166
|
-
|
|
1683
|
+
expect7(newValue).toBe(0);
|
|
1167
1684
|
});
|
|
1168
|
-
|
|
1685
|
+
test7("actor destroy allows recreation via getOrCreate with resolve", async (c) => {
|
|
1169
1686
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1170
1687
|
const actorKey = "test-destroy-getorcreate-resolve";
|
|
1171
1688
|
const observer = client.destroyObserver.getOrCreate(["observer"]);
|
|
@@ -1173,12 +1690,12 @@ function runActorDestroyTests(driverTestConfig) {
|
|
|
1173
1690
|
const destroyActor = client.destroyActor.getOrCreate([actorKey]);
|
|
1174
1691
|
await destroyActor.setValue(123);
|
|
1175
1692
|
const value = await destroyActor.getValue();
|
|
1176
|
-
|
|
1693
|
+
expect7(value).toBe(123);
|
|
1177
1694
|
const actorId = await destroyActor.resolve();
|
|
1178
1695
|
await destroyActor.destroy();
|
|
1179
1696
|
await vi5.waitFor(async () => {
|
|
1180
1697
|
const wasDestroyed = await observer.wasDestroyed(actorKey);
|
|
1181
|
-
|
|
1698
|
+
expect7(wasDestroyed, "actor onDestroy not called").toBeTruthy();
|
|
1182
1699
|
});
|
|
1183
1700
|
await vi5.waitFor(async () => {
|
|
1184
1701
|
let actorRunning = false;
|
|
@@ -1186,17 +1703,17 @@ function runActorDestroyTests(driverTestConfig) {
|
|
|
1186
1703
|
await client.destroyActor.getForId(actorId).getValue();
|
|
1187
1704
|
actorRunning = true;
|
|
1188
1705
|
} catch (err) {
|
|
1189
|
-
|
|
1190
|
-
|
|
1706
|
+
expect7(err.group).toBe("actor");
|
|
1707
|
+
expect7(err.code).toBe("not_found");
|
|
1191
1708
|
}
|
|
1192
|
-
|
|
1709
|
+
expect7(actorRunning, "actor still running").toBeFalsy();
|
|
1193
1710
|
});
|
|
1194
1711
|
const newHandle = client.destroyActor.getOrCreate([actorKey]);
|
|
1195
1712
|
const newActorId = await newHandle.resolve();
|
|
1196
1713
|
const newValue = await newHandle.getValue();
|
|
1197
|
-
|
|
1714
|
+
expect7(newValue).toBe(0);
|
|
1198
1715
|
});
|
|
1199
|
-
|
|
1716
|
+
test7("actor destroy allows recreation via create", async (c) => {
|
|
1200
1717
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1201
1718
|
const actorKey = "test-destroy-create";
|
|
1202
1719
|
const observer = client.destroyObserver.getOrCreate(["observer"]);
|
|
@@ -1204,12 +1721,12 @@ function runActorDestroyTests(driverTestConfig) {
|
|
|
1204
1721
|
const initialHandle = await client.destroyActor.create([actorKey]);
|
|
1205
1722
|
await initialHandle.setValue(456);
|
|
1206
1723
|
const value = await initialHandle.getValue();
|
|
1207
|
-
|
|
1724
|
+
expect7(value).toBe(456);
|
|
1208
1725
|
const actorId = await initialHandle.resolve();
|
|
1209
1726
|
await initialHandle.destroy();
|
|
1210
1727
|
await vi5.waitFor(async () => {
|
|
1211
1728
|
const wasDestroyed = await observer.wasDestroyed(actorKey);
|
|
1212
|
-
|
|
1729
|
+
expect7(wasDestroyed, "actor onDestroy not called").toBeTruthy();
|
|
1213
1730
|
});
|
|
1214
1731
|
await vi5.waitFor(async () => {
|
|
1215
1732
|
let actorRunning = false;
|
|
@@ -1217,31 +1734,31 @@ function runActorDestroyTests(driverTestConfig) {
|
|
|
1217
1734
|
await client.destroyActor.getForId(actorId).getValue();
|
|
1218
1735
|
actorRunning = true;
|
|
1219
1736
|
} catch (err) {
|
|
1220
|
-
|
|
1221
|
-
|
|
1737
|
+
expect7(err.group).toBe("actor");
|
|
1738
|
+
expect7(err.code).toBe("not_found");
|
|
1222
1739
|
}
|
|
1223
|
-
|
|
1740
|
+
expect7(actorRunning, "actor still running").toBeFalsy();
|
|
1224
1741
|
});
|
|
1225
1742
|
const newHandle = await client.destroyActor.create([actorKey]);
|
|
1226
1743
|
const newActorId = await newHandle.resolve();
|
|
1227
1744
|
const newValue = await newHandle.getValue();
|
|
1228
|
-
|
|
1745
|
+
expect7(newValue).toBe(0);
|
|
1229
1746
|
});
|
|
1230
1747
|
});
|
|
1231
1748
|
}
|
|
1232
1749
|
|
|
1233
1750
|
// src/driver-test-suite/tests/actor-driver.ts
|
|
1234
|
-
import { describe as
|
|
1751
|
+
import { describe as describe11 } from "vitest";
|
|
1235
1752
|
|
|
1236
1753
|
// src/driver-test-suite/tests/actor-schedule.ts
|
|
1237
|
-
import { describe as
|
|
1754
|
+
import { describe as describe8, expect as expect8, test as test8 } from "vitest";
|
|
1238
1755
|
function runActorScheduleTests(driverTestConfig) {
|
|
1239
1756
|
var _a;
|
|
1240
|
-
|
|
1757
|
+
describe8.skipIf((_a = driverTestConfig.skip) == null ? void 0 : _a.schedule)(
|
|
1241
1758
|
"Actor Schedule Tests",
|
|
1242
1759
|
() => {
|
|
1243
|
-
|
|
1244
|
-
|
|
1760
|
+
describe8("Scheduled Alarms", () => {
|
|
1761
|
+
test8("executes c.schedule.at() with specific timestamp", async (c) => {
|
|
1245
1762
|
const { client } = await setupDriverTest(
|
|
1246
1763
|
c,
|
|
1247
1764
|
driverTestConfig
|
|
@@ -1252,10 +1769,10 @@ function runActorScheduleTests(driverTestConfig) {
|
|
|
1252
1769
|
await waitFor(driverTestConfig, 500);
|
|
1253
1770
|
const lastRun = await scheduled.getLastRun();
|
|
1254
1771
|
const scheduledCount = await scheduled.getScheduledCount();
|
|
1255
|
-
|
|
1256
|
-
|
|
1772
|
+
expect8(lastRun).toBeGreaterThan(0);
|
|
1773
|
+
expect8(scheduledCount).toBe(1);
|
|
1257
1774
|
});
|
|
1258
|
-
|
|
1775
|
+
test8("executes c.schedule.after() with delay", async (c) => {
|
|
1259
1776
|
const { client } = await setupDriverTest(
|
|
1260
1777
|
c,
|
|
1261
1778
|
driverTestConfig
|
|
@@ -1265,10 +1782,10 @@ function runActorScheduleTests(driverTestConfig) {
|
|
|
1265
1782
|
await waitFor(driverTestConfig, 500);
|
|
1266
1783
|
const lastRun = await scheduled.getLastRun();
|
|
1267
1784
|
const scheduledCount = await scheduled.getScheduledCount();
|
|
1268
|
-
|
|
1269
|
-
|
|
1785
|
+
expect8(lastRun).toBeGreaterThan(0);
|
|
1786
|
+
expect8(scheduledCount).toBe(1);
|
|
1270
1787
|
});
|
|
1271
|
-
|
|
1788
|
+
test8("multiple scheduled tasks execute in order", async (c) => {
|
|
1272
1789
|
const { client } = await setupDriverTest(
|
|
1273
1790
|
c,
|
|
1274
1791
|
driverTestConfig
|
|
@@ -1280,13 +1797,16 @@ function runActorScheduleTests(driverTestConfig) {
|
|
|
1280
1797
|
await scheduled.scheduleTaskAfterWithId("third", 1250);
|
|
1281
1798
|
await waitFor(driverTestConfig, 500);
|
|
1282
1799
|
const history1 = await scheduled.getTaskHistory();
|
|
1283
|
-
|
|
1800
|
+
expect8(history1[0]).toBe("first");
|
|
1284
1801
|
await waitFor(driverTestConfig, 500);
|
|
1285
1802
|
const history2 = await scheduled.getTaskHistory();
|
|
1286
|
-
|
|
1803
|
+
expect8(history2.slice(0, 2)).toEqual([
|
|
1804
|
+
"first",
|
|
1805
|
+
"second"
|
|
1806
|
+
]);
|
|
1287
1807
|
await waitFor(driverTestConfig, 500);
|
|
1288
1808
|
const history3 = await scheduled.getTaskHistory();
|
|
1289
|
-
|
|
1809
|
+
expect8(history3).toEqual(["first", "second", "third"]);
|
|
1290
1810
|
});
|
|
1291
1811
|
});
|
|
1292
1812
|
}
|
|
@@ -1294,33 +1814,33 @@ function runActorScheduleTests(driverTestConfig) {
|
|
|
1294
1814
|
}
|
|
1295
1815
|
|
|
1296
1816
|
// src/driver-test-suite/tests/actor-sleep.ts
|
|
1297
|
-
import { describe as
|
|
1817
|
+
import { describe as describe9, expect as expect9, test as test9 } from "vitest";
|
|
1298
1818
|
function runActorSleepTests(driverTestConfig) {
|
|
1299
1819
|
var _a;
|
|
1300
|
-
|
|
1301
|
-
|
|
1820
|
+
describe9.skipIf((_a = driverTestConfig.skip) == null ? void 0 : _a.sleep)("Actor Sleep Tests", () => {
|
|
1821
|
+
test9("actor sleep persists state", async (c) => {
|
|
1302
1822
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1303
1823
|
const sleepActor = client.sleep.getOrCreate();
|
|
1304
1824
|
{
|
|
1305
1825
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1306
|
-
|
|
1307
|
-
|
|
1826
|
+
expect9(sleepCount).toBe(0);
|
|
1827
|
+
expect9(startCount).toBe(1);
|
|
1308
1828
|
}
|
|
1309
1829
|
await sleepActor.triggerSleep();
|
|
1310
1830
|
await waitFor(driverTestConfig, 250);
|
|
1311
1831
|
{
|
|
1312
1832
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1313
|
-
|
|
1314
|
-
|
|
1833
|
+
expect9(sleepCount).toBe(1);
|
|
1834
|
+
expect9(startCount).toBe(2);
|
|
1315
1835
|
}
|
|
1316
1836
|
});
|
|
1317
|
-
|
|
1837
|
+
test9("actor sleep persists state with connect", async (c) => {
|
|
1318
1838
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1319
1839
|
const sleepActor = client.sleep.getOrCreate().connect();
|
|
1320
1840
|
{
|
|
1321
1841
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1322
|
-
|
|
1323
|
-
|
|
1842
|
+
expect9(sleepCount).toBe(0);
|
|
1843
|
+
expect9(startCount).toBe(1);
|
|
1324
1844
|
}
|
|
1325
1845
|
await sleepActor.triggerSleep();
|
|
1326
1846
|
await sleepActor.dispose();
|
|
@@ -1328,108 +1848,108 @@ function runActorSleepTests(driverTestConfig) {
|
|
|
1328
1848
|
const sleepActor2 = client.sleep.getOrCreate();
|
|
1329
1849
|
{
|
|
1330
1850
|
const { startCount, sleepCount } = await sleepActor2.getCounts();
|
|
1331
|
-
|
|
1332
|
-
|
|
1851
|
+
expect9(sleepCount).toBe(1);
|
|
1852
|
+
expect9(startCount).toBe(2);
|
|
1333
1853
|
}
|
|
1334
1854
|
});
|
|
1335
|
-
|
|
1855
|
+
test9("actor automatically sleeps after timeout", async (c) => {
|
|
1336
1856
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1337
1857
|
const sleepActor = client.sleep.getOrCreate();
|
|
1338
1858
|
{
|
|
1339
1859
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1340
|
-
|
|
1341
|
-
|
|
1860
|
+
expect9(sleepCount).toBe(0);
|
|
1861
|
+
expect9(startCount).toBe(1);
|
|
1342
1862
|
}
|
|
1343
1863
|
await waitFor(driverTestConfig, SLEEP_TIMEOUT + 250);
|
|
1344
1864
|
{
|
|
1345
1865
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1346
|
-
|
|
1347
|
-
|
|
1866
|
+
expect9(sleepCount).toBe(1);
|
|
1867
|
+
expect9(startCount).toBe(2);
|
|
1348
1868
|
}
|
|
1349
1869
|
});
|
|
1350
|
-
|
|
1870
|
+
test9("actor automatically sleeps after timeout with connect", async (c) => {
|
|
1351
1871
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1352
1872
|
const sleepActor = client.sleep.getOrCreate().connect();
|
|
1353
1873
|
{
|
|
1354
1874
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1355
|
-
|
|
1356
|
-
|
|
1875
|
+
expect9(sleepCount).toBe(0);
|
|
1876
|
+
expect9(startCount).toBe(1);
|
|
1357
1877
|
}
|
|
1358
1878
|
await sleepActor.dispose();
|
|
1359
1879
|
await waitFor(driverTestConfig, SLEEP_TIMEOUT + 250);
|
|
1360
1880
|
const sleepActor2 = client.sleep.getOrCreate();
|
|
1361
1881
|
{
|
|
1362
1882
|
const { startCount, sleepCount } = await sleepActor2.getCounts();
|
|
1363
|
-
|
|
1364
|
-
|
|
1883
|
+
expect9(sleepCount).toBe(1);
|
|
1884
|
+
expect9(startCount).toBe(2);
|
|
1365
1885
|
}
|
|
1366
1886
|
});
|
|
1367
|
-
|
|
1887
|
+
test9("rpc calls keep actor awake", async (c) => {
|
|
1368
1888
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1369
1889
|
const sleepActor = client.sleep.getOrCreate();
|
|
1370
1890
|
{
|
|
1371
1891
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1372
|
-
|
|
1373
|
-
|
|
1892
|
+
expect9(sleepCount).toBe(0);
|
|
1893
|
+
expect9(startCount).toBe(1);
|
|
1374
1894
|
}
|
|
1375
1895
|
await waitFor(driverTestConfig, SLEEP_TIMEOUT - 250);
|
|
1376
1896
|
{
|
|
1377
1897
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1378
|
-
|
|
1379
|
-
|
|
1898
|
+
expect9(sleepCount).toBe(0);
|
|
1899
|
+
expect9(startCount).toBe(1);
|
|
1380
1900
|
}
|
|
1381
1901
|
await waitFor(driverTestConfig, SLEEP_TIMEOUT - 250);
|
|
1382
1902
|
{
|
|
1383
1903
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1384
|
-
|
|
1385
|
-
|
|
1904
|
+
expect9(sleepCount).toBe(0);
|
|
1905
|
+
expect9(startCount).toBe(1);
|
|
1386
1906
|
}
|
|
1387
1907
|
await waitFor(driverTestConfig, SLEEP_TIMEOUT + 250);
|
|
1388
1908
|
{
|
|
1389
1909
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1390
|
-
|
|
1391
|
-
|
|
1910
|
+
expect9(sleepCount).toBe(1);
|
|
1911
|
+
expect9(startCount).toBe(2);
|
|
1392
1912
|
}
|
|
1393
1913
|
});
|
|
1394
|
-
|
|
1914
|
+
test9("alarms keep actor awake", async (c) => {
|
|
1395
1915
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1396
1916
|
const sleepActor = client.sleep.getOrCreate();
|
|
1397
1917
|
{
|
|
1398
1918
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1399
|
-
|
|
1400
|
-
|
|
1919
|
+
expect9(sleepCount).toBe(0);
|
|
1920
|
+
expect9(startCount).toBe(1);
|
|
1401
1921
|
}
|
|
1402
1922
|
await sleepActor.setAlarm(SLEEP_TIMEOUT - 250);
|
|
1403
1923
|
await waitFor(driverTestConfig, SLEEP_TIMEOUT + 250);
|
|
1404
1924
|
{
|
|
1405
1925
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1406
|
-
|
|
1407
|
-
|
|
1926
|
+
expect9(sleepCount).toBe(0);
|
|
1927
|
+
expect9(startCount).toBe(1);
|
|
1408
1928
|
}
|
|
1409
1929
|
});
|
|
1410
|
-
|
|
1930
|
+
test9("alarms wake actors", async (c) => {
|
|
1411
1931
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1412
1932
|
const sleepActor = client.sleep.getOrCreate();
|
|
1413
1933
|
{
|
|
1414
1934
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1415
|
-
|
|
1416
|
-
|
|
1935
|
+
expect9(sleepCount).toBe(0);
|
|
1936
|
+
expect9(startCount).toBe(1);
|
|
1417
1937
|
}
|
|
1418
1938
|
await sleepActor.setAlarm(SLEEP_TIMEOUT + 250);
|
|
1419
1939
|
await waitFor(driverTestConfig, SLEEP_TIMEOUT + 200);
|
|
1420
1940
|
{
|
|
1421
1941
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1422
|
-
|
|
1423
|
-
|
|
1942
|
+
expect9(sleepCount).toBe(1);
|
|
1943
|
+
expect9(startCount).toBe(2);
|
|
1424
1944
|
}
|
|
1425
1945
|
});
|
|
1426
|
-
|
|
1946
|
+
test9("long running rpcs keep actor awake", async (c) => {
|
|
1427
1947
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1428
1948
|
const sleepActor = client.sleepWithLongRpc.getOrCreate().connect();
|
|
1429
1949
|
{
|
|
1430
1950
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1431
|
-
|
|
1432
|
-
|
|
1951
|
+
expect9(sleepCount).toBe(0);
|
|
1952
|
+
expect9(startCount).toBe(1);
|
|
1433
1953
|
}
|
|
1434
1954
|
const waitPromise = new Promise(
|
|
1435
1955
|
(resolve) => sleepActor.once("waiting", resolve)
|
|
@@ -1441,19 +1961,19 @@ function runActorSleepTests(driverTestConfig) {
|
|
|
1441
1961
|
await longRunningPromise;
|
|
1442
1962
|
{
|
|
1443
1963
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1444
|
-
|
|
1445
|
-
|
|
1964
|
+
expect9(sleepCount).toBe(0);
|
|
1965
|
+
expect9(startCount).toBe(1);
|
|
1446
1966
|
}
|
|
1447
1967
|
await sleepActor.dispose();
|
|
1448
1968
|
await waitFor(driverTestConfig, SLEEP_TIMEOUT + 250);
|
|
1449
1969
|
const sleepActor2 = client.sleepWithLongRpc.getOrCreate();
|
|
1450
1970
|
{
|
|
1451
1971
|
const { startCount, sleepCount } = await sleepActor2.getCounts();
|
|
1452
|
-
|
|
1453
|
-
|
|
1972
|
+
expect9(sleepCount).toBe(1);
|
|
1973
|
+
expect9(startCount).toBe(2);
|
|
1454
1974
|
}
|
|
1455
1975
|
});
|
|
1456
|
-
|
|
1976
|
+
test9("active raw websockets keep actor awake", async (c) => {
|
|
1457
1977
|
const { client, endpoint: baseUrl } = await setupDriverTest(
|
|
1458
1978
|
c,
|
|
1459
1979
|
driverTestConfig
|
|
@@ -1461,10 +1981,10 @@ function runActorSleepTests(driverTestConfig) {
|
|
|
1461
1981
|
const sleepActor = client.sleepWithRawWebSocket.getOrCreate();
|
|
1462
1982
|
{
|
|
1463
1983
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1464
|
-
|
|
1465
|
-
|
|
1984
|
+
expect9(sleepCount).toBe(0);
|
|
1985
|
+
expect9(startCount).toBe(1);
|
|
1466
1986
|
}
|
|
1467
|
-
const ws = await sleepActor.
|
|
1987
|
+
const ws = await sleepActor.webSocket();
|
|
1468
1988
|
await new Promise((resolve, reject) => {
|
|
1469
1989
|
ws.onopen = () => resolve();
|
|
1470
1990
|
ws.onerror = reject;
|
|
@@ -1487,17 +2007,17 @@ function runActorSleepTests(driverTestConfig) {
|
|
|
1487
2007
|
}
|
|
1488
2008
|
};
|
|
1489
2009
|
});
|
|
1490
|
-
|
|
1491
|
-
|
|
2010
|
+
expect9(counts.sleepCount).toBe(0);
|
|
2011
|
+
expect9(counts.startCount).toBe(1);
|
|
1492
2012
|
ws.close();
|
|
1493
2013
|
await waitFor(driverTestConfig, SLEEP_TIMEOUT + 250);
|
|
1494
2014
|
{
|
|
1495
2015
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1496
|
-
|
|
1497
|
-
|
|
2016
|
+
expect9(sleepCount).toBe(1);
|
|
2017
|
+
expect9(startCount).toBe(2);
|
|
1498
2018
|
}
|
|
1499
2019
|
});
|
|
1500
|
-
|
|
2020
|
+
test9("active raw fetch requests keep actor awake", async (c) => {
|
|
1501
2021
|
const { client, endpoint: baseUrl } = await setupDriverTest(
|
|
1502
2022
|
c,
|
|
1503
2023
|
driverTestConfig
|
|
@@ -1505,8 +2025,8 @@ function runActorSleepTests(driverTestConfig) {
|
|
|
1505
2025
|
const sleepActor = client.sleepWithRawHttp.getOrCreate();
|
|
1506
2026
|
{
|
|
1507
2027
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1508
|
-
|
|
1509
|
-
|
|
2028
|
+
expect9(sleepCount).toBe(0);
|
|
2029
|
+
expect9(startCount).toBe(1);
|
|
1510
2030
|
}
|
|
1511
2031
|
const fetchDuration = SLEEP_TIMEOUT + 250;
|
|
1512
2032
|
const fetchPromise = sleepActor.fetch(
|
|
@@ -1514,67 +2034,67 @@ function runActorSleepTests(driverTestConfig) {
|
|
|
1514
2034
|
);
|
|
1515
2035
|
const response = await fetchPromise;
|
|
1516
2036
|
const result = await response.json();
|
|
1517
|
-
|
|
2037
|
+
expect9(result.completed).toBe(true);
|
|
1518
2038
|
{
|
|
1519
2039
|
const { startCount, sleepCount, requestCount } = await sleepActor.getCounts();
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
2040
|
+
expect9(sleepCount).toBe(0);
|
|
2041
|
+
expect9(startCount).toBe(1);
|
|
2042
|
+
expect9(requestCount).toBe(1);
|
|
1523
2043
|
}
|
|
1524
2044
|
await waitFor(driverTestConfig, SLEEP_TIMEOUT + 250);
|
|
1525
2045
|
{
|
|
1526
2046
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1527
|
-
|
|
1528
|
-
|
|
2047
|
+
expect9(sleepCount).toBe(1);
|
|
2048
|
+
expect9(startCount).toBe(2);
|
|
1529
2049
|
}
|
|
1530
2050
|
});
|
|
1531
|
-
|
|
2051
|
+
test9("noSleep option disables sleeping", async (c) => {
|
|
1532
2052
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1533
2053
|
const sleepActor = client.sleepWithNoSleepOption.getOrCreate();
|
|
1534
2054
|
{
|
|
1535
2055
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1536
|
-
|
|
1537
|
-
|
|
2056
|
+
expect9(sleepCount).toBe(0);
|
|
2057
|
+
expect9(startCount).toBe(1);
|
|
1538
2058
|
}
|
|
1539
2059
|
await waitFor(driverTestConfig, SLEEP_TIMEOUT + 250);
|
|
1540
2060
|
{
|
|
1541
2061
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1542
|
-
|
|
1543
|
-
|
|
2062
|
+
expect9(sleepCount).toBe(0);
|
|
2063
|
+
expect9(startCount).toBe(1);
|
|
1544
2064
|
}
|
|
1545
2065
|
await waitFor(driverTestConfig, SLEEP_TIMEOUT + 250);
|
|
1546
2066
|
{
|
|
1547
2067
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1548
|
-
|
|
1549
|
-
|
|
2068
|
+
expect9(sleepCount).toBe(0);
|
|
2069
|
+
expect9(startCount).toBe(1);
|
|
1550
2070
|
}
|
|
1551
2071
|
});
|
|
1552
2072
|
});
|
|
1553
2073
|
}
|
|
1554
2074
|
|
|
1555
2075
|
// src/driver-test-suite/tests/actor-state.ts
|
|
1556
|
-
import { describe as
|
|
2076
|
+
import { describe as describe10, expect as expect10, test as test10 } from "vitest";
|
|
1557
2077
|
function runActorStateTests(driverTestConfig) {
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
2078
|
+
describe10("Actor State Tests", () => {
|
|
2079
|
+
describe10("State Persistence", () => {
|
|
2080
|
+
test10("persists state between actor instances", async (c) => {
|
|
1561
2081
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1562
2082
|
const counterInstance = client.counter.getOrCreate();
|
|
1563
2083
|
const initialCount = await counterInstance.increment(5);
|
|
1564
|
-
|
|
2084
|
+
expect10(initialCount).toBe(5);
|
|
1565
2085
|
const sameInstance = client.counter.getOrCreate();
|
|
1566
2086
|
const persistedCount = await sameInstance.increment(3);
|
|
1567
|
-
|
|
2087
|
+
expect10(persistedCount).toBe(8);
|
|
1568
2088
|
});
|
|
1569
|
-
|
|
2089
|
+
test10("restores state after actor disconnect/reconnect", async (c) => {
|
|
1570
2090
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1571
2091
|
const counterInstance = client.counter.getOrCreate();
|
|
1572
2092
|
await counterInstance.increment(5);
|
|
1573
2093
|
const reconnectedInstance = client.counter.getOrCreate();
|
|
1574
2094
|
const persistedCount = await reconnectedInstance.increment(0);
|
|
1575
|
-
|
|
2095
|
+
expect10(persistedCount).toBe(5);
|
|
1576
2096
|
});
|
|
1577
|
-
|
|
2097
|
+
test10("maintains separate state for different actors", async (c) => {
|
|
1578
2098
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1579
2099
|
const counterA = client.counter.getOrCreate(["counter-a"]);
|
|
1580
2100
|
await counterA.increment(5);
|
|
@@ -1582,8 +2102,8 @@ function runActorStateTests(driverTestConfig) {
|
|
|
1582
2102
|
await counterB.increment(10);
|
|
1583
2103
|
const countA = await counterA.increment(0);
|
|
1584
2104
|
const countB = await counterB.increment(0);
|
|
1585
|
-
|
|
1586
|
-
|
|
2105
|
+
expect10(countA).toBe(5);
|
|
2106
|
+
expect10(countB).toBe(10);
|
|
1587
2107
|
});
|
|
1588
2108
|
});
|
|
1589
2109
|
});
|
|
@@ -1591,7 +2111,7 @@ function runActorStateTests(driverTestConfig) {
|
|
|
1591
2111
|
|
|
1592
2112
|
// src/driver-test-suite/tests/actor-driver.ts
|
|
1593
2113
|
function runActorDriverTests(driverTestConfig) {
|
|
1594
|
-
|
|
2114
|
+
describe11("Actor Driver Tests", () => {
|
|
1595
2115
|
runActorStateTests(driverTestConfig);
|
|
1596
2116
|
runActorScheduleTests(driverTestConfig);
|
|
1597
2117
|
runActorSleepTests(driverTestConfig);
|
|
@@ -1599,82 +2119,82 @@ function runActorDriverTests(driverTestConfig) {
|
|
|
1599
2119
|
}
|
|
1600
2120
|
|
|
1601
2121
|
// src/driver-test-suite/tests/actor-error-handling.ts
|
|
1602
|
-
import { describe as
|
|
2122
|
+
import { describe as describe12, expect as expect11, test as test11 } from "vitest";
|
|
1603
2123
|
function runActorErrorHandlingTests(driverTestConfig) {
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
2124
|
+
describe12("Actor Error Handling Tests", () => {
|
|
2125
|
+
describe12("UserError Handling", () => {
|
|
2126
|
+
test11("should handle simple UserError with message", async (c) => {
|
|
1607
2127
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1608
2128
|
const handle = client.errorHandlingActor.getOrCreate();
|
|
1609
2129
|
try {
|
|
1610
2130
|
await handle.throwSimpleError();
|
|
1611
|
-
|
|
2131
|
+
expect11(true).toBe(false);
|
|
1612
2132
|
} catch (error) {
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
2133
|
+
expect11(error.message).toBe("Simple error message");
|
|
2134
|
+
expect11(error.code).toBe("user_error");
|
|
2135
|
+
expect11(error.metadata).toBeUndefined();
|
|
1616
2136
|
}
|
|
1617
2137
|
});
|
|
1618
|
-
|
|
2138
|
+
test11("should handle detailed UserError with code and metadata", async (c) => {
|
|
1619
2139
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1620
2140
|
const handle = client.errorHandlingActor.getOrCreate();
|
|
1621
2141
|
try {
|
|
1622
2142
|
await handle.throwDetailedError();
|
|
1623
|
-
|
|
2143
|
+
expect11(true).toBe(false);
|
|
1624
2144
|
} catch (error) {
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
2145
|
+
expect11(error.message).toBe("Detailed error message");
|
|
2146
|
+
expect11(error.code).toBe("detailed_error");
|
|
2147
|
+
expect11(error.metadata).toBeDefined();
|
|
2148
|
+
expect11(error.metadata.reason).toBe("test");
|
|
2149
|
+
expect11(error.metadata.timestamp).toBeDefined();
|
|
1630
2150
|
}
|
|
1631
2151
|
});
|
|
1632
2152
|
});
|
|
1633
|
-
|
|
1634
|
-
|
|
2153
|
+
describe12("Internal Error Handling", () => {
|
|
2154
|
+
test11("should convert internal errors to safe format", async (c) => {
|
|
1635
2155
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1636
2156
|
const handle = client.errorHandlingActor.getOrCreate();
|
|
1637
2157
|
try {
|
|
1638
2158
|
await handle.throwInternalError();
|
|
1639
|
-
|
|
2159
|
+
expect11(true).toBe(false);
|
|
1640
2160
|
} catch (error) {
|
|
1641
|
-
|
|
1642
|
-
|
|
2161
|
+
expect11(error.code).toBe(INTERNAL_ERROR_CODE);
|
|
2162
|
+
expect11(error.message).toBe(INTERNAL_ERROR_DESCRIPTION);
|
|
1643
2163
|
}
|
|
1644
2164
|
});
|
|
1645
2165
|
});
|
|
1646
|
-
|
|
1647
|
-
|
|
2166
|
+
describe12.skip("Action Timeout", () => {
|
|
2167
|
+
test11("should handle action timeouts with custom duration", async (c) => {
|
|
1648
2168
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1649
2169
|
const handle = client.errorHandlingActor.getOrCreate();
|
|
1650
2170
|
const timeoutPromise = handle.timeoutAction();
|
|
1651
2171
|
try {
|
|
1652
2172
|
await timeoutPromise;
|
|
1653
|
-
|
|
2173
|
+
expect11(true).toBe(false);
|
|
1654
2174
|
} catch (error) {
|
|
1655
|
-
|
|
2175
|
+
expect11(error.message).toMatch(/timed out/i);
|
|
1656
2176
|
}
|
|
1657
2177
|
});
|
|
1658
|
-
|
|
2178
|
+
test11("should successfully run actions within timeout", async (c) => {
|
|
1659
2179
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1660
2180
|
const handle = client.errorHandlingActor.getOrCreate();
|
|
1661
2181
|
const result = await handle.delayedAction(200);
|
|
1662
|
-
|
|
2182
|
+
expect11(result).toBe("Completed after 200ms");
|
|
1663
2183
|
});
|
|
1664
|
-
|
|
2184
|
+
test11("should respect different timeouts for different actors", async (c) => {
|
|
1665
2185
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1666
2186
|
try {
|
|
1667
2187
|
await client.customTimeoutActor.getOrCreate().slowAction();
|
|
1668
|
-
|
|
2188
|
+
expect11(true).toBe(false);
|
|
1669
2189
|
} catch (error) {
|
|
1670
|
-
|
|
2190
|
+
expect11(error.message).toMatch(/timed out/i);
|
|
1671
2191
|
}
|
|
1672
2192
|
const quickResult = await client.customTimeoutActor.getOrCreate().quickAction();
|
|
1673
|
-
|
|
2193
|
+
expect11(quickResult).toBe("Quick action completed");
|
|
1674
2194
|
});
|
|
1675
2195
|
});
|
|
1676
|
-
|
|
1677
|
-
|
|
2196
|
+
describe12("Error Recovery", () => {
|
|
2197
|
+
test11("should continue working after errors", async (c) => {
|
|
1678
2198
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1679
2199
|
const handle = client.errorHandlingActor.getOrCreate();
|
|
1680
2200
|
try {
|
|
@@ -1682,27 +2202,27 @@ function runActorErrorHandlingTests(driverTestConfig) {
|
|
|
1682
2202
|
} catch (error) {
|
|
1683
2203
|
}
|
|
1684
2204
|
const result = await handle.successfulAction();
|
|
1685
|
-
|
|
2205
|
+
expect11(result).toBe("success");
|
|
1686
2206
|
});
|
|
1687
2207
|
});
|
|
1688
2208
|
});
|
|
1689
2209
|
}
|
|
1690
2210
|
|
|
1691
2211
|
// src/driver-test-suite/tests/actor-handle.ts
|
|
1692
|
-
import { describe as
|
|
2212
|
+
import { describe as describe13, expect as expect12, test as test12 } from "vitest";
|
|
1693
2213
|
function runActorHandleTests(driverTestConfig) {
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
2214
|
+
describe13("Actor Handle Tests", () => {
|
|
2215
|
+
describe13("Access Methods", () => {
|
|
2216
|
+
test12("should use .get() to access a actor", async (c) => {
|
|
1697
2217
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1698
2218
|
await client.counter.create(["test-get-handle"]);
|
|
1699
2219
|
const handle = client.counter.get(["test-get-handle"]);
|
|
1700
2220
|
const count = await handle.increment(5);
|
|
1701
|
-
|
|
2221
|
+
expect12(count).toBe(5);
|
|
1702
2222
|
const retrievedCount = await handle.getCount();
|
|
1703
|
-
|
|
2223
|
+
expect12(retrievedCount).toBe(5);
|
|
1704
2224
|
});
|
|
1705
|
-
|
|
2225
|
+
test12("should use .getForId() to access a actor by ID", async (c) => {
|
|
1706
2226
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1707
2227
|
const handle = client.counter.getOrCreate([
|
|
1708
2228
|
"test-get-for-id-handle"
|
|
@@ -1711,73 +2231,73 @@ function runActorHandleTests(driverTestConfig) {
|
|
|
1711
2231
|
const actorId = await handle.resolve();
|
|
1712
2232
|
const idHandle = client.counter.getForId(actorId);
|
|
1713
2233
|
const count = await idHandle.getCount();
|
|
1714
|
-
|
|
2234
|
+
expect12(count).toBe(3);
|
|
1715
2235
|
const newCount = await idHandle.increment(4);
|
|
1716
|
-
|
|
2236
|
+
expect12(newCount).toBe(7);
|
|
1717
2237
|
});
|
|
1718
|
-
|
|
2238
|
+
test12("should use .getOrCreate() to access or create a actor", async (c) => {
|
|
1719
2239
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1720
2240
|
const handle = client.counter.getOrCreate([
|
|
1721
2241
|
"test-get-or-create-handle"
|
|
1722
2242
|
]);
|
|
1723
2243
|
const count = await handle.increment(7);
|
|
1724
|
-
|
|
2244
|
+
expect12(count).toBe(7);
|
|
1725
2245
|
const sameHandle = client.counter.getOrCreate([
|
|
1726
2246
|
"test-get-or-create-handle"
|
|
1727
2247
|
]);
|
|
1728
2248
|
const retrievedCount = await sameHandle.getCount();
|
|
1729
|
-
|
|
2249
|
+
expect12(retrievedCount).toBe(7);
|
|
1730
2250
|
});
|
|
1731
|
-
|
|
2251
|
+
test12("should use (await create()) to create and return a handle", async (c) => {
|
|
1732
2252
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1733
2253
|
const handle = await client.counter.create([
|
|
1734
2254
|
"test-create-handle"
|
|
1735
2255
|
]);
|
|
1736
2256
|
const count = await handle.increment(9);
|
|
1737
|
-
|
|
2257
|
+
expect12(count).toBe(9);
|
|
1738
2258
|
const retrievedCount = await handle.getCount();
|
|
1739
|
-
|
|
2259
|
+
expect12(retrievedCount).toBe(9);
|
|
1740
2260
|
});
|
|
1741
|
-
|
|
2261
|
+
test12("errors when calling create twice with the same key", async (c) => {
|
|
1742
2262
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1743
2263
|
const key = ["duplicate-create-handle", crypto.randomUUID()];
|
|
1744
2264
|
await client.counter.create(key);
|
|
1745
2265
|
try {
|
|
1746
2266
|
await client.counter.create(key);
|
|
1747
|
-
|
|
2267
|
+
expect12.fail("did not error on duplicate create");
|
|
1748
2268
|
} catch (err) {
|
|
1749
|
-
|
|
1750
|
-
|
|
2269
|
+
expect12(err.group).toBe("actor");
|
|
2270
|
+
expect12(err.code).toBe("duplicate_key");
|
|
1751
2271
|
}
|
|
1752
2272
|
});
|
|
1753
|
-
|
|
2273
|
+
test12(".get().resolve() errors for non-existent actor", async (c) => {
|
|
1754
2274
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1755
2275
|
const missingId = `nonexistent-${crypto.randomUUID()}`;
|
|
1756
2276
|
try {
|
|
1757
2277
|
await client.counter.get([missingId]).resolve();
|
|
1758
|
-
|
|
2278
|
+
expect12.fail(
|
|
1759
2279
|
"did not error for get().resolve() on missing actor"
|
|
1760
2280
|
);
|
|
1761
2281
|
} catch (err) {
|
|
1762
|
-
|
|
1763
|
-
|
|
2282
|
+
expect12(err.group).toBe("actor");
|
|
2283
|
+
expect12(err.code).toBe("not_found");
|
|
1764
2284
|
}
|
|
1765
2285
|
});
|
|
1766
2286
|
});
|
|
1767
|
-
|
|
1768
|
-
|
|
2287
|
+
describe13("Action Functionality", () => {
|
|
2288
|
+
test12("should call actions directly on the handle", async (c) => {
|
|
1769
2289
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1770
2290
|
const handle = client.counter.getOrCreate([
|
|
1771
2291
|
"test-action-handle"
|
|
1772
2292
|
]);
|
|
1773
2293
|
const count1 = await handle.increment(3);
|
|
1774
|
-
|
|
2294
|
+
expect12(count1).toBe(3);
|
|
1775
2295
|
const count2 = await handle.increment(5);
|
|
1776
|
-
|
|
2296
|
+
expect12(count2).toBe(8);
|
|
1777
2297
|
const retrievedCount = await handle.getCount();
|
|
1778
|
-
|
|
2298
|
+
expect12(retrievedCount).toBe(8);
|
|
1779
2299
|
});
|
|
1780
|
-
|
|
2300
|
+
test12("should handle independent handles to the same actor", async (c) => {
|
|
1781
2301
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1782
2302
|
const handle1 = client.counter.getOrCreate([
|
|
1783
2303
|
"test-multiple-handles"
|
|
@@ -1785,82 +2305,82 @@ function runActorHandleTests(driverTestConfig) {
|
|
|
1785
2305
|
const handle2 = client.counter.get(["test-multiple-handles"]);
|
|
1786
2306
|
await handle1.increment(3);
|
|
1787
2307
|
const count = await handle2.getCount();
|
|
1788
|
-
|
|
2308
|
+
expect12(count).toBe(3);
|
|
1789
2309
|
const finalCount = await handle2.increment(4);
|
|
1790
|
-
|
|
2310
|
+
expect12(finalCount).toBe(7);
|
|
1791
2311
|
const checkCount = await handle1.getCount();
|
|
1792
|
-
|
|
2312
|
+
expect12(checkCount).toBe(7);
|
|
1793
2313
|
});
|
|
1794
|
-
|
|
2314
|
+
test12("should resolve a actor's ID", async (c) => {
|
|
1795
2315
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1796
2316
|
const handle = client.counter.getOrCreate(["test-resolve-id"]);
|
|
1797
2317
|
await handle.increment(1);
|
|
1798
2318
|
const actorId = await handle.resolve();
|
|
1799
|
-
|
|
1800
|
-
|
|
2319
|
+
expect12(typeof actorId).toBe("string");
|
|
2320
|
+
expect12(actorId).not.toBe("");
|
|
1801
2321
|
const idHandle = client.counter.getForId(actorId);
|
|
1802
2322
|
const count = await idHandle.getCount();
|
|
1803
|
-
|
|
2323
|
+
expect12(count).toBe(1);
|
|
1804
2324
|
});
|
|
1805
2325
|
});
|
|
1806
|
-
|
|
1807
|
-
|
|
2326
|
+
describe13("Lifecycle Hooks", () => {
|
|
2327
|
+
test12("should trigger lifecycle hooks on actor creation", async (c) => {
|
|
1808
2328
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1809
2329
|
const handle = client.counterWithLifecycle.getOrCreate([
|
|
1810
2330
|
"test-lifecycle-handle"
|
|
1811
2331
|
]);
|
|
1812
2332
|
const initialEvents = await handle.getEvents();
|
|
1813
|
-
|
|
2333
|
+
expect12(initialEvents).toContain("onWake");
|
|
1814
2334
|
const sameHandle = client.counterWithLifecycle.getOrCreate([
|
|
1815
2335
|
"test-lifecycle-handle"
|
|
1816
2336
|
]);
|
|
1817
2337
|
const events = await sameHandle.getEvents();
|
|
1818
|
-
|
|
1819
|
-
|
|
2338
|
+
expect12(events).toContain("onWake");
|
|
2339
|
+
expect12(events.filter((e) => e === "onWake").length).toBe(1);
|
|
1820
2340
|
});
|
|
1821
|
-
|
|
2341
|
+
test12("should trigger lifecycle hooks for each Action call", async (c) => {
|
|
1822
2342
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1823
2343
|
const viewHandle = client.counterWithLifecycle.getOrCreate([
|
|
1824
2344
|
"test-lifecycle-action"
|
|
1825
2345
|
]);
|
|
1826
2346
|
const initialEvents = await viewHandle.getEvents();
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
2347
|
+
expect12(initialEvents).toContain("onWake");
|
|
2348
|
+
expect12(initialEvents).not.toContain("onBeforeConnect");
|
|
2349
|
+
expect12(initialEvents).not.toContain("onConnect");
|
|
2350
|
+
expect12(initialEvents).not.toContain("onDisconnect");
|
|
1831
2351
|
const trackingHandle = client.counterWithLifecycle.getOrCreate(
|
|
1832
2352
|
["test-lifecycle-action"],
|
|
1833
2353
|
{ params: { trackLifecycle: true } }
|
|
1834
2354
|
);
|
|
1835
2355
|
await trackingHandle.increment(5);
|
|
1836
2356
|
const eventsAfterAction = await viewHandle.getEvents();
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
2357
|
+
expect12(eventsAfterAction).toContain("onBeforeConnect");
|
|
2358
|
+
expect12(eventsAfterAction).toContain("onConnect");
|
|
2359
|
+
expect12(eventsAfterAction).toContain("onDisconnect");
|
|
2360
|
+
expect12(
|
|
1841
2361
|
eventsAfterAction.filter((e) => e === "onBeforeConnect").length
|
|
1842
2362
|
).toBe(1);
|
|
1843
|
-
|
|
2363
|
+
expect12(
|
|
1844
2364
|
eventsAfterAction.filter((e) => e === "onConnect").length
|
|
1845
2365
|
).toBe(1);
|
|
1846
|
-
|
|
2366
|
+
expect12(
|
|
1847
2367
|
eventsAfterAction.filter((e) => e === "onDisconnect").length
|
|
1848
2368
|
).toBe(1);
|
|
1849
2369
|
await trackingHandle.increment(10);
|
|
1850
2370
|
const eventsAfterSecondAction = await viewHandle.getEvents();
|
|
1851
|
-
|
|
2371
|
+
expect12(
|
|
1852
2372
|
eventsAfterSecondAction.filter(
|
|
1853
2373
|
(e) => e === "onBeforeConnect"
|
|
1854
2374
|
).length
|
|
1855
2375
|
).toBe(2);
|
|
1856
|
-
|
|
2376
|
+
expect12(
|
|
1857
2377
|
eventsAfterSecondAction.filter((e) => e === "onConnect").length
|
|
1858
2378
|
).toBe(2);
|
|
1859
|
-
|
|
2379
|
+
expect12(
|
|
1860
2380
|
eventsAfterSecondAction.filter((e) => e === "onDisconnect").length
|
|
1861
2381
|
).toBe(2);
|
|
1862
2382
|
});
|
|
1863
|
-
|
|
2383
|
+
test12("should trigger lifecycle hooks for each Action call across multiple handles", async (c) => {
|
|
1864
2384
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1865
2385
|
const viewHandle = client.counterWithLifecycle.getOrCreate([
|
|
1866
2386
|
"test-lifecycle-multi-handle"
|
|
@@ -1876,12 +2396,12 @@ function runActorHandleTests(driverTestConfig) {
|
|
|
1876
2396
|
await trackingHandle1.increment(5);
|
|
1877
2397
|
await trackingHandle2.increment(10);
|
|
1878
2398
|
const events = await viewHandle.getEvents();
|
|
1879
|
-
|
|
1880
|
-
|
|
2399
|
+
expect12(events.filter((e) => e === "onWake").length).toBe(1);
|
|
2400
|
+
expect12(
|
|
1881
2401
|
events.filter((e) => e === "onBeforeConnect").length
|
|
1882
2402
|
).toBe(2);
|
|
1883
|
-
|
|
1884
|
-
|
|
2403
|
+
expect12(events.filter((e) => e === "onConnect").length).toBe(2);
|
|
2404
|
+
expect12(events.filter((e) => e === "onDisconnect").length).toBe(
|
|
1885
2405
|
2
|
|
1886
2406
|
);
|
|
1887
2407
|
});
|
|
@@ -1890,27 +2410,27 @@ function runActorHandleTests(driverTestConfig) {
|
|
|
1890
2410
|
}
|
|
1891
2411
|
|
|
1892
2412
|
// src/driver-test-suite/tests/actor-inline-client.ts
|
|
1893
|
-
import { describe as
|
|
2413
|
+
import { describe as describe14, expect as expect13, test as test13 } from "vitest";
|
|
1894
2414
|
function runActorInlineClientTests(driverTestConfig) {
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
2415
|
+
describe14("Actor Inline Client Tests", () => {
|
|
2416
|
+
describe14("Stateless Client Calls", () => {
|
|
2417
|
+
test13("should make stateless calls to other actors", async (c) => {
|
|
1898
2418
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1899
2419
|
const inlineClientHandle = client.inlineClientActor.getOrCreate(
|
|
1900
2420
|
["inline-client-test"]
|
|
1901
2421
|
);
|
|
1902
2422
|
const result = await inlineClientHandle.callCounterIncrement(5);
|
|
1903
|
-
|
|
2423
|
+
expect13(result).toBe(5);
|
|
1904
2424
|
const counterState = await inlineClientHandle.getCounterState();
|
|
1905
|
-
|
|
2425
|
+
expect13(counterState).toBe(5);
|
|
1906
2426
|
const messages = await inlineClientHandle.getMessages();
|
|
1907
|
-
|
|
1908
|
-
|
|
2427
|
+
expect13(messages).toHaveLength(2);
|
|
2428
|
+
expect13(messages[0]).toContain(
|
|
1909
2429
|
"Called counter.increment(5), result: 5"
|
|
1910
2430
|
);
|
|
1911
|
-
|
|
2431
|
+
expect13(messages[1]).toContain("Got counter state: 5");
|
|
1912
2432
|
});
|
|
1913
|
-
|
|
2433
|
+
test13("should handle multiple stateless calls", async (c) => {
|
|
1914
2434
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1915
2435
|
const inlineClientHandle = client.inlineClientActor.getOrCreate(
|
|
1916
2436
|
["inline-client-multi"]
|
|
@@ -1919,58 +2439,58 @@ function runActorInlineClientTests(driverTestConfig) {
|
|
|
1919
2439
|
const result1 = await inlineClientHandle.callCounterIncrement(3);
|
|
1920
2440
|
const result2 = await inlineClientHandle.callCounterIncrement(7);
|
|
1921
2441
|
const finalState = await inlineClientHandle.getCounterState();
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
2442
|
+
expect13(result1).toBe(3);
|
|
2443
|
+
expect13(result2).toBe(10);
|
|
2444
|
+
expect13(finalState).toBe(10);
|
|
1925
2445
|
const messages = await inlineClientHandle.getMessages();
|
|
1926
|
-
|
|
1927
|
-
|
|
2446
|
+
expect13(messages).toHaveLength(3);
|
|
2447
|
+
expect13(messages[0]).toContain(
|
|
1928
2448
|
"Called counter.increment(3), result: 3"
|
|
1929
2449
|
);
|
|
1930
|
-
|
|
2450
|
+
expect13(messages[1]).toContain(
|
|
1931
2451
|
"Called counter.increment(7), result: 10"
|
|
1932
2452
|
);
|
|
1933
|
-
|
|
2453
|
+
expect13(messages[2]).toContain("Got counter state: 10");
|
|
1934
2454
|
});
|
|
1935
2455
|
});
|
|
1936
|
-
|
|
1937
|
-
|
|
2456
|
+
describe14("Stateful Client Calls", () => {
|
|
2457
|
+
test13("should connect to other actors and receive events", async (c) => {
|
|
1938
2458
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1939
2459
|
const inlineClientHandle = client.inlineClientActor.getOrCreate(
|
|
1940
2460
|
["inline-client-stateful"]
|
|
1941
2461
|
);
|
|
1942
2462
|
await inlineClientHandle.clearMessages();
|
|
1943
2463
|
const result = await inlineClientHandle.connectToCounterAndIncrement(4);
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
2464
|
+
expect13(result.result1).toBe(4);
|
|
2465
|
+
expect13(result.result2).toBe(12);
|
|
2466
|
+
expect13(result.events).toEqual([4, 12]);
|
|
1947
2467
|
const messages = await inlineClientHandle.getMessages();
|
|
1948
|
-
|
|
1949
|
-
|
|
2468
|
+
expect13(messages).toHaveLength(1);
|
|
2469
|
+
expect13(messages[0]).toContain(
|
|
1950
2470
|
"Connected to counter, incremented by 4 and 8"
|
|
1951
2471
|
);
|
|
1952
|
-
|
|
1953
|
-
|
|
2472
|
+
expect13(messages[0]).toContain("results: 4, 12");
|
|
2473
|
+
expect13(messages[0]).toContain("events: [4,12]");
|
|
1954
2474
|
});
|
|
1955
|
-
|
|
2475
|
+
test13("should handle stateful connection independently", async (c) => {
|
|
1956
2476
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1957
2477
|
const inlineClientHandle = client.inlineClientActor.getOrCreate(
|
|
1958
2478
|
["inline-client-independent"]
|
|
1959
2479
|
);
|
|
1960
2480
|
await inlineClientHandle.clearMessages();
|
|
1961
2481
|
const result = await inlineClientHandle.connectToCounterAndIncrement(2);
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
2482
|
+
expect13(result.result1).toBe(2);
|
|
2483
|
+
expect13(result.result2).toBe(6);
|
|
2484
|
+
expect13(result.events).toEqual([2, 6]);
|
|
1965
2485
|
const messages = await inlineClientHandle.getMessages();
|
|
1966
|
-
|
|
1967
|
-
|
|
2486
|
+
expect13(messages).toHaveLength(1);
|
|
2487
|
+
expect13(messages[0]).toContain(
|
|
1968
2488
|
"Connected to counter, incremented by 2 and 4"
|
|
1969
2489
|
);
|
|
1970
2490
|
});
|
|
1971
2491
|
});
|
|
1972
|
-
|
|
1973
|
-
|
|
2492
|
+
describe14("Mixed Client Usage", () => {
|
|
2493
|
+
test13("should handle both stateless and stateful calls", async (c) => {
|
|
1974
2494
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1975
2495
|
const inlineClientHandle = client.inlineClientActor.getOrCreate(
|
|
1976
2496
|
["inline-client-mixed"]
|
|
@@ -1978,17 +2498,17 @@ function runActorInlineClientTests(driverTestConfig) {
|
|
|
1978
2498
|
await inlineClientHandle.clearMessages();
|
|
1979
2499
|
await inlineClientHandle.callCounterIncrement(1);
|
|
1980
2500
|
const statelessResult = await inlineClientHandle.getCounterState();
|
|
1981
|
-
|
|
2501
|
+
expect13(statelessResult).toBe(1);
|
|
1982
2502
|
const statefulResult = await inlineClientHandle.connectToCounterAndIncrement(3);
|
|
1983
|
-
|
|
1984
|
-
|
|
2503
|
+
expect13(statefulResult.result1).toBe(3);
|
|
2504
|
+
expect13(statefulResult.result2).toBe(9);
|
|
1985
2505
|
const messages = await inlineClientHandle.getMessages();
|
|
1986
|
-
|
|
1987
|
-
|
|
2506
|
+
expect13(messages).toHaveLength(3);
|
|
2507
|
+
expect13(messages[0]).toContain(
|
|
1988
2508
|
"Called counter.increment(1), result: 1"
|
|
1989
2509
|
);
|
|
1990
|
-
|
|
1991
|
-
|
|
2510
|
+
expect13(messages[1]).toContain("Got counter state: 1");
|
|
2511
|
+
expect13(messages[2]).toContain(
|
|
1992
2512
|
"Connected to counter, incremented by 3 and 6"
|
|
1993
2513
|
);
|
|
1994
2514
|
});
|
|
@@ -1997,36 +2517,236 @@ function runActorInlineClientTests(driverTestConfig) {
|
|
|
1997
2517
|
}
|
|
1998
2518
|
|
|
1999
2519
|
// src/driver-test-suite/tests/actor-inspector.ts
|
|
2000
|
-
import { describe as
|
|
2520
|
+
import { describe as describe15, expect as expect14, test as test14 } from "vitest";
|
|
2001
2521
|
function runActorInspectorTests(driverTestConfig) {
|
|
2002
|
-
|
|
2522
|
+
describe15("Actor Inspector HTTP API", () => {
|
|
2523
|
+
test14("GET /inspector/state returns actor state", async (c) => {
|
|
2524
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2525
|
+
const handle = client.counter.getOrCreate(["inspector-state"]);
|
|
2526
|
+
await handle.increment(5);
|
|
2527
|
+
const gatewayUrl = await handle.getGatewayUrl();
|
|
2528
|
+
const response = await fetch(`${gatewayUrl}/inspector/state`, {
|
|
2529
|
+
headers: { Authorization: "Bearer token" }
|
|
2530
|
+
});
|
|
2531
|
+
expect14(response.status).toBe(200);
|
|
2532
|
+
const data = await response.json();
|
|
2533
|
+
expect14(data).toEqual({ state: { count: 5 } });
|
|
2534
|
+
});
|
|
2535
|
+
test14("PATCH /inspector/state updates actor state", async (c) => {
|
|
2536
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2537
|
+
const handle = client.counter.getOrCreate([
|
|
2538
|
+
"inspector-set-state"
|
|
2539
|
+
]);
|
|
2540
|
+
await handle.increment(5);
|
|
2541
|
+
const gatewayUrl = await handle.getGatewayUrl();
|
|
2542
|
+
const patchResponse = await fetch(
|
|
2543
|
+
`${gatewayUrl}/inspector/state`,
|
|
2544
|
+
{
|
|
2545
|
+
method: "PATCH",
|
|
2546
|
+
headers: {
|
|
2547
|
+
"Content-Type": "application/json",
|
|
2548
|
+
Authorization: "Bearer token"
|
|
2549
|
+
},
|
|
2550
|
+
body: JSON.stringify({ state: { count: 42 } })
|
|
2551
|
+
}
|
|
2552
|
+
);
|
|
2553
|
+
expect14(patchResponse.status).toBe(200);
|
|
2554
|
+
const patchData = await patchResponse.json();
|
|
2555
|
+
expect14(patchData).toEqual({ ok: true });
|
|
2556
|
+
const count = await handle.getCount();
|
|
2557
|
+
expect14(count).toBe(42);
|
|
2558
|
+
});
|
|
2559
|
+
test14("GET /inspector/connections returns connections list", async (c) => {
|
|
2560
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2561
|
+
const handle = client.counter.getOrCreate([
|
|
2562
|
+
"inspector-connections"
|
|
2563
|
+
]);
|
|
2564
|
+
await handle.increment(0);
|
|
2565
|
+
const gatewayUrl = await handle.getGatewayUrl();
|
|
2566
|
+
const response = await fetch(
|
|
2567
|
+
`${gatewayUrl}/inspector/connections`,
|
|
2568
|
+
{
|
|
2569
|
+
headers: { Authorization: "Bearer token" }
|
|
2570
|
+
}
|
|
2571
|
+
);
|
|
2572
|
+
expect14(response.status).toBe(200);
|
|
2573
|
+
const data = await response.json();
|
|
2574
|
+
expect14(data).toHaveProperty("connections");
|
|
2575
|
+
expect14(Array.isArray(data.connections)).toBe(true);
|
|
2576
|
+
});
|
|
2577
|
+
test14("GET /inspector/rpcs returns available actions", async (c) => {
|
|
2578
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2579
|
+
const handle = client.counter.getOrCreate(["inspector-rpcs"]);
|
|
2580
|
+
await handle.increment(0);
|
|
2581
|
+
const gatewayUrl = await handle.getGatewayUrl();
|
|
2582
|
+
const response = await fetch(`${gatewayUrl}/inspector/rpcs`, {
|
|
2583
|
+
headers: { Authorization: "Bearer token" }
|
|
2584
|
+
});
|
|
2585
|
+
expect14(response.status).toBe(200);
|
|
2586
|
+
const data = await response.json();
|
|
2587
|
+
expect14(data).toHaveProperty("rpcs");
|
|
2588
|
+
expect14(data.rpcs).toContain("increment");
|
|
2589
|
+
expect14(data.rpcs).toContain("getCount");
|
|
2590
|
+
expect14(data.rpcs).toContain("setCount");
|
|
2591
|
+
});
|
|
2592
|
+
test14("POST /inspector/action/:name executes an action", async (c) => {
|
|
2593
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2594
|
+
const handle = client.counter.getOrCreate([
|
|
2595
|
+
"inspector-action"
|
|
2596
|
+
]);
|
|
2597
|
+
await handle.increment(10);
|
|
2598
|
+
const gatewayUrl = await handle.getGatewayUrl();
|
|
2599
|
+
const response = await fetch(
|
|
2600
|
+
`${gatewayUrl}/inspector/action/increment`,
|
|
2601
|
+
{
|
|
2602
|
+
method: "POST",
|
|
2603
|
+
headers: {
|
|
2604
|
+
"Content-Type": "application/json",
|
|
2605
|
+
Authorization: "Bearer token"
|
|
2606
|
+
},
|
|
2607
|
+
body: JSON.stringify({ args: [5] })
|
|
2608
|
+
}
|
|
2609
|
+
);
|
|
2610
|
+
expect14(response.status).toBe(200);
|
|
2611
|
+
const data = await response.json();
|
|
2612
|
+
expect14(data.output).toBe(15);
|
|
2613
|
+
const count = await handle.getCount();
|
|
2614
|
+
expect14(count).toBe(15);
|
|
2615
|
+
});
|
|
2616
|
+
test14("GET /inspector/queue returns queue status", async (c) => {
|
|
2617
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2618
|
+
const handle = client.counter.getOrCreate(["inspector-queue"]);
|
|
2619
|
+
await handle.increment(0);
|
|
2620
|
+
const gatewayUrl = await handle.getGatewayUrl();
|
|
2621
|
+
const response = await fetch(
|
|
2622
|
+
`${gatewayUrl}/inspector/queue?limit=10`,
|
|
2623
|
+
{
|
|
2624
|
+
headers: { Authorization: "Bearer token" }
|
|
2625
|
+
}
|
|
2626
|
+
);
|
|
2627
|
+
expect14(response.status).toBe(200);
|
|
2628
|
+
const data = await response.json();
|
|
2629
|
+
expect14(data).toHaveProperty("size");
|
|
2630
|
+
expect14(data).toHaveProperty("maxSize");
|
|
2631
|
+
expect14(data).toHaveProperty("truncated");
|
|
2632
|
+
expect14(data).toHaveProperty("messages");
|
|
2633
|
+
expect14(typeof data.size).toBe("number");
|
|
2634
|
+
expect14(typeof data.maxSize).toBe("number");
|
|
2635
|
+
expect14(typeof data.truncated).toBe("boolean");
|
|
2636
|
+
expect14(Array.isArray(data.messages)).toBe(true);
|
|
2637
|
+
});
|
|
2638
|
+
test14("GET /inspector/traces returns trace data", async (c) => {
|
|
2639
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2640
|
+
const handle = client.counter.getOrCreate([
|
|
2641
|
+
"inspector-traces"
|
|
2642
|
+
]);
|
|
2643
|
+
await handle.increment(1);
|
|
2644
|
+
const gatewayUrl = await handle.getGatewayUrl();
|
|
2645
|
+
const response = await fetch(
|
|
2646
|
+
`${gatewayUrl}/inspector/traces?startMs=0&endMs=${Date.now() + 6e4}&limit=100`,
|
|
2647
|
+
{
|
|
2648
|
+
headers: { Authorization: "Bearer token" }
|
|
2649
|
+
}
|
|
2650
|
+
);
|
|
2651
|
+
expect14(response.status).toBe(200);
|
|
2652
|
+
const data = await response.json();
|
|
2653
|
+
expect14(data).toHaveProperty("otlp");
|
|
2654
|
+
expect14(data).toHaveProperty("clamped");
|
|
2655
|
+
expect14(typeof data.clamped).toBe("boolean");
|
|
2656
|
+
});
|
|
2657
|
+
test14("GET /inspector/workflow-history returns workflow status", async (c) => {
|
|
2658
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2659
|
+
const handle = client.counter.getOrCreate([
|
|
2660
|
+
"inspector-workflow"
|
|
2661
|
+
]);
|
|
2662
|
+
await handle.increment(0);
|
|
2663
|
+
const gatewayUrl = await handle.getGatewayUrl();
|
|
2664
|
+
const response = await fetch(
|
|
2665
|
+
`${gatewayUrl}/inspector/workflow-history`,
|
|
2666
|
+
{
|
|
2667
|
+
headers: { Authorization: "Bearer token" }
|
|
2668
|
+
}
|
|
2669
|
+
);
|
|
2670
|
+
expect14(response.status).toBe(200);
|
|
2671
|
+
const data = await response.json();
|
|
2672
|
+
expect14(data).toHaveProperty("history");
|
|
2673
|
+
expect14(data).toHaveProperty("isWorkflowEnabled");
|
|
2674
|
+
expect14(data.isWorkflowEnabled).toBe(false);
|
|
2675
|
+
expect14(data.history).toBeNull();
|
|
2676
|
+
});
|
|
2677
|
+
test14("GET /inspector/summary returns full actor snapshot", async (c) => {
|
|
2678
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2679
|
+
const handle = client.counter.getOrCreate([
|
|
2680
|
+
"inspector-summary"
|
|
2681
|
+
]);
|
|
2682
|
+
await handle.increment(7);
|
|
2683
|
+
const gatewayUrl = await handle.getGatewayUrl();
|
|
2684
|
+
const response = await fetch(
|
|
2685
|
+
`${gatewayUrl}/inspector/summary`,
|
|
2686
|
+
{
|
|
2687
|
+
headers: { Authorization: "Bearer token" }
|
|
2688
|
+
}
|
|
2689
|
+
);
|
|
2690
|
+
expect14(response.status).toBe(200);
|
|
2691
|
+
const data = await response.json();
|
|
2692
|
+
expect14(data.state).toEqual({ count: 7 });
|
|
2693
|
+
expect14(Array.isArray(data.connections)).toBe(true);
|
|
2694
|
+
expect14(data.rpcs).toContain("increment");
|
|
2695
|
+
expect14(typeof data.queueSize).toBe("number");
|
|
2696
|
+
expect14(data.isStateEnabled).toBe(true);
|
|
2697
|
+
expect14(typeof data.isDatabaseEnabled).toBe("boolean");
|
|
2698
|
+
expect14(data.isWorkflowEnabled).toBe(false);
|
|
2699
|
+
expect14(data.workflowHistory).toBeNull();
|
|
2700
|
+
});
|
|
2701
|
+
test14("inspector endpoints require auth in non-dev mode", async (c) => {
|
|
2702
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2703
|
+
const handle = client.counter.getOrCreate([
|
|
2704
|
+
"inspector-auth"
|
|
2705
|
+
]);
|
|
2706
|
+
await handle.increment(0);
|
|
2707
|
+
const gatewayUrl = await handle.getGatewayUrl();
|
|
2708
|
+
const response = await fetch(`${gatewayUrl}/inspector/state`, {
|
|
2709
|
+
headers: { Authorization: "Bearer wrong-token" }
|
|
2710
|
+
});
|
|
2711
|
+
expect14(response.status).toBe(401);
|
|
2712
|
+
});
|
|
2003
2713
|
});
|
|
2004
2714
|
}
|
|
2005
2715
|
|
|
2006
2716
|
// src/driver-test-suite/tests/actor-kv.ts
|
|
2007
|
-
import { describe as
|
|
2717
|
+
import { describe as describe16, expect as expect15, test as test15 } from "vitest";
|
|
2008
2718
|
function runActorKvTests(driverTestConfig) {
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
const { client } = await setupDriverTest(
|
|
2719
|
+
describe16("Actor KV Tests", () => {
|
|
2720
|
+
test15("supports text encoding and decoding", async (c) => {
|
|
2721
|
+
const { client: rawClient } = await setupDriverTest(
|
|
2722
|
+
c,
|
|
2723
|
+
driverTestConfig
|
|
2724
|
+
);
|
|
2725
|
+
const client = rawClient;
|
|
2012
2726
|
const kvHandle = client.kvActor.getOrCreate(["kv-text"]);
|
|
2013
2727
|
await kvHandle.putText("greeting", "hello");
|
|
2014
2728
|
const value = await kvHandle.getText("greeting");
|
|
2015
|
-
|
|
2729
|
+
expect15(value).toBe("hello");
|
|
2016
2730
|
await kvHandle.putText("prefix-a", "alpha");
|
|
2017
2731
|
await kvHandle.putText("prefix-b", "beta");
|
|
2018
2732
|
const results = await kvHandle.listText("prefix-");
|
|
2019
2733
|
const sorted = results.sort((a, b) => a.key.localeCompare(b.key));
|
|
2020
|
-
|
|
2734
|
+
expect15(sorted).toEqual([
|
|
2021
2735
|
{ key: "prefix-a", value: "alpha" },
|
|
2022
2736
|
{ key: "prefix-b", value: "beta" }
|
|
2023
2737
|
]);
|
|
2024
2738
|
});
|
|
2025
|
-
|
|
2739
|
+
test15(
|
|
2026
2740
|
"supports arrayBuffer encoding and decoding",
|
|
2027
2741
|
async (c) => {
|
|
2028
|
-
const { client } = await setupDriverTest(
|
|
2029
|
-
|
|
2742
|
+
const { client: rawClient } = await setupDriverTest(
|
|
2743
|
+
c,
|
|
2744
|
+
driverTestConfig
|
|
2745
|
+
);
|
|
2746
|
+
const client = rawClient;
|
|
2747
|
+
const kvHandle = client.kvActor.getOrCreate([
|
|
2748
|
+
"kv-array-buffer"
|
|
2749
|
+
]);
|
|
2030
2750
|
const values = await kvHandle.roundtripArrayBuffer("bytes", [
|
|
2031
2751
|
4,
|
|
2032
2752
|
8,
|
|
@@ -2035,32 +2755,32 @@ function runActorKvTests(driverTestConfig) {
|
|
|
2035
2755
|
23,
|
|
2036
2756
|
42
|
|
2037
2757
|
]);
|
|
2038
|
-
|
|
2758
|
+
expect15(values).toEqual([4, 8, 15, 16, 23, 42]);
|
|
2039
2759
|
}
|
|
2040
2760
|
);
|
|
2041
2761
|
});
|
|
2042
2762
|
}
|
|
2043
2763
|
|
|
2044
2764
|
// src/driver-test-suite/tests/actor-metadata.ts
|
|
2045
|
-
import { describe as
|
|
2765
|
+
import { describe as describe17, expect as expect16, test as test16 } from "vitest";
|
|
2046
2766
|
function runActorMetadataTests(driverTestConfig) {
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2767
|
+
describe17("Actor Metadata Tests", () => {
|
|
2768
|
+
describe17("Actor Name", () => {
|
|
2769
|
+
test16("should provide access to actor name", async (c) => {
|
|
2050
2770
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2051
2771
|
const handle = client.metadataActor.getOrCreate();
|
|
2052
2772
|
const actorName = await handle.getActorName();
|
|
2053
|
-
|
|
2773
|
+
expect16(actorName).toBe("metadataActor");
|
|
2054
2774
|
});
|
|
2055
|
-
|
|
2775
|
+
test16("should preserve actor name in state during onWake", async (c) => {
|
|
2056
2776
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2057
2777
|
const handle = client.metadataActor.getOrCreate();
|
|
2058
2778
|
const storedName = await handle.getStoredActorName();
|
|
2059
|
-
|
|
2779
|
+
expect16(storedName).toBe("metadataActor");
|
|
2060
2780
|
});
|
|
2061
2781
|
});
|
|
2062
|
-
|
|
2063
|
-
|
|
2782
|
+
describe17("Actor Tags", () => {
|
|
2783
|
+
test16("should provide access to tags", async (c) => {
|
|
2064
2784
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2065
2785
|
const handle = client.metadataActor.getOrCreate();
|
|
2066
2786
|
await handle.setupTestTags({
|
|
@@ -2068,12 +2788,12 @@ function runActorMetadataTests(driverTestConfig) {
|
|
|
2068
2788
|
purpose: "metadata-test"
|
|
2069
2789
|
});
|
|
2070
2790
|
const tags = await handle.getTags();
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2791
|
+
expect16(tags).toHaveProperty("env");
|
|
2792
|
+
expect16(tags.env).toBe("test");
|
|
2793
|
+
expect16(tags).toHaveProperty("purpose");
|
|
2794
|
+
expect16(tags.purpose).toBe("metadata-test");
|
|
2075
2795
|
});
|
|
2076
|
-
|
|
2796
|
+
test16("should allow accessing individual tags", async (c) => {
|
|
2077
2797
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2078
2798
|
const handle = client.metadataActor.getOrCreate();
|
|
2079
2799
|
await handle.setupTestTags({
|
|
@@ -2083,110 +2803,541 @@ function runActorMetadataTests(driverTestConfig) {
|
|
|
2083
2803
|
const category = await handle.getTag("category");
|
|
2084
2804
|
const version = await handle.getTag("version");
|
|
2085
2805
|
const nonexistent = await handle.getTag("nonexistent");
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2806
|
+
expect16(category).toBe("test-actor");
|
|
2807
|
+
expect16(version).toBe("1.0");
|
|
2808
|
+
expect16(nonexistent).toBeNull();
|
|
2089
2809
|
});
|
|
2090
2810
|
});
|
|
2091
|
-
|
|
2092
|
-
|
|
2811
|
+
describe17("Metadata Structure", () => {
|
|
2812
|
+
test16("should provide complete metadata object", async (c) => {
|
|
2093
2813
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2094
2814
|
const handle = client.metadataActor.getOrCreate();
|
|
2095
2815
|
await handle.setupTestTags({ type: "metadata-test" });
|
|
2096
2816
|
await handle.setupTestRegion("us-west-1");
|
|
2097
2817
|
const metadata = await handle.getMetadata();
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2818
|
+
expect16(metadata).toHaveProperty("name");
|
|
2819
|
+
expect16(metadata.name).toBe("metadataActor");
|
|
2820
|
+
expect16(metadata).toHaveProperty("tags");
|
|
2821
|
+
expect16(metadata.tags).toHaveProperty("type");
|
|
2822
|
+
expect16(metadata.tags.type).toBe("metadata-test");
|
|
2823
|
+
expect16(metadata).toHaveProperty("region");
|
|
2824
|
+
expect16(metadata.region).toBe("us-west-1");
|
|
2105
2825
|
});
|
|
2106
2826
|
});
|
|
2107
|
-
|
|
2108
|
-
|
|
2827
|
+
describe17("Region Information", () => {
|
|
2828
|
+
test16("should retrieve region information", async (c) => {
|
|
2109
2829
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2110
2830
|
const handle = client.metadataActor.getOrCreate();
|
|
2111
2831
|
await handle.setupTestRegion("eu-central-1");
|
|
2112
2832
|
const region = await handle.getRegion();
|
|
2113
|
-
|
|
2833
|
+
expect16(region).toBe("eu-central-1");
|
|
2114
2834
|
});
|
|
2115
2835
|
});
|
|
2116
2836
|
});
|
|
2117
2837
|
}
|
|
2118
2838
|
|
|
2119
2839
|
// src/driver-test-suite/tests/actor-onstatechange.ts
|
|
2120
|
-
import { describe as
|
|
2840
|
+
import { describe as describe18, expect as expect17, test as test17 } from "vitest";
|
|
2121
2841
|
function runActorOnStateChangeTests(driverTestConfig) {
|
|
2122
|
-
|
|
2123
|
-
|
|
2842
|
+
describe18("Actor onStateChange Tests", () => {
|
|
2843
|
+
test17("triggers onStateChange when state is modified", async (c) => {
|
|
2124
2844
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2125
2845
|
const actor = client.onStateChangeActor.getOrCreate();
|
|
2126
2846
|
await actor.setValue(10);
|
|
2127
2847
|
const changeCount = await actor.getChangeCount();
|
|
2128
|
-
|
|
2848
|
+
expect17(changeCount).toBe(1);
|
|
2129
2849
|
});
|
|
2130
|
-
|
|
2850
|
+
test17("triggers onChange multiple times for multiple state changes", async (c) => {
|
|
2131
2851
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2132
2852
|
const actor = client.onStateChangeActor.getOrCreate();
|
|
2133
2853
|
await actor.incrementMultiple(3);
|
|
2134
2854
|
const changeCount = await actor.getChangeCount();
|
|
2135
|
-
|
|
2855
|
+
expect17(changeCount).toBe(3);
|
|
2136
2856
|
});
|
|
2137
|
-
|
|
2857
|
+
test17("does NOT trigger onChange for read-only actions", async (c) => {
|
|
2138
2858
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2139
2859
|
const actor = client.onStateChangeActor.getOrCreate();
|
|
2140
2860
|
await actor.setValue(5);
|
|
2141
2861
|
const value = await actor.getValue();
|
|
2142
|
-
|
|
2862
|
+
expect17(value).toBe(5);
|
|
2143
2863
|
const changeCount = await actor.getChangeCount();
|
|
2144
|
-
|
|
2864
|
+
expect17(changeCount).toBe(1);
|
|
2145
2865
|
});
|
|
2146
|
-
|
|
2866
|
+
test17("does NOT trigger onChange for computed values", async (c) => {
|
|
2147
2867
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2148
2868
|
const actor = client.onStateChangeActor.getOrCreate();
|
|
2149
2869
|
await actor.setValue(3);
|
|
2150
2870
|
{
|
|
2151
2871
|
const changeCount = await actor.getChangeCount();
|
|
2152
|
-
|
|
2872
|
+
expect17(changeCount).toBe(1);
|
|
2153
2873
|
}
|
|
2154
2874
|
const doubled = await actor.getDoubled();
|
|
2155
|
-
|
|
2875
|
+
expect17(doubled).toBe(6);
|
|
2156
2876
|
{
|
|
2157
2877
|
const changeCount = await actor.getChangeCount();
|
|
2158
|
-
|
|
2878
|
+
expect17(changeCount).toBe(1);
|
|
2159
2879
|
}
|
|
2160
2880
|
});
|
|
2161
|
-
|
|
2881
|
+
test17("simple: connect, call action, dispose does NOT trigger onChange", async (c) => {
|
|
2162
2882
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2163
2883
|
const actor = client.onStateChangeActor.getOrCreate();
|
|
2164
2884
|
const connection = await actor.connect();
|
|
2165
2885
|
const value = await connection.getValue();
|
|
2166
|
-
|
|
2886
|
+
expect17(value).toBe(0);
|
|
2167
2887
|
await connection.dispose();
|
|
2168
2888
|
const changeCount = await actor.getChangeCount();
|
|
2169
|
-
|
|
2889
|
+
expect17(changeCount).toBe(0);
|
|
2890
|
+
});
|
|
2891
|
+
});
|
|
2892
|
+
}
|
|
2893
|
+
|
|
2894
|
+
// src/driver-test-suite/tests/actor-queue.ts
|
|
2895
|
+
import { describe as describe19, expect as expect18, test as test18 } from "vitest";
|
|
2896
|
+
function runActorQueueTests(driverTestConfig) {
|
|
2897
|
+
describe19("Actor Queue Tests", () => {
|
|
2898
|
+
test18("client can send to actor queue", async (c) => {
|
|
2899
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2900
|
+
const handle = client.queueActor.getOrCreate(["client-send"]);
|
|
2901
|
+
await handle.send("greeting", { hello: "world" });
|
|
2902
|
+
const message = await handle.receiveOne("greeting");
|
|
2903
|
+
expect18(message).toEqual({
|
|
2904
|
+
name: "greeting",
|
|
2905
|
+
body: { hello: "world" }
|
|
2906
|
+
});
|
|
2907
|
+
});
|
|
2908
|
+
test18("actor can send to its own queue", async (c) => {
|
|
2909
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2910
|
+
const handle = client.queueActor.getOrCreate(["self-send"]);
|
|
2911
|
+
await handle.sendToSelf("self", { value: 42 });
|
|
2912
|
+
const message = await handle.receiveOne("self");
|
|
2913
|
+
expect18(message).toEqual({ name: "self", body: { value: 42 } });
|
|
2914
|
+
});
|
|
2915
|
+
test18("next supports name arrays and counts", async (c) => {
|
|
2916
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2917
|
+
const handle = client.queueActor.getOrCreate(["receive-array"]);
|
|
2918
|
+
await handle.send("a", 1);
|
|
2919
|
+
await handle.send("b", 2);
|
|
2920
|
+
await handle.send("c", 3);
|
|
2921
|
+
const messages = await handle.receiveMany(["a", "b"], { count: 2 });
|
|
2922
|
+
expect18(messages).toEqual([
|
|
2923
|
+
{ name: "a", body: 1 },
|
|
2924
|
+
{ name: "b", body: 2 }
|
|
2925
|
+
]);
|
|
2926
|
+
});
|
|
2927
|
+
test18("next supports request objects", async (c) => {
|
|
2928
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2929
|
+
const handle = client.queueActor.getOrCreate(["receive-request"]);
|
|
2930
|
+
await handle.send("one", "first");
|
|
2931
|
+
await handle.send("two", "second");
|
|
2932
|
+
const messages = await handle.receiveRequest({
|
|
2933
|
+
names: ["one", "two"],
|
|
2934
|
+
count: 2
|
|
2935
|
+
});
|
|
2936
|
+
expect18(messages).toEqual([
|
|
2937
|
+
{ name: "one", body: "first" },
|
|
2938
|
+
{ name: "two", body: "second" }
|
|
2939
|
+
]);
|
|
2940
|
+
});
|
|
2941
|
+
test18("next defaults to all names when names is omitted", async (c) => {
|
|
2942
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2943
|
+
const handle = client.queueActor.getOrCreate([
|
|
2944
|
+
"receive-request-all"
|
|
2945
|
+
]);
|
|
2946
|
+
await handle.send("one", "first");
|
|
2947
|
+
await handle.send("two", "second");
|
|
2948
|
+
const messages = await handle.receiveRequest({ count: 2 });
|
|
2949
|
+
expect18(messages).toEqual([
|
|
2950
|
+
{ name: "one", body: "first" },
|
|
2951
|
+
{ name: "two", body: "second" }
|
|
2952
|
+
]);
|
|
2953
|
+
});
|
|
2954
|
+
test18("next timeout returns empty array", async (c) => {
|
|
2955
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2956
|
+
const handle = client.queueActor.getOrCreate(["receive-timeout"]);
|
|
2957
|
+
const promise = handle.receiveMany(["missing"], { timeout: 50 });
|
|
2958
|
+
await waitFor(driverTestConfig, 60);
|
|
2959
|
+
const messages = await promise;
|
|
2960
|
+
expect18(messages).toEqual([]);
|
|
2961
|
+
});
|
|
2962
|
+
test18("tryNext does not wait and returns empty array", async (c) => {
|
|
2963
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2964
|
+
const handle = client.queueActor.getOrCreate(["try-next-empty"]);
|
|
2965
|
+
const messages = await handle.tryReceiveMany({
|
|
2966
|
+
names: ["missing"],
|
|
2967
|
+
count: 1
|
|
2968
|
+
});
|
|
2969
|
+
expect18(messages).toEqual([]);
|
|
2970
|
+
});
|
|
2971
|
+
test18("abort throws ActorAborted", async (c) => {
|
|
2972
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2973
|
+
const handle = client.queueActor.getOrCreate(["abort-test"]);
|
|
2974
|
+
try {
|
|
2975
|
+
await handle.waitForAbort();
|
|
2976
|
+
expect18.fail("expected ActorAborted error");
|
|
2977
|
+
} catch (error) {
|
|
2978
|
+
expect18(error.group).toBe("actor");
|
|
2979
|
+
expect18(error.code).toBe("aborted");
|
|
2980
|
+
}
|
|
2981
|
+
});
|
|
2982
|
+
test18("next supports signal abort", async (c) => {
|
|
2983
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2984
|
+
const handle = client.queueActor.getOrCreate(["signal-abort-next"]);
|
|
2985
|
+
const result = await handle.waitForSignalAbort();
|
|
2986
|
+
expect18(result).toEqual({
|
|
2987
|
+
group: "actor",
|
|
2988
|
+
code: "aborted"
|
|
2989
|
+
});
|
|
2990
|
+
});
|
|
2991
|
+
test18("next supports actor abort when signal is provided", async (c) => {
|
|
2992
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2993
|
+
const handle = client.queueActor.getOrCreate([
|
|
2994
|
+
"actor-abort-with-signal-next"
|
|
2995
|
+
]);
|
|
2996
|
+
const result = await handle.waitForActorAbortWithSignal();
|
|
2997
|
+
expect18(result).toEqual({
|
|
2998
|
+
group: "actor",
|
|
2999
|
+
code: "aborted"
|
|
3000
|
+
});
|
|
3001
|
+
});
|
|
3002
|
+
test18("iter supports signal abort", async (c) => {
|
|
3003
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3004
|
+
const handle = client.queueActor.getOrCreate(["signal-abort-iter"]);
|
|
3005
|
+
const result = await handle.iterWithSignalAbort();
|
|
3006
|
+
expect18(result).toEqual({ ok: true });
|
|
3007
|
+
});
|
|
3008
|
+
test18("enforces queue size limit", async (c) => {
|
|
3009
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3010
|
+
const key = `size-limit-${Date.now()}-${Math.random().toString(16).slice(2)}`;
|
|
3011
|
+
const handle = client.queueLimitedActor.getOrCreate([key]);
|
|
3012
|
+
await handle.send("message", 1);
|
|
3013
|
+
await waitFor(driverTestConfig, 10);
|
|
3014
|
+
try {
|
|
3015
|
+
await handle.send("message", 2);
|
|
3016
|
+
expect18.fail("expected queue full error");
|
|
3017
|
+
} catch (error) {
|
|
3018
|
+
expect18(error).toBeInstanceOf(Error);
|
|
3019
|
+
expect18(error.message).toContain(
|
|
3020
|
+
"Queue is full. Limit is"
|
|
3021
|
+
);
|
|
3022
|
+
if (driverTestConfig.clientType !== "http") {
|
|
3023
|
+
expect18(error.group).toBe("queue");
|
|
3024
|
+
expect18(error.code).toBe("full");
|
|
3025
|
+
}
|
|
3026
|
+
}
|
|
3027
|
+
});
|
|
3028
|
+
test18("enforces message size limit", async (c) => {
|
|
3029
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3030
|
+
const handle = client.queueLimitedActor.getOrCreate([
|
|
3031
|
+
"message-limit"
|
|
3032
|
+
]);
|
|
3033
|
+
const largePayload = "a".repeat(200);
|
|
3034
|
+
try {
|
|
3035
|
+
await handle.send("oversize", largePayload);
|
|
3036
|
+
expect18.fail("expected message_too_large error");
|
|
3037
|
+
} catch (error) {
|
|
3038
|
+
expect18(error.group).toBe("queue");
|
|
3039
|
+
expect18(error.code).toBe("message_too_large");
|
|
3040
|
+
}
|
|
3041
|
+
});
|
|
3042
|
+
test18("wait send returns completion response", async (c) => {
|
|
3043
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3044
|
+
const handle = client.queueActor.getOrCreate(["wait-complete"]);
|
|
3045
|
+
const actionPromise = handle.receiveAndComplete("tasks");
|
|
3046
|
+
const result = await handle.send(
|
|
3047
|
+
"tasks",
|
|
3048
|
+
{ value: 123 },
|
|
3049
|
+
{ wait: true, timeout: 1e3 }
|
|
3050
|
+
);
|
|
3051
|
+
await actionPromise;
|
|
3052
|
+
expect18(result).toEqual({
|
|
3053
|
+
status: "completed",
|
|
3054
|
+
response: { echo: { value: 123 } }
|
|
3055
|
+
});
|
|
3056
|
+
});
|
|
3057
|
+
test18("wait send times out", async (c) => {
|
|
3058
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3059
|
+
const handle = client.queueActor.getOrCreate(["wait-timeout"]);
|
|
3060
|
+
const resultPromise = handle.send(
|
|
3061
|
+
"timeout",
|
|
3062
|
+
{ value: 456 },
|
|
3063
|
+
{ wait: true, timeout: 50 }
|
|
3064
|
+
);
|
|
3065
|
+
await waitFor(driverTestConfig, 60);
|
|
3066
|
+
const result = await resultPromise;
|
|
3067
|
+
expect18(result.status).toBe("timedOut");
|
|
3068
|
+
});
|
|
3069
|
+
test18("manual receive retries message when not completed", async (c) => {
|
|
3070
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3071
|
+
const handle = client.queueActor.getOrCreate([
|
|
3072
|
+
"manual-retry-uncompleted"
|
|
3073
|
+
]);
|
|
3074
|
+
await handle.send("tasks", { value: 789 });
|
|
3075
|
+
const first = await handle.receiveWithoutComplete("tasks");
|
|
3076
|
+
expect18(first).toEqual({ name: "tasks", body: { value: 789 } });
|
|
3077
|
+
const retried = await handle.receiveOne("tasks", { timeout: 1e3 });
|
|
3078
|
+
expect18(retried).toEqual({ name: "tasks", body: { value: 789 } });
|
|
3079
|
+
});
|
|
3080
|
+
test18("next throws when previous manual message is not completed", async (c) => {
|
|
3081
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3082
|
+
const handle = client.queueActor.getOrCreate([
|
|
3083
|
+
"manual-next-requires-complete"
|
|
3084
|
+
]);
|
|
3085
|
+
await handle.send("tasks", { value: 111 });
|
|
3086
|
+
const result = await handle.receiveManualThenNextWithoutComplete(
|
|
3087
|
+
"tasks"
|
|
3088
|
+
);
|
|
3089
|
+
expect18(result).toEqual({
|
|
3090
|
+
group: "queue",
|
|
3091
|
+
code: "previous_message_not_completed"
|
|
3092
|
+
});
|
|
3093
|
+
});
|
|
3094
|
+
test18("manual receive includes complete even without completion schema", async (c) => {
|
|
3095
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3096
|
+
const handle = client.queueActor.getOrCreate([
|
|
3097
|
+
"complete-not-allowed"
|
|
3098
|
+
]);
|
|
3099
|
+
await handle.send("nowait", { value: "test" });
|
|
3100
|
+
const result = await handle.receiveWithoutCompleteMethod("nowait");
|
|
3101
|
+
expect18(result).toEqual({
|
|
3102
|
+
hasComplete: true
|
|
3103
|
+
});
|
|
3104
|
+
});
|
|
3105
|
+
test18("manual receive retries queues without completion schema until completed", async (c) => {
|
|
3106
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3107
|
+
const handle = client.queueActor.getOrCreate([
|
|
3108
|
+
"complete-not-allowed-consume"
|
|
3109
|
+
]);
|
|
3110
|
+
await handle.send("nowait", { value: "test" });
|
|
3111
|
+
const result = await handle.receiveWithoutCompleteMethod("nowait");
|
|
3112
|
+
expect18(result).toEqual({ hasComplete: true });
|
|
3113
|
+
const next = await handle.receiveOne("nowait", { timeout: 1e3 });
|
|
3114
|
+
expect18(next).toEqual({ name: "nowait", body: { value: "test" } });
|
|
3115
|
+
});
|
|
3116
|
+
test18("complete throws when called twice", async (c) => {
|
|
3117
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3118
|
+
const handle = client.queueActor.getOrCreate([
|
|
3119
|
+
"complete-twice"
|
|
3120
|
+
]);
|
|
3121
|
+
await handle.send("twice", { value: "test" });
|
|
3122
|
+
const result = await handle.receiveAndCompleteTwice("twice");
|
|
3123
|
+
expect18(result).toEqual({
|
|
3124
|
+
group: "queue",
|
|
3125
|
+
code: "already_completed"
|
|
3126
|
+
});
|
|
3127
|
+
});
|
|
3128
|
+
test18("wait send no longer requires queue completion schema", async (c) => {
|
|
3129
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3130
|
+
const handle = client.queueActor.getOrCreate([
|
|
3131
|
+
"missing-completion-schema"
|
|
3132
|
+
]);
|
|
3133
|
+
const result = await handle.send(
|
|
3134
|
+
"nowait",
|
|
3135
|
+
{ value: "test" },
|
|
3136
|
+
{ wait: true, timeout: 50 }
|
|
3137
|
+
);
|
|
3138
|
+
expect18(result).toEqual({ status: "timedOut" });
|
|
3139
|
+
});
|
|
3140
|
+
test18("iter can consume queued messages", async (c) => {
|
|
3141
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3142
|
+
const handle = client.queueActor.getOrCreate(["iter-consume"]);
|
|
3143
|
+
await handle.send("one", "first");
|
|
3144
|
+
const message = await handle.receiveWithIterator("one");
|
|
3145
|
+
expect18(message).toEqual({ name: "one", body: "first" });
|
|
3146
|
+
});
|
|
3147
|
+
test18("queue async iterator can consume queued messages", async (c) => {
|
|
3148
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3149
|
+
const handle = client.queueActor.getOrCreate([
|
|
3150
|
+
"async-iter-consume"
|
|
3151
|
+
]);
|
|
3152
|
+
await handle.send("two", "second");
|
|
3153
|
+
const message = await handle.receiveWithAsyncIterator();
|
|
3154
|
+
expect18(message).toEqual({ name: "two", body: "second" });
|
|
3155
|
+
});
|
|
3156
|
+
});
|
|
3157
|
+
}
|
|
3158
|
+
|
|
3159
|
+
// src/driver-test-suite/tests/actor-run.ts
|
|
3160
|
+
import { describe as describe20, expect as expect19, test as test19 } from "vitest";
|
|
3161
|
+
function runActorRunTests(driverTestConfig) {
|
|
3162
|
+
var _a;
|
|
3163
|
+
describe20.skipIf((_a = driverTestConfig.skip) == null ? void 0 : _a.sleep)("Actor Run Tests", () => {
|
|
3164
|
+
test19("run handler starts after actor startup", async (c) => {
|
|
3165
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3166
|
+
const actor = client.runWithTicks.getOrCreate(["run-starts"]);
|
|
3167
|
+
await waitFor(driverTestConfig, 100);
|
|
3168
|
+
const state = await actor.getState();
|
|
3169
|
+
expect19(state.runStarted).toBe(true);
|
|
3170
|
+
expect19(state.tickCount).toBeGreaterThan(0);
|
|
3171
|
+
});
|
|
3172
|
+
test19("run handler ticks continuously", async (c) => {
|
|
3173
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3174
|
+
const actor = client.runWithTicks.getOrCreate(["run-ticks"]);
|
|
3175
|
+
await waitFor(driverTestConfig, 200);
|
|
3176
|
+
const state1 = await actor.getState();
|
|
3177
|
+
expect19(state1.tickCount).toBeGreaterThan(0);
|
|
3178
|
+
const count1 = state1.tickCount;
|
|
3179
|
+
await waitFor(driverTestConfig, 200);
|
|
3180
|
+
const state2 = await actor.getState();
|
|
3181
|
+
expect19(state2.tickCount).toBeGreaterThan(count1);
|
|
3182
|
+
});
|
|
3183
|
+
test19("active run handler keeps actor awake past sleep timeout", async (c) => {
|
|
3184
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3185
|
+
const actor = client.runWithTicks.getOrCreate([
|
|
3186
|
+
"run-stays-awake"
|
|
3187
|
+
]);
|
|
3188
|
+
await waitFor(driverTestConfig, 100);
|
|
3189
|
+
const state1 = await actor.getState();
|
|
3190
|
+
expect19(state1.runStarted).toBe(true);
|
|
3191
|
+
const tickCount1 = state1.tickCount;
|
|
3192
|
+
await waitFor(driverTestConfig, RUN_SLEEP_TIMEOUT + 300);
|
|
3193
|
+
const state2 = await actor.getState();
|
|
3194
|
+
expect19(state2.runStarted).toBe(true);
|
|
3195
|
+
expect19(state2.runExited).toBe(false);
|
|
3196
|
+
expect19(state2.tickCount).toBeGreaterThan(tickCount1);
|
|
3197
|
+
});
|
|
3198
|
+
test19("actor without run handler works normally", async (c) => {
|
|
3199
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3200
|
+
const actor = client.runWithoutHandler.getOrCreate([
|
|
3201
|
+
"no-run-handler"
|
|
3202
|
+
]);
|
|
3203
|
+
const state = await actor.getState();
|
|
3204
|
+
expect19(state.wakeCount).toBe(1);
|
|
3205
|
+
await waitFor(driverTestConfig, RUN_SLEEP_TIMEOUT + 300);
|
|
3206
|
+
const state2 = await actor.getState();
|
|
3207
|
+
expect19(state2.wakeCount).toBe(2);
|
|
3208
|
+
});
|
|
3209
|
+
test19("run handler can consume from queue", async (c) => {
|
|
3210
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3211
|
+
const actor = client.runWithQueueConsumer.getOrCreate([
|
|
3212
|
+
"queue-consumer"
|
|
3213
|
+
]);
|
|
3214
|
+
await waitFor(driverTestConfig, 100);
|
|
3215
|
+
await actor.sendMessage({ type: "test", value: 1 });
|
|
3216
|
+
await actor.sendMessage({ type: "test", value: 2 });
|
|
3217
|
+
await actor.sendMessage({ type: "test", value: 3 });
|
|
3218
|
+
await waitFor(driverTestConfig, 1200);
|
|
3219
|
+
const state = await actor.getState();
|
|
3220
|
+
expect19(state.runStarted).toBe(true);
|
|
3221
|
+
expect19(state.messagesReceived.length).toBe(3);
|
|
3222
|
+
expect19(state.messagesReceived[0].body).toEqual({
|
|
3223
|
+
type: "test",
|
|
3224
|
+
value: 1
|
|
3225
|
+
});
|
|
3226
|
+
expect19(state.messagesReceived[1].body).toEqual({
|
|
3227
|
+
type: "test",
|
|
3228
|
+
value: 2
|
|
3229
|
+
});
|
|
3230
|
+
expect19(state.messagesReceived[2].body).toEqual({
|
|
3231
|
+
type: "test",
|
|
3232
|
+
value: 3
|
|
3233
|
+
});
|
|
3234
|
+
});
|
|
3235
|
+
test19("queue-waiting run handler can sleep and resume", async (c) => {
|
|
3236
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3237
|
+
const actor = client.runWithQueueConsumer.getOrCreate([
|
|
3238
|
+
"queue-consumer-sleep"
|
|
3239
|
+
]);
|
|
3240
|
+
await waitFor(driverTestConfig, 100);
|
|
3241
|
+
const state1 = await actor.getState();
|
|
3242
|
+
expect19(state1.runStarted).toBe(true);
|
|
3243
|
+
await waitFor(driverTestConfig, RUN_SLEEP_TIMEOUT + 500);
|
|
3244
|
+
const state2 = await actor.getState();
|
|
3245
|
+
expect19(state2.wakeCount).toBeGreaterThan(state1.wakeCount);
|
|
3246
|
+
});
|
|
3247
|
+
test19("run handler that exits early triggers destroy", async (c) => {
|
|
3248
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3249
|
+
const actor = client.runWithEarlyExit.getOrCreate(["early-exit"]);
|
|
3250
|
+
await waitFor(driverTestConfig, 100);
|
|
3251
|
+
const state1 = await actor.getState();
|
|
3252
|
+
expect19(state1.runStarted).toBe(true);
|
|
3253
|
+
await waitFor(driverTestConfig, 300);
|
|
3254
|
+
const actor2 = client.runWithEarlyExit.getOrCreate([
|
|
3255
|
+
"early-exit-fresh"
|
|
3256
|
+
]);
|
|
3257
|
+
const state2 = await actor2.getState();
|
|
3258
|
+
expect19(state2.runStarted).toBe(true);
|
|
3259
|
+
});
|
|
3260
|
+
test19("run handler that throws error triggers destroy", async (c) => {
|
|
3261
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3262
|
+
const actor = client.runWithError.getOrCreate(["run-error"]);
|
|
3263
|
+
await waitFor(driverTestConfig, 100);
|
|
3264
|
+
const state1 = await actor.getState();
|
|
3265
|
+
expect19(state1.runStarted).toBe(true);
|
|
3266
|
+
await waitFor(driverTestConfig, 300);
|
|
3267
|
+
const actor2 = client.runWithError.getOrCreate(["run-error-fresh"]);
|
|
3268
|
+
const state2 = await actor2.getState();
|
|
3269
|
+
expect19(state2.runStarted).toBe(true);
|
|
3270
|
+
});
|
|
3271
|
+
});
|
|
3272
|
+
}
|
|
3273
|
+
|
|
3274
|
+
// src/driver-test-suite/tests/actor-stateless.ts
|
|
3275
|
+
import { describe as describe21, expect as expect20, test as test20 } from "vitest";
|
|
3276
|
+
function runActorStatelessTests(driverTestConfig) {
|
|
3277
|
+
describe21("Actor Stateless Tests", () => {
|
|
3278
|
+
describe21("Stateless Actor Operations", () => {
|
|
3279
|
+
test20("can call actions on stateless actor", async (c) => {
|
|
3280
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3281
|
+
const instance = client.statelessActor.getOrCreate();
|
|
3282
|
+
const result = await instance.ping();
|
|
3283
|
+
expect20(result).toBe("pong");
|
|
3284
|
+
});
|
|
3285
|
+
test20("can echo messages", async (c) => {
|
|
3286
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3287
|
+
const instance = client.statelessActor.getOrCreate();
|
|
3288
|
+
const message = "Hello, World!";
|
|
3289
|
+
const result = await instance.echo(message);
|
|
3290
|
+
expect20(result).toBe(message);
|
|
3291
|
+
});
|
|
3292
|
+
test20("can access actorId", async (c) => {
|
|
3293
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3294
|
+
const instance = client.statelessActor.getOrCreate(["test-id"]);
|
|
3295
|
+
const actorId = await instance.getActorId();
|
|
3296
|
+
expect20(actorId).toBeDefined();
|
|
3297
|
+
expect20(typeof actorId).toBe("string");
|
|
3298
|
+
});
|
|
3299
|
+
test20("accessing state throws StateNotEnabled", async (c) => {
|
|
3300
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3301
|
+
const instance = client.statelessActor.getOrCreate();
|
|
3302
|
+
const result = await instance.tryGetState();
|
|
3303
|
+
expect20(result.success).toBe(false);
|
|
3304
|
+
expect20(result.error).toContain("state");
|
|
3305
|
+
});
|
|
3306
|
+
test20("accessing db throws DatabaseNotEnabled", async (c) => {
|
|
3307
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3308
|
+
const instance = client.statelessActor.getOrCreate();
|
|
3309
|
+
const result = await instance.tryGetDb();
|
|
3310
|
+
expect20(result.success).toBe(false);
|
|
3311
|
+
expect20(result.error).toContain("database");
|
|
3312
|
+
});
|
|
3313
|
+
test20("multiple stateless actors can exist independently", async (c) => {
|
|
3314
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3315
|
+
const actor1 = client.statelessActor.getOrCreate(["actor-1"]);
|
|
3316
|
+
const actor2 = client.statelessActor.getOrCreate(["actor-2"]);
|
|
3317
|
+
const id1 = await actor1.getActorId();
|
|
3318
|
+
const id2 = await actor2.getActorId();
|
|
3319
|
+
expect20(id1).not.toBe(id2);
|
|
3320
|
+
});
|
|
2170
3321
|
});
|
|
2171
3322
|
});
|
|
2172
3323
|
}
|
|
2173
3324
|
|
|
2174
3325
|
// src/driver-test-suite/tests/actor-vars.ts
|
|
2175
|
-
import { describe as
|
|
3326
|
+
import { describe as describe22, expect as expect21, test as test21 } from "vitest";
|
|
2176
3327
|
function runActorVarsTests(driverTestConfig) {
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
3328
|
+
describe22("Actor Variables", () => {
|
|
3329
|
+
describe22("Static vars", () => {
|
|
3330
|
+
test21("should provide access to static vars", async (c) => {
|
|
2180
3331
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2181
3332
|
const instance = client.staticVarActor.getOrCreate();
|
|
2182
3333
|
const result = await instance.getVars();
|
|
2183
|
-
|
|
3334
|
+
expect21(result).toEqual({ counter: 42, name: "test-actor" });
|
|
2184
3335
|
const name = await instance.getName();
|
|
2185
|
-
|
|
3336
|
+
expect21(name).toBe("test-actor");
|
|
2186
3337
|
});
|
|
2187
3338
|
});
|
|
2188
|
-
|
|
2189
|
-
|
|
3339
|
+
describe22("Deep cloning of static vars", () => {
|
|
3340
|
+
test21("should deep clone static vars between actor instances", async (c) => {
|
|
2190
3341
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2191
3342
|
const instance1 = client.nestedVarActor.getOrCreate([
|
|
2192
3343
|
"instance1"
|
|
@@ -2195,100 +3346,183 @@ function runActorVarsTests(driverTestConfig) {
|
|
|
2195
3346
|
"instance2"
|
|
2196
3347
|
]);
|
|
2197
3348
|
const modifiedVars = await instance1.modifyNested();
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
3349
|
+
expect21(modifiedVars.nested.value).toBe("modified");
|
|
3350
|
+
expect21(modifiedVars.nested.array).toContain(4);
|
|
3351
|
+
expect21(modifiedVars.nested.obj.key).toBe("new-value");
|
|
2201
3352
|
const instance2Vars = await instance2.getVars();
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
3353
|
+
expect21(instance2Vars.nested.value).toBe("original");
|
|
3354
|
+
expect21(instance2Vars.nested.array).toEqual([1, 2, 3]);
|
|
3355
|
+
expect21(instance2Vars.nested.obj.key).toBe("value");
|
|
2205
3356
|
});
|
|
2206
3357
|
});
|
|
2207
|
-
|
|
2208
|
-
|
|
3358
|
+
describe22("createVars", () => {
|
|
3359
|
+
test21("should support dynamic vars creation", async (c) => {
|
|
2209
3360
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2210
3361
|
const instance = client.dynamicVarActor.getOrCreate();
|
|
2211
3362
|
const vars = await instance.getVars();
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
3363
|
+
expect21(vars).toHaveProperty("random");
|
|
3364
|
+
expect21(vars).toHaveProperty("computed");
|
|
3365
|
+
expect21(typeof vars.random).toBe("number");
|
|
3366
|
+
expect21(typeof vars.computed).toBe("string");
|
|
3367
|
+
expect21(vars.computed).toMatch(/^Actor-\d+$/);
|
|
2217
3368
|
});
|
|
2218
|
-
|
|
3369
|
+
test21("should create different vars for different instances", async (c) => {
|
|
2219
3370
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2220
3371
|
const instance1 = client.uniqueVarActor.getOrCreate(["test1"]);
|
|
2221
3372
|
const instance2 = client.uniqueVarActor.getOrCreate(["test2"]);
|
|
2222
3373
|
const vars1 = await instance1.getVars();
|
|
2223
3374
|
const vars2 = await instance2.getVars();
|
|
2224
|
-
|
|
3375
|
+
expect21(vars1.id).not.toBe(vars2.id);
|
|
2225
3376
|
});
|
|
2226
3377
|
});
|
|
2227
|
-
|
|
2228
|
-
|
|
3378
|
+
describe22("Driver Context", () => {
|
|
3379
|
+
test21("should provide access to driver context", async (c) => {
|
|
2229
3380
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2230
3381
|
const instance = client.driverCtxActor.getOrCreate();
|
|
2231
3382
|
const vars = await instance.getVars();
|
|
2232
|
-
|
|
3383
|
+
expect21(vars).toHaveProperty("hasDriverCtx");
|
|
3384
|
+
});
|
|
3385
|
+
});
|
|
3386
|
+
});
|
|
3387
|
+
}
|
|
3388
|
+
|
|
3389
|
+
// src/driver-test-suite/tests/actor-workflow.ts
|
|
3390
|
+
import { describe as describe23, expect as expect22, test as test22 } from "vitest";
|
|
3391
|
+
function runActorWorkflowTests(driverTestConfig) {
|
|
3392
|
+
describe23("Actor Workflow Tests", () => {
|
|
3393
|
+
var _a;
|
|
3394
|
+
test22("replays steps and guards state access", async (c) => {
|
|
3395
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3396
|
+
const actor = client.workflowCounterActor.getOrCreate([
|
|
3397
|
+
"workflow-basic"
|
|
3398
|
+
]);
|
|
3399
|
+
await waitFor(driverTestConfig, 1e3);
|
|
3400
|
+
const state = await actor.getState();
|
|
3401
|
+
expect22(state.runCount).toBeGreaterThan(0);
|
|
3402
|
+
expect22(state.history.length).toBeGreaterThan(0);
|
|
3403
|
+
expect22(state.guardTriggered).toBe(true);
|
|
3404
|
+
});
|
|
3405
|
+
test22("consumes queue messages via workflow queue.next", async (c) => {
|
|
3406
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3407
|
+
const actor = client.workflowQueueActor.getOrCreate(["workflow-queue"]);
|
|
3408
|
+
await actor.send(WORKFLOW_QUEUE_NAME, {
|
|
3409
|
+
hello: "world"
|
|
3410
|
+
});
|
|
3411
|
+
await waitFor(driverTestConfig, 200);
|
|
3412
|
+
const messages = await actor.getMessages();
|
|
3413
|
+
expect22(messages).toEqual([{ hello: "world" }]);
|
|
3414
|
+
});
|
|
3415
|
+
test22("workflow queue.next supports completing wait sends", async (c) => {
|
|
3416
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3417
|
+
const actor = client.workflowQueueActor.getOrCreate([
|
|
3418
|
+
"workflow-queue-wait"
|
|
3419
|
+
]);
|
|
3420
|
+
const result = await actor.sendAndWait({ value: 123 });
|
|
3421
|
+
expect22(result).toEqual({
|
|
3422
|
+
status: "completed",
|
|
3423
|
+
response: { echo: { value: 123 } }
|
|
2233
3424
|
});
|
|
2234
3425
|
});
|
|
3426
|
+
test22("db and client are step-only in workflow context", async (c) => {
|
|
3427
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3428
|
+
const actor = client.workflowAccessActor.getOrCreate([
|
|
3429
|
+
"workflow-access"
|
|
3430
|
+
]);
|
|
3431
|
+
let state = await actor.getState();
|
|
3432
|
+
for (let i = 0; i < 20 && state.insideDbCount === 0; i++) {
|
|
3433
|
+
await waitFor(driverTestConfig, 50);
|
|
3434
|
+
state = await actor.getState();
|
|
3435
|
+
}
|
|
3436
|
+
expect22(state.outsideDbError).toBe(
|
|
3437
|
+
"db is only available inside workflow steps"
|
|
3438
|
+
);
|
|
3439
|
+
expect22(state.outsideClientError).toBe(
|
|
3440
|
+
"client is only available inside workflow steps"
|
|
3441
|
+
);
|
|
3442
|
+
expect22(state.insideDbCount).toBeGreaterThan(0);
|
|
3443
|
+
expect22(state.insideClientAvailable).toBe(true);
|
|
3444
|
+
});
|
|
3445
|
+
test22("sleeps and resumes between ticks", async (c) => {
|
|
3446
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3447
|
+
const actor = client.workflowSleepActor.getOrCreate(["workflow-sleep"]);
|
|
3448
|
+
const initial = await actor.getState();
|
|
3449
|
+
await waitFor(driverTestConfig, 200);
|
|
3450
|
+
const next = await actor.getState();
|
|
3451
|
+
expect22(next.ticks).toBeGreaterThan(initial.ticks);
|
|
3452
|
+
});
|
|
3453
|
+
test22.skipIf((_a = driverTestConfig.skip) == null ? void 0 : _a.sleep)(
|
|
3454
|
+
"workflow run teardown does not wait for runStopTimeout",
|
|
3455
|
+
async (c) => {
|
|
3456
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3457
|
+
const actor = client.workflowStopTeardownActor.getOrCreate([
|
|
3458
|
+
"workflow-stop-teardown"
|
|
3459
|
+
]);
|
|
3460
|
+
await actor.getTimeline();
|
|
3461
|
+
await waitFor(driverTestConfig, 1200);
|
|
3462
|
+
const timeline = await actor.getTimeline();
|
|
3463
|
+
expect22(timeline.wakeAts.length).toBeGreaterThanOrEqual(2);
|
|
3464
|
+
expect22(timeline.sleepAts.length).toBeGreaterThanOrEqual(1);
|
|
3465
|
+
const firstSleepDelayMs = timeline.sleepAts[0] - timeline.wakeAts[0];
|
|
3466
|
+
expect22(firstSleepDelayMs).toBeLessThan(1800);
|
|
3467
|
+
}
|
|
3468
|
+
);
|
|
2235
3469
|
});
|
|
2236
3470
|
}
|
|
2237
3471
|
|
|
2238
3472
|
// src/driver-test-suite/tests/manager-driver.ts
|
|
2239
|
-
import { describe as
|
|
3473
|
+
import { describe as describe24, expect as expect23, test as test23 } from "vitest";
|
|
2240
3474
|
function runManagerDriverTests(driverTestConfig) {
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
3475
|
+
describe24("Manager Driver Tests", () => {
|
|
3476
|
+
describe24("Client Connection Methods", () => {
|
|
3477
|
+
test23("connect() - finds or creates a actor", async (c) => {
|
|
2244
3478
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2245
3479
|
const counterA = client.counter.getOrCreate();
|
|
2246
3480
|
await counterA.increment(5);
|
|
2247
3481
|
const counterAAgain = client.counter.getOrCreate();
|
|
2248
3482
|
const count = await counterAAgain.increment(0);
|
|
2249
|
-
|
|
3483
|
+
expect23(count).toBe(5);
|
|
2250
3484
|
const counterB = client.counter.getOrCreate([
|
|
2251
3485
|
"counter-b",
|
|
2252
3486
|
"testing"
|
|
2253
3487
|
]);
|
|
2254
3488
|
await counterB.increment(10);
|
|
2255
3489
|
const countB = await counterB.increment(0);
|
|
2256
|
-
|
|
3490
|
+
expect23(countB).toBe(10);
|
|
2257
3491
|
});
|
|
2258
|
-
|
|
3492
|
+
test23("throws ActorAlreadyExists when creating duplicate actors", async (c) => {
|
|
2259
3493
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2260
3494
|
const uniqueKey = ["duplicate-actor-test", crypto.randomUUID()];
|
|
2261
3495
|
const counter = client.counter.getOrCreate(uniqueKey);
|
|
2262
3496
|
await counter.increment(5);
|
|
2263
3497
|
try {
|
|
2264
3498
|
await client.counter.create(uniqueKey);
|
|
2265
|
-
|
|
3499
|
+
expect23.fail("did not error on duplicate create");
|
|
2266
3500
|
} catch (err) {
|
|
2267
|
-
|
|
2268
|
-
|
|
3501
|
+
expect23(err.group).toBe("actor");
|
|
3502
|
+
expect23(err.code).toBe("duplicate_key");
|
|
2269
3503
|
}
|
|
2270
3504
|
const count = await counter.increment(0);
|
|
2271
|
-
|
|
3505
|
+
expect23(count).toBe(5);
|
|
2272
3506
|
});
|
|
2273
3507
|
});
|
|
2274
|
-
|
|
2275
|
-
|
|
3508
|
+
describe24("Connection Options", () => {
|
|
3509
|
+
test23("get without create prevents actor creation", async (c) => {
|
|
2276
3510
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2277
3511
|
const nonexistentId = `nonexistent-${crypto.randomUUID()}`;
|
|
2278
3512
|
try {
|
|
2279
3513
|
await client.counter.get([nonexistentId]).resolve();
|
|
2280
|
-
|
|
3514
|
+
expect23.fail("did not error for get");
|
|
2281
3515
|
} catch (err) {
|
|
2282
|
-
|
|
2283
|
-
|
|
3516
|
+
expect23(err.group).toBe("actor");
|
|
3517
|
+
expect23(err.code).toBe("not_found");
|
|
2284
3518
|
}
|
|
2285
3519
|
const createdCounter = client.counter.getOrCreate(nonexistentId);
|
|
2286
3520
|
await createdCounter.increment(3);
|
|
2287
3521
|
const retrievedCounter = client.counter.get(nonexistentId);
|
|
2288
3522
|
const count = await retrievedCounter.increment(0);
|
|
2289
|
-
|
|
3523
|
+
expect23(count).toBe(3);
|
|
2290
3524
|
});
|
|
2291
|
-
|
|
3525
|
+
test23("connection params are passed to actors", async (c) => {
|
|
2292
3526
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2293
3527
|
const counter = client.counter.getOrCreate(void 0, {
|
|
2294
3528
|
params: {
|
|
@@ -2299,20 +3533,20 @@ function runManagerDriverTests(driverTestConfig) {
|
|
|
2299
3533
|
});
|
|
2300
3534
|
await counter.increment(1);
|
|
2301
3535
|
const count = await counter.increment(0);
|
|
2302
|
-
|
|
3536
|
+
expect23(count).toBe(1);
|
|
2303
3537
|
});
|
|
2304
3538
|
});
|
|
2305
|
-
|
|
2306
|
-
|
|
3539
|
+
describe24("Actor Creation & Retrieval", () => {
|
|
3540
|
+
test23("creates and retrieves actors by ID", async (c) => {
|
|
2307
3541
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2308
3542
|
const uniqueId = `test-counter-${crypto.randomUUID()}`;
|
|
2309
3543
|
const counter = client.counter.getOrCreate([uniqueId]);
|
|
2310
3544
|
await counter.increment(10);
|
|
2311
3545
|
const retrievedCounter = client.counter.getOrCreate([uniqueId]);
|
|
2312
3546
|
const count = await retrievedCounter.increment(0);
|
|
2313
|
-
|
|
3547
|
+
expect23(count).toBe(10);
|
|
2314
3548
|
});
|
|
2315
|
-
|
|
3549
|
+
test23("passes input to actor during creation", async (c) => {
|
|
2316
3550
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2317
3551
|
const testInput = {
|
|
2318
3552
|
name: "test-actor",
|
|
@@ -2323,17 +3557,17 @@ function runManagerDriverTests(driverTestConfig) {
|
|
|
2323
3557
|
input: testInput
|
|
2324
3558
|
});
|
|
2325
3559
|
const inputs = await actor.getInputs();
|
|
2326
|
-
|
|
2327
|
-
|
|
3560
|
+
expect23(inputs.initialInput).toEqual(testInput);
|
|
3561
|
+
expect23(inputs.onCreateInput).toEqual(testInput);
|
|
2328
3562
|
});
|
|
2329
|
-
|
|
3563
|
+
test23("input is undefined when not provided", async (c) => {
|
|
2330
3564
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2331
3565
|
const actor = await client.inputActor.create();
|
|
2332
3566
|
const inputs = await actor.getInputs();
|
|
2333
|
-
|
|
2334
|
-
|
|
3567
|
+
expect23(inputs.initialInput).toBeUndefined();
|
|
3568
|
+
expect23(inputs.onCreateInput).toBeUndefined();
|
|
2335
3569
|
});
|
|
2336
|
-
|
|
3570
|
+
test23("getOrCreate passes input to actor during creation", async (c) => {
|
|
2337
3571
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2338
3572
|
const uniqueKey = [`input-test-${crypto.randomUUID()}`];
|
|
2339
3573
|
const testInput = {
|
|
@@ -2345,16 +3579,22 @@ function runManagerDriverTests(driverTestConfig) {
|
|
|
2345
3579
|
createWithInput: testInput
|
|
2346
3580
|
});
|
|
2347
3581
|
const inputs = await actor.getInputs();
|
|
2348
|
-
|
|
2349
|
-
|
|
3582
|
+
expect23(inputs.initialInput).toEqual(testInput);
|
|
3583
|
+
expect23(inputs.onCreateInput).toEqual(testInput);
|
|
2350
3584
|
const existingActor = client.inputActor.getOrCreate(uniqueKey);
|
|
2351
3585
|
const existingInputs = await existingActor.getInputs();
|
|
2352
|
-
|
|
2353
|
-
|
|
3586
|
+
expect23(existingInputs.initialInput).toEqual(testInput);
|
|
3587
|
+
expect23(existingInputs.onCreateInput).toEqual(testInput);
|
|
2354
3588
|
});
|
|
2355
3589
|
});
|
|
2356
|
-
|
|
2357
|
-
|
|
3590
|
+
describe24("Key Matching", () => {
|
|
3591
|
+
test23("multi-part actor keys are passed through correctly", async (c) => {
|
|
3592
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3593
|
+
const multiPartKey = ["tenant/with/slash", "room"];
|
|
3594
|
+
const counter = client.counter.getOrCreate(multiPartKey);
|
|
3595
|
+
expect23(await counter.getKey()).toEqual(multiPartKey);
|
|
3596
|
+
});
|
|
3597
|
+
test23("matches actors only with exactly the same keys", async (c) => {
|
|
2358
3598
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2359
3599
|
const originalCounter = client.counter.getOrCreate([
|
|
2360
3600
|
"counter-match",
|
|
@@ -2368,20 +3608,20 @@ function runManagerDriverTests(driverTestConfig) {
|
|
|
2368
3608
|
"us-east"
|
|
2369
3609
|
]);
|
|
2370
3610
|
const exactMatchCount = await exactMatchCounter.increment(0);
|
|
2371
|
-
|
|
3611
|
+
expect23(exactMatchCount).toBe(10);
|
|
2372
3612
|
const subsetMatchCounter = client.counter.getOrCreate([
|
|
2373
3613
|
"counter-match",
|
|
2374
3614
|
"test"
|
|
2375
3615
|
]);
|
|
2376
3616
|
const subsetMatchCount = await subsetMatchCounter.increment(0);
|
|
2377
|
-
|
|
3617
|
+
expect23(subsetMatchCount).toBe(0);
|
|
2378
3618
|
const singleKeyCounter = client.counter.getOrCreate([
|
|
2379
3619
|
"counter-match"
|
|
2380
3620
|
]);
|
|
2381
3621
|
const singleKeyCount = await singleKeyCounter.increment(0);
|
|
2382
|
-
|
|
3622
|
+
expect23(singleKeyCount).toBe(0);
|
|
2383
3623
|
});
|
|
2384
|
-
|
|
3624
|
+
test23("string key matches array with single string key", async (c) => {
|
|
2385
3625
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2386
3626
|
const stringKeyCounter = client.counter.getOrCreate("string-key-test");
|
|
2387
3627
|
await stringKeyCounter.increment(7);
|
|
@@ -2389,20 +3629,20 @@ function runManagerDriverTests(driverTestConfig) {
|
|
|
2389
3629
|
"string-key-test"
|
|
2390
3630
|
]);
|
|
2391
3631
|
const count = await arrayKeyCounter.increment(0);
|
|
2392
|
-
|
|
3632
|
+
expect23(count).toBe(7);
|
|
2393
3633
|
});
|
|
2394
|
-
|
|
3634
|
+
test23("undefined key matches empty array key and no key", async (c) => {
|
|
2395
3635
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2396
3636
|
const undefinedKeyCounter = client.counter.getOrCreate(void 0);
|
|
2397
3637
|
await undefinedKeyCounter.increment(12);
|
|
2398
3638
|
const emptyArrayKeyCounter = client.counter.getOrCreate([]);
|
|
2399
3639
|
const emptyArrayCount = await emptyArrayKeyCounter.increment(0);
|
|
2400
|
-
|
|
3640
|
+
expect23(emptyArrayCount).toBe(12);
|
|
2401
3641
|
const noKeyCounter = client.counter.getOrCreate();
|
|
2402
3642
|
const noKeyCount = await noKeyCounter.increment(0);
|
|
2403
|
-
|
|
3643
|
+
expect23(noKeyCount).toBe(12);
|
|
2404
3644
|
});
|
|
2405
|
-
|
|
3645
|
+
test23("no keys does not match actors with keys", async (c) => {
|
|
2406
3646
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2407
3647
|
const keyedCounter = client.counter.getOrCreate([
|
|
2408
3648
|
"counter-with-keys",
|
|
@@ -2411,9 +3651,9 @@ function runManagerDriverTests(driverTestConfig) {
|
|
|
2411
3651
|
await keyedCounter.increment(15);
|
|
2412
3652
|
const noKeysCounter = client.counter.getOrCreate();
|
|
2413
3653
|
const count = await noKeysCounter.increment(10);
|
|
2414
|
-
|
|
3654
|
+
expect23(count).toBe(10);
|
|
2415
3655
|
});
|
|
2416
|
-
|
|
3656
|
+
test23("actors with keys match actors with no keys", async (c) => {
|
|
2417
3657
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2418
3658
|
const noKeysCounter = client.counter.getOrCreate();
|
|
2419
3659
|
await noKeysCounter.increment(25);
|
|
@@ -2422,11 +3662,11 @@ function runManagerDriverTests(driverTestConfig) {
|
|
|
2422
3662
|
"prod"
|
|
2423
3663
|
]);
|
|
2424
3664
|
const keyedCount = await keyedCounter.increment(0);
|
|
2425
|
-
|
|
3665
|
+
expect23(keyedCount).toBe(0);
|
|
2426
3666
|
});
|
|
2427
3667
|
});
|
|
2428
|
-
|
|
2429
|
-
|
|
3668
|
+
describe24("Multiple Actor Instances", () => {
|
|
3669
|
+
test23("creates multiple actor instances of the same type", async (c) => {
|
|
2430
3670
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2431
3671
|
const instance1 = client.counter.getOrCreate(["multi-1"]);
|
|
2432
3672
|
const instance2 = client.counter.getOrCreate(["multi-2"]);
|
|
@@ -2437,35 +3677,35 @@ function runManagerDriverTests(driverTestConfig) {
|
|
|
2437
3677
|
const retrieved1 = client.counter.getOrCreate(["multi-1"]);
|
|
2438
3678
|
const retrieved2 = client.counter.getOrCreate(["multi-2"]);
|
|
2439
3679
|
const retrieved3 = client.counter.getOrCreate(["multi-3"]);
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
3680
|
+
expect23(await retrieved1.increment(0)).toBe(1);
|
|
3681
|
+
expect23(await retrieved2.increment(0)).toBe(2);
|
|
3682
|
+
expect23(await retrieved3.increment(0)).toBe(3);
|
|
2443
3683
|
});
|
|
2444
|
-
|
|
3684
|
+
test23("handles default instance with no explicit ID", async (c) => {
|
|
2445
3685
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2446
3686
|
const defaultCounter = client.counter.getOrCreate();
|
|
2447
3687
|
await defaultCounter.increment(5);
|
|
2448
3688
|
const sameDefaultCounter = client.counter.getOrCreate();
|
|
2449
3689
|
const count = await sameDefaultCounter.increment(0);
|
|
2450
|
-
|
|
3690
|
+
expect23(count).toBe(5);
|
|
2451
3691
|
});
|
|
2452
3692
|
});
|
|
2453
3693
|
});
|
|
2454
3694
|
}
|
|
2455
3695
|
|
|
2456
3696
|
// src/driver-test-suite/tests/raw-http.ts
|
|
2457
|
-
import { describe as
|
|
3697
|
+
import { describe as describe25, expect as expect24, test as test24 } from "vitest";
|
|
2458
3698
|
function runRawHttpTests(driverTestConfig) {
|
|
2459
|
-
|
|
2460
|
-
|
|
3699
|
+
describe25("raw http", () => {
|
|
3700
|
+
test24("should handle raw HTTP GET requests", async (c) => {
|
|
2461
3701
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2462
3702
|
const actor = client.rawHttpActor.getOrCreate(["test"]);
|
|
2463
3703
|
const helloResponse = await actor.fetch("api/hello");
|
|
2464
|
-
|
|
3704
|
+
expect24(helloResponse.ok).toBe(true);
|
|
2465
3705
|
const helloData = await helloResponse.json();
|
|
2466
|
-
|
|
3706
|
+
expect24(helloData).toEqual({ message: "Hello from actor!" });
|
|
2467
3707
|
});
|
|
2468
|
-
|
|
3708
|
+
test24("should handle raw HTTP POST requests with echo", async (c) => {
|
|
2469
3709
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2470
3710
|
const actor = client.rawHttpActor.getOrCreate(["test"]);
|
|
2471
3711
|
const testData = { test: "data", number: 123 };
|
|
@@ -2476,22 +3716,22 @@ function runRawHttpTests(driverTestConfig) {
|
|
|
2476
3716
|
},
|
|
2477
3717
|
body: JSON.stringify(testData)
|
|
2478
3718
|
});
|
|
2479
|
-
|
|
3719
|
+
expect24(echoResponse.ok).toBe(true);
|
|
2480
3720
|
const echoData = await echoResponse.json();
|
|
2481
|
-
|
|
3721
|
+
expect24(echoData).toEqual(testData);
|
|
2482
3722
|
});
|
|
2483
|
-
|
|
3723
|
+
test24("should track state across raw HTTP requests", async (c) => {
|
|
2484
3724
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2485
3725
|
const actor = client.rawHttpActor.getOrCreate(["state-test"]);
|
|
2486
3726
|
await actor.fetch("api/hello");
|
|
2487
3727
|
await actor.fetch("api/hello");
|
|
2488
3728
|
await actor.fetch("api/state");
|
|
2489
3729
|
const stateResponse = await actor.fetch("api/state");
|
|
2490
|
-
|
|
3730
|
+
expect24(stateResponse.ok).toBe(true);
|
|
2491
3731
|
const stateData = await stateResponse.json();
|
|
2492
|
-
|
|
3732
|
+
expect24(stateData.requestCount).toBe(4);
|
|
2493
3733
|
});
|
|
2494
|
-
|
|
3734
|
+
test24("should pass headers correctly", async (c) => {
|
|
2495
3735
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2496
3736
|
const actor = client.rawHttpActor.getOrCreate(["headers-test"]);
|
|
2497
3737
|
const customHeaders = {
|
|
@@ -2501,44 +3741,44 @@ function runRawHttpTests(driverTestConfig) {
|
|
|
2501
3741
|
const response = await actor.fetch("api/headers", {
|
|
2502
3742
|
headers: customHeaders
|
|
2503
3743
|
});
|
|
2504
|
-
|
|
3744
|
+
expect24(response.ok).toBe(true);
|
|
2505
3745
|
const headers = await response.json();
|
|
2506
|
-
|
|
2507
|
-
|
|
3746
|
+
expect24(headers["x-custom-header"]).toBe("test-value");
|
|
3747
|
+
expect24(headers["x-another-header"]).toBe("another-value");
|
|
2508
3748
|
});
|
|
2509
|
-
|
|
3749
|
+
test24("should return 404 for unhandled paths", async (c) => {
|
|
2510
3750
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2511
3751
|
const actor = client.rawHttpActor.getOrCreate(["404-test"]);
|
|
2512
3752
|
const response = await actor.fetch("api/nonexistent");
|
|
2513
|
-
|
|
2514
|
-
|
|
3753
|
+
expect24(response.ok).toBe(false);
|
|
3754
|
+
expect24(response.status).toBe(404);
|
|
2515
3755
|
});
|
|
2516
|
-
|
|
3756
|
+
test24("should return 404 when no onRequest handler defined", async (c) => {
|
|
2517
3757
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2518
3758
|
const actor = client.rawHttpNoHandlerActor.getOrCreate([
|
|
2519
3759
|
"no-handler"
|
|
2520
3760
|
]);
|
|
2521
3761
|
const response = await actor.fetch("api/anything");
|
|
2522
|
-
|
|
2523
|
-
|
|
3762
|
+
expect24(response.ok).toBe(false);
|
|
3763
|
+
expect24(response.status).toBe(404);
|
|
2524
3764
|
});
|
|
2525
|
-
|
|
3765
|
+
test24("should return 500 error when onRequest returns void", async (c) => {
|
|
2526
3766
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2527
3767
|
const actor = client.rawHttpVoidReturnActor.getOrCreate([
|
|
2528
3768
|
"void-return"
|
|
2529
3769
|
]);
|
|
2530
3770
|
const response = await actor.fetch("api/anything");
|
|
2531
|
-
|
|
2532
|
-
|
|
3771
|
+
expect24(response.ok).toBe(false);
|
|
3772
|
+
expect24(response.status).toBe(500);
|
|
2533
3773
|
try {
|
|
2534
3774
|
const errorData = await response.json();
|
|
2535
|
-
|
|
3775
|
+
expect24(errorData.message).toContain(
|
|
2536
3776
|
"onRequest handler must return a Response"
|
|
2537
3777
|
);
|
|
2538
3778
|
} catch {
|
|
2539
3779
|
}
|
|
2540
3780
|
});
|
|
2541
|
-
|
|
3781
|
+
test24("should handle different HTTP methods", async (c) => {
|
|
2542
3782
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2543
3783
|
const actor = client.rawHttpActor.getOrCreate(["methods-test"]);
|
|
2544
3784
|
const methods = ["GET", "POST", "PUT", "DELETE", "PATCH"];
|
|
@@ -2548,17 +3788,17 @@ function runRawHttpTests(driverTestConfig) {
|
|
|
2548
3788
|
body: ["POST", "PUT", "PATCH"].includes(method) ? JSON.stringify({ method }) : void 0
|
|
2549
3789
|
});
|
|
2550
3790
|
if (method === "POST") {
|
|
2551
|
-
|
|
3791
|
+
expect24(response.ok).toBe(true);
|
|
2552
3792
|
const data = await response.json();
|
|
2553
|
-
|
|
3793
|
+
expect24(data).toEqual({ method });
|
|
2554
3794
|
} else if (method === "GET") {
|
|
2555
|
-
|
|
3795
|
+
expect24(response.status).toBe(404);
|
|
2556
3796
|
} else {
|
|
2557
|
-
|
|
3797
|
+
expect24(response.status).toBe(404);
|
|
2558
3798
|
}
|
|
2559
3799
|
}
|
|
2560
3800
|
});
|
|
2561
|
-
|
|
3801
|
+
test24("should handle binary data", async (c) => {
|
|
2562
3802
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2563
3803
|
const actor = client.rawHttpActor.getOrCreate(["binary-test"]);
|
|
2564
3804
|
const binaryData = new Uint8Array([1, 2, 3, 4, 5]);
|
|
@@ -2569,82 +3809,82 @@ function runRawHttpTests(driverTestConfig) {
|
|
|
2569
3809
|
},
|
|
2570
3810
|
body: binaryData
|
|
2571
3811
|
});
|
|
2572
|
-
|
|
3812
|
+
expect24(response.ok).toBe(true);
|
|
2573
3813
|
const responseBuffer = await response.arrayBuffer();
|
|
2574
3814
|
const responseArray = new Uint8Array(responseBuffer);
|
|
2575
|
-
|
|
3815
|
+
expect24(Array.from(responseArray)).toEqual([1, 2, 3, 4, 5]);
|
|
2576
3816
|
});
|
|
2577
|
-
|
|
3817
|
+
test24("should work with Hono router using createVars", async (c) => {
|
|
2578
3818
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2579
3819
|
const actor = client.rawHttpHonoActor.getOrCreate(["hono-test"]);
|
|
2580
3820
|
const rootResponse = await actor.fetch("/");
|
|
2581
|
-
|
|
3821
|
+
expect24(rootResponse.ok).toBe(true);
|
|
2582
3822
|
const rootData = await rootResponse.json();
|
|
2583
|
-
|
|
3823
|
+
expect24(rootData).toEqual({ message: "Welcome to Hono actor!" });
|
|
2584
3824
|
const usersResponse = await actor.fetch("/users");
|
|
2585
|
-
|
|
3825
|
+
expect24(usersResponse.ok).toBe(true);
|
|
2586
3826
|
const users = await usersResponse.json();
|
|
2587
|
-
|
|
3827
|
+
expect24(users).toEqual([
|
|
2588
3828
|
{ id: 1, name: "Alice" },
|
|
2589
3829
|
{ id: 2, name: "Bob" }
|
|
2590
3830
|
]);
|
|
2591
3831
|
const userResponse = await actor.fetch("/users/1");
|
|
2592
|
-
|
|
3832
|
+
expect24(userResponse.ok).toBe(true);
|
|
2593
3833
|
const user = await userResponse.json();
|
|
2594
|
-
|
|
3834
|
+
expect24(user).toEqual({ id: 1, name: "Alice" });
|
|
2595
3835
|
const newUser = { name: "Charlie" };
|
|
2596
3836
|
const createResponse = await actor.fetch("/users", {
|
|
2597
3837
|
method: "POST",
|
|
2598
3838
|
headers: { "Content-Type": "application/json" },
|
|
2599
3839
|
body: JSON.stringify(newUser)
|
|
2600
3840
|
});
|
|
2601
|
-
|
|
2602
|
-
|
|
3841
|
+
expect24(createResponse.ok).toBe(true);
|
|
3842
|
+
expect24(createResponse.status).toBe(201);
|
|
2603
3843
|
const createdUser = await createResponse.json();
|
|
2604
|
-
|
|
3844
|
+
expect24(createdUser).toEqual({ id: 3, name: "Charlie" });
|
|
2605
3845
|
const updateData = { name: "Alice Updated" };
|
|
2606
3846
|
const updateResponse = await actor.fetch("/users/1", {
|
|
2607
3847
|
method: "PUT",
|
|
2608
3848
|
headers: { "Content-Type": "application/json" },
|
|
2609
3849
|
body: JSON.stringify(updateData)
|
|
2610
3850
|
});
|
|
2611
|
-
|
|
3851
|
+
expect24(updateResponse.ok).toBe(true);
|
|
2612
3852
|
const updatedUser = await updateResponse.json();
|
|
2613
|
-
|
|
3853
|
+
expect24(updatedUser).toEqual({ id: 1, name: "Alice Updated" });
|
|
2614
3854
|
const deleteResponse = await actor.fetch("/users/2", {
|
|
2615
3855
|
method: "DELETE"
|
|
2616
3856
|
});
|
|
2617
|
-
|
|
3857
|
+
expect24(deleteResponse.ok).toBe(true);
|
|
2618
3858
|
const deleteResult = await deleteResponse.json();
|
|
2619
|
-
|
|
3859
|
+
expect24(deleteResult).toEqual({ message: "User 2 deleted" });
|
|
2620
3860
|
const notFoundResponse = await actor.fetch("/api/unknown");
|
|
2621
|
-
|
|
2622
|
-
|
|
3861
|
+
expect24(notFoundResponse.ok).toBe(false);
|
|
3862
|
+
expect24(notFoundResponse.status).toBe(404);
|
|
2623
3863
|
});
|
|
2624
|
-
|
|
3864
|
+
test24("should handle paths with and without leading slashes", async (c) => {
|
|
2625
3865
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2626
3866
|
const actor = client.rawHttpActor.getOrCreate(["path-test"]);
|
|
2627
3867
|
const responseWithoutSlash = await actor.fetch("api/hello");
|
|
2628
|
-
|
|
3868
|
+
expect24(responseWithoutSlash.ok).toBe(true);
|
|
2629
3869
|
const dataWithoutSlash = await responseWithoutSlash.json();
|
|
2630
|
-
|
|
3870
|
+
expect24(dataWithoutSlash).toEqual({ message: "Hello from actor!" });
|
|
2631
3871
|
const responseWithSlash = await actor.fetch("/api/hello");
|
|
2632
|
-
|
|
3872
|
+
expect24(responseWithSlash.ok).toBe(true);
|
|
2633
3873
|
const dataWithSlash = await responseWithSlash.json();
|
|
2634
|
-
|
|
3874
|
+
expect24(dataWithSlash).toEqual({ message: "Hello from actor!" });
|
|
2635
3875
|
});
|
|
2636
|
-
|
|
3876
|
+
test24("should not create double slashes in request URLs", async (c) => {
|
|
2637
3877
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2638
3878
|
const actor = client.rawHttpHonoActor.getOrCreate(["url-test"]);
|
|
2639
3879
|
const response = await actor.fetch("/users");
|
|
2640
|
-
|
|
3880
|
+
expect24(response.ok).toBe(true);
|
|
2641
3881
|
const data = await response.json();
|
|
2642
|
-
|
|
3882
|
+
expect24(data).toEqual([
|
|
2643
3883
|
{ id: 1, name: "Alice" },
|
|
2644
3884
|
{ id: 2, name: "Bob" }
|
|
2645
3885
|
]);
|
|
2646
3886
|
});
|
|
2647
|
-
|
|
3887
|
+
test24("should handle forwarded requests correctly without double slashes", async (c) => {
|
|
2648
3888
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2649
3889
|
const actor = client.rawHttpHonoActor.getOrCreate(["forward-test"]);
|
|
2650
3890
|
const truncatedPath = "/users";
|
|
@@ -2656,14 +3896,14 @@ function runRawHttpTests(driverTestConfig) {
|
|
|
2656
3896
|
truncatedPath,
|
|
2657
3897
|
newRequest
|
|
2658
3898
|
);
|
|
2659
|
-
|
|
3899
|
+
expect24(response.ok).toBe(true);
|
|
2660
3900
|
const users = await response.json();
|
|
2661
|
-
|
|
3901
|
+
expect24(users).toEqual([
|
|
2662
3902
|
{ id: 1, name: "Alice" },
|
|
2663
3903
|
{ id: 2, name: "Bob" }
|
|
2664
3904
|
]);
|
|
2665
3905
|
});
|
|
2666
|
-
|
|
3906
|
+
test24("example fix: should properly forward requests using just Request object", async (c) => {
|
|
2667
3907
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2668
3908
|
const actor = client.rawHttpHonoActor.getOrCreate(["forward-fix"]);
|
|
2669
3909
|
const truncatedPath = "/users/1";
|
|
@@ -2672,11 +3912,11 @@ function runRawHttpTests(driverTestConfig) {
|
|
|
2672
3912
|
method: "GET"
|
|
2673
3913
|
});
|
|
2674
3914
|
const response = await actor.fetch(newRequest);
|
|
2675
|
-
|
|
3915
|
+
expect24(response.ok).toBe(true);
|
|
2676
3916
|
const user = await response.json();
|
|
2677
|
-
|
|
3917
|
+
expect24(user).toEqual({ id: 1, name: "Alice" });
|
|
2678
3918
|
});
|
|
2679
|
-
|
|
3919
|
+
test24("should support standard fetch API with URL and Request objects", async (c) => {
|
|
2680
3920
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2681
3921
|
const actor = client.rawHttpActor.getOrCreate(["fetch-api-test"]);
|
|
2682
3922
|
const url = new URL("/api/echo", "http://example.com");
|
|
@@ -2685,18 +3925,18 @@ function runRawHttpTests(driverTestConfig) {
|
|
|
2685
3925
|
headers: { "Content-Type": "application/json" },
|
|
2686
3926
|
body: JSON.stringify({ from: "URL object" })
|
|
2687
3927
|
});
|
|
2688
|
-
|
|
3928
|
+
expect24(urlResponse.ok).toBe(true);
|
|
2689
3929
|
const urlData = await urlResponse.json();
|
|
2690
|
-
|
|
3930
|
+
expect24(urlData).toEqual({ from: "URL object" });
|
|
2691
3931
|
const request = new Request("http://example.com/api/echo", {
|
|
2692
3932
|
method: "POST",
|
|
2693
3933
|
headers: { "Content-Type": "application/json" },
|
|
2694
3934
|
body: JSON.stringify({ from: "Request object" })
|
|
2695
3935
|
});
|
|
2696
3936
|
const requestResponse = await actor.fetch(request);
|
|
2697
|
-
|
|
3937
|
+
expect24(requestResponse.ok).toBe(true);
|
|
2698
3938
|
const requestData = await requestResponse.json();
|
|
2699
|
-
|
|
3939
|
+
expect24(requestData).toEqual({ from: "Request object" });
|
|
2700
3940
|
const request2 = new Request("http://example.com/api/headers", {
|
|
2701
3941
|
method: "GET",
|
|
2702
3942
|
headers: { "X-Original": "request-header" }
|
|
@@ -2704,19 +3944,19 @@ function runRawHttpTests(driverTestConfig) {
|
|
|
2704
3944
|
const overrideResponse = await actor.fetch(request2, {
|
|
2705
3945
|
headers: { "X-Override": "init-header" }
|
|
2706
3946
|
});
|
|
2707
|
-
|
|
3947
|
+
expect24(overrideResponse.ok).toBe(true);
|
|
2708
3948
|
const headers = await overrideResponse.json();
|
|
2709
|
-
|
|
2710
|
-
|
|
3949
|
+
expect24(headers["x-override"]).toBe("init-header");
|
|
3950
|
+
expect24(headers["x-original"]).toBe("request-header");
|
|
2711
3951
|
});
|
|
2712
3952
|
});
|
|
2713
3953
|
}
|
|
2714
3954
|
|
|
2715
3955
|
// src/driver-test-suite/tests/raw-http-request-properties.ts
|
|
2716
|
-
import { describe as
|
|
3956
|
+
import { describe as describe26, expect as expect25, test as test25 } from "vitest";
|
|
2717
3957
|
function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
2718
|
-
|
|
2719
|
-
|
|
3958
|
+
describe26("raw http request properties", () => {
|
|
3959
|
+
test25("should pass all Request properties correctly to onRequest", async (c) => {
|
|
2720
3960
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2721
3961
|
const actor = client.rawHttpRequestPropertiesActor.getOrCreate([
|
|
2722
3962
|
"test"
|
|
@@ -2730,22 +3970,22 @@ function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
|
2730
3970
|
},
|
|
2731
3971
|
body: JSON.stringify({ test: "data" })
|
|
2732
3972
|
});
|
|
2733
|
-
|
|
3973
|
+
expect25(response.ok).toBe(true);
|
|
2734
3974
|
const data = await response.json();
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
3975
|
+
expect25(data.url).toContain("/test/path?foo=bar&baz=qux");
|
|
3976
|
+
expect25(data.pathname).toBe("/test/path");
|
|
3977
|
+
expect25(data.search).toBe("?foo=bar&baz=qux");
|
|
3978
|
+
expect25(data.searchParams).toEqual({
|
|
2739
3979
|
foo: "bar",
|
|
2740
3980
|
baz: "qux"
|
|
2741
3981
|
});
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
3982
|
+
expect25(data.method).toBe("POST");
|
|
3983
|
+
expect25(data.headers["content-type"]).toBe("application/json");
|
|
3984
|
+
expect25(data.headers["x-custom-header"]).toBe("custom-value");
|
|
3985
|
+
expect25(data.headers["authorization"]).toBe("Bearer test-token");
|
|
3986
|
+
expect25(data.body).toEqual({ test: "data" });
|
|
2747
3987
|
});
|
|
2748
|
-
|
|
3988
|
+
test25("should handle GET requests with no body", async (c) => {
|
|
2749
3989
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2750
3990
|
const actor = client.rawHttpRequestPropertiesActor.getOrCreate([
|
|
2751
3991
|
"test"
|
|
@@ -2753,12 +3993,12 @@ function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
|
2753
3993
|
const response = await actor.fetch("test/get", {
|
|
2754
3994
|
method: "GET"
|
|
2755
3995
|
});
|
|
2756
|
-
|
|
3996
|
+
expect25(response.ok).toBe(true);
|
|
2757
3997
|
const data = await response.json();
|
|
2758
|
-
|
|
2759
|
-
|
|
3998
|
+
expect25(data.method).toBe("GET");
|
|
3999
|
+
expect25(data.body).toBeNull();
|
|
2760
4000
|
});
|
|
2761
|
-
|
|
4001
|
+
test25("should handle different content types", async (c) => {
|
|
2762
4002
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2763
4003
|
const actor = client.rawHttpRequestPropertiesActor.getOrCreate([
|
|
2764
4004
|
"test"
|
|
@@ -2773,12 +4013,12 @@ function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
|
2773
4013
|
},
|
|
2774
4014
|
body: formData.toString()
|
|
2775
4015
|
});
|
|
2776
|
-
|
|
4016
|
+
expect25(formResponse.ok).toBe(true);
|
|
2777
4017
|
const formResult = await formResponse.json();
|
|
2778
|
-
|
|
4018
|
+
expect25(formResult.headers["content-type"]).toBe(
|
|
2779
4019
|
"application/x-www-form-urlencoded"
|
|
2780
4020
|
);
|
|
2781
|
-
|
|
4021
|
+
expect25(formResult.bodyText).toBe("field1=value1&field2=value2");
|
|
2782
4022
|
const textResponse = await actor.fetch("test/text", {
|
|
2783
4023
|
method: "POST",
|
|
2784
4024
|
headers: {
|
|
@@ -2786,12 +4026,12 @@ function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
|
2786
4026
|
},
|
|
2787
4027
|
body: "Hello, World!"
|
|
2788
4028
|
});
|
|
2789
|
-
|
|
4029
|
+
expect25(textResponse.ok).toBe(true);
|
|
2790
4030
|
const textResult = await textResponse.json();
|
|
2791
|
-
|
|
2792
|
-
|
|
4031
|
+
expect25(textResult.headers["content-type"]).toBe("text/plain");
|
|
4032
|
+
expect25(textResult.bodyText).toBe("Hello, World!");
|
|
2793
4033
|
});
|
|
2794
|
-
|
|
4034
|
+
test25("should preserve all header casing and values", async (c) => {
|
|
2795
4035
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2796
4036
|
const actor = client.rawHttpRequestPropertiesActor.getOrCreate([
|
|
2797
4037
|
"test"
|
|
@@ -2805,38 +4045,38 @@ function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
|
2805
4045
|
"X-Request-ID": "12345"
|
|
2806
4046
|
}
|
|
2807
4047
|
});
|
|
2808
|
-
|
|
4048
|
+
expect25(response.ok).toBe(true);
|
|
2809
4049
|
const data = await response.json();
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
4050
|
+
expect25(data.headers["accept"]).toBe("application/json");
|
|
4051
|
+
expect25(data.headers["accept-language"]).toBe("en-US,en;q=0.9");
|
|
4052
|
+
expect25(data.headers["cache-control"]).toBe("no-cache");
|
|
4053
|
+
expect25(data.headers["user-agent"]).toBeTruthy();
|
|
4054
|
+
expect25(data.headers["x-request-id"]).toBe("12345");
|
|
2815
4055
|
});
|
|
2816
|
-
|
|
4056
|
+
test25("should handle empty and special URL paths", async (c) => {
|
|
2817
4057
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2818
4058
|
const actor = client.rawHttpRequestPropertiesActor.getOrCreate([
|
|
2819
4059
|
"test"
|
|
2820
4060
|
]);
|
|
2821
4061
|
const rootResponse = await actor.fetch("");
|
|
2822
|
-
|
|
4062
|
+
expect25(rootResponse.ok).toBe(true);
|
|
2823
4063
|
const rootData = await rootResponse.json();
|
|
2824
|
-
|
|
4064
|
+
expect25(rootData.pathname).toBe("/");
|
|
2825
4065
|
const specialResponse = await actor.fetch(
|
|
2826
4066
|
"test/path%20with%20spaces/and%2Fslashes"
|
|
2827
4067
|
);
|
|
2828
|
-
|
|
4068
|
+
expect25(specialResponse.ok).toBe(true);
|
|
2829
4069
|
const specialData = await specialResponse.json();
|
|
2830
|
-
|
|
4070
|
+
expect25(specialData.pathname).toMatch(
|
|
2831
4071
|
/path.*with.*spaces.*and.*slashes/
|
|
2832
4072
|
);
|
|
2833
4073
|
const fragmentResponse = await actor.fetch("test/path#fragment");
|
|
2834
|
-
|
|
4074
|
+
expect25(fragmentResponse.ok).toBe(true);
|
|
2835
4075
|
const fragmentData = await fragmentResponse.json();
|
|
2836
|
-
|
|
2837
|
-
|
|
4076
|
+
expect25(fragmentData.pathname).toBe("/test/path");
|
|
4077
|
+
expect25(fragmentData.hash).toBe("");
|
|
2838
4078
|
});
|
|
2839
|
-
|
|
4079
|
+
test25("should handle request properties for all HTTP methods", async (c) => {
|
|
2840
4080
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2841
4081
|
const actor = client.rawHttpRequestPropertiesActor.getOrCreate([
|
|
2842
4082
|
"test"
|
|
@@ -2860,21 +4100,21 @@ function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
|
2860
4100
|
}
|
|
2861
4101
|
);
|
|
2862
4102
|
if (method === "HEAD") {
|
|
2863
|
-
|
|
4103
|
+
expect25(response.status).toBe(200);
|
|
2864
4104
|
const text = await response.text();
|
|
2865
|
-
|
|
4105
|
+
expect25(text).toBe("");
|
|
2866
4106
|
} else if (method === "OPTIONS") {
|
|
2867
|
-
|
|
4107
|
+
expect25(response.status).toBe(204);
|
|
2868
4108
|
const text = await response.text();
|
|
2869
|
-
|
|
4109
|
+
expect25(text).toBe("");
|
|
2870
4110
|
} else {
|
|
2871
|
-
|
|
4111
|
+
expect25(response.ok).toBe(true);
|
|
2872
4112
|
const data = await response.json();
|
|
2873
|
-
|
|
4113
|
+
expect25(data.method).toBe(method);
|
|
2874
4114
|
}
|
|
2875
4115
|
}
|
|
2876
4116
|
});
|
|
2877
|
-
|
|
4117
|
+
test25("should handle complex query parameters", async (c) => {
|
|
2878
4118
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2879
4119
|
const actor = client.rawHttpRequestPropertiesActor.getOrCreate([
|
|
2880
4120
|
"test"
|
|
@@ -2882,13 +4122,13 @@ function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
|
2882
4122
|
const response = await actor.fetch(
|
|
2883
4123
|
"test?key=value1&key=value2&array[]=1&array[]=2&nested[prop]=val"
|
|
2884
4124
|
);
|
|
2885
|
-
|
|
4125
|
+
expect25(response.ok).toBe(true);
|
|
2886
4126
|
const data = await response.json();
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
4127
|
+
expect25(data.searchParams.key).toBe("value2");
|
|
4128
|
+
expect25(data.searchParams["array[]"]).toBe("2");
|
|
4129
|
+
expect25(data.searchParams["nested[prop]"]).toBe("val");
|
|
2890
4130
|
});
|
|
2891
|
-
|
|
4131
|
+
test25("should handle multipart form data", async (c) => {
|
|
2892
4132
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2893
4133
|
const actor = client.rawHttpRequestPropertiesActor.getOrCreate([
|
|
2894
4134
|
"test"
|
|
@@ -2912,27 +4152,27 @@ function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
|
2912
4152
|
},
|
|
2913
4153
|
body
|
|
2914
4154
|
});
|
|
2915
|
-
|
|
4155
|
+
expect25(response.ok).toBe(true);
|
|
2916
4156
|
const data = await response.json();
|
|
2917
|
-
|
|
4157
|
+
expect25(data.headers["content-type"]).toContain(
|
|
2918
4158
|
"multipart/form-data"
|
|
2919
4159
|
);
|
|
2920
|
-
|
|
2921
|
-
|
|
4160
|
+
expect25(data.bodyText).toContain("field1");
|
|
4161
|
+
expect25(data.bodyText).toContain("value1");
|
|
2922
4162
|
});
|
|
2923
|
-
|
|
4163
|
+
test25("should handle very long URLs", async (c) => {
|
|
2924
4164
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2925
4165
|
const actor = client.rawHttpRequestPropertiesActor.getOrCreate([
|
|
2926
4166
|
"test"
|
|
2927
4167
|
]);
|
|
2928
4168
|
const longValue = "x".repeat(1e3);
|
|
2929
4169
|
const response = await actor.fetch(`test/long?param=${longValue}`);
|
|
2930
|
-
|
|
4170
|
+
expect25(response.ok).toBe(true);
|
|
2931
4171
|
const data = await response.json();
|
|
2932
|
-
|
|
2933
|
-
|
|
4172
|
+
expect25(data.searchParams.param).toBe(longValue);
|
|
4173
|
+
expect25(data.search.length).toBeGreaterThan(1e3);
|
|
2934
4174
|
});
|
|
2935
|
-
|
|
4175
|
+
test25.skip("should handle large request bodies", async (c) => {
|
|
2936
4176
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2937
4177
|
const actor = client.rawHttpRequestPropertiesActor.getOrCreate([
|
|
2938
4178
|
"test"
|
|
@@ -2949,11 +4189,11 @@ function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
|
2949
4189
|
},
|
|
2950
4190
|
body: JSON.stringify(largeArray)
|
|
2951
4191
|
});
|
|
2952
|
-
|
|
4192
|
+
expect25(response.ok).toBe(true);
|
|
2953
4193
|
const data = await response.json();
|
|
2954
|
-
|
|
4194
|
+
expect25(data.body).toHaveLength(1e4);
|
|
2955
4195
|
});
|
|
2956
|
-
|
|
4196
|
+
test25("should handle missing content-type header", async (c) => {
|
|
2957
4197
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2958
4198
|
const actor = client.rawHttpRequestPropertiesActor.getOrCreate([
|
|
2959
4199
|
"test"
|
|
@@ -2962,11 +4202,11 @@ function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
|
2962
4202
|
method: "POST",
|
|
2963
4203
|
body: "plain text without content-type"
|
|
2964
4204
|
});
|
|
2965
|
-
|
|
4205
|
+
expect25(response.ok).toBe(true);
|
|
2966
4206
|
const data = await response.json();
|
|
2967
|
-
|
|
4207
|
+
expect25(data.bodyText).toBe("plain text without content-type");
|
|
2968
4208
|
});
|
|
2969
|
-
|
|
4209
|
+
test25("should handle empty request body", async (c) => {
|
|
2970
4210
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2971
4211
|
const actor = client.rawHttpRequestPropertiesActor.getOrCreate([
|
|
2972
4212
|
"test"
|
|
@@ -2978,9 +4218,9 @@ function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
|
2978
4218
|
},
|
|
2979
4219
|
body: ""
|
|
2980
4220
|
});
|
|
2981
|
-
|
|
4221
|
+
expect25(response.ok).toBe(true);
|
|
2982
4222
|
});
|
|
2983
|
-
|
|
4223
|
+
test25("should handle custom HTTP methods", async (c) => {
|
|
2984
4224
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2985
4225
|
const actor = client.rawHttpRequestPropertiesActor.getOrCreate([
|
|
2986
4226
|
"test"
|
|
@@ -2991,12 +4231,12 @@ function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
|
2991
4231
|
});
|
|
2992
4232
|
if (response.ok) {
|
|
2993
4233
|
const data = await response.json();
|
|
2994
|
-
|
|
4234
|
+
expect25(data.method).toBe("CUSTOM");
|
|
2995
4235
|
}
|
|
2996
4236
|
} catch (error) {
|
|
2997
4237
|
}
|
|
2998
4238
|
});
|
|
2999
|
-
|
|
4239
|
+
test25("should handle cookies in headers", async (c) => {
|
|
3000
4240
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3001
4241
|
const actor = client.rawHttpRequestPropertiesActor.getOrCreate([
|
|
3002
4242
|
"test"
|
|
@@ -3006,13 +4246,13 @@ function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
|
3006
4246
|
Cookie: "session=abc123; user=test; preferences=dark_mode"
|
|
3007
4247
|
}
|
|
3008
4248
|
});
|
|
3009
|
-
|
|
4249
|
+
expect25(response.ok).toBe(true);
|
|
3010
4250
|
const data = await response.json();
|
|
3011
|
-
|
|
4251
|
+
expect25(data.headers.cookie).toBe(
|
|
3012
4252
|
"session=abc123; user=test; preferences=dark_mode"
|
|
3013
4253
|
);
|
|
3014
4254
|
});
|
|
3015
|
-
|
|
4255
|
+
test25("should handle URL encoding properly", async (c) => {
|
|
3016
4256
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3017
4257
|
const actor = client.rawHttpRequestPropertiesActor.getOrCreate([
|
|
3018
4258
|
"test"
|
|
@@ -3020,13 +4260,13 @@ function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
|
3020
4260
|
const response = await actor.fetch(
|
|
3021
4261
|
"test/encoded?special=%20%21%40%23%24%25%5E%26&unicode=%E2%9C%93&email=test%40example.com"
|
|
3022
4262
|
);
|
|
3023
|
-
|
|
4263
|
+
expect25(response.ok).toBe(true);
|
|
3024
4264
|
const data = await response.json();
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
4265
|
+
expect25(data.searchParams.special).toBe(" !@#$%^&");
|
|
4266
|
+
expect25(data.searchParams.unicode).toBe("\u2713");
|
|
4267
|
+
expect25(data.searchParams.email).toBe("test@example.com");
|
|
3028
4268
|
});
|
|
3029
|
-
|
|
4269
|
+
test25("should handle concurrent requests maintaining separate contexts", async (c) => {
|
|
3030
4270
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3031
4271
|
const actor = client.rawHttpRequestPropertiesActor.getOrCreate([
|
|
3032
4272
|
"test"
|
|
@@ -3050,27 +4290,27 @@ function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
|
3050
4290
|
const results = await Promise.all(
|
|
3051
4291
|
responses.map((r) => r.json())
|
|
3052
4292
|
);
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
4293
|
+
expect25(results[0].searchParams.id).toBe("1");
|
|
4294
|
+
expect25(results[0].method).toBe("POST");
|
|
4295
|
+
expect25(results[0].body).toEqual({ request: 1 });
|
|
4296
|
+
expect25(results[1].searchParams.id).toBe("2");
|
|
4297
|
+
expect25(results[1].method).toBe("PUT");
|
|
4298
|
+
expect25(results[1].body).toEqual({ request: 2 });
|
|
4299
|
+
expect25(results[2].searchParams.id).toBe("3");
|
|
4300
|
+
expect25(results[2].method).toBe("DELETE");
|
|
4301
|
+
expect25(results[2].body).toBeNull();
|
|
3062
4302
|
});
|
|
3063
4303
|
});
|
|
3064
4304
|
}
|
|
3065
4305
|
|
|
3066
4306
|
// src/driver-test-suite/tests/raw-websocket.ts
|
|
3067
|
-
import { describe as
|
|
4307
|
+
import { describe as describe27, expect as expect26, test as test26 } from "vitest";
|
|
3068
4308
|
function runRawWebSocketTests(driverTestConfig) {
|
|
3069
|
-
|
|
3070
|
-
|
|
4309
|
+
describe27("raw websocket", () => {
|
|
4310
|
+
test26("should establish raw WebSocket connection", async (c) => {
|
|
3071
4311
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3072
4312
|
const actor = client.rawWebSocketActor.getOrCreate(["basic"]);
|
|
3073
|
-
const ws = await actor.
|
|
4313
|
+
const ws = await actor.webSocket();
|
|
3074
4314
|
await new Promise((resolve) => {
|
|
3075
4315
|
if (ws.readyState === WebSocket.OPEN) {
|
|
3076
4316
|
resolve();
|
|
@@ -3094,14 +4334,14 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
3094
4334
|
);
|
|
3095
4335
|
ws.addEventListener("close", reject);
|
|
3096
4336
|
});
|
|
3097
|
-
|
|
3098
|
-
|
|
4337
|
+
expect26(welcomeMessage.type).toBe("welcome");
|
|
4338
|
+
expect26(welcomeMessage.connectionCount).toBe(1);
|
|
3099
4339
|
ws.close();
|
|
3100
4340
|
});
|
|
3101
|
-
|
|
4341
|
+
test26("should echo messages", async (c) => {
|
|
3102
4342
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3103
4343
|
const actor = client.rawWebSocketActor.getOrCreate(["echo"]);
|
|
3104
|
-
const ws = await actor.
|
|
4344
|
+
const ws = await actor.webSocket();
|
|
3105
4345
|
if (ws.readyState !== WebSocket.OPEN) {
|
|
3106
4346
|
await new Promise((resolve, reject) => {
|
|
3107
4347
|
ws.addEventListener("open", () => resolve(), {
|
|
@@ -3126,13 +4366,13 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
3126
4366
|
);
|
|
3127
4367
|
ws.addEventListener("close", reject);
|
|
3128
4368
|
});
|
|
3129
|
-
|
|
4369
|
+
expect26(echoMessage).toEqual(testMessage);
|
|
3130
4370
|
ws.close();
|
|
3131
4371
|
});
|
|
3132
|
-
|
|
4372
|
+
test26("should handle ping/pong protocol", async (c) => {
|
|
3133
4373
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3134
4374
|
const actor = client.rawWebSocketActor.getOrCreate(["ping"]);
|
|
3135
|
-
const ws = await actor.
|
|
4375
|
+
const ws = await actor.webSocket();
|
|
3136
4376
|
if (ws.readyState !== WebSocket.OPEN) {
|
|
3137
4377
|
await new Promise((resolve, reject) => {
|
|
3138
4378
|
ws.addEventListener("open", () => resolve(), {
|
|
@@ -3155,14 +4395,14 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
3155
4395
|
});
|
|
3156
4396
|
ws.addEventListener("close", reject);
|
|
3157
4397
|
});
|
|
3158
|
-
|
|
3159
|
-
|
|
4398
|
+
expect26(pongMessage.type).toBe("pong");
|
|
4399
|
+
expect26(pongMessage.timestamp).toBeDefined();
|
|
3160
4400
|
ws.close();
|
|
3161
4401
|
});
|
|
3162
|
-
|
|
4402
|
+
test26("should track stats across connections", async (c) => {
|
|
3163
4403
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3164
4404
|
const actor1 = client.rawWebSocketActor.getOrCreate(["stats"]);
|
|
3165
|
-
const ws1 = await actor1.
|
|
4405
|
+
const ws1 = await actor1.webSocket();
|
|
3166
4406
|
const ws1MessagePromise = new Promise((resolve, reject) => {
|
|
3167
4407
|
ws1.addEventListener("message", () => resolve(), {
|
|
3168
4408
|
once: true
|
|
@@ -3171,7 +4411,7 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
3171
4411
|
});
|
|
3172
4412
|
await ws1MessagePromise;
|
|
3173
4413
|
const actor2 = client.rawWebSocketActor.get(["stats"]);
|
|
3174
|
-
const ws2 = await actor2.
|
|
4414
|
+
const ws2 = await actor2.webSocket();
|
|
3175
4415
|
const ws2MessagePromise = new Promise((resolve, reject) => {
|
|
3176
4416
|
ws2.addEventListener("message", () => resolve(), {
|
|
3177
4417
|
once: true
|
|
@@ -3203,20 +4443,20 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
3203
4443
|
});
|
|
3204
4444
|
ws1.send(JSON.stringify({ type: "getStats" }));
|
|
3205
4445
|
const stats = await statsPromise;
|
|
3206
|
-
|
|
3207
|
-
|
|
4446
|
+
expect26(stats.connectionCount).toBe(2);
|
|
4447
|
+
expect26(stats.messageCount).toBe(4);
|
|
3208
4448
|
const actionStats = await actor1.getStats();
|
|
3209
|
-
|
|
3210
|
-
|
|
4449
|
+
expect26(actionStats.connectionCount).toBe(2);
|
|
4450
|
+
expect26(actionStats.messageCount).toBe(4);
|
|
3211
4451
|
ws1.close();
|
|
3212
4452
|
ws2.close();
|
|
3213
4453
|
});
|
|
3214
|
-
|
|
4454
|
+
test26("should handle binary data", async (c) => {
|
|
3215
4455
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3216
4456
|
const actor = client.rawWebSocketBinaryActor.getOrCreate([
|
|
3217
4457
|
"binary"
|
|
3218
4458
|
]);
|
|
3219
|
-
const ws = await actor.
|
|
4459
|
+
const ws = await actor.webSocket();
|
|
3220
4460
|
if (ws.readyState !== WebSocket.OPEN) {
|
|
3221
4461
|
await new Promise((resolve, reject) => {
|
|
3222
4462
|
ws.addEventListener("open", () => resolve(), {
|
|
@@ -3244,7 +4484,7 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
3244
4484
|
const smallData = new Uint8Array([1, 2, 3, 4, 5]);
|
|
3245
4485
|
ws.send(smallData);
|
|
3246
4486
|
const smallReversed = await receiveBinaryMessage();
|
|
3247
|
-
|
|
4487
|
+
expect26(Array.from(smallReversed)).toEqual([5, 4, 3, 2, 1]);
|
|
3248
4488
|
const largeData = new Uint8Array(1024);
|
|
3249
4489
|
for (let i = 0; i < largeData.length; i++) {
|
|
3250
4490
|
largeData[i] = i % 256;
|
|
@@ -3252,16 +4492,16 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
3252
4492
|
ws.send(largeData);
|
|
3253
4493
|
const largeReversed = await receiveBinaryMessage();
|
|
3254
4494
|
for (let i = 0; i < largeData.length; i++) {
|
|
3255
|
-
|
|
4495
|
+
expect26(largeReversed[i]).toBe(
|
|
3256
4496
|
largeData[largeData.length - 1 - i]
|
|
3257
4497
|
);
|
|
3258
4498
|
}
|
|
3259
4499
|
ws.close();
|
|
3260
4500
|
});
|
|
3261
|
-
|
|
4501
|
+
test26("should work with custom paths", async (c) => {
|
|
3262
4502
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3263
4503
|
const actor = client.rawWebSocketActor.getOrCreate(["paths"]);
|
|
3264
|
-
const ws = await actor.
|
|
4504
|
+
const ws = await actor.webSocket("custom/path");
|
|
3265
4505
|
await new Promise((resolve, reject) => {
|
|
3266
4506
|
ws.addEventListener("open", () => {
|
|
3267
4507
|
resolve();
|
|
@@ -3278,13 +4518,13 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
3278
4518
|
{ once: true }
|
|
3279
4519
|
);
|
|
3280
4520
|
});
|
|
3281
|
-
|
|
4521
|
+
expect26(welcomeMessage.type).toBe("welcome");
|
|
3282
4522
|
ws.close();
|
|
3283
4523
|
});
|
|
3284
|
-
|
|
4524
|
+
test26("should handle connection close properly", async (c) => {
|
|
3285
4525
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3286
4526
|
const actor = client.rawWebSocketActor.getOrCreate(["close-test"]);
|
|
3287
|
-
const ws = await actor.
|
|
4527
|
+
const ws = await actor.webSocket();
|
|
3288
4528
|
if (ws.readyState !== WebSocket.OPEN) {
|
|
3289
4529
|
await new Promise((resolve, reject) => {
|
|
3290
4530
|
ws.addEventListener("open", () => resolve(), {
|
|
@@ -3294,7 +4534,7 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
3294
4534
|
});
|
|
3295
4535
|
}
|
|
3296
4536
|
const initialStats = await actor.getStats();
|
|
3297
|
-
|
|
4537
|
+
expect26(initialStats.connectionCount).toBe(1);
|
|
3298
4538
|
const closePromise = new Promise((resolve) => {
|
|
3299
4539
|
ws.addEventListener("close", () => resolve(), { once: true });
|
|
3300
4540
|
});
|
|
@@ -3308,14 +4548,14 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
3308
4548
|
}
|
|
3309
4549
|
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
3310
4550
|
}
|
|
3311
|
-
|
|
4551
|
+
expect26(finalStats == null ? void 0 : finalStats.connectionCount).toBe(0);
|
|
3312
4552
|
});
|
|
3313
|
-
|
|
4553
|
+
test26("should properly handle onWebSocket open and close events", async (c) => {
|
|
3314
4554
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3315
4555
|
const actor = client.rawWebSocketActor.getOrCreate([
|
|
3316
4556
|
"open-close-test"
|
|
3317
4557
|
]);
|
|
3318
|
-
const ws1 = await actor.
|
|
4558
|
+
const ws1 = await actor.webSocket();
|
|
3319
4559
|
await new Promise((resolve, reject) => {
|
|
3320
4560
|
ws1.addEventListener("open", () => resolve(), { once: true });
|
|
3321
4561
|
ws1.addEventListener("close", reject);
|
|
@@ -3330,9 +4570,9 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
3330
4570
|
);
|
|
3331
4571
|
ws1.addEventListener("close", reject);
|
|
3332
4572
|
});
|
|
3333
|
-
|
|
3334
|
-
|
|
3335
|
-
const ws2 = await actor.
|
|
4573
|
+
expect26(welcome1.type).toBe("welcome");
|
|
4574
|
+
expect26(welcome1.connectionCount).toBe(1);
|
|
4575
|
+
const ws2 = await actor.webSocket();
|
|
3336
4576
|
await new Promise((resolve, reject) => {
|
|
3337
4577
|
ws2.addEventListener("open", () => resolve(), { once: true });
|
|
3338
4578
|
ws2.addEventListener("close", reject);
|
|
@@ -3347,10 +4587,10 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
3347
4587
|
);
|
|
3348
4588
|
ws2.addEventListener("close", reject);
|
|
3349
4589
|
});
|
|
3350
|
-
|
|
3351
|
-
|
|
4590
|
+
expect26(welcome2.type).toBe("welcome");
|
|
4591
|
+
expect26(welcome2.connectionCount).toBe(2);
|
|
3352
4592
|
const midStats = await actor.getStats();
|
|
3353
|
-
|
|
4593
|
+
expect26(midStats.connectionCount).toBe(2);
|
|
3354
4594
|
ws1.close();
|
|
3355
4595
|
await new Promise((resolve) => {
|
|
3356
4596
|
ws1.addEventListener("close", () => resolve(), { once: true });
|
|
@@ -3363,7 +4603,7 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
3363
4603
|
}
|
|
3364
4604
|
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
3365
4605
|
}
|
|
3366
|
-
|
|
4606
|
+
expect26(afterFirstClose == null ? void 0 : afterFirstClose.connectionCount).toBe(1);
|
|
3367
4607
|
ws2.close();
|
|
3368
4608
|
await new Promise((resolve) => {
|
|
3369
4609
|
ws2.addEventListener("close", () => resolve(), { once: true });
|
|
@@ -3376,14 +4616,14 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
3376
4616
|
}
|
|
3377
4617
|
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
3378
4618
|
}
|
|
3379
|
-
|
|
4619
|
+
expect26(finalStats == null ? void 0 : finalStats.connectionCount).toBe(0);
|
|
3380
4620
|
});
|
|
3381
|
-
|
|
4621
|
+
test26("should handle query parameters in websocket paths", async (c) => {
|
|
3382
4622
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3383
4623
|
const actor = client.rawWebSocketActor.getOrCreate([
|
|
3384
4624
|
"query-params"
|
|
3385
4625
|
]);
|
|
3386
|
-
const ws = await actor.
|
|
4626
|
+
const ws = await actor.webSocket(
|
|
3387
4627
|
"api/v1/stream?token=abc123&user=test"
|
|
3388
4628
|
);
|
|
3389
4629
|
await new Promise((resolve, reject) => {
|
|
@@ -3401,17 +4641,17 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
3401
4641
|
});
|
|
3402
4642
|
ws.send(JSON.stringify({ type: "getRequestInfo" }));
|
|
3403
4643
|
const requestInfo = await requestInfoPromise;
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
|
|
4644
|
+
expect26(requestInfo.url).toContain("api/v1/stream");
|
|
4645
|
+
expect26(requestInfo.url).toContain("token=abc123");
|
|
4646
|
+
expect26(requestInfo.url).toContain("user=test");
|
|
3407
4647
|
ws.close();
|
|
3408
4648
|
});
|
|
3409
|
-
|
|
4649
|
+
test26("should handle query parameters on base websocket path (no subpath)", async (c) => {
|
|
3410
4650
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3411
4651
|
const actor = client.rawWebSocketActor.getOrCreate([
|
|
3412
4652
|
"base-path-query-params"
|
|
3413
4653
|
]);
|
|
3414
|
-
const ws = await actor.
|
|
4654
|
+
const ws = await actor.webSocket("?token=secret&session=123");
|
|
3415
4655
|
await new Promise((resolve, reject) => {
|
|
3416
4656
|
ws.addEventListener("open", () => resolve(), { once: true });
|
|
3417
4657
|
ws.addEventListener("error", reject);
|
|
@@ -3430,18 +4670,18 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
3430
4670
|
});
|
|
3431
4671
|
ws.send(JSON.stringify({ type: "getRequestInfo" }));
|
|
3432
4672
|
const requestInfo = await requestInfoPromise;
|
|
3433
|
-
|
|
3434
|
-
|
|
4673
|
+
expect26(requestInfo.url).toContain("token=secret");
|
|
4674
|
+
expect26(requestInfo.url).toContain("session=123");
|
|
3435
4675
|
ws.close();
|
|
3436
4676
|
});
|
|
3437
4677
|
});
|
|
3438
4678
|
}
|
|
3439
4679
|
|
|
3440
4680
|
// src/driver-test-suite/tests/request-access.ts
|
|
3441
|
-
import { describe as
|
|
4681
|
+
import { describe as describe28, expect as expect27, test as test27 } from "vitest";
|
|
3442
4682
|
function runRequestAccessTests(driverTestConfig) {
|
|
3443
|
-
|
|
3444
|
-
|
|
4683
|
+
describe28("Request Access in Lifecycle Hooks", () => {
|
|
4684
|
+
test27("should have access to request object in onBeforeConnect and createConnState", async (c) => {
|
|
3445
4685
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3446
4686
|
const handle = client.requestAccessActor.getOrCreate(
|
|
3447
4687
|
["test-request"],
|
|
@@ -3452,23 +4692,23 @@ function runRequestAccessTests(driverTestConfig) {
|
|
|
3452
4692
|
const connection = handle.connect();
|
|
3453
4693
|
const requestInfo = await connection.getRequestInfo();
|
|
3454
4694
|
if (driverTestConfig.clientType === "http") {
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
4695
|
+
expect27(requestInfo.onBeforeConnect.hasRequest).toBe(true);
|
|
4696
|
+
expect27(requestInfo.onBeforeConnect.requestUrl).toBeDefined();
|
|
4697
|
+
expect27(requestInfo.onBeforeConnect.requestMethod).toBeDefined();
|
|
4698
|
+
expect27(
|
|
3459
4699
|
requestInfo.onBeforeConnect.requestHeaders
|
|
3460
4700
|
).toBeDefined();
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
4701
|
+
expect27(requestInfo.createConnState.hasRequest).toBe(true);
|
|
4702
|
+
expect27(requestInfo.createConnState.requestUrl).toBeDefined();
|
|
4703
|
+
expect27(requestInfo.createConnState.requestMethod).toBeDefined();
|
|
4704
|
+
expect27(
|
|
3465
4705
|
requestInfo.createConnState.requestHeaders
|
|
3466
4706
|
).toBeDefined();
|
|
3467
4707
|
} else {
|
|
3468
4708
|
}
|
|
3469
4709
|
await connection.dispose();
|
|
3470
4710
|
});
|
|
3471
|
-
|
|
4711
|
+
test27("should not have request when trackRequest is false", async (c) => {
|
|
3472
4712
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3473
4713
|
const handle = client.requestAccessActor.getOrCreate(
|
|
3474
4714
|
["test-no-request"],
|
|
@@ -3478,21 +4718,21 @@ function runRequestAccessTests(driverTestConfig) {
|
|
|
3478
4718
|
);
|
|
3479
4719
|
const connection = handle.connect();
|
|
3480
4720
|
const requestInfo = await connection.getRequestInfo();
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
4721
|
+
expect27(requestInfo.onBeforeConnect.hasRequest).toBe(false);
|
|
4722
|
+
expect27(requestInfo.onBeforeConnect.requestUrl).toBeNull();
|
|
4723
|
+
expect27(requestInfo.onBeforeConnect.requestMethod).toBeNull();
|
|
4724
|
+
expect27(
|
|
3485
4725
|
Object.keys(requestInfo.onBeforeConnect.requestHeaders)
|
|
3486
4726
|
).toHaveLength(0);
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
4727
|
+
expect27(requestInfo.createConnState.hasRequest).toBe(false);
|
|
4728
|
+
expect27(requestInfo.createConnState.requestUrl).toBeNull();
|
|
4729
|
+
expect27(requestInfo.createConnState.requestMethod).toBeNull();
|
|
4730
|
+
expect27(
|
|
3491
4731
|
Object.keys(requestInfo.createConnState.requestHeaders)
|
|
3492
4732
|
).toHaveLength(0);
|
|
3493
4733
|
await connection.dispose();
|
|
3494
4734
|
});
|
|
3495
|
-
|
|
4735
|
+
test27("should capture request headers and method", async (c) => {
|
|
3496
4736
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3497
4737
|
const handle = client.requestAccessActor.getOrCreate(
|
|
3498
4738
|
["test-headers"],
|
|
@@ -3503,18 +4743,18 @@ function runRequestAccessTests(driverTestConfig) {
|
|
|
3503
4743
|
const connection = handle.connect();
|
|
3504
4744
|
const requestInfo = await connection.getRequestInfo();
|
|
3505
4745
|
if (driverTestConfig.clientType === "http") {
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
4746
|
+
expect27(requestInfo.onBeforeConnect.hasRequest).toBe(true);
|
|
4747
|
+
expect27(requestInfo.onBeforeConnect.requestMethod).toBeTruthy();
|
|
4748
|
+
expect27(requestInfo.onBeforeConnect.requestUrl).toBeTruthy();
|
|
4749
|
+
expect27(requestInfo.onBeforeConnect.requestHeaders).toBeTruthy();
|
|
4750
|
+
expect27(typeof requestInfo.onBeforeConnect.requestHeaders).toBe(
|
|
3511
4751
|
"object"
|
|
3512
4752
|
);
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
|
|
4753
|
+
expect27(requestInfo.createConnState.hasRequest).toBe(true);
|
|
4754
|
+
expect27(requestInfo.createConnState.requestMethod).toBeTruthy();
|
|
4755
|
+
expect27(requestInfo.createConnState.requestUrl).toBeTruthy();
|
|
4756
|
+
expect27(requestInfo.createConnState.requestHeaders).toBeTruthy();
|
|
4757
|
+
expect27(typeof requestInfo.createConnState.requestHeaders).toBe(
|
|
3518
4758
|
"object"
|
|
3519
4759
|
);
|
|
3520
4760
|
} else {
|
|
@@ -3526,41 +4766,49 @@ function runRequestAccessTests(driverTestConfig) {
|
|
|
3526
4766
|
|
|
3527
4767
|
// src/driver-test-suite/mod.ts
|
|
3528
4768
|
function runDriverTests(driverTestConfigPartial) {
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
|
|
3537
|
-
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
|
|
4769
|
+
describe29("Driver Tests", () => {
|
|
4770
|
+
var _a;
|
|
4771
|
+
const clientTypes = ((_a = driverTestConfigPartial.skip) == null ? void 0 : _a.inline) ? ["http"] : ["http", "inline"];
|
|
4772
|
+
for (const clientType of clientTypes) {
|
|
4773
|
+
describe29(`client type (${clientType})`, () => {
|
|
4774
|
+
const encodings = ["bare", "cbor", "json"];
|
|
4775
|
+
for (const encoding of encodings) {
|
|
4776
|
+
describe29(`encoding (${encoding})`, () => {
|
|
4777
|
+
const driverTestConfig = {
|
|
4778
|
+
...driverTestConfigPartial,
|
|
4779
|
+
clientType,
|
|
4780
|
+
encoding
|
|
4781
|
+
};
|
|
4782
|
+
runActorDriverTests(driverTestConfig);
|
|
4783
|
+
runManagerDriverTests(driverTestConfig);
|
|
4784
|
+
runActorConnTests(driverTestConfig);
|
|
4785
|
+
runActorConnStateTests(driverTestConfig);
|
|
4786
|
+
runActorConnHibernationTests(driverTestConfig);
|
|
4787
|
+
runActorDbTests(driverTestConfig);
|
|
4788
|
+
runActorDestroyTests(driverTestConfig);
|
|
4789
|
+
runRequestAccessTests(driverTestConfig);
|
|
4790
|
+
runActorHandleTests(driverTestConfig);
|
|
4791
|
+
runActionFeaturesTests(driverTestConfig);
|
|
4792
|
+
runAccessControlTests(driverTestConfig);
|
|
4793
|
+
runActorVarsTests(driverTestConfig);
|
|
4794
|
+
runActorMetadataTests(driverTestConfig);
|
|
4795
|
+
runActorOnStateChangeTests(driverTestConfig);
|
|
4796
|
+
runActorErrorHandlingTests(driverTestConfig);
|
|
4797
|
+
runActorQueueTests(driverTestConfig);
|
|
4798
|
+
runActorRunTests(driverTestConfig);
|
|
4799
|
+
runActorInlineClientTests(driverTestConfig);
|
|
4800
|
+
runActorKvTests(driverTestConfig);
|
|
4801
|
+
runActorWorkflowTests(driverTestConfig);
|
|
4802
|
+
runActorStatelessTests(driverTestConfig);
|
|
4803
|
+
runRawHttpTests(driverTestConfig);
|
|
4804
|
+
runRawHttpRequestPropertiesTests(driverTestConfig);
|
|
4805
|
+
runRawWebSocketTests(driverTestConfig);
|
|
4806
|
+
runActorInspectorTests(driverTestConfig);
|
|
4807
|
+
});
|
|
4808
|
+
}
|
|
4809
|
+
});
|
|
4810
|
+
}
|
|
4811
|
+
});
|
|
3564
4812
|
}
|
|
3565
4813
|
async function createTestRuntime(registryPath, driverFactory) {
|
|
3566
4814
|
var _a;
|
|
@@ -3598,17 +4846,24 @@ async function createTestRuntime(registryPath, driverFactory) {
|
|
|
3598
4846
|
const nodeWebSocket = createNodeWebSocket({ app: router });
|
|
3599
4847
|
upgradeWebSocket = nodeWebSocket.upgradeWebSocket;
|
|
3600
4848
|
managerDriver.setGetUpgradeWebSocket(() => upgradeWebSocket);
|
|
3601
|
-
const port = await getPort();
|
|
3602
4849
|
const server = honoServe({
|
|
3603
4850
|
fetch: router.fetch,
|
|
3604
4851
|
hostname: "127.0.0.1",
|
|
3605
|
-
port
|
|
4852
|
+
port: 0
|
|
3606
4853
|
});
|
|
4854
|
+
if (!server.listening) {
|
|
4855
|
+
await new Promise((resolve) => {
|
|
4856
|
+
server.once("listening", () => resolve());
|
|
4857
|
+
});
|
|
4858
|
+
}
|
|
3607
4859
|
invariant2(
|
|
3608
4860
|
nodeWebSocket.injectWebSocket !== void 0,
|
|
3609
4861
|
"should have injectWebSocket"
|
|
3610
4862
|
);
|
|
3611
4863
|
nodeWebSocket.injectWebSocket(server);
|
|
4864
|
+
const address = server.address();
|
|
4865
|
+
invariant2(address && typeof address !== "string", "missing server address");
|
|
4866
|
+
const port = address.port;
|
|
3612
4867
|
const serverEndpoint = `http://127.0.0.1:${port}`;
|
|
3613
4868
|
logger().info({ msg: "test serer listening", port });
|
|
3614
4869
|
const cleanup = async () => {
|