@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
package/dist/index.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// @fitness-ignore-file module-coupling-fan-out -- Package barrel by design: re-exports the public surface of every kind module; fan-out is the whole job of this file
|
|
2
|
+
/**
|
|
3
|
+
* @opensip-cli/simulation — Simulation scenarios for codebase analysis.
|
|
4
|
+
*
|
|
5
|
+
* The package exposes two kind-specific scenario authoring entry points
|
|
6
|
+
* sharing one runtime contract:
|
|
7
|
+
*
|
|
8
|
+
* - `defineLoadScenario` ← BYO target + workload + assert SLO
|
|
9
|
+
* - `defineChaosScenario` ← BYO target + client-side faults + recovery
|
|
10
|
+
*/
|
|
11
|
+
// =============================================================================
|
|
12
|
+
// RUNSCOPE AUGMENTATION — D7 (tool subscopes via module augmentation).
|
|
13
|
+
// Side-effect import so importing the simulation package surfaces
|
|
14
|
+
// `scope.simulation` on the augmented RunScope interface.
|
|
15
|
+
// =============================================================================
|
|
16
|
+
import './scope-augmentation.js';
|
|
17
|
+
export { SCENARIO_KINDS } from './types/kind-types.js';
|
|
18
|
+
// =============================================================================
|
|
19
|
+
// LOAD KIND
|
|
20
|
+
// =============================================================================
|
|
21
|
+
export { defineLoadScenario, validateLoadScenarioConfig, } from './kinds/load/define.js';
|
|
22
|
+
// =============================================================================
|
|
23
|
+
// CHAOS KIND
|
|
24
|
+
// =============================================================================
|
|
25
|
+
export { defineChaosScenario, validateChaosScenarioConfig, } from './kinds/chaos/define.js';
|
|
26
|
+
// =============================================================================
|
|
27
|
+
// TOOL PLUGIN — simulation as a Tool implementation
|
|
28
|
+
// =============================================================================
|
|
29
|
+
// Re-exported as `tool` so the third-party plugin-discovery walker
|
|
30
|
+
// (which keys on `mod.tool`) treats first-party and third-party Tool
|
|
31
|
+
// packages uniformly; dedup at register-tools.ts handles the
|
|
32
|
+
// duplicate-id case.
|
|
33
|
+
export { simulationTool, simulationTool as tool } from './tool.js';
|
|
34
|
+
export { SIMULATION_CONTRACT_VERSION } from './tool.js';
|
|
35
|
+
// =============================================================================
|
|
36
|
+
// SHARED INFRASTRUCTURE
|
|
37
|
+
// =============================================================================
|
|
38
|
+
// Authoring helpers (assertions, BYO target + fault builders) and runtime
|
|
39
|
+
// utilities (result builder, metric resolver, abort/sleep helpers) shared by
|
|
40
|
+
// every kind.
|
|
41
|
+
export { ASSERTIONS, evaluateAssertion, evaluateOperator, getOperatorDescription, } from './framework/assertions.js';
|
|
42
|
+
// BYO-target authoring surface: the `Target` seam, the neutral workload, and
|
|
43
|
+
// the client-side fault vocabulary + ergonomic builders.
|
|
44
|
+
export { httpTarget } from './framework/execution/http-target.js';
|
|
45
|
+
export { fault } from './framework/execution/fault-builders.js';
|
|
46
|
+
export { ScenarioResultBuilder, createEmptyMetrics, mergeMetrics, } from './framework/result-builder.js';
|
|
47
|
+
export { resolveMetric } from './framework/resolve-metric.js';
|
|
48
|
+
export { ScenarioAbortedError, scenarioAborted, validateAssertions, updateLatencyMetrics, sleepWithAbort, } from './framework/execution/execution-engine.js';
|
|
49
|
+
// =============================================================================
|
|
50
|
+
// RECIPES — sim recipes mirror the fitness recipe shape
|
|
51
|
+
// =============================================================================
|
|
52
|
+
export { defineSimulationRecipe } from './recipes/define-recipe.js';
|
|
53
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sKAAsK;AACtK;;;;;;;;GAQG;AAEH,gFAAgF;AAChF,uEAAuE;AACvE,kEAAkE;AAClE,0DAA0D;AAC1D,gFAAgF;AAEhF,OAAO,yBAAyB,CAAC;AAQjC,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAavD,gFAAgF;AAChF,YAAY;AACZ,gFAAgF;AAEhF,OAAO,EACL,kBAAkB,EAClB,0BAA0B,GAE3B,MAAM,wBAAwB,CAAC;AAGhC,gFAAgF;AAChF,aAAa;AACb,gFAAgF;AAEhF,OAAO,EACL,mBAAmB,EACnB,2BAA2B,GAE5B,MAAM,yBAAyB,CAAC;AAGjC,gFAAgF;AAChF,oDAAoD;AACpD,gFAAgF;AAEhF,mEAAmE;AACnE,qEAAqE;AACrE,6DAA6D;AAC7D,qBAAqB;AACrB,OAAO,EAAE,cAAc,EAAE,cAAc,IAAI,IAAI,EAAE,MAAM,WAAW,CAAC;AACnE,OAAO,EAAE,2BAA2B,EAAE,MAAM,WAAW,CAAC;AAaxD,gFAAgF;AAChF,wBAAwB;AACxB,gFAAgF;AAChF,0EAA0E;AAC1E,6EAA6E;AAC7E,cAAc;AAEd,OAAO,EACL,UAAU,EAEV,iBAAiB,EACjB,gBAAgB,EAChB,sBAAsB,GACvB,MAAM,2BAA2B,CAAC;AAEnC,6EAA6E;AAC7E,yDAAyD;AACzD,OAAO,EAAE,UAAU,EAA0B,MAAM,sCAAsC,CAAC;AAC1F,OAAO,EAAE,KAAK,EAAE,MAAM,yCAAyC,CAAC;AAKhE,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,YAAY,GACb,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EAAE,aAAa,EAA0B,MAAM,+BAA+B,CAAC;AAEtF,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,kBAAkB,EAClB,oBAAoB,EACpB,cAAc,GACf,MAAM,2CAA2C,CAAC;AAEnD,gFAAgF;AAChF,wDAAwD;AACxD,gFAAgF;AAEhF,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @opensip-cli/simulation/internal
|
|
3
|
+
*
|
|
4
|
+
* Internal simulation engine seams for package-owned tests and tool integration
|
|
5
|
+
* code that needs registry/lifecycle plumbing. This entrypoint is intentionally
|
|
6
|
+
* excluded from published package exports; production packages must use
|
|
7
|
+
* `@opensip-cli/simulation` and the Tool contract instead.
|
|
8
|
+
*/
|
|
9
|
+
export { ensureScenariosLoaded } from './cli/sim.js';
|
|
10
|
+
export { createScenarioRegistry, currentScenarioRegistry, getRegisteredScenarios, getScenario, getScenariosByTag, getScenariosByKind, clearScenarioRegistry, } from './framework/registry.js';
|
|
11
|
+
export { loadAllSimPlugins } from './plugins/loader.js';
|
|
12
|
+
export { readScenarioPackagePreferences } from './plugins/scenario-package-discovery.js';
|
|
13
|
+
export type { SimPluginExports } from './plugins/types.js';
|
|
14
|
+
export { builtInSimulationRecipes, builtInSimulationRecipesByName, isBuiltInSimulationRecipe, } from './recipes/built-in-recipes.js';
|
|
15
|
+
export { SimulationRecipeRegistry, createSimulationRecipeRegistry, currentSimulationRecipeRegistry, } from './recipes/registry.js';
|
|
16
|
+
export type { SimulationRecipeDisplayInfo } from './recipes/registry.js';
|
|
17
|
+
export { SimulationRecipeService } from './recipes/service.js';
|
|
18
|
+
export type { SimulationRecipeServiceConfig, SimulationScenarioResult, SimulationRecipeResult, } from './recipes/service.js';
|
|
19
|
+
//# sourceMappingURL=internal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAErD,OAAO,EACL,sBAAsB,EACtB,uBAAuB,EACvB,sBAAsB,EACtB,WAAW,EACX,iBAAiB,EACjB,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,8BAA8B,EAAE,MAAM,yCAAyC,CAAC;AACzF,YAAY,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE3D,OAAO,EACL,wBAAwB,EACxB,8BAA8B,EAC9B,yBAAyB,GAC1B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,wBAAwB,EACxB,8BAA8B,EAC9B,+BAA+B,GAChC,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,2BAA2B,EAAE,MAAM,uBAAuB,CAAC;AACzE,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,YAAY,EACV,6BAA6B,EAC7B,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,sBAAsB,CAAC"}
|
package/dist/internal.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @opensip-cli/simulation/internal
|
|
3
|
+
*
|
|
4
|
+
* Internal simulation engine seams for package-owned tests and tool integration
|
|
5
|
+
* code that needs registry/lifecycle plumbing. This entrypoint is intentionally
|
|
6
|
+
* excluded from published package exports; production packages must use
|
|
7
|
+
* `@opensip-cli/simulation` and the Tool contract instead.
|
|
8
|
+
*/
|
|
9
|
+
export { ensureScenariosLoaded } from './cli/sim.js';
|
|
10
|
+
export { createScenarioRegistry, currentScenarioRegistry, getRegisteredScenarios, getScenario, getScenariosByTag, getScenariosByKind, clearScenarioRegistry, } from './framework/registry.js';
|
|
11
|
+
export { loadAllSimPlugins } from './plugins/loader.js';
|
|
12
|
+
export { readScenarioPackagePreferences } from './plugins/scenario-package-discovery.js';
|
|
13
|
+
export { builtInSimulationRecipes, builtInSimulationRecipesByName, isBuiltInSimulationRecipe, } from './recipes/built-in-recipes.js';
|
|
14
|
+
export { SimulationRecipeRegistry, createSimulationRecipeRegistry, currentSimulationRecipeRegistry, } from './recipes/registry.js';
|
|
15
|
+
export { SimulationRecipeService } from './recipes/service.js';
|
|
16
|
+
//# sourceMappingURL=internal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"internal.js","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAErD,OAAO,EACL,sBAAsB,EACtB,uBAAuB,EACvB,sBAAsB,EACtB,WAAW,EACX,iBAAiB,EACjB,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,8BAA8B,EAAE,MAAM,yCAAyC,CAAC;AAGzF,OAAO,EACL,wBAAwB,EACxB,8BAA8B,EAC9B,yBAAyB,GAC1B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,wBAAwB,EACxB,8BAA8B,EAC9B,+BAA+B,GAChC,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.test.d.ts","sourceRoot":"","sources":["../../../../src/kinds/chaos/__tests__/executor.test.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Behaviour + validation tests for the chaos kind against the
|
|
3
|
+
* real driver + fault model.
|
|
4
|
+
*/
|
|
5
|
+
import { describe, expect, it } from 'vitest';
|
|
6
|
+
import { failingTarget, noopTarget } from '../../../__tests__/test-utils/targets.js';
|
|
7
|
+
import { ASSERTIONS } from '../../../framework/assertions.js';
|
|
8
|
+
import { fault } from '../../../framework/execution/fault-builders.js';
|
|
9
|
+
import { defineChaosScenario, validateChaosScenarioConfig } from '../define.js';
|
|
10
|
+
import { createChaosScenarioRunner } from '../executor.js';
|
|
11
|
+
const base = (o = {}) => ({
|
|
12
|
+
id: 'c',
|
|
13
|
+
name: 'c',
|
|
14
|
+
description: 'c',
|
|
15
|
+
tags: [],
|
|
16
|
+
target: noopTarget,
|
|
17
|
+
workload: { rps: 50 },
|
|
18
|
+
duration: 0.3,
|
|
19
|
+
fault: fault.of([fault.drop()], { probability: 1 }),
|
|
20
|
+
steadyStateAssertions: [ASSERTIONS.lowErrorRate(0.5)],
|
|
21
|
+
recoveryAssertions: [ASSERTIONS.lowErrorRate(0.5)],
|
|
22
|
+
recoveryWindow: 100,
|
|
23
|
+
...o,
|
|
24
|
+
});
|
|
25
|
+
describe('chaos executor', () => {
|
|
26
|
+
it('faults degrade the steady window; recovery recovers', async () => {
|
|
27
|
+
const r = await createChaosScenarioRunner(base()).run(new AbortController().signal);
|
|
28
|
+
if (r.kind !== 'chaos')
|
|
29
|
+
throw new Error('expected chaos result');
|
|
30
|
+
// probability-1 drop → all steady requests fail; recovery (bare noop) succeeds.
|
|
31
|
+
expect(r.outcome.steadyStateMetrics.failedRequests).toBeGreaterThan(0);
|
|
32
|
+
expect(r.outcome.steadyStateMetrics.successfulRequests).toBe(0);
|
|
33
|
+
expect(r.outcome.steadyStateAssertions.failed.length).toBeGreaterThan(0);
|
|
34
|
+
expect(r.outcome.recoveryMetrics.successfulRequests).toBeGreaterThan(0);
|
|
35
|
+
expect(r.outcome.recoveryAssertions.failed).toHaveLength(0);
|
|
36
|
+
expect(r.passed).toBe(false);
|
|
37
|
+
expect(r.outcome.chaosEvents.length).toBeGreaterThan(0);
|
|
38
|
+
expect(r.outcome.chaosEvents[0]?.type).toBe('drop');
|
|
39
|
+
expect(r.outcome.recoveryWindowMs).toBe(100);
|
|
40
|
+
});
|
|
41
|
+
it('passes when both windows hold (no faults injected)', async () => {
|
|
42
|
+
const r = await createChaosScenarioRunner(base({ fault: fault.of([fault.drop()], { probability: 0 }) })).run(new AbortController().signal);
|
|
43
|
+
if (r.kind !== 'chaos')
|
|
44
|
+
throw new Error('expected chaos result');
|
|
45
|
+
expect(r.passed).toBe(true);
|
|
46
|
+
expect(r.outcome.chaosEvents).toHaveLength(0);
|
|
47
|
+
});
|
|
48
|
+
it('fails recovery when the target never recovers', async () => {
|
|
49
|
+
const r = await createChaosScenarioRunner(base({
|
|
50
|
+
target: failingTarget,
|
|
51
|
+
fault: fault.of([fault.drop()], { probability: 0 }),
|
|
52
|
+
steadyStateAssertions: [ASSERTIONS.lowErrorRate(1)],
|
|
53
|
+
recoveryAssertions: [ASSERTIONS.lowErrorRate(0.1)],
|
|
54
|
+
})).run(new AbortController().signal);
|
|
55
|
+
if (r.kind !== 'chaos')
|
|
56
|
+
throw new Error('expected chaos result');
|
|
57
|
+
expect(r.outcome.recoveryAssertions.failed.length).toBeGreaterThan(0);
|
|
58
|
+
expect(r.passed).toBe(false);
|
|
59
|
+
});
|
|
60
|
+
it('honours an injected rng deterministically (no perturbation)', async () => {
|
|
61
|
+
const r = await createChaosScenarioRunner(base({ fault: fault.of([fault.drop()], { probability: 0.5 }) }), { rng: () => 0.9 }).run(new AbortController().signal);
|
|
62
|
+
if (r.kind !== 'chaos')
|
|
63
|
+
throw new Error('expected chaos result');
|
|
64
|
+
// rng always 0.9 ≥ 0.5 ⇒ never perturb.
|
|
65
|
+
expect(r.outcome.chaosEvents).toHaveLength(0);
|
|
66
|
+
expect(r.outcome.steadyStateMetrics.failedRequests).toBe(0);
|
|
67
|
+
});
|
|
68
|
+
it('throws on a pre-aborted signal', async () => {
|
|
69
|
+
const ac = new AbortController();
|
|
70
|
+
ac.abort();
|
|
71
|
+
await expect(createChaosScenarioRunner(base()).run(ac.signal)).rejects.toThrow(/abort/i);
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
describe('validateChaosScenarioConfig', () => {
|
|
75
|
+
it('accepts a valid config via defineChaosScenario', () => {
|
|
76
|
+
expect(defineChaosScenario(base()).kind).toBe('chaos');
|
|
77
|
+
});
|
|
78
|
+
it('rejects a non-function target', () => {
|
|
79
|
+
expect(() => validateChaosScenarioConfig(base({ target: undefined }))).toThrow(/target/);
|
|
80
|
+
});
|
|
81
|
+
it('rejects a probability outside [0,1]', () => {
|
|
82
|
+
expect(() => validateChaosScenarioConfig(base({ fault: fault.of([fault.drop()], { probability: 2 }) }))).toThrow(/probability/);
|
|
83
|
+
});
|
|
84
|
+
it('rejects an empty faults array', () => {
|
|
85
|
+
expect(() => validateChaosScenarioConfig(base({ fault: { faults: [], probability: 0.5 } }))).toThrow(/faults/);
|
|
86
|
+
});
|
|
87
|
+
it('rejects a non-positive rps', () => {
|
|
88
|
+
expect(() => validateChaosScenarioConfig(base({ workload: { rps: 0 } }))).toThrow(/rps/);
|
|
89
|
+
});
|
|
90
|
+
it('rejects empty steady-state assertions', () => {
|
|
91
|
+
expect(() => validateChaosScenarioConfig(base({ steadyStateAssertions: [] }))).toThrow(/steady/i);
|
|
92
|
+
});
|
|
93
|
+
it('rejects empty recovery assertions', () => {
|
|
94
|
+
expect(() => validateChaosScenarioConfig(base({ recoveryAssertions: [] }))).toThrow(/recovery assertion/i);
|
|
95
|
+
});
|
|
96
|
+
it('rejects an invalid recoveryWindow (negative / non-number)', () => {
|
|
97
|
+
expect(() => validateChaosScenarioConfig(base({ recoveryWindow: -1 }))).toThrow(/recoveryWindow/);
|
|
98
|
+
expect(() => validateChaosScenarioConfig(base({ recoveryWindow: 'soon' }))).toThrow(/recoveryWindow/);
|
|
99
|
+
});
|
|
100
|
+
it('rejects a negative rampUp', () => {
|
|
101
|
+
expect(() => validateChaosScenarioConfig(base({ workload: { rps: 1, rampUp: -1 } }))).toThrow(/rampUp must be non-negative/);
|
|
102
|
+
});
|
|
103
|
+
it('rejects a non-positive duration', () => {
|
|
104
|
+
expect(() => validateChaosScenarioConfig(base({ duration: 0 }))).toThrow(/duration/);
|
|
105
|
+
});
|
|
106
|
+
it('rejects a missing fault spec', () => {
|
|
107
|
+
expect(() => validateChaosScenarioConfig(base({ fault: undefined }))).toThrow(/fault spec is required/);
|
|
108
|
+
});
|
|
109
|
+
it('rejects an unknown fault kind', () => {
|
|
110
|
+
expect(() => validateChaosScenarioConfig(base({ fault: { faults: [{ kind: 'meltdown' }], probability: 0.5 } }))).toThrow(/fault kind must be one of/);
|
|
111
|
+
});
|
|
112
|
+
it('rejects a latency fault with a missing or negative ms', () => {
|
|
113
|
+
expect(() => validateChaosScenarioConfig(base({ fault: { faults: [{ kind: 'latency' }], probability: 0.5 } }))).toThrow(/latency fault requires a non-negative ms/);
|
|
114
|
+
expect(() => validateChaosScenarioConfig(base({ fault: { faults: [{ kind: 'latency', ms: -5 }], probability: 0.5 } }))).toThrow(/latency fault requires a non-negative ms/);
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
//# sourceMappingURL=executor.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.test.js","sourceRoot":"","sources":["../../../../src/kinds/chaos/__tests__/executor.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview `ChaosScenarioConfig` — author-facing configuration type.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from `define.ts` into its own leaf module so `executor.ts`
|
|
5
|
+
* can reference the config shape without forming a file-level cycle:
|
|
6
|
+
*
|
|
7
|
+
* `define.ts` → `executor.ts` (uses `createChaosScenarioRunner`)
|
|
8
|
+
* `executor.ts` → `define.ts` (uses `ChaosScenarioConfig`)
|
|
9
|
+
*
|
|
10
|
+
* The split inverts the dependency. Both files import the config shape from
|
|
11
|
+
* here, and nothing in this file imports back. `define.ts` re-exports
|
|
12
|
+
* `ChaosScenarioConfig` so callers keep one import path.
|
|
13
|
+
*/
|
|
14
|
+
import type { FaultSpec } from '../../framework/execution/fault-spec.js';
|
|
15
|
+
import type { Target } from '../../framework/execution/target.js';
|
|
16
|
+
import type { ScenarioAssertion } from '../../types/framework-types.js';
|
|
17
|
+
import type { Workload } from '../../types/workload.js';
|
|
18
|
+
/**
|
|
19
|
+
* Author-facing configuration for a chaos scenario.
|
|
20
|
+
*
|
|
21
|
+
* The `kind` discriminator is set by the entry point.
|
|
22
|
+
*
|
|
23
|
+
* Chaos drives a real BYO `target` under client-side fault injection: a
|
|
24
|
+
* steady-state window with the fault model active, then a recovery window with
|
|
25
|
+
* faults lifted. There is intentionally no custom-`execute` escape hatch — the
|
|
26
|
+
* `target` IS the BYO seam.
|
|
27
|
+
*/
|
|
28
|
+
export interface ChaosScenarioConfig {
|
|
29
|
+
readonly id: string;
|
|
30
|
+
readonly name: string;
|
|
31
|
+
readonly description: string;
|
|
32
|
+
readonly tags: readonly string[];
|
|
33
|
+
/** The BYO target driven once per request (throws on failure). */
|
|
34
|
+
readonly target: Target;
|
|
35
|
+
/** Arrival-rate workload (rps + optional concurrency/ramp). */
|
|
36
|
+
readonly workload: Workload;
|
|
37
|
+
/** Steady-state (fault-active) window duration, in seconds. */
|
|
38
|
+
readonly duration: number;
|
|
39
|
+
/** Client-side faults injected during the steady-state window. */
|
|
40
|
+
readonly fault: FaultSpec;
|
|
41
|
+
/** Assertions evaluated on the steady-state (fault-active) metrics. */
|
|
42
|
+
readonly steadyStateAssertions: readonly ScenarioAssertion[];
|
|
43
|
+
/** Assertions evaluated on the recovery (faults-lifted) metrics. */
|
|
44
|
+
readonly recoveryAssertions: readonly ScenarioAssertion[];
|
|
45
|
+
/** Recovery window in milliseconds after faults lift. */
|
|
46
|
+
readonly recoveryWindow: number;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/kinds/chaos/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qCAAqC,CAAC;AAClE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAExD;;;;;;;;;GASG;AACH,MAAM,WAAW,mBAAmB;IAElC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IAGjC,kEAAkE;IAClE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,+DAA+D;IAC/D,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,+DAA+D;IAC/D,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAG1B,kEAAkE;IAClE,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAC1B,uEAAuE;IACvE,QAAQ,CAAC,qBAAqB,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC7D,oEAAoE;IACpE,QAAQ,CAAC,kBAAkB,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC1D,yDAAyD;IACzD,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview `ChaosScenarioConfig` — author-facing configuration type.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from `define.ts` into its own leaf module so `executor.ts`
|
|
5
|
+
* can reference the config shape without forming a file-level cycle:
|
|
6
|
+
*
|
|
7
|
+
* `define.ts` → `executor.ts` (uses `createChaosScenarioRunner`)
|
|
8
|
+
* `executor.ts` → `define.ts` (uses `ChaosScenarioConfig`)
|
|
9
|
+
*
|
|
10
|
+
* The split inverts the dependency. Both files import the config shape from
|
|
11
|
+
* here, and nothing in this file imports back. `define.ts` re-exports
|
|
12
|
+
* `ChaosScenarioConfig` so callers keep one import path.
|
|
13
|
+
*/
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/kinds/chaos/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview `defineChaosScenario` — chaos-kind entry point.
|
|
3
|
+
*
|
|
4
|
+
* The chaos kind drives a real BYO `target` under client-side fault injection
|
|
5
|
+
* with a recovery-window assertion contract. Authors supply:
|
|
6
|
+
* - a `target` (the BYO seam) + a `workload` (rps/concurrency/ramp) + `duration`
|
|
7
|
+
* - a `fault` spec (client-side faults + probability)
|
|
8
|
+
* - `steadyStateAssertions` evaluated while faults are active
|
|
9
|
+
* - `recoveryAssertions` evaluated during the post-fault recovery window
|
|
10
|
+
* - `recoveryWindow` (ms) — how long after faults lift to evaluate recovery
|
|
11
|
+
*/
|
|
12
|
+
import type { ChaosScenarioConfig } from './config.js';
|
|
13
|
+
import type { RunnableScenario } from '../../framework/runnable-scenario.js';
|
|
14
|
+
export type { ChaosScenarioConfig } from './config.js';
|
|
15
|
+
/**
|
|
16
|
+
* Validate a chaos scenario configuration. Throws on invalid input.
|
|
17
|
+
*
|
|
18
|
+
* Uniqueness against an existing scenario registry is checked at
|
|
19
|
+
* registration time, not here.
|
|
20
|
+
*
|
|
21
|
+
* @throws {ValidationError} When the chaos scenario configuration is invalid
|
|
22
|
+
*/
|
|
23
|
+
export declare function validateChaosScenarioConfig(config: ChaosScenarioConfig): void;
|
|
24
|
+
/**
|
|
25
|
+
* Define a chaos-kind simulation scenario. Returns the scenario; the
|
|
26
|
+
* caller (typically the simulation plugin loader) is responsible for
|
|
27
|
+
* registering it into `scope.registries.scenarios`.
|
|
28
|
+
*
|
|
29
|
+
* @throws {ValidationError} When the scenario configuration is invalid
|
|
30
|
+
*/
|
|
31
|
+
export declare function defineChaosScenario(config: ChaosScenarioConfig): RunnableScenario;
|
|
32
|
+
//# sourceMappingURL=define.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define.d.ts","sourceRoot":"","sources":["../../../src/kinds/chaos/define.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAWH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AAM7E,YAAY,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAgFvD;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI,CAS7E;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,mBAAmB,GAAG,gBAAgB,CAGjF"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview `defineChaosScenario` — chaos-kind entry point.
|
|
3
|
+
*
|
|
4
|
+
* The chaos kind drives a real BYO `target` under client-side fault injection
|
|
5
|
+
* with a recovery-window assertion contract. Authors supply:
|
|
6
|
+
* - a `target` (the BYO seam) + a `workload` (rps/concurrency/ramp) + `duration`
|
|
7
|
+
* - a `fault` spec (client-side faults + probability)
|
|
8
|
+
* - `steadyStateAssertions` evaluated while faults are active
|
|
9
|
+
* - `recoveryAssertions` evaluated during the post-fault recovery window
|
|
10
|
+
* - `recoveryWindow` (ms) — how long after faults lift to evaluate recovery
|
|
11
|
+
*/
|
|
12
|
+
import { throwValidationErrors, validateScenarioMetadata, validateTargetAndWorkload, } from '../../framework/validation.js';
|
|
13
|
+
import { createChaosScenarioRunner } from './executor.js';
|
|
14
|
+
const VALID_FAULT_KINDS = new Set(['latency', 'abort', 'drop']);
|
|
15
|
+
/**
|
|
16
|
+
* Chaos-specific workload-timing checks: `rampUp` must be non-negative and
|
|
17
|
+
* `duration` must be positive. The common `target`/`workload.rps`/
|
|
18
|
+
* `workload.concurrency` checks live in the shared
|
|
19
|
+
* `validateTargetAndWorkload`; these stay inline because chaos uses a
|
|
20
|
+
* different `rampUp` message ("must be non-negative") than load and does not
|
|
21
|
+
* cross-check `rampUp` against `duration`.
|
|
22
|
+
*/
|
|
23
|
+
function validateChaosWorkloadTiming(config, errors) {
|
|
24
|
+
if (config.workload?.rampUp !== undefined && config.workload.rampUp < 0) {
|
|
25
|
+
errors.push({ field: 'workload.rampUp', message: 'workload.rampUp must be non-negative' });
|
|
26
|
+
}
|
|
27
|
+
if (typeof config.duration !== 'number' || config.duration <= 0) {
|
|
28
|
+
errors.push({ field: 'duration', message: 'duration must be a positive number' });
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function validateFault(config, errors) {
|
|
32
|
+
if (!config.fault) {
|
|
33
|
+
errors.push({ field: 'fault', message: 'fault spec is required for chaos scenarios' });
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
if (typeof config.fault.probability !== 'number' ||
|
|
37
|
+
config.fault.probability < 0 ||
|
|
38
|
+
config.fault.probability > 1) {
|
|
39
|
+
errors.push({
|
|
40
|
+
field: 'fault.probability',
|
|
41
|
+
message: 'fault.probability must be in [0, 1]',
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
if (config.fault.faults.length === 0) {
|
|
45
|
+
errors.push({ field: 'fault.faults', message: 'fault.faults must be a non-empty array' });
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
for (const [i, f] of config.fault.faults.entries()) {
|
|
49
|
+
if (!VALID_FAULT_KINDS.has(f.kind)) {
|
|
50
|
+
errors.push({
|
|
51
|
+
field: `fault.faults[${i}].kind`,
|
|
52
|
+
message: "fault kind must be one of 'latency' | 'abort' | 'drop'",
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
if (f.kind === 'latency' && (typeof f.ms !== 'number' || f.ms < 0)) {
|
|
56
|
+
errors.push({
|
|
57
|
+
field: `fault.faults[${i}].ms`,
|
|
58
|
+
message: 'latency fault requires a non-negative ms',
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function validateAssertions(config, errors) {
|
|
64
|
+
if (config.steadyStateAssertions.length === 0) {
|
|
65
|
+
errors.push({
|
|
66
|
+
field: 'steadyStateAssertions',
|
|
67
|
+
message: 'at least one steady-state assertion is required',
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
if (config.recoveryAssertions.length === 0) {
|
|
71
|
+
errors.push({
|
|
72
|
+
field: 'recoveryAssertions',
|
|
73
|
+
message: 'at least one recovery assertion is required',
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
if (typeof config.recoveryWindow !== 'number' || config.recoveryWindow < 0) {
|
|
77
|
+
errors.push({
|
|
78
|
+
field: 'recoveryWindow',
|
|
79
|
+
message: 'recoveryWindow must be a non-negative number (milliseconds)',
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Validate a chaos scenario configuration. Throws on invalid input.
|
|
85
|
+
*
|
|
86
|
+
* Uniqueness against an existing scenario registry is checked at
|
|
87
|
+
* registration time, not here.
|
|
88
|
+
*
|
|
89
|
+
* @throws {ValidationError} When the chaos scenario configuration is invalid
|
|
90
|
+
*/
|
|
91
|
+
export function validateChaosScenarioConfig(config) {
|
|
92
|
+
const errors = [];
|
|
93
|
+
validateScenarioMetadata(config, errors);
|
|
94
|
+
validateTargetAndWorkload(config, errors);
|
|
95
|
+
validateChaosWorkloadTiming(config, errors);
|
|
96
|
+
validateFault(config, errors);
|
|
97
|
+
validateAssertions(config, errors);
|
|
98
|
+
throwValidationErrors(errors, 'chaos');
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Define a chaos-kind simulation scenario. Returns the scenario; the
|
|
102
|
+
* caller (typically the simulation plugin loader) is responsible for
|
|
103
|
+
* registering it into `scope.registries.scenarios`.
|
|
104
|
+
*
|
|
105
|
+
* @throws {ValidationError} When the scenario configuration is invalid
|
|
106
|
+
*/
|
|
107
|
+
export function defineChaosScenario(config) {
|
|
108
|
+
validateChaosScenarioConfig(config);
|
|
109
|
+
return createChaosScenarioRunner(config);
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=define.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define.js","sourceRoot":"","sources":["../../../src/kinds/chaos/define.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Chaos-kind executor.
|
|
3
|
+
*
|
|
4
|
+
* Composes the real `runLoadWindow` driver with the client-side fault model:
|
|
5
|
+
* a steady-state window drives the BYO `target` wrapped by the fault model
|
|
6
|
+
* (latency/abort/drop injected at the configured probability), then a recovery
|
|
7
|
+
* window drives the bare target with faults lifted. Each window's measured
|
|
8
|
+
* metrics are scored against its assertion set; the scenario passes iff both
|
|
9
|
+
* windows hold.
|
|
10
|
+
*/
|
|
11
|
+
import type { ChaosScenarioConfig } from './config.js';
|
|
12
|
+
import type { FaultModelDeps } from '../../framework/execution/fault-model.js';
|
|
13
|
+
import type { RunnableScenario } from '../../framework/runnable-scenario.js';
|
|
14
|
+
/**
|
|
15
|
+
* Build a `RunnableScenario` for a chaos-kind config.
|
|
16
|
+
*
|
|
17
|
+
* `deps.rng` is forwarded to the fault model so tests can drive the
|
|
18
|
+
* probability gate deterministically; production defaults to `Math.random`.
|
|
19
|
+
*/
|
|
20
|
+
export declare function createChaosScenarioRunner(config: ChaosScenarioConfig, deps?: FaultModelDeps): RunnableScenario;
|
|
21
|
+
//# sourceMappingURL=executor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../../src/kinds/chaos/executor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAWH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAC;AAC/E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AAsB7E;;;;;GAKG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,mBAAmB,EAC3B,IAAI,GAAE,cAAmB,GACxB,gBAAgB,CA8FlB"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Chaos-kind executor.
|
|
3
|
+
*
|
|
4
|
+
* Composes the real `runLoadWindow` driver with the client-side fault model:
|
|
5
|
+
* a steady-state window drives the BYO `target` wrapped by the fault model
|
|
6
|
+
* (latency/abort/drop injected at the configured probability), then a recovery
|
|
7
|
+
* window drives the bare target with faults lifted. Each window's measured
|
|
8
|
+
* metrics are scored against its assertion set; the scenario passes iff both
|
|
9
|
+
* windows hold.
|
|
10
|
+
*/
|
|
11
|
+
import { ScenarioAbortedError } from '../../framework/execution/execution-engine.js';
|
|
12
|
+
import { createFaultModel } from '../../framework/execution/fault-model.js';
|
|
13
|
+
import { runLoadWindow } from '../../framework/execution/run-load-window.js';
|
|
14
|
+
import { buildFailedScenarioSignal, ScenarioResultBuilder, } from '../../framework/result-builder.js';
|
|
15
|
+
import { createScenarioLogger } from '../../framework/scenario-logger.js';
|
|
16
|
+
function evaluateAssertionsForWindow(scenarioId, metrics, durationSeconds, assertions) {
|
|
17
|
+
const built = ScenarioResultBuilder.create(scenarioId)
|
|
18
|
+
.withMetrics(metrics)
|
|
19
|
+
.withDuration(durationSeconds)
|
|
20
|
+
.evaluateAssertions(assertions)
|
|
21
|
+
.build();
|
|
22
|
+
return {
|
|
23
|
+
passed: built.assertions.passed,
|
|
24
|
+
failed: built.assertions.failed,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Build a `RunnableScenario` for a chaos-kind config.
|
|
29
|
+
*
|
|
30
|
+
* `deps.rng` is forwarded to the fault model so tests can drive the
|
|
31
|
+
* probability gate deterministically; production defaults to `Math.random`.
|
|
32
|
+
*/
|
|
33
|
+
export function createChaosScenarioRunner(config, deps = {}) {
|
|
34
|
+
return Object.freeze({
|
|
35
|
+
kind: 'chaos',
|
|
36
|
+
id: config.id,
|
|
37
|
+
name: config.name,
|
|
38
|
+
description: config.description,
|
|
39
|
+
tags: Object.freeze([...config.tags]),
|
|
40
|
+
run:
|
|
41
|
+
/** @throws {ScenarioAbortedError} When the scenario is aborted via AbortSignal */
|
|
42
|
+
async (abortSignal) => {
|
|
43
|
+
const correlationId = `scenario-${config.id}-${Date.now().toString(36)}`;
|
|
44
|
+
const context = {
|
|
45
|
+
scenarioId: config.id,
|
|
46
|
+
correlationId,
|
|
47
|
+
abortSignal,
|
|
48
|
+
logger: createScenarioLogger(config.id),
|
|
49
|
+
};
|
|
50
|
+
if (abortSignal.aborted) {
|
|
51
|
+
throw new ScenarioAbortedError(config.id);
|
|
52
|
+
}
|
|
53
|
+
const startTime = Date.now();
|
|
54
|
+
try {
|
|
55
|
+
const faultModel = createFaultModel(config.fault, deps);
|
|
56
|
+
// Steady-state window: drive the fault-decorated target.
|
|
57
|
+
const steadyStart = Date.now();
|
|
58
|
+
const steady = await runLoadWindow({ workload: config.workload }, context, {
|
|
59
|
+
windowMs: config.duration * 1000,
|
|
60
|
+
target: faultModel.wrap(config.target),
|
|
61
|
+
});
|
|
62
|
+
// Recovery window: faults lifted — drive the bare target.
|
|
63
|
+
const recovery = await runLoadWindow({ workload: config.workload }, context, {
|
|
64
|
+
windowMs: config.recoveryWindow,
|
|
65
|
+
target: config.target,
|
|
66
|
+
});
|
|
67
|
+
const steadyVerdict = evaluateAssertionsForWindow(config.id, steady.metrics, config.duration, config.steadyStateAssertions);
|
|
68
|
+
const recoveryVerdict = evaluateAssertionsForWindow(config.id, recovery.metrics, config.recoveryWindow / 1000, config.recoveryAssertions);
|
|
69
|
+
const failedAssertions = [...steadyVerdict.failed, ...recoveryVerdict.failed];
|
|
70
|
+
const passed = failedAssertions.length === 0;
|
|
71
|
+
const chaosEvents = Object.freeze(faultModel.drained().map((f) => Object.freeze({
|
|
72
|
+
type: f.kind,
|
|
73
|
+
atMs: Math.max(0, f.at - steadyStart),
|
|
74
|
+
target: 'client',
|
|
75
|
+
})));
|
|
76
|
+
return Object.freeze({
|
|
77
|
+
kind: 'chaos',
|
|
78
|
+
scenarioId: config.id,
|
|
79
|
+
passed,
|
|
80
|
+
durationMs: Date.now() - startTime,
|
|
81
|
+
// ADR-0035: surface a failed chaos scenario in the signal currency
|
|
82
|
+
// (steady- and recovery-window assertion failures), so the host
|
|
83
|
+
// verdict sees it. The load path emits via build(); chaos builds its
|
|
84
|
+
// own payload, so it must emit here.
|
|
85
|
+
signals: passed
|
|
86
|
+
? Object.freeze([])
|
|
87
|
+
: Object.freeze([buildFailedScenarioSignal(config.id, failedAssertions)]),
|
|
88
|
+
outcome: Object.freeze({
|
|
89
|
+
steadyStateMetrics: steady.metrics,
|
|
90
|
+
recoveryMetrics: recovery.metrics,
|
|
91
|
+
steadyStateAssertions: steadyVerdict,
|
|
92
|
+
recoveryAssertions: recoveryVerdict,
|
|
93
|
+
chaosEvents,
|
|
94
|
+
recoveryWindowMs: config.recoveryWindow,
|
|
95
|
+
}),
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
if (abortSignal.aborted) {
|
|
100
|
+
throw new ScenarioAbortedError(config.id);
|
|
101
|
+
}
|
|
102
|
+
throw error;
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../src/kinds/chaos/executor.ts"],"names":[],"mappings":"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"}
|