@opensip-cli/simulation 0.1.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/LICENSE +202 -0
- package/NOTICE +8 -0
- package/README.md +31 -0
- package/dist/__tests__/internal-surface.test.d.ts +9 -0
- package/dist/__tests__/internal-surface.test.d.ts.map +1 -0
- package/dist/__tests__/internal-surface.test.js +38 -0
- package/dist/__tests__/internal-surface.test.js.map +1 -0
- package/dist/__tests__/plugin-loader.test.d.ts +2 -0
- package/dist/__tests__/plugin-loader.test.d.ts.map +1 -0
- package/dist/__tests__/plugin-loader.test.js +64 -0
- package/dist/__tests__/plugin-loader.test.js.map +1 -0
- package/dist/__tests__/public-api.test.d.ts +15 -0
- package/dist/__tests__/public-api.test.d.ts.map +1 -0
- package/dist/__tests__/public-api.test.js +73 -0
- package/dist/__tests__/public-api.test.js.map +1 -0
- package/dist/__tests__/registry-cross-kind.test.d.ts +6 -0
- package/dist/__tests__/registry-cross-kind.test.d.ts.map +1 -0
- package/dist/__tests__/registry-cross-kind.test.js +86 -0
- package/dist/__tests__/registry-cross-kind.test.js.map +1 -0
- package/dist/__tests__/scenario-execution.test.d.ts +10 -0
- package/dist/__tests__/scenario-execution.test.d.ts.map +1 -0
- package/dist/__tests__/scenario-execution.test.js +92 -0
- package/dist/__tests__/scenario-execution.test.js.map +1 -0
- package/dist/__tests__/sim-capability-contract.test.d.ts +10 -0
- package/dist/__tests__/sim-capability-contract.test.d.ts.map +1 -0
- package/dist/__tests__/sim-capability-contract.test.js +131 -0
- package/dist/__tests__/sim-capability-contract.test.js.map +1 -0
- package/dist/__tests__/sim-config-schema.test.d.ts +5 -0
- package/dist/__tests__/sim-config-schema.test.d.ts.map +1 -0
- package/dist/__tests__/sim-config-schema.test.js +23 -0
- package/dist/__tests__/sim-config-schema.test.js.map +1 -0
- package/dist/__tests__/sim-failure-signal.test.d.ts +10 -0
- package/dist/__tests__/sim-failure-signal.test.d.ts.map +1 -0
- package/dist/__tests__/sim-failure-signal.test.js +86 -0
- package/dist/__tests__/sim-failure-signal.test.js.map +1 -0
- package/dist/__tests__/surviving-surface-edges.test.d.ts +10 -0
- package/dist/__tests__/surviving-surface-edges.test.d.ts.map +1 -0
- package/dist/__tests__/surviving-surface-edges.test.js +122 -0
- package/dist/__tests__/surviving-surface-edges.test.js.map +1 -0
- package/dist/__tests__/test-utils/targets.d.ts +26 -0
- package/dist/__tests__/test-utils/targets.d.ts.map +1 -0
- package/dist/__tests__/test-utils/targets.js +38 -0
- package/dist/__tests__/test-utils/targets.js.map +1 -0
- package/dist/__tests__/test-utils/with-sim-scope.d.ts +12 -0
- package/dist/__tests__/test-utils/with-sim-scope.d.ts.map +1 -0
- package/dist/__tests__/test-utils/with-sim-scope.js +22 -0
- package/dist/__tests__/test-utils/with-sim-scope.js.map +1 -0
- package/dist/__tests__/tool-live-view.test.d.ts +20 -0
- package/dist/__tests__/tool-live-view.test.d.ts.map +1 -0
- package/dist/__tests__/tool-live-view.test.js +146 -0
- package/dist/__tests__/tool-live-view.test.js.map +1 -0
- package/dist/__tests__/tool-show-mode.test.d.ts +10 -0
- package/dist/__tests__/tool-show-mode.test.d.ts.map +1 -0
- package/dist/__tests__/tool-show-mode.test.js +156 -0
- package/dist/__tests__/tool-show-mode.test.js.map +1 -0
- package/dist/__tests__/tool.test.d.ts +15 -0
- package/dist/__tests__/tool.test.d.ts.map +1 -0
- package/dist/__tests__/tool.test.js +250 -0
- package/dist/__tests__/tool.test.js.map +1 -0
- package/dist/cli/__tests__/sim-config.test.d.ts +2 -0
- package/dist/cli/__tests__/sim-config.test.d.ts.map +1 -0
- package/dist/cli/__tests__/sim-config.test.js +94 -0
- package/dist/cli/__tests__/sim-config.test.js.map +1 -0
- package/dist/cli/__tests__/sim-runner.test.d.ts +23 -0
- package/dist/cli/__tests__/sim-runner.test.d.ts.map +1 -0
- package/dist/cli/__tests__/sim-runner.test.js +188 -0
- package/dist/cli/__tests__/sim-runner.test.js.map +1 -0
- package/dist/cli/__tests__/sim-worker.test.d.ts +12 -0
- package/dist/cli/__tests__/sim-worker.test.d.ts.map +1 -0
- package/dist/cli/__tests__/sim-worker.test.js +69 -0
- package/dist/cli/__tests__/sim-worker.test.js.map +1 -0
- package/dist/cli/__tests__/sim.test.d.ts +2 -0
- package/dist/cli/__tests__/sim.test.d.ts.map +1 -0
- package/dist/cli/__tests__/sim.test.js +232 -0
- package/dist/cli/__tests__/sim.test.js.map +1 -0
- package/dist/cli/sim-config-schema.d.ts +30 -0
- package/dist/cli/sim-config-schema.d.ts.map +1 -0
- package/dist/cli/sim-config-schema.js +33 -0
- package/dist/cli/sim-config-schema.js.map +1 -0
- package/dist/cli/sim-config.d.ts +22 -0
- package/dist/cli/sim-config.d.ts.map +1 -0
- package/dist/cli/sim-config.js +73 -0
- package/dist/cli/sim-config.js.map +1 -0
- package/dist/cli/sim-runner.d.ts +60 -0
- package/dist/cli/sim-runner.d.ts.map +1 -0
- package/dist/cli/sim-runner.js +175 -0
- package/dist/cli/sim-runner.js.map +1 -0
- package/dist/cli/sim-worker.d.ts +24 -0
- package/dist/cli/sim-worker.d.ts.map +1 -0
- package/dist/cli/sim-worker.js +65 -0
- package/dist/cli/sim-worker.js.map +1 -0
- package/dist/cli/sim.d.ts +56 -0
- package/dist/cli/sim.d.ts.map +1 -0
- package/dist/cli/sim.js +265 -0
- package/dist/cli/sim.js.map +1 -0
- package/dist/framework/__tests__/assertions.test.d.ts +2 -0
- package/dist/framework/__tests__/assertions.test.d.ts.map +1 -0
- package/dist/framework/__tests__/assertions.test.js +122 -0
- package/dist/framework/__tests__/assertions.test.js.map +1 -0
- package/dist/framework/__tests__/misc-coverage.test.d.ts +18 -0
- package/dist/framework/__tests__/misc-coverage.test.d.ts.map +1 -0
- package/dist/framework/__tests__/misc-coverage.test.js +142 -0
- package/dist/framework/__tests__/misc-coverage.test.js.map +1 -0
- package/dist/framework/__tests__/resolve-metric.test.d.ts +12 -0
- package/dist/framework/__tests__/resolve-metric.test.d.ts.map +1 -0
- package/dist/framework/__tests__/resolve-metric.test.js +124 -0
- package/dist/framework/__tests__/resolve-metric.test.js.map +1 -0
- package/dist/framework/__tests__/result-builder.test.d.ts +2 -0
- package/dist/framework/__tests__/result-builder.test.d.ts.map +1 -0
- package/dist/framework/__tests__/result-builder.test.js +180 -0
- package/dist/framework/__tests__/result-builder.test.js.map +1 -0
- package/dist/framework/__tests__/scenario-logger.test.d.ts +9 -0
- package/dist/framework/__tests__/scenario-logger.test.d.ts.map +1 -0
- package/dist/framework/__tests__/scenario-logger.test.js +110 -0
- package/dist/framework/__tests__/scenario-logger.test.js.map +1 -0
- package/dist/framework/__tests__/validation.test.d.ts +9 -0
- package/dist/framework/__tests__/validation.test.d.ts.map +1 -0
- package/dist/framework/__tests__/validation.test.js +126 -0
- package/dist/framework/__tests__/validation.test.js.map +1 -0
- package/dist/framework/assertions.d.ts +106 -0
- package/dist/framework/assertions.d.ts.map +1 -0
- package/dist/framework/assertions.js +256 -0
- package/dist/framework/assertions.js.map +1 -0
- package/dist/framework/execution/__tests__/execution-engine.test.d.ts +9 -0
- package/dist/framework/execution/__tests__/execution-engine.test.d.ts.map +1 -0
- package/dist/framework/execution/__tests__/execution-engine.test.js +138 -0
- package/dist/framework/execution/__tests__/execution-engine.test.js.map +1 -0
- package/dist/framework/execution/__tests__/fault-builders.test.d.ts +5 -0
- package/dist/framework/execution/__tests__/fault-builders.test.d.ts.map +1 -0
- package/dist/framework/execution/__tests__/fault-builders.test.js +23 -0
- package/dist/framework/execution/__tests__/fault-builders.test.js.map +1 -0
- package/dist/framework/execution/__tests__/fault-model.test.d.ts +6 -0
- package/dist/framework/execution/__tests__/fault-model.test.d.ts.map +1 -0
- package/dist/framework/execution/__tests__/fault-model.test.js +64 -0
- package/dist/framework/execution/__tests__/fault-model.test.js.map +1 -0
- package/dist/framework/execution/__tests__/http-target.test.d.ts +5 -0
- package/dist/framework/execution/__tests__/http-target.test.d.ts.map +1 -0
- package/dist/framework/execution/__tests__/http-target.test.js +36 -0
- package/dist/framework/execution/__tests__/http-target.test.js.map +1 -0
- package/dist/framework/execution/__tests__/run-load-window.test.d.ts +7 -0
- package/dist/framework/execution/__tests__/run-load-window.test.d.ts.map +1 -0
- package/dist/framework/execution/__tests__/run-load-window.test.js +89 -0
- package/dist/framework/execution/__tests__/run-load-window.test.js.map +1 -0
- package/dist/framework/execution/execution-engine.d.ts +55 -0
- package/dist/framework/execution/execution-engine.d.ts.map +1 -0
- package/dist/framework/execution/execution-engine.js +111 -0
- package/dist/framework/execution/execution-engine.js.map +1 -0
- package/dist/framework/execution/fault-builders.d.ts +26 -0
- package/dist/framework/execution/fault-builders.d.ts.map +1 -0
- package/dist/framework/execution/fault-builders.js +24 -0
- package/dist/framework/execution/fault-builders.js.map +1 -0
- package/dist/framework/execution/fault-model.d.ts +49 -0
- package/dist/framework/execution/fault-model.d.ts.map +1 -0
- package/dist/framework/execution/fault-model.js +108 -0
- package/dist/framework/execution/fault-model.js.map +1 -0
- package/dist/framework/execution/fault-spec.d.ts +40 -0
- package/dist/framework/execution/fault-spec.d.ts.map +1 -0
- package/dist/framework/execution/fault-spec.js +23 -0
- package/dist/framework/execution/fault-spec.js.map +1 -0
- package/dist/framework/execution/http-target.d.ts +34 -0
- package/dist/framework/execution/http-target.d.ts.map +1 -0
- package/dist/framework/execution/http-target.js +41 -0
- package/dist/framework/execution/http-target.js.map +1 -0
- package/dist/framework/execution/latency-tracker.d.ts +44 -0
- package/dist/framework/execution/latency-tracker.d.ts.map +1 -0
- package/dist/framework/execution/latency-tracker.js +76 -0
- package/dist/framework/execution/latency-tracker.js.map +1 -0
- package/dist/framework/execution/run-load-window.d.ts +45 -0
- package/dist/framework/execution/run-load-window.d.ts.map +1 -0
- package/dist/framework/execution/run-load-window.js +136 -0
- package/dist/framework/execution/run-load-window.js.map +1 -0
- package/dist/framework/execution/scenario-aborted-error.d.ts +14 -0
- package/dist/framework/execution/scenario-aborted-error.d.ts.map +1 -0
- package/dist/framework/execution/scenario-aborted-error.js +24 -0
- package/dist/framework/execution/scenario-aborted-error.js.map +1 -0
- package/dist/framework/execution/target.d.ts +35 -0
- package/dist/framework/execution/target.d.ts.map +1 -0
- package/dist/framework/execution/target.js +21 -0
- package/dist/framework/execution/target.js.map +1 -0
- package/dist/framework/registry.d.ts +67 -0
- package/dist/framework/registry.d.ts.map +1 -0
- package/dist/framework/registry.js +113 -0
- package/dist/framework/registry.js.map +1 -0
- package/dist/framework/resolve-metric.d.ts +79 -0
- package/dist/framework/resolve-metric.d.ts.map +1 -0
- package/dist/framework/resolve-metric.js +135 -0
- package/dist/framework/resolve-metric.js.map +1 -0
- package/dist/framework/result-builder.d.ts +72 -0
- package/dist/framework/result-builder.d.ts.map +1 -0
- package/dist/framework/result-builder.js +214 -0
- package/dist/framework/result-builder.js.map +1 -0
- package/dist/framework/result-renderers.d.ts +37 -0
- package/dist/framework/result-renderers.d.ts.map +1 -0
- package/dist/framework/result-renderers.js +62 -0
- package/dist/framework/result-renderers.js.map +1 -0
- package/dist/framework/runnable-scenario.d.ts +37 -0
- package/dist/framework/runnable-scenario.d.ts.map +1 -0
- package/dist/framework/runnable-scenario.js +9 -0
- package/dist/framework/runnable-scenario.js.map +1 -0
- package/dist/framework/scenario-executor-result.d.ts +44 -0
- package/dist/framework/scenario-executor-result.d.ts.map +1 -0
- package/dist/framework/scenario-executor-result.js +13 -0
- package/dist/framework/scenario-executor-result.js.map +1 -0
- package/dist/framework/scenario-logger.d.ts +18 -0
- package/dist/framework/scenario-logger.d.ts.map +1 -0
- package/dist/framework/scenario-logger.js +39 -0
- package/dist/framework/scenario-logger.js.map +1 -0
- package/dist/framework/scenario-metric-key.d.ts +24 -0
- package/dist/framework/scenario-metric-key.d.ts.map +1 -0
- package/dist/framework/scenario-metric-key.js +17 -0
- package/dist/framework/scenario-metric-key.js.map +1 -0
- package/dist/framework/validation.d.ts +83 -0
- package/dist/framework/validation.d.ts.map +1 -0
- package/dist/framework/validation.js +93 -0
- package/dist/framework/validation.js.map +1 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +53 -0
- package/dist/index.js.map +1 -0
- package/dist/internal.d.ts +19 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +16 -0
- package/dist/internal.js.map +1 -0
- package/dist/kinds/chaos/__tests__/executor.test.d.ts +6 -0
- package/dist/kinds/chaos/__tests__/executor.test.d.ts.map +1 -0
- package/dist/kinds/chaos/__tests__/executor.test.js +117 -0
- package/dist/kinds/chaos/__tests__/executor.test.js.map +1 -0
- package/dist/kinds/chaos/config.d.ts +48 -0
- package/dist/kinds/chaos/config.d.ts.map +1 -0
- package/dist/kinds/chaos/config.js +15 -0
- package/dist/kinds/chaos/config.js.map +1 -0
- package/dist/kinds/chaos/define.d.ts +32 -0
- package/dist/kinds/chaos/define.d.ts.map +1 -0
- package/dist/kinds/chaos/define.js +111 -0
- package/dist/kinds/chaos/define.js.map +1 -0
- package/dist/kinds/chaos/executor.d.ts +21 -0
- package/dist/kinds/chaos/executor.d.ts.map +1 -0
- package/dist/kinds/chaos/executor.js +107 -0
- package/dist/kinds/chaos/executor.js.map +1 -0
- package/dist/kinds/chaos/result.d.ts +43 -0
- package/dist/kinds/chaos/result.d.ts.map +1 -0
- package/dist/kinds/chaos/result.js +12 -0
- package/dist/kinds/chaos/result.js.map +1 -0
- package/dist/kinds/load/__tests__/executor.test.d.ts +6 -0
- package/dist/kinds/load/__tests__/executor.test.d.ts.map +1 -0
- package/dist/kinds/load/__tests__/executor.test.js +75 -0
- package/dist/kinds/load/__tests__/executor.test.js.map +1 -0
- package/dist/kinds/load/config.d.ts +30 -0
- package/dist/kinds/load/config.d.ts.map +1 -0
- package/dist/kinds/load/config.js +9 -0
- package/dist/kinds/load/config.js.map +1 -0
- package/dist/kinds/load/define.d.ts +47 -0
- package/dist/kinds/load/define.d.ts.map +1 -0
- package/dist/kinds/load/define.js +76 -0
- package/dist/kinds/load/define.js.map +1 -0
- package/dist/kinds/load/executor.d.ts +16 -0
- package/dist/kinds/load/executor.d.ts.map +1 -0
- package/dist/kinds/load/executor.js +90 -0
- package/dist/kinds/load/executor.js.map +1 -0
- package/dist/kinds/load/result.d.ts +21 -0
- package/dist/kinds/load/result.d.ts.map +1 -0
- package/dist/kinds/load/result.js +10 -0
- package/dist/kinds/load/result.js.map +1 -0
- package/dist/persistence/session-payload.d.ts +32 -0
- package/dist/persistence/session-payload.d.ts.map +1 -0
- package/dist/persistence/session-payload.js +46 -0
- package/dist/persistence/session-payload.js.map +1 -0
- package/dist/persistence/session-replay.d.ts +13 -0
- package/dist/persistence/session-replay.d.ts.map +1 -0
- package/dist/persistence/session-replay.js +76 -0
- package/dist/persistence/session-replay.js.map +1 -0
- package/dist/persistence/session-replay.test.d.ts +10 -0
- package/dist/persistence/session-replay.test.d.ts.map +1 -0
- package/dist/persistence/session-replay.test.js +169 -0
- package/dist/persistence/session-replay.test.js.map +1 -0
- package/dist/plugins/__tests__/loader-scenarios.test.d.ts +12 -0
- package/dist/plugins/__tests__/loader-scenarios.test.d.ts.map +1 -0
- package/dist/plugins/__tests__/loader-scenarios.test.js +61 -0
- package/dist/plugins/__tests__/loader-scenarios.test.js.map +1 -0
- package/dist/plugins/__tests__/scenario-package-discovery.test.d.ts +2 -0
- package/dist/plugins/__tests__/scenario-package-discovery.test.d.ts.map +1 -0
- package/dist/plugins/__tests__/scenario-package-discovery.test.js +43 -0
- package/dist/plugins/__tests__/scenario-package-discovery.test.js.map +1 -0
- package/dist/plugins/loader.d.ts +32 -0
- package/dist/plugins/loader.d.ts.map +1 -0
- package/dist/plugins/loader.js +119 -0
- package/dist/plugins/loader.js.map +1 -0
- package/dist/plugins/scenario-package-discovery.d.ts +23 -0
- package/dist/plugins/scenario-package-discovery.d.ts.map +1 -0
- package/dist/plugins/scenario-package-discovery.js +42 -0
- package/dist/plugins/scenario-package-discovery.js.map +1 -0
- package/dist/plugins/types.d.ts +24 -0
- package/dist/plugins/types.d.ts.map +1 -0
- package/dist/plugins/types.js +18 -0
- package/dist/plugins/types.js.map +1 -0
- package/dist/recipes/__tests__/recipes.test.d.ts +2 -0
- package/dist/recipes/__tests__/recipes.test.d.ts.map +1 -0
- package/dist/recipes/__tests__/recipes.test.js +515 -0
- package/dist/recipes/__tests__/recipes.test.js.map +1 -0
- package/dist/recipes/built-in-recipes.d.ts +16 -0
- package/dist/recipes/built-in-recipes.d.ts.map +1 -0
- package/dist/recipes/built-in-recipes.js +37 -0
- package/dist/recipes/built-in-recipes.js.map +1 -0
- package/dist/recipes/define-recipe.d.ts +29 -0
- package/dist/recipes/define-recipe.d.ts.map +1 -0
- package/dist/recipes/define-recipe.js +68 -0
- package/dist/recipes/define-recipe.js.map +1 -0
- package/dist/recipes/registry.d.ts +54 -0
- package/dist/recipes/registry.d.ts.map +1 -0
- package/dist/recipes/registry.js +89 -0
- package/dist/recipes/registry.js.map +1 -0
- package/dist/recipes/service.d.ts +61 -0
- package/dist/recipes/service.d.ts.map +1 -0
- package/dist/recipes/service.js +205 -0
- package/dist/recipes/service.js.map +1 -0
- package/dist/recipes/types.d.ts +62 -0
- package/dist/recipes/types.d.ts.map +1 -0
- package/dist/recipes/types.js +10 -0
- package/dist/recipes/types.js.map +1 -0
- package/dist/scaffold/examples.d.ts +22 -0
- package/dist/scaffold/examples.d.ts.map +1 -0
- package/dist/scaffold/examples.js +91 -0
- package/dist/scaffold/examples.js.map +1 -0
- package/dist/scope-augmentation.d.ts +70 -0
- package/dist/scope-augmentation.d.ts.map +1 -0
- package/dist/scope-augmentation.js +28 -0
- package/dist/scope-augmentation.js.map +1 -0
- package/dist/tool.d.ts +21 -0
- package/dist/tool.d.ts.map +1 -0
- package/dist/tool.js +347 -0
- package/dist/tool.js.map +1 -0
- package/dist/types/base-types.d.ts +35 -0
- package/dist/types/base-types.d.ts.map +1 -0
- package/dist/types/base-types.js +8 -0
- package/dist/types/base-types.js.map +1 -0
- package/dist/types/framework-types.d.ts +62 -0
- package/dist/types/framework-types.d.ts.map +1 -0
- package/dist/types/framework-types.js +15 -0
- package/dist/types/framework-types.js.map +1 -0
- package/dist/types/kind-types.d.ts +24 -0
- package/dist/types/kind-types.d.ts.map +1 -0
- package/dist/types/kind-types.js +22 -0
- package/dist/types/kind-types.js.map +1 -0
- package/dist/types/workload.d.ts +30 -0
- package/dist/types/workload.d.ts.map +1 -0
- package/dist/types/workload.js +20 -0
- package/dist/types/workload.js.map +1 -0
- package/package.json +120 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Cross-kind scenario registry — per-RunScope.
|
|
3
|
+
*
|
|
4
|
+
* Each `RunScope` owns its own `Registry<RunnableScenario>` (Item 1 /
|
|
5
|
+
* D7 — tool subscopes via module augmentation).
|
|
6
|
+
* The simulation tool's `contributeScope` hook constructs a fresh registry
|
|
7
|
+
* per CLI invocation and attaches it to `scope.simulation.scenarios`.
|
|
8
|
+
*
|
|
9
|
+
* Built on the kernel's unified `Registry<T>` with
|
|
10
|
+
* `duplicatePolicy: 'silent-skip'` (re-importing the same scenario is a
|
|
11
|
+
* no-op) + `nameCollisionMode: 'throw'` (two different scenario ids
|
|
12
|
+
* sharing a name would corrupt the dual-key state). This is the same
|
|
13
|
+
* shape the legacy `IdNameTagRegistry` provided (which has been deleted).
|
|
14
|
+
*
|
|
15
|
+
* Public API:
|
|
16
|
+
* - `createScenarioRegistry()` — factory used by `contributeScope`.
|
|
17
|
+
* - `currentScenarioRegistry()` — reads the scope-bound registry;
|
|
18
|
+
* throws when called outside a scope
|
|
19
|
+
* or when `simulation` subscope is
|
|
20
|
+
* absent.
|
|
21
|
+
* - `getRegisteredScenarios()` / `getScenario` / `getScenariosByTag` /
|
|
22
|
+
* `getScenariosByKind` / `clearScenarioRegistry` — thin helpers that
|
|
23
|
+
* route through the scope-bound registry.
|
|
24
|
+
*/
|
|
25
|
+
import { Registry, currentScope } from '@opensip-cli/core';
|
|
26
|
+
/** Construct a fresh `ensureScenariosLoaded` lifecycle slot for a single `RunScope` (audit F1). */
|
|
27
|
+
export function createSimulationLoadState() {
|
|
28
|
+
return { loadedFor: null, pluginLoadErrors: [] };
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Read the current scope's simulation load state (`scope.simulation.load`).
|
|
32
|
+
* Throws when no scope/subscope is active — same contract as
|
|
33
|
+
* {@link currentScenarioRegistry}.
|
|
34
|
+
*
|
|
35
|
+
* @throws {Error} When called outside `runWithScope(...)`, or when the active
|
|
36
|
+
* scope has no simulation subscope.
|
|
37
|
+
*/
|
|
38
|
+
export function currentSimulationLoadState() {
|
|
39
|
+
const scope = currentScope();
|
|
40
|
+
if (!scope?.simulation) {
|
|
41
|
+
throw new Error('simulation: currentSimulationLoadState() requires an active RunScope with a ' +
|
|
42
|
+
'simulation subscope (production: the pre-action-hook; tests: makeTestScope + ' +
|
|
43
|
+
'simulationTool.contributeScope()).');
|
|
44
|
+
}
|
|
45
|
+
return scope.simulation.load;
|
|
46
|
+
}
|
|
47
|
+
/** Construct a fresh scenario registry for a single `RunScope`. */
|
|
48
|
+
export function createScenarioRegistry() {
|
|
49
|
+
return new Registry({
|
|
50
|
+
module: 'simulation:scenarios',
|
|
51
|
+
duplicatePolicy: 'silent-skip',
|
|
52
|
+
evtPrefix: 'scenario.registry',
|
|
53
|
+
nameCollisionMode: 'throw',
|
|
54
|
+
validationCode: 'VALIDATION.REGISTRY.NAME_COLLISION',
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Read the current scope's scenario registry. Throws when no scope is
|
|
59
|
+
* active or when the simulation subscope is missing — both indicate the
|
|
60
|
+
* caller is running outside the CLI's pre-action-hook (or the test
|
|
61
|
+
* fixture forgot to construct + enter a scope).
|
|
62
|
+
*
|
|
63
|
+
* @throws {Error} When called outside `runWithScope(...)`, or when the
|
|
64
|
+
* active scope has no simulation subscope.
|
|
65
|
+
*/
|
|
66
|
+
export function currentScenarioRegistry() {
|
|
67
|
+
const scope = currentScope();
|
|
68
|
+
if (!scope) {
|
|
69
|
+
throw new Error('simulation: currentScenarioRegistry() called outside a RunScope. ' +
|
|
70
|
+
'Wrap the call site in runWithScope (production: pre-action-hook handles ' +
|
|
71
|
+
'this; tests: use makeTestScope + simulationTool.contributeScope or construct ' +
|
|
72
|
+
'a Registry directly).');
|
|
73
|
+
}
|
|
74
|
+
if (!scope.simulation) {
|
|
75
|
+
throw new Error('simulation: scope.simulation is missing. The simulation tool must be ' +
|
|
76
|
+
'registered and its contributeScope hook must run before scenario reads. ' +
|
|
77
|
+
'(production: bootstrap registers simulationTool; tests: call ' +
|
|
78
|
+
'simulationTool.contributeScope() after makeTestScope.)');
|
|
79
|
+
}
|
|
80
|
+
return scope.simulation.scenarios;
|
|
81
|
+
}
|
|
82
|
+
/** Get all registered scenarios from the current scope's registry. */
|
|
83
|
+
export function getRegisteredScenarios() {
|
|
84
|
+
const map = new Map();
|
|
85
|
+
for (const scenario of currentScenarioRegistry().getAll()) {
|
|
86
|
+
map.set(scenario.id, scenario);
|
|
87
|
+
}
|
|
88
|
+
return map;
|
|
89
|
+
}
|
|
90
|
+
/** Get a scenario by id or name from the current scope's registry. */
|
|
91
|
+
export function getScenario(idOrName) {
|
|
92
|
+
return currentScenarioRegistry().get(idOrName);
|
|
93
|
+
}
|
|
94
|
+
/** Get scenarios filtered by tag (any kind). */
|
|
95
|
+
export function getScenariosByTag(tag) {
|
|
96
|
+
return currentScenarioRegistry().getByTag(tag);
|
|
97
|
+
}
|
|
98
|
+
/** Get scenarios filtered by kind. */
|
|
99
|
+
export function getScenariosByKind(kind) {
|
|
100
|
+
return currentScenarioRegistry()
|
|
101
|
+
.getAll()
|
|
102
|
+
.filter((s) => s.kind === kind);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Clear the current scope's scenario registry. Used by tests, by host
|
|
106
|
+
* applications that need to swap the scenario set at runtime, and by
|
|
107
|
+
* recipe-reset code paths. The simulation engine's plugin loader
|
|
108
|
+
* re-populates it on the next load cycle.
|
|
109
|
+
*/
|
|
110
|
+
export function clearScenarioRegistry() {
|
|
111
|
+
currentScenarioRegistry().clear();
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/framework/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAM3D,mGAAmG;AACnG,MAAM,UAAU,yBAAyB;IACvC,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,gBAAgB,EAAE,EAAE,EAAE,CAAC;AACnD,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,0BAA0B;IACxC,MAAM,KAAK,GAAG,YAAY,EAAE,CAAC;IAC7B,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CACb,8EAA8E;YAC5E,+EAA+E;YAC/E,oCAAoC,CACvC,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC;AAC/B,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,sBAAsB;IACpC,OAAO,IAAI,QAAQ,CAAmB;QACpC,MAAM,EAAE,sBAAsB;QAC9B,eAAe,EAAE,aAAa;QAC9B,SAAS,EAAE,mBAAmB;QAC9B,iBAAiB,EAAE,OAAO;QAC1B,cAAc,EAAE,oCAAoC;KACrD,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,uBAAuB;IACrC,MAAM,KAAK,GAAG,YAAY,EAAE,CAAC;IAC7B,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CACb,mEAAmE;YACjE,0EAA0E;YAC1E,+EAA+E;YAC/E,uBAAuB,CAC1B,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CACb,uEAAuE;YACrE,0EAA0E;YAC1E,+DAA+D;YAC/D,wDAAwD,CAC3D,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC;AACpC,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,sBAAsB;IACpC,MAAM,GAAG,GAAG,IAAI,GAAG,EAA4B,CAAC;IAChD,KAAK,MAAM,QAAQ,IAAI,uBAAuB,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC;QAC1D,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;IACjC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,WAAW,CAAC,QAAgB;IAC1C,OAAO,uBAAuB,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AACjD,CAAC;AAED,gDAAgD;AAChD,MAAM,UAAU,iBAAiB,CAAC,GAAW;IAC3C,OAAO,uBAAuB,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AACjD,CAAC;AAED,sCAAsC;AACtC,MAAM,UAAU,kBAAkB,CAAC,IAAkB;IACnD,OAAO,uBAAuB,EAAE;SAC7B,MAAM,EAAE;SACR,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;AACpC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB;IACnC,uBAAuB,EAAE,CAAC,KAAK,EAAE,CAAC;AACpC,CAAC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Single source of truth for resolving simulation-metric keys
|
|
3
|
+
* to numeric values.
|
|
4
|
+
*
|
|
5
|
+
* Both `validateAssertions` (in `execution/execution-engine.ts`) and
|
|
6
|
+
* `ScenarioResultBuilder.evaluateAssertions` (in `result-builder.ts`)
|
|
7
|
+
* delegate here. Before this module existed, each kept its own resolver
|
|
8
|
+
* and the two diverged — most visibly on `success_rate` when
|
|
9
|
+
* `totalRequests === 0`.
|
|
10
|
+
*
|
|
11
|
+
* ## Supported keys
|
|
12
|
+
*
|
|
13
|
+
* Computed (derived from raw counters):
|
|
14
|
+
*
|
|
15
|
+
* - `error_rate` — `failedRequests / totalRequests`,
|
|
16
|
+
* `0` when `totalRequests === 0`.
|
|
17
|
+
* - `success_rate` — `successfulRequests / totalRequests`,
|
|
18
|
+
* **`0` when `totalRequests === 0`**. See note below.
|
|
19
|
+
* - `recovery_rate` — `1 - failedRequests / errorsGenerated`,
|
|
20
|
+
* `1` when `errorsGenerated === 0` (no errors to
|
|
21
|
+
* recover from ⇒ trivially fully recovered).
|
|
22
|
+
* - `requests_per_second` — `totalRequests / durationSeconds`,
|
|
23
|
+
* `0` when `durationSeconds` is missing or `<= 0`.
|
|
24
|
+
*
|
|
25
|
+
* Direct field accessors (passthrough to `SimulationMetrics`):
|
|
26
|
+
*
|
|
27
|
+
* - `avg_latency_ms`, `avg_latency` → `avgLatencyMs`
|
|
28
|
+
* - `p50_latency_ms`, `p50_latency` → `p50LatencyMs`
|
|
29
|
+
* - `p95_latency_ms`, `p95_latency` → `p95LatencyMs`
|
|
30
|
+
* - `p99_latency_ms`, `p99_latency` → `p99LatencyMs`
|
|
31
|
+
* - `total_requests` → `totalRequests`
|
|
32
|
+
* - `successful_requests` → `successfulRequests`
|
|
33
|
+
* - `failed_requests` → `failedRequests`
|
|
34
|
+
* - `errors_generated` → `errorsGenerated`
|
|
35
|
+
*
|
|
36
|
+
* Reserved keys (recognised at type-level, not yet populated by any executor;
|
|
37
|
+
* resolver returns `0`):
|
|
38
|
+
*
|
|
39
|
+
* - `max_latency_ms` — produced by `ASSERTIONS.maxLatency()`.
|
|
40
|
+
* - `memory_mb` — produced by `ASSERTIONS.memoryUsage()`.
|
|
41
|
+
* - `cpu_percent` — produced by `ASSERTIONS.cpuUsage()`.
|
|
42
|
+
*
|
|
43
|
+
* These exist so the standard ASSERTIONS factories continue to type-check.
|
|
44
|
+
* Until an executor records the underlying field on `SimulationMetrics`, the
|
|
45
|
+
* resolver returns `0` (assertions like `cpuUsage(80)` with operator `lt`
|
|
46
|
+
* therefore pass trivially). Promote a reserved key to a real one by adding
|
|
47
|
+
* the underlying field to `SimulationMetrics` and a case here.
|
|
48
|
+
*
|
|
49
|
+
* ## Note: `success_rate` with no requests
|
|
50
|
+
*
|
|
51
|
+
* When `totalRequests === 0`, `successfulRequests / totalRequests` is `0/0`.
|
|
52
|
+
* The two historical resolvers disagreed:
|
|
53
|
+
*
|
|
54
|
+
* - The execution-engine path returned `1` (no failures ⇒ pass).
|
|
55
|
+
* - The result-builder path returned `0` (no successes ⇒ fail).
|
|
56
|
+
*
|
|
57
|
+
* We pick **`0`**, matching the result-builder's existing pinned behaviour
|
|
58
|
+
* (see `result-builder.test.ts` "success_rate is 0 when no requests"). The
|
|
59
|
+
* rationale: a scenario that produced zero requests is misconfigured or
|
|
60
|
+
* aborted-early, and a `highSuccessRate` assertion should _fail_ in that
|
|
61
|
+
* case, not silently pass. The execution-engine path's old `1` result was
|
|
62
|
+
* the looser, more-permissive choice and is the one being tightened.
|
|
63
|
+
*/
|
|
64
|
+
import type { ScenarioMetricKey } from './scenario-metric-key.js';
|
|
65
|
+
import type { SimulationMetrics } from '../types/base-types.js';
|
|
66
|
+
export type { ScenarioMetricKey } from './scenario-metric-key.js';
|
|
67
|
+
/**
|
|
68
|
+
* Resolve a metric key to its numeric value.
|
|
69
|
+
*
|
|
70
|
+
* @param metric - The metric key to resolve. See module-level docs for the
|
|
71
|
+
* full supported set and edge-case semantics.
|
|
72
|
+
* @param metrics - The collected simulation metrics.
|
|
73
|
+
* @param durationSeconds - Required only for `requests_per_second`. When
|
|
74
|
+
* missing or non-positive for that key, the function returns `0`.
|
|
75
|
+
* @returns The numeric value. Unknown keys (post-narrowing — should be
|
|
76
|
+
* prevented at compile time) fall through to `0`.
|
|
77
|
+
*/
|
|
78
|
+
export declare function resolveMetric(metric: ScenarioMetricKey, metrics: SimulationMetrics, durationSeconds?: number): number;
|
|
79
|
+
//# sourceMappingURL=resolve-metric.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-metric.d.ts","sourceRoot":"","sources":["../../src/framework/resolve-metric.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAOhE,YAAY,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAElE;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,iBAAiB,EACzB,OAAO,EAAE,iBAAiB,EAC1B,eAAe,CAAC,EAAE,MAAM,GACvB,MAAM,CA2DR"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Single source of truth for resolving simulation-metric keys
|
|
3
|
+
* to numeric values.
|
|
4
|
+
*
|
|
5
|
+
* Both `validateAssertions` (in `execution/execution-engine.ts`) and
|
|
6
|
+
* `ScenarioResultBuilder.evaluateAssertions` (in `result-builder.ts`)
|
|
7
|
+
* delegate here. Before this module existed, each kept its own resolver
|
|
8
|
+
* and the two diverged — most visibly on `success_rate` when
|
|
9
|
+
* `totalRequests === 0`.
|
|
10
|
+
*
|
|
11
|
+
* ## Supported keys
|
|
12
|
+
*
|
|
13
|
+
* Computed (derived from raw counters):
|
|
14
|
+
*
|
|
15
|
+
* - `error_rate` — `failedRequests / totalRequests`,
|
|
16
|
+
* `0` when `totalRequests === 0`.
|
|
17
|
+
* - `success_rate` — `successfulRequests / totalRequests`,
|
|
18
|
+
* **`0` when `totalRequests === 0`**. See note below.
|
|
19
|
+
* - `recovery_rate` — `1 - failedRequests / errorsGenerated`,
|
|
20
|
+
* `1` when `errorsGenerated === 0` (no errors to
|
|
21
|
+
* recover from ⇒ trivially fully recovered).
|
|
22
|
+
* - `requests_per_second` — `totalRequests / durationSeconds`,
|
|
23
|
+
* `0` when `durationSeconds` is missing or `<= 0`.
|
|
24
|
+
*
|
|
25
|
+
* Direct field accessors (passthrough to `SimulationMetrics`):
|
|
26
|
+
*
|
|
27
|
+
* - `avg_latency_ms`, `avg_latency` → `avgLatencyMs`
|
|
28
|
+
* - `p50_latency_ms`, `p50_latency` → `p50LatencyMs`
|
|
29
|
+
* - `p95_latency_ms`, `p95_latency` → `p95LatencyMs`
|
|
30
|
+
* - `p99_latency_ms`, `p99_latency` → `p99LatencyMs`
|
|
31
|
+
* - `total_requests` → `totalRequests`
|
|
32
|
+
* - `successful_requests` → `successfulRequests`
|
|
33
|
+
* - `failed_requests` → `failedRequests`
|
|
34
|
+
* - `errors_generated` → `errorsGenerated`
|
|
35
|
+
*
|
|
36
|
+
* Reserved keys (recognised at type-level, not yet populated by any executor;
|
|
37
|
+
* resolver returns `0`):
|
|
38
|
+
*
|
|
39
|
+
* - `max_latency_ms` — produced by `ASSERTIONS.maxLatency()`.
|
|
40
|
+
* - `memory_mb` — produced by `ASSERTIONS.memoryUsage()`.
|
|
41
|
+
* - `cpu_percent` — produced by `ASSERTIONS.cpuUsage()`.
|
|
42
|
+
*
|
|
43
|
+
* These exist so the standard ASSERTIONS factories continue to type-check.
|
|
44
|
+
* Until an executor records the underlying field on `SimulationMetrics`, the
|
|
45
|
+
* resolver returns `0` (assertions like `cpuUsage(80)` with operator `lt`
|
|
46
|
+
* therefore pass trivially). Promote a reserved key to a real one by adding
|
|
47
|
+
* the underlying field to `SimulationMetrics` and a case here.
|
|
48
|
+
*
|
|
49
|
+
* ## Note: `success_rate` with no requests
|
|
50
|
+
*
|
|
51
|
+
* When `totalRequests === 0`, `successfulRequests / totalRequests` is `0/0`.
|
|
52
|
+
* The two historical resolvers disagreed:
|
|
53
|
+
*
|
|
54
|
+
* - The execution-engine path returned `1` (no failures ⇒ pass).
|
|
55
|
+
* - The result-builder path returned `0` (no successes ⇒ fail).
|
|
56
|
+
*
|
|
57
|
+
* We pick **`0`**, matching the result-builder's existing pinned behaviour
|
|
58
|
+
* (see `result-builder.test.ts` "success_rate is 0 when no requests"). The
|
|
59
|
+
* rationale: a scenario that produced zero requests is misconfigured or
|
|
60
|
+
* aborted-early, and a `highSuccessRate` assertion should _fail_ in that
|
|
61
|
+
* case, not silently pass. The execution-engine path's old `1` result was
|
|
62
|
+
* the looser, more-permissive choice and is the one being tightened.
|
|
63
|
+
*/
|
|
64
|
+
/**
|
|
65
|
+
* Resolve a metric key to its numeric value.
|
|
66
|
+
*
|
|
67
|
+
* @param metric - The metric key to resolve. See module-level docs for the
|
|
68
|
+
* full supported set and edge-case semantics.
|
|
69
|
+
* @param metrics - The collected simulation metrics.
|
|
70
|
+
* @param durationSeconds - Required only for `requests_per_second`. When
|
|
71
|
+
* missing or non-positive for that key, the function returns `0`.
|
|
72
|
+
* @returns The numeric value. Unknown keys (post-narrowing — should be
|
|
73
|
+
* prevented at compile time) fall through to `0`.
|
|
74
|
+
*/
|
|
75
|
+
export function resolveMetric(metric, metrics, durationSeconds) {
|
|
76
|
+
switch (metric) {
|
|
77
|
+
case 'error_rate': {
|
|
78
|
+
return metrics.totalRequests > 0 ? metrics.failedRequests / metrics.totalRequests : 0;
|
|
79
|
+
}
|
|
80
|
+
case 'success_rate': {
|
|
81
|
+
// See module-level docs: `0` when totalRequests === 0 (tightening choice).
|
|
82
|
+
return metrics.totalRequests > 0 ? metrics.successfulRequests / metrics.totalRequests : 0;
|
|
83
|
+
}
|
|
84
|
+
case 'recovery_rate': {
|
|
85
|
+
// No errors to recover from ⇒ trivially fully recovered (1).
|
|
86
|
+
return metrics.errorsGenerated > 0 ? 1 - metrics.failedRequests / metrics.errorsGenerated : 1;
|
|
87
|
+
}
|
|
88
|
+
case 'requests_per_second': {
|
|
89
|
+
if (durationSeconds === undefined || durationSeconds <= 0) {
|
|
90
|
+
return 0;
|
|
91
|
+
}
|
|
92
|
+
return metrics.totalRequests / durationSeconds;
|
|
93
|
+
}
|
|
94
|
+
case 'avg_latency':
|
|
95
|
+
case 'avg_latency_ms': {
|
|
96
|
+
return metrics.avgLatencyMs;
|
|
97
|
+
}
|
|
98
|
+
case 'p50_latency':
|
|
99
|
+
case 'p50_latency_ms': {
|
|
100
|
+
return metrics.p50LatencyMs;
|
|
101
|
+
}
|
|
102
|
+
case 'p95_latency':
|
|
103
|
+
case 'p95_latency_ms': {
|
|
104
|
+
return metrics.p95LatencyMs;
|
|
105
|
+
}
|
|
106
|
+
case 'p99_latency':
|
|
107
|
+
case 'p99_latency_ms': {
|
|
108
|
+
return metrics.p99LatencyMs;
|
|
109
|
+
}
|
|
110
|
+
case 'total_requests': {
|
|
111
|
+
return metrics.totalRequests;
|
|
112
|
+
}
|
|
113
|
+
case 'successful_requests': {
|
|
114
|
+
return metrics.successfulRequests;
|
|
115
|
+
}
|
|
116
|
+
case 'failed_requests': {
|
|
117
|
+
return metrics.failedRequests;
|
|
118
|
+
}
|
|
119
|
+
case 'errors_generated': {
|
|
120
|
+
return metrics.errorsGenerated;
|
|
121
|
+
}
|
|
122
|
+
case 'max_latency_ms':
|
|
123
|
+
case 'memory_mb':
|
|
124
|
+
case 'cpu_percent': {
|
|
125
|
+
// Reserved: no underlying field on SimulationMetrics yet.
|
|
126
|
+
return 0;
|
|
127
|
+
}
|
|
128
|
+
default: {
|
|
129
|
+
// Exhaustive — `ScenarioMetricKey` should narrow to never here. This
|
|
130
|
+
// branch only fires if a caller deliberately bypasses the type check.
|
|
131
|
+
return 0;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=resolve-metric.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-metric.js","sourceRoot":"","sources":["../../src/framework/resolve-metric.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AAYH;;;;;;;;;;GAUG;AACH,MAAM,UAAU,aAAa,CAC3B,MAAyB,EACzB,OAA0B,EAC1B,eAAwB;IAExB,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,YAAY,CAAC,CAAC,CAAC;YAClB,OAAO,OAAO,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;QACxF,CAAC;QACD,KAAK,cAAc,CAAC,CAAC,CAAC;YACpB,2EAA2E;YAC3E,OAAO,OAAO,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5F,CAAC;QACD,KAAK,eAAe,CAAC,CAAC,CAAC;YACrB,6DAA6D;YAC7D,OAAO,OAAO,CAAC,eAAe,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;QAChG,CAAC;QACD,KAAK,qBAAqB,CAAC,CAAC,CAAC;YAC3B,IAAI,eAAe,KAAK,SAAS,IAAI,eAAe,IAAI,CAAC,EAAE,CAAC;gBAC1D,OAAO,CAAC,CAAC;YACX,CAAC;YACD,OAAO,OAAO,CAAC,aAAa,GAAG,eAAe,CAAC;QACjD,CAAC;QACD,KAAK,aAAa,CAAC;QACnB,KAAK,gBAAgB,CAAC,CAAC,CAAC;YACtB,OAAO,OAAO,CAAC,YAAY,CAAC;QAC9B,CAAC;QACD,KAAK,aAAa,CAAC;QACnB,KAAK,gBAAgB,CAAC,CAAC,CAAC;YACtB,OAAO,OAAO,CAAC,YAAY,CAAC;QAC9B,CAAC;QACD,KAAK,aAAa,CAAC;QACnB,KAAK,gBAAgB,CAAC,CAAC,CAAC;YACtB,OAAO,OAAO,CAAC,YAAY,CAAC;QAC9B,CAAC;QACD,KAAK,aAAa,CAAC;QACnB,KAAK,gBAAgB,CAAC,CAAC,CAAC;YACtB,OAAO,OAAO,CAAC,YAAY,CAAC;QAC9B,CAAC;QACD,KAAK,gBAAgB,CAAC,CAAC,CAAC;YACtB,OAAO,OAAO,CAAC,aAAa,CAAC;QAC/B,CAAC;QACD,KAAK,qBAAqB,CAAC,CAAC,CAAC;YAC3B,OAAO,OAAO,CAAC,kBAAkB,CAAC;QACpC,CAAC;QACD,KAAK,iBAAiB,CAAC,CAAC,CAAC;YACvB,OAAO,OAAO,CAAC,cAAc,CAAC;QAChC,CAAC;QACD,KAAK,kBAAkB,CAAC,CAAC,CAAC;YACxB,OAAO,OAAO,CAAC,eAAe,CAAC;QACjC,CAAC;QACD,KAAK,gBAAgB,CAAC;QACtB,KAAK,WAAW,CAAC;QACjB,KAAK,aAAa,CAAC,CAAC,CAAC;YACnB,0DAA0D;YAC1D,OAAO,CAAC,CAAC;QACX,CAAC;QACD,OAAO,CAAC,CAAC,CAAC;YACR,qEAAqE;YACrE,sEAAsE;YACtE,OAAO,CAAC,CAAC;QACX,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Fluent builder for scenario execution results
|
|
3
|
+
*
|
|
4
|
+
* Metrics must be set before build(). Result is immutable after build().
|
|
5
|
+
* Assertions are evaluated in order.
|
|
6
|
+
*/
|
|
7
|
+
import type { SimulationMetrics } from '../types/base-types.js';
|
|
8
|
+
import type { ScenarioAssertion, FailedAssertion, LoadResultPayload } from '../types/framework-types.js';
|
|
9
|
+
import type { Signal } from '@opensip-cli/core';
|
|
10
|
+
/**
|
|
11
|
+
* Build the single error-severity signal that represents a failed scenario
|
|
12
|
+
* (ADR-0011 / ADR-0035). A failed scenario must surface in the signal currency
|
|
13
|
+
* so the host verdict — and every sink (`--json`, SARIF, cloud) — sees it; the
|
|
14
|
+
* pre-ADR-0035 sim emitted no signal on failure, leaving `errors === 0` for a
|
|
15
|
+
* run that should fail. One `high`-severity signal per failed scenario,
|
|
16
|
+
* attributed to its `scenarioId`, summarizing the failed assertions. Shared by
|
|
17
|
+
* the load path (via `build()`) and the chaos executor.
|
|
18
|
+
*/
|
|
19
|
+
export declare function buildFailedScenarioSignal(scenarioId: string, failedAssertions: readonly FailedAssertion[]): Signal;
|
|
20
|
+
/**
|
|
21
|
+
* Builder for scenario execution results.
|
|
22
|
+
* Ensures consistent result structure across all scenarios.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* const result = ScenarioResultBuilder.create('my-scenario')
|
|
27
|
+
* .withMetrics(collectedMetrics)
|
|
28
|
+
* .evaluateAssertions(scenario.assertions)
|
|
29
|
+
* .addSignals(generatedSignals)
|
|
30
|
+
* .build();
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare class ScenarioResultBuilder {
|
|
34
|
+
private readonly scenarioId;
|
|
35
|
+
private _metrics;
|
|
36
|
+
private _duration;
|
|
37
|
+
private readonly _passedAssertions;
|
|
38
|
+
private readonly _failedAssertions;
|
|
39
|
+
private readonly _signals;
|
|
40
|
+
private constructor();
|
|
41
|
+
/** Get the scenario ID for this builder. */
|
|
42
|
+
getScenarioId(): string;
|
|
43
|
+
/** Create a new result builder. */
|
|
44
|
+
static create(scenarioId: string): ScenarioResultBuilder;
|
|
45
|
+
/** Set the simulation metrics. */
|
|
46
|
+
withMetrics(metrics: SimulationMetrics): this;
|
|
47
|
+
/** Set the scenario duration in seconds (used for derived metrics like RPS). */
|
|
48
|
+
withDuration(seconds: number): this;
|
|
49
|
+
/** Record a passed assertion. */
|
|
50
|
+
assertionPassed(assertion: ScenarioAssertion): this;
|
|
51
|
+
/** Record a failed assertion. */
|
|
52
|
+
assertionFailed(assertion: ScenarioAssertion, actual: number): this;
|
|
53
|
+
/** Evaluate all assertions against the current metrics. */
|
|
54
|
+
evaluateAssertions(assertions: readonly ScenarioAssertion[]): this;
|
|
55
|
+
/** Add a single signal. */
|
|
56
|
+
addSignal(signal: Signal): this;
|
|
57
|
+
/** Add multiple signals. */
|
|
58
|
+
addSignals(signals: readonly Signal[]): this;
|
|
59
|
+
/** Build the final load-shaped payload. Throws if metrics are not set. */
|
|
60
|
+
build(): LoadResultPayload;
|
|
61
|
+
private resolveAssertionMetric;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Create an empty/initial metrics object.
|
|
65
|
+
*/
|
|
66
|
+
export declare function createEmptyMetrics(): SimulationMetrics;
|
|
67
|
+
/**
|
|
68
|
+
* Merge multiple metrics objects.
|
|
69
|
+
* Useful for aggregating metrics from parallel execution.
|
|
70
|
+
*/
|
|
71
|
+
export declare function mergeMetrics(metricsList: readonly SimulationMetrics[]): SimulationMetrics;
|
|
72
|
+
//# sourceMappingURL=result-builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"result-builder.d.ts","sourceRoot":"","sources":["../../src/framework/result-builder.ts"],"names":[],"mappings":"AACA;;;;;GAKG;AAOH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,KAAK,EACV,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EAClB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,MAAM,EAClB,gBAAgB,EAAE,SAAS,eAAe,EAAE,GAC3C,MAAM,CAWR;AAMD;;;;;;;;;;;;GAYG;AACH,qBAAa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAkC;IAClD,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA2B;IAC7D,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAyB;IAC3D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgB;IAEzC,OAAO;IAIP,4CAA4C;IAC5C,aAAa,IAAI,MAAM;IAIvB,mCAAmC;IACnC,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,qBAAqB;IAQxD,kCAAkC;IAClC,WAAW,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI;IAK7C,gFAAgF;IAChF,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IASnC,iCAAiC;IACjC,eAAe,CAAC,SAAS,EAAE,iBAAiB,GAAG,IAAI;IAKnD,iCAAiC;IACjC,eAAe,CAAC,SAAS,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAKnE,2DAA2D;IAC3D,kBAAkB,CAAC,UAAU,EAAE,SAAS,iBAAiB,EAAE,GAAG,IAAI;IAyBlE,2BAA2B;IAC3B,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAK/B,4BAA4B;IAC5B,UAAU,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI;IAS5C,0EAA0E;IAE1E,KAAK,IAAI,iBAAiB;IA+B1B,OAAO,CAAC,sBAAsB;CAS/B;AAMD;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,iBAAiB,CAWtD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,WAAW,EAAE,SAAS,iBAAiB,EAAE,GAAG,iBAAiB,CAiCzF"}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
// @fitness-ignore-file batch-operation-limits -- iterates bounded collections (config entries, registry items, or small analysis results)
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview Fluent builder for scenario execution results
|
|
4
|
+
*
|
|
5
|
+
* Metrics must be set before build(). Result is immutable after build().
|
|
6
|
+
* Assertions are evaluated in order.
|
|
7
|
+
*/
|
|
8
|
+
import { createSignal, isErrorSignal, ValidationError } from '@opensip-cli/core';
|
|
9
|
+
import { evaluateAssertion } from './assertions.js';
|
|
10
|
+
import { resolveMetric } from './resolve-metric.js';
|
|
11
|
+
/**
|
|
12
|
+
* Build the single error-severity signal that represents a failed scenario
|
|
13
|
+
* (ADR-0011 / ADR-0035). A failed scenario must surface in the signal currency
|
|
14
|
+
* so the host verdict — and every sink (`--json`, SARIF, cloud) — sees it; the
|
|
15
|
+
* pre-ADR-0035 sim emitted no signal on failure, leaving `errors === 0` for a
|
|
16
|
+
* run that should fail. One `high`-severity signal per failed scenario,
|
|
17
|
+
* attributed to its `scenarioId`, summarizing the failed assertions. Shared by
|
|
18
|
+
* the load path (via `build()`) and the chaos executor.
|
|
19
|
+
*/
|
|
20
|
+
export function buildFailedScenarioSignal(scenarioId, failedAssertions) {
|
|
21
|
+
const detail = failedAssertions
|
|
22
|
+
.map((a) => `${a.metric} ${a.operator} ${String(a.value)} (actual ${String(a.actual)})`)
|
|
23
|
+
.join('; ');
|
|
24
|
+
return createSignal({
|
|
25
|
+
source: scenarioId,
|
|
26
|
+
severity: 'high',
|
|
27
|
+
category: 'resilience',
|
|
28
|
+
ruleId: `sim:${scenarioId}`,
|
|
29
|
+
message: `Scenario '${scenarioId}' failed ${String(failedAssertions.length)} assertion(s): ${detail}`,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
// =============================================================================
|
|
33
|
+
// RESULT BUILDER
|
|
34
|
+
// =============================================================================
|
|
35
|
+
/**
|
|
36
|
+
* Builder for scenario execution results.
|
|
37
|
+
* Ensures consistent result structure across all scenarios.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```typescript
|
|
41
|
+
* const result = ScenarioResultBuilder.create('my-scenario')
|
|
42
|
+
* .withMetrics(collectedMetrics)
|
|
43
|
+
* .evaluateAssertions(scenario.assertions)
|
|
44
|
+
* .addSignals(generatedSignals)
|
|
45
|
+
* .build();
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export class ScenarioResultBuilder {
|
|
49
|
+
scenarioId;
|
|
50
|
+
_metrics = null;
|
|
51
|
+
_duration = null;
|
|
52
|
+
_passedAssertions = [];
|
|
53
|
+
_failedAssertions = [];
|
|
54
|
+
_signals = [];
|
|
55
|
+
constructor(scenarioId) {
|
|
56
|
+
this.scenarioId = scenarioId;
|
|
57
|
+
}
|
|
58
|
+
/** Get the scenario ID for this builder. */
|
|
59
|
+
getScenarioId() {
|
|
60
|
+
return this.scenarioId;
|
|
61
|
+
}
|
|
62
|
+
/** Create a new result builder. */
|
|
63
|
+
static create(scenarioId) {
|
|
64
|
+
return new ScenarioResultBuilder(scenarioId);
|
|
65
|
+
}
|
|
66
|
+
// ===========================================================================
|
|
67
|
+
// METRICS
|
|
68
|
+
// ===========================================================================
|
|
69
|
+
/** Set the simulation metrics. */
|
|
70
|
+
withMetrics(metrics) {
|
|
71
|
+
this._metrics = metrics;
|
|
72
|
+
return this;
|
|
73
|
+
}
|
|
74
|
+
/** Set the scenario duration in seconds (used for derived metrics like RPS). */
|
|
75
|
+
withDuration(seconds) {
|
|
76
|
+
this._duration = seconds;
|
|
77
|
+
return this;
|
|
78
|
+
}
|
|
79
|
+
// ===========================================================================
|
|
80
|
+
// ASSERTIONS
|
|
81
|
+
// ===========================================================================
|
|
82
|
+
/** Record a passed assertion. */
|
|
83
|
+
assertionPassed(assertion) {
|
|
84
|
+
this._passedAssertions.push(assertion);
|
|
85
|
+
return this;
|
|
86
|
+
}
|
|
87
|
+
/** Record a failed assertion. */
|
|
88
|
+
assertionFailed(assertion, actual) {
|
|
89
|
+
this._failedAssertions.push({ ...assertion, actual });
|
|
90
|
+
return this;
|
|
91
|
+
}
|
|
92
|
+
/** Evaluate all assertions against the current metrics. */
|
|
93
|
+
evaluateAssertions(assertions) {
|
|
94
|
+
if (!this._metrics) {
|
|
95
|
+
// @fitness-ignore-next-line result-pattern-consistency -- builder precondition, throw is appropriate
|
|
96
|
+
throw new ValidationError('Metrics must be set before evaluating assertions. Call withMetrics() first.', { code: 'VALIDATION.RESULT_BUILDER.METRICS_REQUIRED' });
|
|
97
|
+
}
|
|
98
|
+
for (const assertion of assertions) {
|
|
99
|
+
const actual = this.resolveAssertionMetric(assertion.metric);
|
|
100
|
+
if (evaluateAssertion(assertion, actual)) {
|
|
101
|
+
this.assertionPassed(assertion);
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
this.assertionFailed(assertion, actual);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return this;
|
|
108
|
+
}
|
|
109
|
+
// ===========================================================================
|
|
110
|
+
// SIGNALS
|
|
111
|
+
// ===========================================================================
|
|
112
|
+
/** Add a single signal. */
|
|
113
|
+
addSignal(signal) {
|
|
114
|
+
this._signals.push(signal);
|
|
115
|
+
return this;
|
|
116
|
+
}
|
|
117
|
+
/** Add multiple signals. */
|
|
118
|
+
addSignals(signals) {
|
|
119
|
+
this._signals.push(...signals);
|
|
120
|
+
return this;
|
|
121
|
+
}
|
|
122
|
+
// ===========================================================================
|
|
123
|
+
// BUILD
|
|
124
|
+
// ===========================================================================
|
|
125
|
+
/** Build the final load-shaped payload. Throws if metrics are not set. */
|
|
126
|
+
// @fitness-ignore-next-line result-pattern-consistency -- return type is LoadResultPayload (not canonical Result); throw is a builder precondition
|
|
127
|
+
build() {
|
|
128
|
+
if (!this._metrics) {
|
|
129
|
+
// @fitness-ignore-next-line result-pattern-consistency -- builder precondition, throw is appropriate
|
|
130
|
+
throw new ValidationError('Metrics are required. Call withMetrics() before build().', {
|
|
131
|
+
code: 'VALIDATION.RESULT_BUILDER.METRICS_REQUIRED',
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
// ADR-0035: a failed scenario must emit an error-severity signal so the host
|
|
135
|
+
// verdict sees the failure (the signal currency, not just `passed`). Append
|
|
136
|
+
// one unless the scenario already authored an error signal of its own.
|
|
137
|
+
const signals = [...this._signals];
|
|
138
|
+
if (this._failedAssertions.length > 0 && !signals.some(isErrorSignal)) {
|
|
139
|
+
signals.push(buildFailedScenarioSignal(this.scenarioId, this._failedAssertions));
|
|
140
|
+
}
|
|
141
|
+
return Object.freeze({
|
|
142
|
+
passed: this._failedAssertions.length === 0,
|
|
143
|
+
metrics: this._metrics,
|
|
144
|
+
assertions: Object.freeze({
|
|
145
|
+
passed: Object.freeze([...this._passedAssertions]),
|
|
146
|
+
failed: Object.freeze([...this._failedAssertions]),
|
|
147
|
+
}),
|
|
148
|
+
signals: Object.freeze(signals),
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
// ===========================================================================
|
|
152
|
+
// PRIVATE
|
|
153
|
+
// ===========================================================================
|
|
154
|
+
resolveAssertionMetric(metric) {
|
|
155
|
+
/* v8 ignore next 3 -- unreachable defensive guard: the only caller
|
|
156
|
+
(evaluateAssertions) already throws when `_metrics` is unset, so this
|
|
157
|
+
branch can never fire through the public API. */
|
|
158
|
+
if (!this._metrics) {
|
|
159
|
+
return 0;
|
|
160
|
+
}
|
|
161
|
+
return resolveMetric(metric, this._metrics, this._duration ?? undefined);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
// =============================================================================
|
|
165
|
+
// HELPER FUNCTIONS
|
|
166
|
+
// =============================================================================
|
|
167
|
+
/**
|
|
168
|
+
* Create an empty/initial metrics object.
|
|
169
|
+
*/
|
|
170
|
+
export function createEmptyMetrics() {
|
|
171
|
+
return {
|
|
172
|
+
totalRequests: 0,
|
|
173
|
+
successfulRequests: 0,
|
|
174
|
+
failedRequests: 0,
|
|
175
|
+
avgLatencyMs: 0,
|
|
176
|
+
p50LatencyMs: 0,
|
|
177
|
+
p95LatencyMs: 0,
|
|
178
|
+
p99LatencyMs: 0,
|
|
179
|
+
errorsGenerated: 0,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Merge multiple metrics objects.
|
|
184
|
+
* Useful for aggregating metrics from parallel execution.
|
|
185
|
+
*/
|
|
186
|
+
export function mergeMetrics(metricsList) {
|
|
187
|
+
if (metricsList.length === 0) {
|
|
188
|
+
return createEmptyMetrics();
|
|
189
|
+
}
|
|
190
|
+
if (metricsList.length === 1) {
|
|
191
|
+
const first = metricsList[0];
|
|
192
|
+
return first ?? createEmptyMetrics();
|
|
193
|
+
}
|
|
194
|
+
const totalRequests = metricsList.reduce((sum, m) => sum + m.totalRequests, 0);
|
|
195
|
+
const totalSuccessful = metricsList.reduce((sum, m) => sum + m.successfulRequests, 0);
|
|
196
|
+
const totalFailed = metricsList.reduce((sum, m) => sum + m.failedRequests, 0);
|
|
197
|
+
const weightedAvgLatency = totalRequests > 0
|
|
198
|
+
? metricsList.reduce((sum, m) => sum + m.avgLatencyMs * m.totalRequests, 0) / totalRequests
|
|
199
|
+
: 0;
|
|
200
|
+
const p50 = Math.max(...metricsList.map((m) => m.p50LatencyMs));
|
|
201
|
+
const p95 = Math.max(...metricsList.map((m) => m.p95LatencyMs));
|
|
202
|
+
const p99 = Math.max(...metricsList.map((m) => m.p99LatencyMs));
|
|
203
|
+
return {
|
|
204
|
+
totalRequests,
|
|
205
|
+
successfulRequests: totalSuccessful,
|
|
206
|
+
failedRequests: totalFailed,
|
|
207
|
+
avgLatencyMs: weightedAvgLatency,
|
|
208
|
+
p50LatencyMs: p50,
|
|
209
|
+
p95LatencyMs: p95,
|
|
210
|
+
p99LatencyMs: p99,
|
|
211
|
+
errorsGenerated: metricsList.reduce((sum, m) => sum + m.errorsGenerated, 0),
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
//# sourceMappingURL=result-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"result-builder.js","sourceRoot":"","sources":["../../src/framework/result-builder.ts"],"names":[],"mappings":"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"}
|