@fuzdev/fuz_app 0.146.1 → 0.148.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/actions/CLAUDE.md +6 -4
- package/dist/actions/action_codegen.d.ts +15 -1
- package/dist/actions/action_codegen.d.ts.map +1 -1
- package/dist/actions/action_codegen.js +23 -2
- package/dist/actions/perform_action.js +1 -1
- package/dist/auth/CLAUDE.md +1 -1
- package/dist/auth/bootstrap_account.d.ts +2 -1
- package/dist/auth/bootstrap_account.d.ts.map +1 -1
- package/dist/auth/bootstrap_account.js +17 -6
- package/dist/auth/cell_action_specs.d.ts +3 -1
- package/dist/auth/cell_action_specs.d.ts.map +1 -1
- package/dist/auth/cell_action_specs.js +5 -5
- package/dist/auth/cell_actions.d.ts.map +1 -1
- package/dist/auth/cell_actions.js +2 -3
- package/dist/auth/cell_data_schema.d.ts +1 -1
- package/dist/auth/cell_data_schema.js +1 -1
- package/dist/auth/cell_field_action_specs.d.ts +4 -3
- package/dist/auth/cell_field_action_specs.d.ts.map +1 -1
- package/dist/auth/cell_field_action_specs.js +5 -6
- package/dist/auth/cell_field_actions.d.ts.map +1 -1
- package/dist/auth/cell_field_actions.js +8 -1
- package/dist/auth/cell_item_action_specs.d.ts +4 -2
- package/dist/auth/cell_item_action_specs.d.ts.map +1 -1
- package/dist/auth/cell_item_action_specs.js +5 -5
- package/dist/auth/cell_item_actions.d.ts.map +1 -1
- package/dist/auth/cell_item_actions.js +8 -1
- package/dist/auth/keyring.d.ts +35 -38
- package/dist/auth/keyring.d.ts.map +1 -1
- package/dist/auth/keyring.js +43 -50
- package/dist/auth/password_argon2.d.ts.map +1 -1
- package/dist/auth/password_argon2.js +11 -8
- package/dist/auth/role_grant_offer_action_specs.d.ts +2 -0
- package/dist/auth/role_grant_offer_action_specs.d.ts.map +1 -1
- package/dist/auth/role_grant_offer_action_specs.js +3 -1
- package/dist/auth/session_cookie.d.ts.map +1 -1
- package/dist/auth/session_cookie.js +5 -2
- package/dist/db/CLAUDE.md +18 -16
- package/dist/db/cell_queries.d.ts +3 -2
- package/dist/db/cell_queries.d.ts.map +1 -1
- package/dist/db/cell_queries.js +3 -2
- package/dist/db/fact_disk_storage.d.ts +15 -15
- package/dist/db/fact_disk_storage.d.ts.map +1 -1
- package/dist/db/fact_disk_storage.js +22 -28
- package/dist/db/fact_queries.d.ts +2 -3
- package/dist/db/fact_queries.d.ts.map +1 -1
- package/dist/db/fact_queries.js +2 -3
- package/dist/db/fact_store.d.ts +20 -18
- package/dist/db/fact_store.d.ts.map +1 -1
- package/dist/db/fact_store.js +30 -44
- package/dist/db/file_fact_url.d.ts +19 -4
- package/dist/db/file_fact_url.d.ts.map +1 -1
- package/dist/db/file_fact_url.js +19 -4
- package/dist/primitive_schemas.d.ts +1 -1
- package/dist/primitive_schemas.d.ts.map +1 -1
- package/dist/primitive_schemas.js +2 -1
- package/dist/schema_meta.d.ts +20 -0
- package/dist/schema_meta.d.ts.map +1 -1
- package/dist/schema_meta.js +7 -1
- package/dist/server/env.d.ts.map +1 -1
- package/dist/server/env.js +2 -2
- package/dist/server/serve_fact_route.d.ts +9 -5
- package/dist/server/serve_fact_route.d.ts.map +1 -1
- package/dist/server/serve_fact_route.js +15 -7
- package/dist/testing/CLAUDE.md +737 -114
- package/dist/testing/admin_integration.d.ts.map +1 -1
- package/dist/testing/admin_integration.js +73 -5
- package/dist/testing/adversarial_input.d.ts +0 -47
- package/dist/testing/adversarial_input.d.ts.map +1 -1
- package/dist/testing/adversarial_input.js +4 -340
- package/dist/testing/adversarial_input_cases.d.ts +64 -0
- package/dist/testing/adversarial_input_cases.d.ts.map +1 -0
- package/dist/testing/adversarial_input_cases.js +348 -0
- package/dist/testing/app_server.d.ts.map +1 -1
- package/dist/testing/app_server.js +2 -2
- package/dist/testing/audit_completeness.d.ts.map +1 -1
- package/dist/testing/audit_completeness.js +24 -20
- package/dist/testing/audit_drift_guard.d.ts +27 -1
- package/dist/testing/audit_drift_guard.d.ts.map +1 -1
- package/dist/testing/audit_drift_guard.js +50 -0
- package/dist/testing/cross_backend/account_lifecycle.d.ts.map +1 -1
- package/dist/testing/cross_backend/account_lifecycle.js +29 -12
- package/dist/testing/cross_backend/actor_lookup.d.ts.map +1 -1
- package/dist/testing/cross_backend/actor_lookup.js +7 -25
- package/dist/testing/cross_backend/app_settings.d.ts.map +1 -1
- package/dist/testing/cross_backend/app_settings.js +4 -6
- package/dist/testing/cross_backend/audit_cross_helpers.d.ts +51 -0
- package/dist/testing/cross_backend/audit_cross_helpers.d.ts.map +1 -0
- package/dist/testing/cross_backend/audit_cross_helpers.js +78 -0
- package/dist/testing/cross_backend/backend_config.d.ts +2 -1
- package/dist/testing/cross_backend/backend_config.d.ts.map +1 -1
- package/dist/testing/cross_backend/body_size.d.ts +6 -0
- package/dist/testing/cross_backend/body_size.d.ts.map +1 -1
- package/dist/testing/cross_backend/body_size.js +26 -44
- package/dist/testing/cross_backend/body_size_smuggling.d.ts +5 -0
- package/dist/testing/cross_backend/body_size_smuggling.d.ts.map +1 -1
- package/dist/testing/cross_backend/body_size_smuggling.js +7 -14
- package/dist/testing/cross_backend/bootstrap_backend.d.ts +11 -1
- package/dist/testing/cross_backend/bootstrap_backend.d.ts.map +1 -1
- package/dist/testing/cross_backend/bootstrap_backend.js +2 -1
- package/dist/testing/cross_backend/build_test_backend_paths.d.ts +3 -1
- package/dist/testing/cross_backend/build_test_backend_paths.d.ts.map +1 -1
- package/dist/testing/cross_backend/capabilities.d.ts +55 -59
- package/dist/testing/cross_backend/capabilities.d.ts.map +1 -1
- package/dist/testing/cross_backend/capabilities.js +20 -23
- package/dist/testing/cross_backend/cargo_binary.d.ts +70 -0
- package/dist/testing/cross_backend/cargo_binary.d.ts.map +1 -0
- package/dist/testing/cross_backend/cargo_binary.js +148 -0
- package/dist/testing/cross_backend/cell_crud.d.ts.map +1 -1
- package/dist/testing/cross_backend/cell_crud.js +57 -1
- package/dist/testing/cross_backend/cell_gated_create.d.ts +0 -60
- package/dist/testing/cross_backend/cell_gated_create.d.ts.map +1 -1
- package/dist/testing/cross_backend/cell_gated_create.js +9 -487
- package/dist/testing/cross_backend/cell_grant_role.d.ts +14 -2
- package/dist/testing/cross_backend/cell_grant_role.d.ts.map +1 -1
- package/dist/testing/cross_backend/cell_grant_role.js +22 -12
- package/dist/testing/cross_backend/cell_moderate.d.ts +66 -0
- package/dist/testing/cross_backend/cell_moderate.d.ts.map +1 -0
- package/dist/testing/cross_backend/cell_moderate.js +511 -0
- package/dist/testing/cross_backend/cell_ref_admission.d.ts.map +1 -1
- package/dist/testing/cross_backend/cell_ref_admission.js +1 -1
- package/dist/testing/cross_backend/cell_relations.d.ts.map +1 -1
- package/dist/testing/cross_backend/cell_relations.js +40 -19
- package/dist/testing/cross_backend/conformance_case.d.ts +43 -4
- package/dist/testing/cross_backend/conformance_case.d.ts.map +1 -1
- package/dist/testing/cross_backend/conformance_case.js +29 -1
- package/dist/testing/cross_backend/conformance_rpc_auth.d.ts +93 -0
- package/dist/testing/cross_backend/conformance_rpc_auth.d.ts.map +1 -0
- package/dist/testing/cross_backend/conformance_rpc_auth.js +125 -0
- package/dist/testing/cross_backend/conformance_table.d.ts +144 -4
- package/dist/testing/cross_backend/conformance_table.d.ts.map +1 -1
- package/dist/testing/cross_backend/conformance_table.js +297 -65
- package/dist/testing/cross_backend/cookie_attributes.d.ts.map +1 -1
- package/dist/testing/cross_backend/cookie_attributes.js +3 -2
- package/dist/testing/cross_backend/create_cross_backend_global_setup.d.ts +38 -5
- package/dist/testing/cross_backend/create_cross_backend_global_setup.d.ts.map +1 -1
- package/dist/testing/cross_backend/create_cross_backend_global_setup.js +24 -3
- package/dist/testing/cross_backend/create_dual_spawn_global_setup.d.ts +5 -5
- package/dist/testing/cross_backend/create_dual_spawn_global_setup.d.ts.map +1 -1
- package/dist/testing/cross_backend/credential_deadline.d.ts +10 -6
- package/dist/testing/cross_backend/credential_deadline.d.ts.map +1 -1
- package/dist/testing/cross_backend/credential_deadline.js +32 -31
- package/dist/testing/cross_backend/credential_header_robustness.d.ts.map +1 -1
- package/dist/testing/cross_backend/credential_header_robustness.js +4 -6
- package/dist/testing/cross_backend/{cell_cross_helpers.d.ts → cross_rpc.d.ts} +12 -2
- package/dist/testing/cross_backend/cross_rpc.d.ts.map +1 -0
- package/dist/testing/cross_backend/{cell_cross_helpers.js → cross_rpc.js} +31 -7
- package/dist/testing/cross_backend/default_backend_configs.d.ts +56 -61
- package/dist/testing/cross_backend/default_backend_configs.d.ts.map +1 -1
- package/dist/testing/cross_backend/default_backend_configs.js +97 -91
- package/dist/testing/cross_backend/default_spine_surface.d.ts.map +1 -1
- package/dist/testing/cross_backend/default_spine_surface.js +2 -2
- package/dist/testing/cross_backend/differential.d.ts +126 -0
- package/dist/testing/cross_backend/differential.d.ts.map +1 -0
- package/dist/testing/cross_backend/differential.js +201 -0
- package/dist/testing/cross_backend/differential_normalize.d.ts +150 -0
- package/dist/testing/cross_backend/differential_normalize.d.ts.map +1 -0
- package/dist/testing/cross_backend/differential_normalize.js +153 -0
- package/dist/testing/cross_backend/fact_serving.d.ts +5 -0
- package/dist/testing/cross_backend/fact_serving.d.ts.map +1 -1
- package/dist/testing/cross_backend/fact_serving.js +41 -7
- package/dist/testing/cross_backend/full_spine_mount.d.ts +15 -0
- package/dist/testing/cross_backend/full_spine_mount.d.ts.map +1 -1
- package/dist/testing/cross_backend/full_spine_mount.js +55 -1
- package/dist/testing/cross_backend/identity_parity.d.ts.map +1 -1
- package/dist/testing/cross_backend/identity_parity.js +6 -5
- package/dist/testing/cross_backend/in_process_setup.d.ts +12 -2
- package/dist/testing/cross_backend/in_process_setup.d.ts.map +1 -1
- package/dist/testing/cross_backend/in_process_setup.js +10 -7
- package/dist/testing/cross_backend/login_security.d.ts.map +1 -1
- package/dist/testing/cross_backend/login_security.js +13 -18
- package/dist/testing/cross_backend/origin.js +1 -1
- package/dist/testing/cross_backend/origin_conformance.js +1 -1
- package/dist/testing/cross_backend/origin_scope.d.ts +6 -0
- package/dist/testing/cross_backend/origin_scope.d.ts.map +1 -1
- package/dist/testing/cross_backend/origin_scope.js +13 -12
- package/dist/testing/cross_backend/peer_ping_ws.d.ts +2 -5
- package/dist/testing/cross_backend/peer_ping_ws.d.ts.map +1 -1
- package/dist/testing/cross_backend/peer_ping_ws.js +14 -24
- package/dist/testing/cross_backend/postgres_database.d.ts +85 -0
- package/dist/testing/cross_backend/postgres_database.d.ts.map +1 -0
- package/dist/testing/cross_backend/postgres_database.js +140 -0
- package/dist/testing/cross_backend/provided_context.d.ts +28 -0
- package/dist/testing/cross_backend/provided_context.d.ts.map +1 -0
- package/dist/testing/cross_backend/provided_context.js +35 -0
- package/dist/testing/cross_backend/query_shape.d.ts.map +1 -1
- package/dist/testing/cross_backend/query_shape.js +10 -12
- package/dist/testing/cross_backend/ready.js +2 -2
- package/dist/testing/cross_backend/revocation_drivers.d.ts +4 -3
- package/dist/testing/cross_backend/revocation_drivers.d.ts.map +1 -1
- package/dist/testing/cross_backend/revocation_drivers.js +1 -1
- package/dist/testing/cross_backend/role_grant_cross_helpers.d.ts +3 -2
- package/dist/testing/cross_backend/role_grant_cross_helpers.d.ts.map +1 -1
- package/dist/testing/cross_backend/role_grant_offer_lifecycle.d.ts +13 -0
- package/dist/testing/cross_backend/role_grant_offer_lifecycle.d.ts.map +1 -0
- package/dist/testing/cross_backend/role_grant_offer_lifecycle.js +203 -0
- package/dist/testing/cross_backend/role_grant_offer_notification_ws.d.ts +2 -5
- package/dist/testing/cross_backend/role_grant_offer_notification_ws.d.ts.map +1 -1
- package/dist/testing/cross_backend/role_grant_offer_notification_ws.js +203 -111
- package/dist/testing/cross_backend/role_grant_participation.d.ts +13 -0
- package/dist/testing/cross_backend/role_grant_participation.d.ts.map +1 -1
- package/dist/testing/cross_backend/role_grant_participation.js +32 -21
- package/dist/testing/cross_backend/role_grant_role_grammar.d.ts.map +1 -1
- package/dist/testing/cross_backend/role_grant_role_grammar.js +6 -9
- package/dist/testing/cross_backend/rpc_adversarial.d.ts +38 -0
- package/dist/testing/cross_backend/rpc_adversarial.d.ts.map +1 -0
- package/dist/testing/cross_backend/rpc_adversarial.js +292 -0
- package/dist/testing/cross_backend/rpc_success_fixtures.d.ts +24 -0
- package/dist/testing/cross_backend/rpc_success_fixtures.d.ts.map +1 -0
- package/dist/testing/cross_backend/rpc_success_fixtures.js +124 -0
- package/dist/testing/cross_backend/rust_spine_consumer_surface.d.ts +101 -0
- package/dist/testing/cross_backend/rust_spine_consumer_surface.d.ts.map +1 -0
- package/dist/testing/cross_backend/rust_spine_consumer_surface.js +113 -0
- package/dist/testing/cross_backend/rust_spine_stub_backend_config.d.ts +10 -0
- package/dist/testing/cross_backend/rust_spine_stub_backend_config.d.ts.map +1 -1
- package/dist/testing/cross_backend/rust_spine_stub_backend_config.js +27 -18
- package/dist/testing/cross_backend/session_cap.d.ts +9 -8
- package/dist/testing/cross_backend/session_cap.d.ts.map +1 -1
- package/dist/testing/cross_backend/session_cap.js +9 -4
- package/dist/testing/cross_backend/session_cookie_codec.d.ts +19 -0
- package/dist/testing/cross_backend/session_cookie_codec.d.ts.map +1 -0
- package/dist/testing/cross_backend/session_cookie_codec.js +128 -0
- package/dist/testing/cross_backend/setup.d.ts +56 -54
- package/dist/testing/cross_backend/setup.d.ts.map +1 -1
- package/dist/testing/cross_backend/setup.js +29 -29
- package/dist/testing/cross_backend/simple_request.d.ts.map +1 -1
- package/dist/testing/cross_backend/simple_request.js +4 -4
- package/dist/testing/cross_backend/spawn_backend.d.ts +59 -10
- package/dist/testing/cross_backend/spawn_backend.d.ts.map +1 -1
- package/dist/testing/cross_backend/spawn_backend.js +219 -60
- package/dist/testing/cross_backend/spine_suites.d.ts +231 -0
- package/dist/testing/cross_backend/spine_suites.d.ts.map +1 -0
- package/dist/testing/cross_backend/spine_suites.js +626 -0
- package/dist/testing/cross_backend/spine_surface_constants.d.ts +29 -0
- package/dist/testing/cross_backend/spine_surface_constants.d.ts.map +1 -1
- package/dist/testing/cross_backend/spine_surface_constants.js +29 -0
- package/dist/testing/cross_backend/sse_round_trip.d.ts.map +1 -1
- package/dist/testing/cross_backend/sse_round_trip.js +3 -4
- package/dist/testing/cross_backend/standard.d.ts +18 -1
- package/dist/testing/cross_backend/standard.d.ts.map +1 -1
- package/dist/testing/cross_backend/standard.js +2 -0
- package/dist/testing/cross_backend/test_cell_gated_create_authorize.d.ts +24 -0
- package/dist/testing/cross_backend/test_cell_gated_create_authorize.d.ts.map +1 -1
- package/dist/testing/cross_backend/test_cell_gated_create_authorize.js +15 -0
- package/dist/testing/cross_backend/testing_backdoor.d.ts +2 -8
- package/dist/testing/cross_backend/testing_backdoor.d.ts.map +1 -1
- package/dist/testing/cross_backend/testing_backdoor.js +7 -10
- package/dist/testing/cross_backend/testing_reset_actions.d.ts +10 -5
- package/dist/testing/cross_backend/testing_reset_actions.d.ts.map +1 -1
- package/dist/testing/cross_backend/testing_reset_actions.js +21 -12
- package/dist/testing/cross_backend/testing_server_bun.js +1 -1
- package/dist/testing/cross_backend/token_lifetime.js +1 -1
- package/dist/testing/cross_backend/token_scope_surface.d.ts.map +1 -1
- package/dist/testing/cross_backend/token_scope_surface.js +9 -13
- package/dist/testing/cross_backend/transport_composition.d.ts +26 -2
- package/dist/testing/cross_backend/transport_composition.d.ts.map +1 -1
- package/dist/testing/cross_backend/transport_composition.js +81 -51
- package/dist/testing/cross_backend/ts_spine_backend_config.d.ts +8 -0
- package/dist/testing/cross_backend/ts_spine_backend_config.d.ts.map +1 -1
- package/dist/testing/cross_backend/ts_spine_backend_config.js +17 -10
- package/dist/testing/cross_backend/ws_action_rate_limit.d.ts +2 -5
- package/dist/testing/cross_backend/ws_action_rate_limit.d.ts.map +1 -1
- package/dist/testing/cross_backend/ws_action_rate_limit.js +8 -14
- package/dist/testing/cross_backend/ws_connection_cap.d.ts +4 -9
- package/dist/testing/cross_backend/ws_connection_cap.d.ts.map +1 -1
- package/dist/testing/cross_backend/ws_connection_cap.js +11 -12
- package/dist/testing/cross_backend/ws_endpoint.d.ts +52 -0
- package/dist/testing/cross_backend/ws_endpoint.d.ts.map +1 -0
- package/dist/testing/cross_backend/ws_endpoint.js +54 -0
- package/dist/testing/cross_backend/ws_inbound_dispatch.d.ts +2 -5
- package/dist/testing/cross_backend/ws_inbound_dispatch.d.ts.map +1 -1
- package/dist/testing/cross_backend/ws_inbound_dispatch.js +9 -15
- package/dist/testing/cross_backend/ws_outbound_overflow.d.ts +2 -7
- package/dist/testing/cross_backend/ws_outbound_overflow.d.ts.map +1 -1
- package/dist/testing/cross_backend/ws_outbound_overflow.js +5 -9
- package/dist/testing/cross_backend/ws_role_gated.d.ts +4 -5
- package/dist/testing/cross_backend/ws_role_gated.d.ts.map +1 -1
- package/dist/testing/cross_backend/ws_role_gated.js +12 -21
- package/dist/testing/cross_backend/ws_round_trip.d.ts +12 -9
- package/dist/testing/cross_backend/ws_round_trip.d.ts.map +1 -1
- package/dist/testing/cross_backend/ws_round_trip.js +29 -34
- package/dist/testing/db_entities.d.ts +16 -3
- package/dist/testing/db_entities.d.ts.map +1 -1
- package/dist/testing/db_entities.js +28 -5
- package/dist/testing/integration_helpers.d.ts +61 -2
- package/dist/testing/integration_helpers.d.ts.map +1 -1
- package/dist/testing/integration_helpers.js +75 -18
- package/dist/testing/round_trip.d.ts +17 -0
- package/dist/testing/round_trip.d.ts.map +1 -1
- package/dist/testing/round_trip.js +67 -24
- package/dist/testing/rpc_attack_surface.d.ts.map +1 -1
- package/dist/testing/rpc_attack_surface.js +13 -138
- package/dist/testing/rpc_envelope_cases.d.ts +111 -0
- package/dist/testing/rpc_envelope_cases.d.ts.map +1 -0
- package/dist/testing/rpc_envelope_cases.js +240 -0
- package/dist/testing/rpc_helpers.d.ts +31 -0
- package/dist/testing/rpc_helpers.d.ts.map +1 -1
- package/dist/testing/rpc_helpers.js +35 -14
- package/dist/testing/rpc_round_trip.d.ts +62 -6
- package/dist/testing/rpc_round_trip.d.ts.map +1 -1
- package/dist/testing/rpc_round_trip.js +151 -39
- package/dist/testing/schema_generators.d.ts.map +1 -1
- package/dist/testing/schema_generators.js +22 -2
- package/dist/testing/standard.d.ts +26 -0
- package/dist/testing/standard.d.ts.map +1 -1
- package/dist/testing/standard.js +4 -1
- package/dist/testing/transports/raw_http.d.ts +21 -0
- package/dist/testing/transports/raw_http.d.ts.map +1 -1
- package/dist/testing/transports/raw_http.js +30 -0
- package/package.json +10 -8
- package/dist/testing/cross_backend/actor_search.d.ts +0 -6
- package/dist/testing/cross_backend/actor_search.d.ts.map +0 -1
- package/dist/testing/cross_backend/actor_search.js +0 -90
- package/dist/testing/cross_backend/cell_cross_helpers.d.ts.map +0 -1
|
@@ -5,18 +5,30 @@ import '../assert_dev_env.js';
|
|
|
5
5
|
*
|
|
6
6
|
* Lifecycle:
|
|
7
7
|
*
|
|
8
|
-
* 1.
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* 1. Refuse when `config.base_url`'s port already accepts a TCP connection —
|
|
9
|
+
* another cross run or a stale backend holds it, and the health probe
|
|
10
|
+
* would otherwise drive that process instead of the one spawned here.
|
|
11
|
+
* 2. Write the bootstrap token (`config.bootstrap.token`) to
|
|
12
|
+
* `config.bootstrap.token_path` so the binary picks it up at startup, and
|
|
13
|
+
* delete any `config.bootstrap.daemon_token_path` a previous run left, so
|
|
14
|
+
* step 5 can only read the token this binary writes.
|
|
15
|
+
* 3. `child_process.spawn(...)` the binary with `detached: true` —
|
|
11
16
|
* creates a new process group so a `SIGTERM` to the negative PID
|
|
12
17
|
* tears down any descendants the binary spawned (PTYs, child
|
|
13
|
-
* workers). vitest worker death +
|
|
14
|
-
* group teardown so ports never strand.
|
|
15
|
-
*
|
|
16
|
-
* `startup_timeout_ms` elapses
|
|
17
|
-
*
|
|
18
|
+
* workers). vitest worker death + `SIGINT` / `SIGTERM` / `SIGHUP`
|
|
19
|
+
* handlers also fire the group teardown so ports never strand.
|
|
20
|
+
* 4. Poll `{base_url}{health_path}` until it returns 2xx or
|
|
21
|
+
* `startup_timeout_ms` elapses — each probe bounded by its own timeout, so
|
|
22
|
+
* a listener that accepts but never answers can't outlast the deadline.
|
|
23
|
+
* 5. Read `config.bootstrap.daemon_token_path` to load the binary's
|
|
18
24
|
* deterministic daemon token; thread it onto `BackendHandle` so
|
|
19
25
|
* `_testing_reset` and other keeper-credential calls can authenticate.
|
|
26
|
+
* 6. Log one line with the time from spawn to step 5 done, so a run shows
|
|
27
|
+
* what each backend costs to bring up.
|
|
28
|
+
*
|
|
29
|
+
* The child's stderr is kept as a bounded tail (`STDERR_TAIL_MAX_BYTES`):
|
|
30
|
+
* a startup failure reports it with the exit code or signal, and an exit
|
|
31
|
+
* after startup that teardown didn't cause is logged with it.
|
|
20
32
|
*
|
|
21
33
|
* Bootstrapping (`POST /api/account/bootstrap`) is a separate concern —
|
|
22
34
|
* the caller composes `bootstrap()` from `testing/transports/bootstrap.ts`
|
|
@@ -27,10 +39,26 @@ import '../assert_dev_env.js';
|
|
|
27
39
|
* @module
|
|
28
40
|
*/
|
|
29
41
|
import { spawn } from 'node:child_process';
|
|
30
|
-
import { readFile, writeFile, mkdir } from 'node:fs/promises';
|
|
42
|
+
import { readFile, writeFile, mkdir, rm } from 'node:fs/promises';
|
|
43
|
+
import { connect } from 'node:net';
|
|
31
44
|
import { dirname } from 'node:path';
|
|
32
45
|
/** Number of ms between health-probe attempts. Tuned to be cheap on busy CI runners. */
|
|
33
46
|
const HEALTH_PROBE_INTERVAL_MS = 100;
|
|
47
|
+
/**
|
|
48
|
+
* Upper bound on one health-probe request (ms), further capped by the time
|
|
49
|
+
* left before `startup_timeout_ms`. A backend answers `/health` in
|
|
50
|
+
* milliseconds once it listens; this only fires for a listener that accepts
|
|
51
|
+
* and never responds.
|
|
52
|
+
*/
|
|
53
|
+
const HEALTH_PROBE_REQUEST_TIMEOUT_MS = 2_000;
|
|
54
|
+
/** How long the pre-spawn port check waits for a TCP connection (ms). */
|
|
55
|
+
const PORT_PROBE_TIMEOUT_MS = 1_000;
|
|
56
|
+
/**
|
|
57
|
+
* How much of the child's stderr is kept (bytes) — the tail a startup failure
|
|
58
|
+
* or an unexpected exit reports. Bounded so a backend that logs to stderr for
|
|
59
|
+
* a whole suite doesn't grow the runner's memory with it.
|
|
60
|
+
*/
|
|
61
|
+
export const STDERR_TAIL_MAX_BYTES = 16 * 1024;
|
|
34
62
|
/**
|
|
35
63
|
* Grace window after teardown's SIGTERM before escalating to SIGKILL on the
|
|
36
64
|
* process group. A well-behaved backend exits within milliseconds; this only
|
|
@@ -39,6 +67,8 @@ const HEALTH_PROBE_INTERVAL_MS = 100;
|
|
|
39
67
|
* the await below can't strand the whole run forever.
|
|
40
68
|
*/
|
|
41
69
|
const TEARDOWN_SIGKILL_GRACE_MS = 3_000;
|
|
70
|
+
/** How often teardown checks whether the process group has exited (ms). */
|
|
71
|
+
const TEARDOWN_POLL_INTERVAL_MS = 20;
|
|
42
72
|
/**
|
|
43
73
|
* Sleep helper for the probe loop. Resolves after `ms`.
|
|
44
74
|
*/
|
|
@@ -48,17 +78,19 @@ const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
|
48
78
|
* Network errors during the wait window are expected (binary not yet
|
|
49
79
|
* listening) — they reset the loop, not throw.
|
|
50
80
|
*/
|
|
51
|
-
const wait_for_health = async (url, timeout_ms,
|
|
81
|
+
const wait_for_health = async (url, timeout_ms, exit_status) => {
|
|
52
82
|
const deadline = Date.now() + timeout_ms;
|
|
53
83
|
let last_error;
|
|
54
84
|
while (Date.now() < deadline) {
|
|
55
|
-
|
|
56
|
-
|
|
85
|
+
const exited = exit_status();
|
|
86
|
+
if (exited !== null) {
|
|
87
|
+
throw new Error(`backend process ${exited} before becoming healthy${last_error
|
|
57
88
|
? ` (last probe error: ${last_error.message ?? String(last_error)})`
|
|
58
89
|
: ''}`);
|
|
59
90
|
}
|
|
60
91
|
try {
|
|
61
|
-
const
|
|
92
|
+
const request_timeout_ms = Math.max(1, Math.min(HEALTH_PROBE_REQUEST_TIMEOUT_MS, deadline - Date.now()));
|
|
93
|
+
const response = await fetch(url, { signal: AbortSignal.timeout(request_timeout_ms) });
|
|
62
94
|
if (response.ok) {
|
|
63
95
|
// Drain the body so the connection can be released back to
|
|
64
96
|
// the agent pool — unconsumed bodies keep the socket open.
|
|
@@ -74,6 +106,57 @@ const wait_for_health = async (url, timeout_ms, is_alive) => {
|
|
|
74
106
|
}
|
|
75
107
|
throw new Error(`health probe to ${url} timed out after ${timeout_ms}ms (last error: ${last_error ? (last_error.message ?? String(last_error)) : 'none'})`);
|
|
76
108
|
};
|
|
109
|
+
/**
|
|
110
|
+
* Whether something accepts TCP connections at `base_url`'s host and port.
|
|
111
|
+
* A refused connection, an unresolvable host or no answer within
|
|
112
|
+
* `PORT_PROBE_TIMEOUT_MS` all read as free.
|
|
113
|
+
*
|
|
114
|
+
* @param base_url - an `http://` or `https://` URL; a missing port is the scheme's default
|
|
115
|
+
*/
|
|
116
|
+
export const is_port_accepting = (base_url) => {
|
|
117
|
+
const url = new URL(base_url);
|
|
118
|
+
const port = Number(url.port || (url.protocol === 'https:' ? 443 : 80));
|
|
119
|
+
// `URL` keeps an IPv6 literal's brackets, which `connect` doesn't take
|
|
120
|
+
const host = url.hostname.replace(/^\[(.*)\]$/, '$1');
|
|
121
|
+
return new Promise((resolve) => {
|
|
122
|
+
const socket = connect({ host, port });
|
|
123
|
+
const settle = (accepting) => {
|
|
124
|
+
socket.destroy();
|
|
125
|
+
resolve(accepting);
|
|
126
|
+
};
|
|
127
|
+
socket.setTimeout(PORT_PROBE_TIMEOUT_MS, () => settle(false));
|
|
128
|
+
socket.once('connect', () => settle(true));
|
|
129
|
+
socket.once('error', () => settle(false));
|
|
130
|
+
});
|
|
131
|
+
};
|
|
132
|
+
/**
|
|
133
|
+
* Create an `OutputTail` keeping at most `max_bytes`.
|
|
134
|
+
*
|
|
135
|
+
* @param max_bytes - how many trailing bytes to keep
|
|
136
|
+
*/
|
|
137
|
+
export const create_output_tail = (max_bytes) => {
|
|
138
|
+
let chunks = [];
|
|
139
|
+
let size = 0;
|
|
140
|
+
let dropped = false;
|
|
141
|
+
return {
|
|
142
|
+
push: (chunk) => {
|
|
143
|
+
chunks.push(chunk);
|
|
144
|
+
size += chunk.length;
|
|
145
|
+
if (size <= max_bytes)
|
|
146
|
+
return;
|
|
147
|
+
dropped = true;
|
|
148
|
+
const joined = Buffer.concat(chunks).subarray(size - max_bytes);
|
|
149
|
+
chunks = [joined];
|
|
150
|
+
size = joined.length;
|
|
151
|
+
},
|
|
152
|
+
text: () => {
|
|
153
|
+
const text = Buffer.concat(chunks).toString('utf-8');
|
|
154
|
+
return dropped ? `[earlier output dropped]\n${text}` : text;
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
};
|
|
158
|
+
/** `code=N` or `signal=SIG` for a child's exit, as `ChildProcess`'s `'exit'` reports it. */
|
|
159
|
+
const format_exit = (code, signal) => signal !== null ? `signal=${signal}` : `code=${code}`;
|
|
77
160
|
/**
|
|
78
161
|
* Process-level cleanup registry — every `spawn_backend` registers its
|
|
79
162
|
* teardown here so vitest worker death or interactive Ctrl+C kills the
|
|
@@ -107,6 +190,9 @@ const install_process_handlers = () => {
|
|
|
107
190
|
};
|
|
108
191
|
process.on('SIGINT', () => passthrough_signal('SIGINT'));
|
|
109
192
|
process.on('SIGTERM', () => passthrough_signal('SIGTERM'));
|
|
193
|
+
// a closed terminal: without a handler the default action kills the process
|
|
194
|
+
// before `'exit'` runs, and the detached backends would keep their ports
|
|
195
|
+
process.on('SIGHUP', () => passthrough_signal('SIGHUP'));
|
|
110
196
|
};
|
|
111
197
|
/**
|
|
112
198
|
* Read the daemon token file. The file is `{"token": "<value>"}` JSON —
|
|
@@ -152,17 +238,31 @@ const read_daemon_token = async (path) => {
|
|
|
152
238
|
*
|
|
153
239
|
* Errors at any stage SIGTERM the child group before rethrowing — the
|
|
154
240
|
* caller never sees a half-started backend.
|
|
241
|
+
*
|
|
242
|
+
* @throws Error when `config.base_url`'s port already accepts connections,
|
|
243
|
+
* before anything is spawned; when the child exits before it is healthy
|
|
244
|
+
* (with its exit code or signal and stderr tail); or when the health probe
|
|
245
|
+
* or the daemon-token read times out
|
|
155
246
|
*/
|
|
156
247
|
export const spawn_backend = async (config) => {
|
|
157
248
|
if (config.start_command.length === 0) {
|
|
158
249
|
throw new Error(`spawn_backend(${config.name}): start_command is empty`);
|
|
159
250
|
}
|
|
251
|
+
// a process already on the port would answer the health probe and every
|
|
252
|
+
// request after it, so the run would drive it instead of this spawn
|
|
253
|
+
if (await is_port_accepting(config.base_url)) {
|
|
254
|
+
throw new Error(`spawn_backend(${config.name}): ${config.base_url} already accepts connections — ` +
|
|
255
|
+
'another cross run or a stale backend?');
|
|
256
|
+
}
|
|
160
257
|
// Write the bootstrap token file before spawn so the binary reads it
|
|
161
258
|
// at boot.
|
|
162
259
|
await mkdir(dirname(config.bootstrap.token_path), { recursive: true });
|
|
163
260
|
await writeFile(config.bootstrap.token_path, config.bootstrap.token, { mode: 0o600 });
|
|
261
|
+
// a token a previous run left would read as this binary's
|
|
262
|
+
await rm(config.bootstrap.daemon_token_path, { force: true });
|
|
164
263
|
install_process_handlers();
|
|
165
264
|
const [command, ...args] = config.start_command;
|
|
265
|
+
const spawned_at = performance.now();
|
|
166
266
|
const child = spawn(command, args, {
|
|
167
267
|
env: { ...process.env, ...config.env },
|
|
168
268
|
// Own process group so SIGTERM to the negative PID tears down the
|
|
@@ -170,11 +270,15 @@ export const spawn_backend = async (config) => {
|
|
|
170
270
|
detached: true,
|
|
171
271
|
stdio: ['ignore', 'pipe', 'pipe']
|
|
172
272
|
});
|
|
173
|
-
//
|
|
174
|
-
const
|
|
273
|
+
// Keep a bounded stderr tail so a crash surfaces with context.
|
|
274
|
+
const stderr_tail = create_output_tail(STDERR_TAIL_MAX_BYTES);
|
|
175
275
|
child.stderr?.on('data', (chunk) => {
|
|
176
|
-
|
|
276
|
+
stderr_tail.push(chunk);
|
|
177
277
|
});
|
|
278
|
+
const format_stderr_tail = () => {
|
|
279
|
+
const text = stderr_tail.text();
|
|
280
|
+
return text.length > 0 ? `\nstderr:\n${text}` : '';
|
|
281
|
+
};
|
|
178
282
|
// Drain stdout — discard, but the read is mandatory. `stdio: 'pipe'`
|
|
179
283
|
// leaves the stream paused until something consumes it; an unread
|
|
180
284
|
// pipe fills its OS buffer (~64KB pipe / ~208KB AF_UNIX socketpair on
|
|
@@ -191,67 +295,122 @@ export const spawn_backend = async (config) => {
|
|
|
191
295
|
// operational logging whose unbounded retention would leak across a
|
|
192
296
|
// long suite.
|
|
193
297
|
child.stdout?.on('data', () => { });
|
|
298
|
+
// how the child ended: an exit, or a spawn that never produced a process
|
|
299
|
+
// (a command that doesn't exist emits `'error'` and never `'exit'`)
|
|
194
300
|
let exit_info = null;
|
|
301
|
+
let started = false;
|
|
302
|
+
let teardown_invoked = false;
|
|
303
|
+
// The child leads its own process group (`detached: true`), so its pid is
|
|
304
|
+
// the group id; a descendant stays in the group after the child exits. Once
|
|
305
|
+
// the group is seen empty it is never signalled again: its id is a pid the
|
|
306
|
+
// kernel may hand to an unrelated process, whose new group a later
|
|
307
|
+
// `kill(-pid)` would hit — say a backend that crashed mid-run, torn down
|
|
308
|
+
// minutes later. One window stays open: a crash that left a descendant
|
|
309
|
+
// running keeps the flag false, and if that descendant exits on its own,
|
|
310
|
+
// the next signal goes out before its ESRCH sets the flag. Closing it needs
|
|
311
|
+
// a pidfd, which Node lacks.
|
|
312
|
+
let group_gone = false;
|
|
313
|
+
const signal_group = (signal) => {
|
|
314
|
+
if (child.pid === undefined || group_gone)
|
|
315
|
+
return false;
|
|
316
|
+
try {
|
|
317
|
+
// Negative pid → process group.
|
|
318
|
+
process.kill(-child.pid, signal);
|
|
319
|
+
return true;
|
|
320
|
+
}
|
|
321
|
+
catch (err) {
|
|
322
|
+
const code = err.code;
|
|
323
|
+
// ESRCH: no process is left in the group; EPERM: one is, but not ours
|
|
324
|
+
// to signal
|
|
325
|
+
if (code === 'ESRCH')
|
|
326
|
+
group_gone = true;
|
|
327
|
+
return code === 'EPERM';
|
|
328
|
+
}
|
|
329
|
+
};
|
|
195
330
|
child.on('exit', (code, signal) => {
|
|
196
|
-
exit_info = { code, signal };
|
|
331
|
+
exit_info = { kind: 'exit', code, signal };
|
|
332
|
+
// a crash that left no descendant marks the group gone now, before its
|
|
333
|
+
// id can be reused
|
|
334
|
+
signal_group(0);
|
|
335
|
+
// a startup failure is reported by the throw below; an exit teardown
|
|
336
|
+
// caused is expected
|
|
337
|
+
if (started && !teardown_invoked) {
|
|
338
|
+
console.error(`spawn_backend(${config.name}): backend exited unexpectedly (${format_exit(code, signal)})` +
|
|
339
|
+
format_stderr_tail());
|
|
340
|
+
}
|
|
197
341
|
});
|
|
198
|
-
|
|
199
|
-
|
|
342
|
+
child.on('error', (err) => {
|
|
343
|
+
if (child.pid === undefined) {
|
|
344
|
+
// never spawned — the health wait below reports it
|
|
345
|
+
exit_info ??= { kind: 'spawn_error', message: err.message };
|
|
346
|
+
}
|
|
347
|
+
else {
|
|
348
|
+
// Node emits `'error'` on a spawned child only from `child.kill()` or
|
|
349
|
+
// `child.send()`, neither of which this module calls (it signals the
|
|
350
|
+
// group through `process.kill`), so this branch is not expected to run;
|
|
351
|
+
// it logs rather than recording an exit, since `'exit'` still follows
|
|
352
|
+
console.error(`spawn_backend(${config.name}): ${err.message}`);
|
|
353
|
+
}
|
|
354
|
+
});
|
|
355
|
+
const exit_status = () => {
|
|
356
|
+
if (exit_info === null)
|
|
357
|
+
return null;
|
|
358
|
+
return exit_info.kind === 'spawn_error'
|
|
359
|
+
? `failed to spawn (${exit_info.message})`
|
|
360
|
+
: `exited (${format_exit(exit_info.code, exit_info.signal)})`;
|
|
361
|
+
};
|
|
362
|
+
/** Whether the child or any process left in its group is still running. */
|
|
363
|
+
const is_group_running = () => child.pid !== undefined && (exit_info === null || signal_group(0));
|
|
200
364
|
const teardown_sync = () => {
|
|
201
365
|
if (teardown_invoked)
|
|
202
366
|
return;
|
|
203
367
|
teardown_invoked = true;
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
process.kill(-child.pid, 'SIGTERM');
|
|
208
|
-
}
|
|
209
|
-
catch {
|
|
210
|
-
// Already dead; ignore.
|
|
211
|
-
}
|
|
212
|
-
}
|
|
368
|
+
// the group, not just the child: a descendant outlives a child that has
|
|
369
|
+
// already exited, and would hold the port or the database
|
|
370
|
+
signal_group('SIGTERM');
|
|
213
371
|
};
|
|
214
|
-
|
|
372
|
+
let teardown_done = null;
|
|
373
|
+
const teardown = () => {
|
|
215
374
|
teardown_sync();
|
|
216
375
|
live_teardowns.delete(teardown_sync);
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
}
|
|
376
|
+
return (teardown_done ??= wait_for_group_exit());
|
|
377
|
+
};
|
|
378
|
+
// Wait for the child and every process left in its group to exit, so callers
|
|
379
|
+
// can be sure the port is free. A backend that ignores SIGTERM — or whose
|
|
380
|
+
// graceful shutdown wedges (e.g. a runtime whose `server.stop()` never
|
|
381
|
+
// resolves) — would otherwise hold this wait forever and strand the run, so
|
|
382
|
+
// escalate to SIGKILL on the process group after a grace window. SIGKILL is
|
|
383
|
+
// uncatchable, so the group then exits. Defense-in-depth: the per-runtime
|
|
384
|
+
// adapter shutdown is the primary fix; this guarantees teardown completes
|
|
385
|
+
// regardless — bounded at a second grace window after the SIGKILL, which
|
|
386
|
+
// only a process stuck in the kernel outlasts.
|
|
387
|
+
const wait_for_group_exit = async () => {
|
|
388
|
+
const kill_at = Date.now() + TEARDOWN_SIGKILL_GRACE_MS;
|
|
389
|
+
const give_up_at = kill_at + TEARDOWN_SIGKILL_GRACE_MS;
|
|
390
|
+
let killed = false;
|
|
391
|
+
while (is_group_running()) {
|
|
392
|
+
const now = Date.now();
|
|
393
|
+
if (now >= give_up_at) {
|
|
394
|
+
console.error(`spawn_backend(${config.name}): teardown gave up with the process group still running`);
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
if (!killed && now >= kill_at) {
|
|
398
|
+
killed = true;
|
|
399
|
+
signal_group('SIGKILL');
|
|
400
|
+
}
|
|
401
|
+
await sleep(TEARDOWN_POLL_INTERVAL_MS);
|
|
402
|
+
}
|
|
244
403
|
};
|
|
245
404
|
live_teardowns.add(teardown_sync);
|
|
246
405
|
try {
|
|
247
|
-
await wait_for_health(`${config.base_url}${config.health_path}`, config.startup_timeout_ms,
|
|
406
|
+
await wait_for_health(`${config.base_url}${config.health_path}`, config.startup_timeout_ms, exit_status);
|
|
248
407
|
const daemon_token = await read_daemon_token(config.bootstrap.daemon_token_path);
|
|
408
|
+
started = true;
|
|
409
|
+
console.log(`spawn_backend(${config.name}): healthy in ${Math.round(performance.now() - spawned_at)}ms`);
|
|
249
410
|
return { config, child, daemon_token, teardown };
|
|
250
411
|
}
|
|
251
412
|
catch (err) {
|
|
252
413
|
await teardown();
|
|
253
|
-
|
|
254
|
-
const stderr_tail = stderr_dump.length > 0 ? `\nstderr:\n${stderr_dump}` : '';
|
|
255
|
-
throw new Error(`spawn_backend(${config.name}) failed: ${err.message}${stderr_tail}`);
|
|
414
|
+
throw new Error(`spawn_backend(${config.name}) failed: ${err.message}${format_stderr_tail()}`);
|
|
256
415
|
}
|
|
257
416
|
};
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import '../assert_dev_env.js';
|
|
2
|
+
import { type RoleSchemaResult } from '../../auth/role_schema.js';
|
|
3
|
+
import type { SessionOptions } from '../../auth/session_cookie.js';
|
|
4
|
+
import type { AppSurfaceSpec } from '../../http/surface.js';
|
|
5
|
+
import { type RpcEndpointsSuiteOption } from '../rpc_helpers.js';
|
|
6
|
+
import type { RpcSuccessFixtures } from '../rpc_round_trip.js';
|
|
7
|
+
import { type AccountLifecycleCrossTestOptions } from './account_lifecycle.js';
|
|
8
|
+
import { type ActorLookupCrossTestOptions } from './actor_lookup.js';
|
|
9
|
+
import { type AppSettingsCrossTestOptions } from './app_settings.js';
|
|
10
|
+
import { type BodySizeCrossTestOptions } from './body_size.js';
|
|
11
|
+
import { type BodySizeSmugglingCrossTestOptions } from './body_size_smuggling.js';
|
|
12
|
+
import type { BackendCapabilities } from './capabilities.js';
|
|
13
|
+
import { type CellGrantRoleCrossTestOptions } from './cell_grant_role.js';
|
|
14
|
+
import { type CookieAttributesCrossTestOptions } from './cookie_attributes.js';
|
|
15
|
+
import { type CredentialDeadlineCrossTestOptions } from './credential_deadline.js';
|
|
16
|
+
import { type CredentialHeaderRobustnessCrossTestOptions } from './credential_header_robustness.js';
|
|
17
|
+
import { type FactServingCrossTestOptions } from './fact_serving.js';
|
|
18
|
+
import { type IdentityParityCrossTestOptions } from './identity_parity.js';
|
|
19
|
+
import { type OriginCrossTestOptions } from './origin.js';
|
|
20
|
+
import { type OriginConformanceCrossTestOptions } from './origin_conformance.js';
|
|
21
|
+
import { type OriginScopeCrossTestOptions } from './origin_scope.js';
|
|
22
|
+
import { type PeerPingWsTestOptions } from './peer_ping_ws.js';
|
|
23
|
+
import { type QueryShapeCrossTestOptions } from './query_shape.js';
|
|
24
|
+
import { type ReadyCrossTestOptions } from './ready.js';
|
|
25
|
+
import { type RoleGrantOfferEnumerationCrossTestOptions } from './role_grant_offer_enumeration.js';
|
|
26
|
+
import { type RoleGrantOfferLifecycleCrossTestOptions } from './role_grant_offer_lifecycle.js';
|
|
27
|
+
import { type RoleGrantOfferNotificationWsTestOptions } from './role_grant_offer_notification_ws.js';
|
|
28
|
+
import { type RoleGrantParticipationCrossTestOptions } from './role_grant_participation.js';
|
|
29
|
+
import { type RoleGrantRoleGrammarCrossTestOptions } from './role_grant_role_grammar.js';
|
|
30
|
+
import { type RpcAdversarialCrossTestOptions } from './rpc_adversarial.js';
|
|
31
|
+
import { type SessionCapCrossTestOptions } from './session_cap.js';
|
|
32
|
+
import { type SessionCookieCodecCrossTestOptions } from './session_cookie_codec.js';
|
|
33
|
+
import { type CrossProcessSetupOptions, type ReconstructedBootstrappedBackendHandle, type RpcPathCapabilityGatedCrossSuiteOptions } from './setup.js';
|
|
34
|
+
import { type SimpleRequestCrossTestOptions } from './simple_request.js';
|
|
35
|
+
import { type CrossProcessSseTestOptions } from './sse_round_trip.js';
|
|
36
|
+
import { type StandardCrossProcessTestOptions } from './standard.js';
|
|
37
|
+
import { type TestingBackdoorCrossTestOptions } from './testing_backdoor.js';
|
|
38
|
+
import { type TokenLifetimeCrossTestOptions } from './token_lifetime.js';
|
|
39
|
+
import { type TokenScopeSurfaceCrossTestOptions } from './token_scope_surface.js';
|
|
40
|
+
import { type TransportCompositionCrossTestOptions } from './transport_composition.js';
|
|
41
|
+
import { type WsConnectionCapCrossTestOptions } from './ws_connection_cap.js';
|
|
42
|
+
import { type WsInboundDispatchCrossTestOptions } from './ws_inbound_dispatch.js';
|
|
43
|
+
import { type WsOutboundOverflowCrossTestOptions } from './ws_outbound_overflow.js';
|
|
44
|
+
import { type WsRoleGatedCrossTestOptions } from './ws_role_gated.js';
|
|
45
|
+
import { type CrossProcessWsTestOptions } from './ws_round_trip.js';
|
|
46
|
+
/**
|
|
47
|
+
* Every shipped suite `describe_spine_cross_suites` runs, each named by its
|
|
48
|
+
* module under `testing/cross_backend/` (`ws_round_trip` is
|
|
49
|
+
* `describe_cross_process_ws_tests`, `standard` the standard bundle). Closed: a
|
|
50
|
+
* guard test holds it, with `STANDALONE_CROSS_SUITES`, to every module that
|
|
51
|
+
* exports a `describe_*` suite, so a new suite fails until it is registered.
|
|
52
|
+
*/
|
|
53
|
+
export declare const SUITE_NAMES: readonly ["account_lifecycle", "actor_lookup", "app_settings", "body_size", "body_size_smuggling", "cell_crud", "cell_gated_create", "cell_grant_role", "cell_moderate", "cell_ref_admission", "cell_relations", "cookie_attributes", "credential_deadline", "credential_header_robustness", "fact_serving", "identity_parity", "origin", "origin_conformance", "origin_scope", "peer_ping_ws", "query_shape", "ready", "role_grant_offer_enumeration", "role_grant_offer_lifecycle", "role_grant_offer_notification_ws", "role_grant_participation", "role_grant_role_grammar", "rpc_adversarial", "session_cap", "session_cookie_codec", "simple_request", "sse_round_trip", "standard", "testing_backdoor", "token_lifetime", "token_scope_surface", "transport_composition", "ws_connection_cap", "ws_inbound_dispatch", "ws_outbound_overflow", "ws_role_gated", "ws_round_trip"];
|
|
54
|
+
/** A shipped single-backend cross suite, named by its module. */
|
|
55
|
+
export type SuiteName = (typeof SUITE_NAMES)[number];
|
|
56
|
+
/** A shipped suite module `describe_spine_cross_suites` leaves out. */
|
|
57
|
+
export type StandaloneSuiteName = 'conformance_table' | 'differential' | 'login_security' | 'ws_action_rate_limit';
|
|
58
|
+
/**
|
|
59
|
+
* The shipped suite modules `describe_spine_cross_suites` leaves out, each with
|
|
60
|
+
* why. Their entry points stay as they are; a consumer calls them beside the
|
|
61
|
+
* one call.
|
|
62
|
+
*/
|
|
63
|
+
export declare const STANDALONE_CROSS_SUITES: Readonly<Record<StandaloneSuiteName, string>>;
|
|
64
|
+
/** The options each suite takes, by `SuiteName` — what `overrides` entries are partials of. */
|
|
65
|
+
export interface SuiteOptionsMap {
|
|
66
|
+
account_lifecycle: AccountLifecycleCrossTestOptions;
|
|
67
|
+
actor_lookup: ActorLookupCrossTestOptions;
|
|
68
|
+
app_settings: AppSettingsCrossTestOptions;
|
|
69
|
+
body_size: BodySizeCrossTestOptions;
|
|
70
|
+
body_size_smuggling: BodySizeSmugglingCrossTestOptions;
|
|
71
|
+
cell_crud: RpcPathCapabilityGatedCrossSuiteOptions;
|
|
72
|
+
cell_gated_create: RpcPathCapabilityGatedCrossSuiteOptions;
|
|
73
|
+
cell_grant_role: CellGrantRoleCrossTestOptions;
|
|
74
|
+
cell_moderate: RpcPathCapabilityGatedCrossSuiteOptions;
|
|
75
|
+
cell_ref_admission: RpcPathCapabilityGatedCrossSuiteOptions;
|
|
76
|
+
cell_relations: RpcPathCapabilityGatedCrossSuiteOptions;
|
|
77
|
+
cookie_attributes: CookieAttributesCrossTestOptions;
|
|
78
|
+
credential_deadline: CredentialDeadlineCrossTestOptions;
|
|
79
|
+
credential_header_robustness: CredentialHeaderRobustnessCrossTestOptions;
|
|
80
|
+
fact_serving: FactServingCrossTestOptions;
|
|
81
|
+
identity_parity: IdentityParityCrossTestOptions;
|
|
82
|
+
origin: OriginCrossTestOptions;
|
|
83
|
+
origin_conformance: OriginConformanceCrossTestOptions;
|
|
84
|
+
origin_scope: OriginScopeCrossTestOptions;
|
|
85
|
+
peer_ping_ws: PeerPingWsTestOptions;
|
|
86
|
+
query_shape: QueryShapeCrossTestOptions;
|
|
87
|
+
ready: ReadyCrossTestOptions;
|
|
88
|
+
role_grant_offer_enumeration: RoleGrantOfferEnumerationCrossTestOptions;
|
|
89
|
+
role_grant_offer_lifecycle: RoleGrantOfferLifecycleCrossTestOptions;
|
|
90
|
+
role_grant_offer_notification_ws: RoleGrantOfferNotificationWsTestOptions;
|
|
91
|
+
role_grant_participation: RoleGrantParticipationCrossTestOptions;
|
|
92
|
+
role_grant_role_grammar: RoleGrantRoleGrammarCrossTestOptions;
|
|
93
|
+
rpc_adversarial: RpcAdversarialCrossTestOptions;
|
|
94
|
+
session_cap: SessionCapCrossTestOptions;
|
|
95
|
+
session_cookie_codec: SessionCookieCodecCrossTestOptions;
|
|
96
|
+
simple_request: SimpleRequestCrossTestOptions;
|
|
97
|
+
sse_round_trip: CrossProcessSseTestOptions;
|
|
98
|
+
standard: StandardCrossProcessTestOptions;
|
|
99
|
+
testing_backdoor: TestingBackdoorCrossTestOptions;
|
|
100
|
+
token_lifetime: TokenLifetimeCrossTestOptions;
|
|
101
|
+
token_scope_surface: TokenScopeSurfaceCrossTestOptions;
|
|
102
|
+
transport_composition: TransportCompositionCrossTestOptions;
|
|
103
|
+
ws_connection_cap: WsConnectionCapCrossTestOptions;
|
|
104
|
+
ws_inbound_dispatch: WsInboundDispatchCrossTestOptions;
|
|
105
|
+
ws_outbound_overflow: WsOutboundOverflowCrossTestOptions;
|
|
106
|
+
ws_role_gated: WsRoleGatedCrossTestOptions;
|
|
107
|
+
ws_round_trip: CrossProcessWsTestOptions;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* One suite's override: options shallow-merged over the ones the handle gives,
|
|
111
|
+
* or a function of those derived options returning them — for a change that
|
|
112
|
+
* builds on a derived value (a seeded `setup_test`, the capabilities) rather
|
|
113
|
+
* than restating it.
|
|
114
|
+
*/
|
|
115
|
+
export type SuiteOverride<K extends SuiteName> = Partial<SuiteOptionsMap[K]> | ((derived: SuiteOptionsMap[K]) => Partial<SuiteOptionsMap[K]>);
|
|
116
|
+
/** Per-suite option overrides, each merged over the options the handle gives. */
|
|
117
|
+
export type SuiteOverrides = {
|
|
118
|
+
readonly [K in SuiteName]?: SuiteOverride<K>;
|
|
119
|
+
};
|
|
120
|
+
/** The suite options a backend's `BackendConfig` supplies. */
|
|
121
|
+
export interface CrossSuiteHandleOptions {
|
|
122
|
+
readonly capabilities: BackendCapabilities;
|
|
123
|
+
readonly base_url: string;
|
|
124
|
+
readonly rpc_path: string;
|
|
125
|
+
readonly ws_path: string;
|
|
126
|
+
readonly sse_path: string | undefined;
|
|
127
|
+
readonly cookie_name: string;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* The suite options a handle's `config` supplies — the fields most cross
|
|
131
|
+
* suites take beside `setup_test`. For a suite called on its own:
|
|
132
|
+
* `describe_ready_cross_tests({setup_test, ...to_cross_suite_options(handle)})`
|
|
133
|
+
* passes extra fields the suite's type doesn't list, so destructure what it
|
|
134
|
+
* takes instead when calling it with an object literal.
|
|
135
|
+
*/
|
|
136
|
+
export declare const to_cross_suite_options: (handle: Pick<ReconstructedBootstrappedBackendHandle, "config">) => CrossSuiteHandleOptions;
|
|
137
|
+
/**
|
|
138
|
+
* The roles the role-shaped suites use, for a backend whose registry lacks
|
|
139
|
+
* the spine's own. Set them here rather than in `overrides`: the call seeds
|
|
140
|
+
* the holder each needs.
|
|
141
|
+
*/
|
|
142
|
+
export interface SpineSuiteRoles {
|
|
143
|
+
/**
|
|
144
|
+
* The role `cell_grant_role`'s grants name, seeded on its holder at reset.
|
|
145
|
+
* Default `SPINE_CELL_EDITOR_ROLE`. `ROLE_KEEPER` serves a backend with only
|
|
146
|
+
* the builtin roles; `ROLE_ADMIN` can't (an admin reaches every cell).
|
|
147
|
+
*/
|
|
148
|
+
readonly cell_grant?: string;
|
|
149
|
+
/**
|
|
150
|
+
* The admin-grantable role `role_grant_offer_lifecycle` offers and
|
|
151
|
+
* `role_grant_participation` confers. Default `SPINE_PARTICIPANT_ROLE`;
|
|
152
|
+
* `ROLE_ADMIN` serves a backend with only the builtin roles (the scoped
|
|
153
|
+
* assign case then skips, as a builtin is global-only).
|
|
154
|
+
*/
|
|
155
|
+
readonly conferral?: string;
|
|
156
|
+
}
|
|
157
|
+
/** Options for `describe_spine_cross_suites`. */
|
|
158
|
+
export interface SpineCrossSuitesOptions {
|
|
159
|
+
/** The declared surface — the standard bundle and `rpc_adversarial` enumerate it. */
|
|
160
|
+
readonly surface_source: AppSurfaceSpec;
|
|
161
|
+
/** The backend's session config, for the standard bundle. */
|
|
162
|
+
readonly session_options: SessionOptions<string>;
|
|
163
|
+
/** The backend's RPC endpoints, for the standard bundle. */
|
|
164
|
+
readonly rpc_endpoints: RpcEndpointsSuiteOption;
|
|
165
|
+
/**
|
|
166
|
+
* The RPC endpoints the backend live-mounts, for the methods it keeps off
|
|
167
|
+
* the declared surface (cell verbs, opt-in resolvers, `_testing_*`
|
|
168
|
+
* backdoors); given, `rpc_adversarial` sends them bad envelopes and params
|
|
169
|
+
* too. A backend's whole live mount is a fine value — a declared method
|
|
170
|
+
* still runs once, from the declared surface.
|
|
171
|
+
*/
|
|
172
|
+
readonly live_rpc_endpoints?: RpcEndpointsSuiteOption;
|
|
173
|
+
/** The backend's role schema; given, the standard bundle runs its admin suite. */
|
|
174
|
+
readonly roles?: RoleSchemaResult;
|
|
175
|
+
/**
|
|
176
|
+
* Setup options every suite's `setup_test` starts from — a signup path the
|
|
177
|
+
* backend mounts elsewhere, `reject_unknown_audit_metadata_keys` for a
|
|
178
|
+
* backend's own spine suite. A suite's own seeding is added to it (the role,
|
|
179
|
+
* account and actor lists concatenate).
|
|
180
|
+
*/
|
|
181
|
+
readonly setup?: CrossProcessSetupOptions;
|
|
182
|
+
/**
|
|
183
|
+
* Suites this backend doesn't run, each with a non-empty reason. Each shows
|
|
184
|
+
* in the run as one skipped test carrying the reason.
|
|
185
|
+
*/
|
|
186
|
+
readonly exclude?: Readonly<Partial<Record<SuiteName, string>>>;
|
|
187
|
+
/** Per-suite option overrides, a shallow merge over what the handle gives. */
|
|
188
|
+
readonly overrides?: SuiteOverrides;
|
|
189
|
+
/** The roles the role-shaped suites use, when the backend lacks the spine's own. */
|
|
190
|
+
readonly suite_roles?: SpineSuiteRoles;
|
|
191
|
+
/**
|
|
192
|
+
* The roles the backend's WS upgrade on `ws_path` requires (an admin-gated
|
|
193
|
+
* `/api/ws`: `[ROLE_ADMIN]`). Given, the suites that open sockets for
|
|
194
|
+
* accounts they create — `credential_deadline`, `session_cap`,
|
|
195
|
+
* `ws_round_trip` — create them holding these (`ws_account_roles`), and
|
|
196
|
+
* `role_grant_offer_notification_ws` expects revoking one to close the
|
|
197
|
+
* socket (`ws_required_roles`). Each must be admin-grantable.
|
|
198
|
+
*/
|
|
199
|
+
readonly ws_required_roles?: ReadonlyArray<string>;
|
|
200
|
+
/**
|
|
201
|
+
* The backend's request-body cap on `rpc_path`, in bytes, when it isn't the
|
|
202
|
+
* spine default (`SPINE_BODY_LIMIT_DEFAULT_BYTES`): the boundary
|
|
203
|
+
* `body_size`, `body_size_smuggling` and `transport_composition`'s RPC
|
|
204
|
+
* over-cap row probe.
|
|
205
|
+
*/
|
|
206
|
+
readonly rpc_max_body_bytes?: number;
|
|
207
|
+
/**
|
|
208
|
+
* The backend's inbound WebSocket message cap on `ws_path`, in bytes, when
|
|
209
|
+
* it isn't the spine default (`DEFAULT_WS_MAX_MESSAGE_BYTES`): the boundary
|
|
210
|
+
* `ws_round_trip`'s oversized-message case sends past.
|
|
211
|
+
*/
|
|
212
|
+
readonly ws_max_message_bytes?: number;
|
|
213
|
+
/** Forwarded to the standard bundle (`StandardCrossProcessTestOptions.rpc_success_fixtures`). */
|
|
214
|
+
readonly rpc_success_fixtures?: RpcSuccessFixtures;
|
|
215
|
+
/** Forwarded to the standard bundle (`StandardCrossProcessTestOptions.rpc_skip_methods`). */
|
|
216
|
+
readonly rpc_skip_methods?: Array<string>;
|
|
217
|
+
/** Forwarded to the standard bundle (`StandardCrossProcessTestOptions.rpc_input_overrides`). */
|
|
218
|
+
readonly rpc_input_overrides?: Map<string, Record<string, unknown>>;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Run every shipped single-backend cross suite against one spawned backend —
|
|
222
|
+
* see the module doc for what the options add and what stays outside.
|
|
223
|
+
*
|
|
224
|
+
* @param handle - the backend, as `inject_backend_handle()` returns it
|
|
225
|
+
* @param options - the declared surface, plus excludes and overrides
|
|
226
|
+
* @throws Error - on an exclude with no reason, an unknown suite name, a suite
|
|
227
|
+
* both excluded and overridden, or a suite missing an input the handle
|
|
228
|
+
* doesn't carry
|
|
229
|
+
*/
|
|
230
|
+
export declare const describe_spine_cross_suites: (handle: ReconstructedBootstrappedBackendHandle, options: SpineCrossSuitesOptions) => void;
|
|
231
|
+
//# sourceMappingURL=spine_suites.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spine_suites.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/spine_suites.ts"],"names":[],"mappings":"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"}
|