@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,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `sim-run-worker` — the headless sim run forked by the live view
|
|
3
|
+
* (`executeSimWorker`, ADR-0028). It reads a serializable sim-args spec, runs
|
|
4
|
+
* `executeSim` headless, streams pool progress over the fork IPC channel
|
|
5
|
+
* (`process.send`), and posts the final result. A bad spec is reported as a
|
|
6
|
+
* `{ kind: 'error' }` message, not a throw.
|
|
7
|
+
*
|
|
8
|
+
* The test stubs `process.send` (the process is not actually forked under vitest)
|
|
9
|
+
* and registers a scenario so the default recipe has work to run.
|
|
10
|
+
*/
|
|
11
|
+
import { mkdtempSync, rmSync, writeFileSync } from 'node:fs';
|
|
12
|
+
import { tmpdir } from 'node:os';
|
|
13
|
+
import { join } from 'node:path';
|
|
14
|
+
import { enterScope } from '@opensip-cli/core';
|
|
15
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
16
|
+
import { noopTarget } from '../../__tests__/test-utils/targets.js';
|
|
17
|
+
import { makeSimTestScope } from '../../__tests__/test-utils/with-sim-scope.js';
|
|
18
|
+
import { ASSERTIONS } from '../../framework/assertions.js';
|
|
19
|
+
import { clearScenarioRegistry, currentScenarioRegistry } from '../../framework/registry.js';
|
|
20
|
+
import { defineLoadScenario } from '../../kinds/load/define.js';
|
|
21
|
+
import { executeSimWorker } from '../sim-worker.js';
|
|
22
|
+
let dir;
|
|
23
|
+
let messages;
|
|
24
|
+
beforeEach(() => {
|
|
25
|
+
enterScope(makeSimTestScope());
|
|
26
|
+
dir = mkdtempSync(join(tmpdir(), 'sim-worker-test-'));
|
|
27
|
+
messages = [];
|
|
28
|
+
// The worker posts via process.send (a no-op when not forked); stub it to capture.
|
|
29
|
+
// process.send is undefined under vitest, so deleting it in afterEach restores state.
|
|
30
|
+
process.send = vi.fn((m) => {
|
|
31
|
+
messages.push(m);
|
|
32
|
+
return true;
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
afterEach(() => {
|
|
36
|
+
clearScenarioRegistry();
|
|
37
|
+
delete process.send;
|
|
38
|
+
rmSync(dir, { recursive: true, force: true });
|
|
39
|
+
});
|
|
40
|
+
describe('executeSimWorker', () => {
|
|
41
|
+
it('runs the sim and posts progress + a result over IPC', async () => {
|
|
42
|
+
currentScenarioRegistry().register(defineLoadScenario({
|
|
43
|
+
id: 'worker-probe',
|
|
44
|
+
name: 'worker-probe',
|
|
45
|
+
description: 'worker-probe',
|
|
46
|
+
tags: [],
|
|
47
|
+
target: noopTarget,
|
|
48
|
+
workload: { rps: 1 },
|
|
49
|
+
duration: 1,
|
|
50
|
+
assertions: [ASSERTIONS.lowErrorRate(1)],
|
|
51
|
+
}));
|
|
52
|
+
const specPath = join(dir, 'spec.json');
|
|
53
|
+
writeFileSync(specPath, JSON.stringify({ json: false, cwd: dir, debug: false }), 'utf8');
|
|
54
|
+
await executeSimWorker(specPath);
|
|
55
|
+
expect(messages.some((m) => m.kind === 'progress')).toBe(true);
|
|
56
|
+
const result = messages.find((m) => m.kind === 'result');
|
|
57
|
+
expect(result?.kind).toBe('result');
|
|
58
|
+
if (result?.kind !== 'result')
|
|
59
|
+
throw new Error('no result message');
|
|
60
|
+
expect(result.value.result.type).toBe('sim-done');
|
|
61
|
+
});
|
|
62
|
+
it('reports a bad spec path as an error message, not a throw', async () => {
|
|
63
|
+
await expect(executeSimWorker(join(dir, 'missing.json'))).resolves.toBeUndefined();
|
|
64
|
+
const err = messages.find((m) => m.kind === 'error');
|
|
65
|
+
expect(err?.kind).toBe('error');
|
|
66
|
+
expect(messages.some((m) => m.kind === 'result')).toBe(false);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
//# sourceMappingURL=sim-worker.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sim-worker.test.js","sourceRoot":"","sources":["../../../src/cli/__tests__/sim-worker.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sim.test.d.ts","sourceRoot":"","sources":["../../../src/cli/__tests__/sim.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import { createSignal, enterScope, generatePrefixedId } from '@opensip-cli/core';
|
|
2
|
+
import { DataStoreFactory } from '@opensip-cli/datastore';
|
|
3
|
+
import { SessionRepo } from '@opensip-cli/session-store';
|
|
4
|
+
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
5
|
+
import { noopTarget } from '../../__tests__/test-utils/targets.js';
|
|
6
|
+
import { makeSimTestScope } from '../../__tests__/test-utils/with-sim-scope.js';
|
|
7
|
+
import { ASSERTIONS } from '../../framework/assertions.js';
|
|
8
|
+
import { clearScenarioRegistry, currentScenarioRegistry } from '../../framework/registry.js';
|
|
9
|
+
import { defineLoadScenario } from '../../kinds/load/define.js';
|
|
10
|
+
import { buildSimulationSessionPayload } from '../../persistence/session-payload.js';
|
|
11
|
+
import { executeSim } from '../sim.js';
|
|
12
|
+
const args = (overrides = {}) => ({
|
|
13
|
+
json: false,
|
|
14
|
+
cwd: process.cwd(),
|
|
15
|
+
debug: false,
|
|
16
|
+
...overrides,
|
|
17
|
+
});
|
|
18
|
+
/** A passing load-kind executor result carrying one signal — lets a test
|
|
19
|
+
* exercise the envelope assembler's source-remap + critical-signal verdict
|
|
20
|
+
* folding without running the real load loop. */
|
|
21
|
+
const loadResultWithSignal = (scenarioId, source, severity, message) => ({
|
|
22
|
+
kind: 'load',
|
|
23
|
+
scenarioId,
|
|
24
|
+
passed: true,
|
|
25
|
+
durationMs: 0,
|
|
26
|
+
outcome: {
|
|
27
|
+
metrics: {
|
|
28
|
+
totalRequests: 0,
|
|
29
|
+
successfulRequests: 0,
|
|
30
|
+
failedRequests: 0,
|
|
31
|
+
avgLatencyMs: 0,
|
|
32
|
+
p50LatencyMs: 0,
|
|
33
|
+
p95LatencyMs: 0,
|
|
34
|
+
p99LatencyMs: 0,
|
|
35
|
+
errorsGenerated: 0,
|
|
36
|
+
},
|
|
37
|
+
assertions: { passed: [], failed: [] },
|
|
38
|
+
},
|
|
39
|
+
signals: [createSignal({ source, severity, ruleId: 'sim.test', message })],
|
|
40
|
+
});
|
|
41
|
+
beforeEach(() => {
|
|
42
|
+
// Item 1: registries are per-RunScope. Enter a fresh scope per test.
|
|
43
|
+
enterScope(makeSimTestScope());
|
|
44
|
+
});
|
|
45
|
+
afterEach(() => {
|
|
46
|
+
clearScenarioRegistry();
|
|
47
|
+
});
|
|
48
|
+
describe('executeSim', () => {
|
|
49
|
+
it('returns ErrorResult when the recipe name is unknown', async () => {
|
|
50
|
+
const { result } = await executeSim(args({ recipe: 'does-not-exist' }));
|
|
51
|
+
expect(result.type).toBe('error');
|
|
52
|
+
if (result.type === 'error') {
|
|
53
|
+
expect(result.message).toContain('does-not-exist');
|
|
54
|
+
expect(result.exitCode).toBe(2);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
it('runs the built-in default recipe when no --recipe is passed', async () => {
|
|
58
|
+
// Register a scenario so the default recipe has something to run — an
|
|
59
|
+
// empty selection now fails closed (see the zero-scenario guard tests
|
|
60
|
+
// below), so this test must supply work to exercise the happy path.
|
|
61
|
+
currentScenarioRegistry().register(defineLoadScenario({
|
|
62
|
+
id: 'default-probe',
|
|
63
|
+
name: 'default-probe',
|
|
64
|
+
description: 'default-probe',
|
|
65
|
+
tags: [],
|
|
66
|
+
target: noopTarget,
|
|
67
|
+
workload: { rps: 1 },
|
|
68
|
+
duration: 1,
|
|
69
|
+
assertions: [ASSERTIONS.lowErrorRate(1)],
|
|
70
|
+
}));
|
|
71
|
+
const { result } = await executeSim(args());
|
|
72
|
+
expect(result.type).toBe('sim-done');
|
|
73
|
+
if (result.type === 'sim-done') {
|
|
74
|
+
expect(result.recipeName).toBe('default');
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
it('returns SimDoneResult with per-scenario outcomes', async () => {
|
|
78
|
+
currentScenarioRegistry().register(defineLoadScenario({
|
|
79
|
+
id: 'load-a',
|
|
80
|
+
name: 'load-a',
|
|
81
|
+
description: 'load a',
|
|
82
|
+
tags: ['demo'],
|
|
83
|
+
target: noopTarget,
|
|
84
|
+
workload: { rps: 1 },
|
|
85
|
+
duration: 1,
|
|
86
|
+
assertions: [ASSERTIONS.lowErrorRate(1)],
|
|
87
|
+
}));
|
|
88
|
+
const { result } = await executeSim(args());
|
|
89
|
+
expect(result.type).toBe('sim-done');
|
|
90
|
+
if (result.type === 'sim-done') {
|
|
91
|
+
// ADR-0011: per-scenario facts live on the envelope's `units` sidecar
|
|
92
|
+
// (one unit per scenario, slug === scenarioId).
|
|
93
|
+
expect(result.envelope.units).toHaveLength(1);
|
|
94
|
+
expect(result.envelope.units[0]?.slug).toBe('load-a');
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
it('marks the run verdict failed when at least one scenario fails (ADR-0035)', async () => {
|
|
98
|
+
// A bare RunnableScenario whose run() rejects to force a failure
|
|
99
|
+
currentScenarioRegistry().register({
|
|
100
|
+
id: 'crashes',
|
|
101
|
+
name: 'crashes',
|
|
102
|
+
description: 'crashes',
|
|
103
|
+
kind: 'load',
|
|
104
|
+
tags: [],
|
|
105
|
+
run: () => Promise.reject(new Error('boom')),
|
|
106
|
+
});
|
|
107
|
+
const { result } = await executeSim(args());
|
|
108
|
+
expect(result.type).toBe('sim-done');
|
|
109
|
+
if (result.type === 'sim-done') {
|
|
110
|
+
expect(result.envelope.verdict.summary.failed).toBe(1);
|
|
111
|
+
// ADR-0035: the single host verdict drives the exit (no `shouldFail` field).
|
|
112
|
+
// A crashed scenario carries a unit error → the run verdict fails.
|
|
113
|
+
expect(result.envelope.verdict.passed).toBe(false);
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
it('fails closed (exit 2) when the scenario registry is empty (audit P1c)', async () => {
|
|
117
|
+
// "Empty work is not success": with no scenarios registered at all, a run
|
|
118
|
+
// simulated nothing. That must be a configuration/unavailable error (exit
|
|
119
|
+
// 2), never a green sim-done pass that masks a misconfig/missing-dep.
|
|
120
|
+
const { result } = await executeSim(args());
|
|
121
|
+
expect(result.type).toBe('error');
|
|
122
|
+
if (result.type === 'error') {
|
|
123
|
+
expect(result.exitCode).toBe(2);
|
|
124
|
+
// Registry-empty cause → install/scaffold guidance.
|
|
125
|
+
expect(result.message).toContain('No scenarios were loaded');
|
|
126
|
+
expect(result.suggestion).toContain('init');
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
it('preserves error messages on failed scenarios', async () => {
|
|
130
|
+
currentScenarioRegistry().register({
|
|
131
|
+
id: 'msg',
|
|
132
|
+
name: 'msg',
|
|
133
|
+
description: 'msg',
|
|
134
|
+
kind: 'load',
|
|
135
|
+
tags: [],
|
|
136
|
+
run: () => Promise.reject(new Error('a-specific-message')),
|
|
137
|
+
});
|
|
138
|
+
const { result } = await executeSim(args());
|
|
139
|
+
if (result.type === 'sim-done') {
|
|
140
|
+
// The scenario's thrown error is carried on its unit (slug === scenarioId).
|
|
141
|
+
expect(result.envelope.units[0]?.error).toContain('a-specific-message');
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
it('remaps each scenario signal to source = scenarioId in the run envelope', async () => {
|
|
145
|
+
// A scenario whose result emits a signal with a DIVERGENT `source`; the
|
|
146
|
+
// envelope assembler must re-attribute it to the scenarioId so the shared
|
|
147
|
+
// grouped table credits the right unit row (ADR-0011).
|
|
148
|
+
currentScenarioRegistry().register({
|
|
149
|
+
id: 'sig-scenario',
|
|
150
|
+
name: 'sig-scenario',
|
|
151
|
+
description: 'emits a signal',
|
|
152
|
+
kind: 'load',
|
|
153
|
+
tags: [],
|
|
154
|
+
run: () => Promise.resolve(loadResultWithSignal('sig-scenario', 'some-other-source', 'low', 'fyi')),
|
|
155
|
+
});
|
|
156
|
+
const { result } = await executeSim(args());
|
|
157
|
+
expect(result.type).toBe('sim-done');
|
|
158
|
+
if (result.type === 'sim-done') {
|
|
159
|
+
const sig = result.envelope.signals.find((s) => s.message === 'fyi');
|
|
160
|
+
expect(sig?.source).toBe('sig-scenario');
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
it('fails the unit verdict when a scenario emits a critical signal even though it passed', async () => {
|
|
164
|
+
// scenarioPassed folds the no-critical/high rule into the unit verdict: a
|
|
165
|
+
// scenario can report passed:true yet still fail because it surfaced a
|
|
166
|
+
// critical signal.
|
|
167
|
+
currentScenarioRegistry().register({
|
|
168
|
+
id: 'crit-scenario',
|
|
169
|
+
name: 'crit-scenario',
|
|
170
|
+
description: 'passes but emits a critical signal',
|
|
171
|
+
kind: 'load',
|
|
172
|
+
tags: [],
|
|
173
|
+
run: () => Promise.resolve(loadResultWithSignal('crit-scenario', 'crit-scenario', 'critical', 'meltdown')),
|
|
174
|
+
});
|
|
175
|
+
const { result } = await executeSim(args());
|
|
176
|
+
expect(result.type).toBe('sim-done');
|
|
177
|
+
if (result.type === 'sim-done') {
|
|
178
|
+
const unit = result.envelope.units.find((u) => u.slug === 'crit-scenario');
|
|
179
|
+
// passed:true from the executor, but the critical signal flips the unit.
|
|
180
|
+
expect(unit?.passed).toBe(false);
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
/** Run a minimal sim and return its SimDoneResult — the caller persists it.
|
|
185
|
+
* Hoisted to module scope (called inside the per-test scope from beforeEach). */
|
|
186
|
+
async function simDone() {
|
|
187
|
+
currentScenarioRegistry().register(defineLoadScenario({
|
|
188
|
+
id: 'persist-probe',
|
|
189
|
+
name: 'persist-probe',
|
|
190
|
+
description: 'persist-probe',
|
|
191
|
+
tags: [],
|
|
192
|
+
target: noopTarget,
|
|
193
|
+
workload: { rps: 1 },
|
|
194
|
+
duration: 1,
|
|
195
|
+
assertions: [ASSERTIONS.lowErrorRate(1)],
|
|
196
|
+
}));
|
|
197
|
+
const { result } = await executeSim(args());
|
|
198
|
+
if (result.type !== 'sim-done')
|
|
199
|
+
throw new Error(`expected sim-done, got ${result.type}`);
|
|
200
|
+
return result;
|
|
201
|
+
}
|
|
202
|
+
describe('sim session contribution → SessionRepo', () => {
|
|
203
|
+
it('a sim contribution persisted via SessionRepo writes exactly one row', async () => {
|
|
204
|
+
// host-owned-run-timing Phase 3 removed the production `persistSimSession`
|
|
205
|
+
// helper — the host run plane owns persistence. This test-only write mirrors
|
|
206
|
+
// the row the host writes from the sim handler's returned ToolSessionContribution.
|
|
207
|
+
// (Best-effort persistence semantics are covered by the run-plane tests.)
|
|
208
|
+
const ds = DataStoreFactory.open({ backend: 'memory' });
|
|
209
|
+
try {
|
|
210
|
+
const result = await simDone();
|
|
211
|
+
new SessionRepo(ds).save({
|
|
212
|
+
id: generatePrefixedId('sim'),
|
|
213
|
+
tool: 'sim',
|
|
214
|
+
startedAt: '1970-01-01T00:00:00.000Z',
|
|
215
|
+
completedAt: '1970-01-01T00:00:00.000Z',
|
|
216
|
+
cwd: result.cwd,
|
|
217
|
+
recipe: result.recipeName,
|
|
218
|
+
score: result.envelope.verdict.score,
|
|
219
|
+
passed: result.envelope.verdict.passed,
|
|
220
|
+
durationMs: 0,
|
|
221
|
+
payload: buildSimulationSessionPayload(result.envelope),
|
|
222
|
+
});
|
|
223
|
+
const sessions = new SessionRepo(ds).list({ tool: 'sim' });
|
|
224
|
+
expect(sessions).toHaveLength(1);
|
|
225
|
+
expect(sessions[0]?.recipe).toBe('default');
|
|
226
|
+
}
|
|
227
|
+
finally {
|
|
228
|
+
ds.close?.();
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
//# sourceMappingURL=sim.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sim.test.js","sourceRoot":"","sources":["../../../src/cli/__tests__/sim.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* sim-config-schema — the simulation tool's namespaced Zod config schema
|
|
3
|
+
* (launch, ADR-0023, Phase 4 Task 4.2).
|
|
4
|
+
*
|
|
5
|
+
* Describes the `simulation:` top-level block of `opensip-cli.config.yml`.
|
|
6
|
+
* Today simulation owns a single knob — the tool-scoped `recipe` default
|
|
7
|
+
* (ADR-0022) — so the schema is minimal; it grows as sim gains config.
|
|
8
|
+
*
|
|
9
|
+
* This is the schema simulation contributes to the host's composed
|
|
10
|
+
* whole-document validation. The matching namespace KEY in the config file is
|
|
11
|
+
* `simulation` (see `sim-config.ts`'s `readSimulationRecipe`), so a typo like
|
|
12
|
+
* `simulation: { recpe: ... }` now fails strict at dispatch (ADR-0023).
|
|
13
|
+
*/
|
|
14
|
+
import { z } from 'zod';
|
|
15
|
+
import type { ToolConfigDeclaration } from '@opensip-cli/config';
|
|
16
|
+
/**
|
|
17
|
+
* Zod object for the `simulation:` namespace. The `recipe` field is optional;
|
|
18
|
+
* an absent block means sim falls back to the built-in `default` recipe.
|
|
19
|
+
*/
|
|
20
|
+
export declare const SimulationNamespaceSchema: z.ZodObject<{
|
|
21
|
+
recipe: z.ZodOptional<z.ZodString>;
|
|
22
|
+
}, z.core.$strip>;
|
|
23
|
+
/**
|
|
24
|
+
* The simulation tool's contribution to the composed configuration document.
|
|
25
|
+
* `namespace: 'simulation'` (matches the config file key); the composer makes
|
|
26
|
+
* it strict (typo-rejecting) and optional. No defaults — the recipe falls back
|
|
27
|
+
* through the shared `resolveToolRecipeName` precedence when absent.
|
|
28
|
+
*/
|
|
29
|
+
export declare const simulationConfigDeclaration: ToolConfigDeclaration;
|
|
30
|
+
//# sourceMappingURL=sim-config-schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sim-config-schema.d.ts","sourceRoot":"","sources":["../../src/cli/sim-config-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAEjE;;;GAGG;AACH,eAAO,MAAM,yBAAyB;;iBAGpC,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,2BAA2B,EAAE,qBAGzC,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* sim-config-schema — the simulation tool's namespaced Zod config schema
|
|
3
|
+
* (launch, ADR-0023, Phase 4 Task 4.2).
|
|
4
|
+
*
|
|
5
|
+
* Describes the `simulation:` top-level block of `opensip-cli.config.yml`.
|
|
6
|
+
* Today simulation owns a single knob — the tool-scoped `recipe` default
|
|
7
|
+
* (ADR-0022) — so the schema is minimal; it grows as sim gains config.
|
|
8
|
+
*
|
|
9
|
+
* This is the schema simulation contributes to the host's composed
|
|
10
|
+
* whole-document validation. The matching namespace KEY in the config file is
|
|
11
|
+
* `simulation` (see `sim-config.ts`'s `readSimulationRecipe`), so a typo like
|
|
12
|
+
* `simulation: { recpe: ... }` now fails strict at dispatch (ADR-0023).
|
|
13
|
+
*/
|
|
14
|
+
import { z } from 'zod';
|
|
15
|
+
/**
|
|
16
|
+
* Zod object for the `simulation:` namespace. The `recipe` field is optional;
|
|
17
|
+
* an absent block means sim falls back to the built-in `default` recipe.
|
|
18
|
+
*/
|
|
19
|
+
export const SimulationNamespaceSchema = z.object({
|
|
20
|
+
/** Tool-scoped default recipe for `sim` runs (ADR-0022). */
|
|
21
|
+
recipe: z.string().min(1).max(128).optional(),
|
|
22
|
+
});
|
|
23
|
+
/**
|
|
24
|
+
* The simulation tool's contribution to the composed configuration document.
|
|
25
|
+
* `namespace: 'simulation'` (matches the config file key); the composer makes
|
|
26
|
+
* it strict (typo-rejecting) and optional. No defaults — the recipe falls back
|
|
27
|
+
* through the shared `resolveToolRecipeName` precedence when absent.
|
|
28
|
+
*/
|
|
29
|
+
export const simulationConfigDeclaration = {
|
|
30
|
+
namespace: 'simulation',
|
|
31
|
+
schema: SimulationNamespaceSchema,
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=sim-config-schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sim-config-schema.js","sourceRoot":"","sources":["../../src/cli/sim-config-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB;;;GAGG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChD,4DAA4D;IAC5D,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;CAC9C,CAAC,CAAC;AAEH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAA0B;IAChE,SAAS,EAAE,YAAY;IACvB,MAAM,EAAE,yBAAyB;CAClC,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* sim-config — resolve the `sim` recipe default (ADR-0022).
|
|
3
|
+
*
|
|
4
|
+
* Recipes are tool-scoped: `sim` reads its own `simulation.recipe` block from
|
|
5
|
+
* `opensip-cli.config.yml`. The `simulation:` block is read permissively here
|
|
6
|
+
* (mirroring graph's `graph-config.ts`) — simulation must not depend on fitness,
|
|
7
|
+
* which owns the strict Zod config schema, so it parses its own slice of the
|
|
8
|
+
* document.
|
|
9
|
+
*/
|
|
10
|
+
import { type ResolvedRecipe } from '@opensip-cli/contracts';
|
|
11
|
+
/**
|
|
12
|
+
* Resolve which recipe NAME a `sim` run should use, applying tool-scoped
|
|
13
|
+
* precedence (ADR-0022): explicit `--recipe` > `simulation.recipe` > built-in
|
|
14
|
+
* `default`. The caller looks up the returned `name` in the recipe registry and,
|
|
15
|
+
* when `tolerant`, falls back to `default` on a miss.
|
|
16
|
+
*
|
|
17
|
+
* @param cwd Project root for config resolution.
|
|
18
|
+
* @param explicit The `--recipe <name>` flag value (undefined when absent).
|
|
19
|
+
* @param explicitPath Optional `--config <path>` override.
|
|
20
|
+
*/
|
|
21
|
+
export declare function resolveSimRecipeSelection(cwd: string, explicit: string | undefined, explicitPath?: string): ResolvedRecipe;
|
|
22
|
+
//# sourceMappingURL=sim-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sim-config.d.ts","sourceRoot":"","sources":["../../src/cli/sim-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAyB,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AA+CpF;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,YAAY,CAAC,EAAE,MAAM,GACpB,cAAc,CAMhB"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* sim-config — resolve the `sim` recipe default (ADR-0022).
|
|
3
|
+
*
|
|
4
|
+
* Recipes are tool-scoped: `sim` reads its own `simulation.recipe` block from
|
|
5
|
+
* `opensip-cli.config.yml`. The `simulation:` block is read permissively here
|
|
6
|
+
* (mirroring graph's `graph-config.ts`) — simulation must not depend on fitness,
|
|
7
|
+
* which owns the strict Zod config schema, so it parses its own slice of the
|
|
8
|
+
* document.
|
|
9
|
+
*/
|
|
10
|
+
import { resolveToolRecipeName } from '@opensip-cli/contracts';
|
|
11
|
+
import { currentScope, logger, readYamlFile, resolveProjectConfigPath } from '@opensip-cli/core';
|
|
12
|
+
/** Accept anything that looks like a plain object; everything else → undefined. */
|
|
13
|
+
function isPlainObject(v) {
|
|
14
|
+
return typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Best-effort read of `simulation.recipe` from the project config.
|
|
18
|
+
*
|
|
19
|
+
* ADR-0023, Phase 4: the resolved `simulation:` block rides on the per-run scope
|
|
20
|
+
* (`scope.toolConfig.simulation`) — the host already strict-validated +
|
|
21
|
+
* precedence-resolved the whole document before dispatch. When a scope is
|
|
22
|
+
* present (every CLI dispatch path) this reads the SCOPE value and does NOT
|
|
23
|
+
* re-read YAML. The YAML read below is the fallback for a caller with no scope
|
|
24
|
+
* (a direct unit-test call); there it stays best-effort: a missing config,
|
|
25
|
+
* malformed YAML, or no `simulation.recipe` string yields `undefined`.
|
|
26
|
+
*/
|
|
27
|
+
function readSimulationRecipe(cwd, explicitPath) {
|
|
28
|
+
// Scope-first: the resolved, strict-validated `simulation:` block.
|
|
29
|
+
const scoped = currentScope()?.toolConfig?.simulation;
|
|
30
|
+
if (isPlainObject(scoped)) {
|
|
31
|
+
return typeof scoped.recipe === 'string' ? scoped.recipe : undefined;
|
|
32
|
+
}
|
|
33
|
+
let filePath;
|
|
34
|
+
try {
|
|
35
|
+
filePath = resolveProjectConfigPath(cwd, explicitPath);
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
// No config file found — expected on a config-less project; sim then uses
|
|
39
|
+
// the built-in default. Debug-only so it never adds noise. Mirrors
|
|
40
|
+
// loadGraphConfig's not-found path.
|
|
41
|
+
logger.debug({
|
|
42
|
+
evt: 'sim.config.not_found',
|
|
43
|
+
module: 'cli:sim',
|
|
44
|
+
err: error instanceof Error ? error.message : String(error),
|
|
45
|
+
});
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
const doc = readYamlFile(filePath);
|
|
49
|
+
if (!isPlainObject(doc))
|
|
50
|
+
return undefined;
|
|
51
|
+
const block = doc.simulation;
|
|
52
|
+
if (!isPlainObject(block))
|
|
53
|
+
return undefined;
|
|
54
|
+
return typeof block.recipe === 'string' ? block.recipe : undefined;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Resolve which recipe NAME a `sim` run should use, applying tool-scoped
|
|
58
|
+
* precedence (ADR-0022): explicit `--recipe` > `simulation.recipe` > built-in
|
|
59
|
+
* `default`. The caller looks up the returned `name` in the recipe registry and,
|
|
60
|
+
* when `tolerant`, falls back to `default` on a miss.
|
|
61
|
+
*
|
|
62
|
+
* @param cwd Project root for config resolution.
|
|
63
|
+
* @param explicit The `--recipe <name>` flag value (undefined when absent).
|
|
64
|
+
* @param explicitPath Optional `--config <path>` override.
|
|
65
|
+
*/
|
|
66
|
+
export function resolveSimRecipeSelection(cwd, explicit, explicitPath) {
|
|
67
|
+
const toolRecipe = readSimulationRecipe(cwd, explicitPath);
|
|
68
|
+
return resolveToolRecipeName({
|
|
69
|
+
explicit,
|
|
70
|
+
toolRecipe,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=sim-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sim-config.js","sourceRoot":"","sources":["../../src/cli/sim-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,qBAAqB,EAAuB,MAAM,wBAAwB,CAAC;AACpF,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAEjG,mFAAmF;AACnF,SAAS,aAAa,CAAC,CAAU;IAC/B,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAClE,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAS,oBAAoB,CAAC,GAAW,EAAE,YAAqB;IAC9D,mEAAmE;IACnE,MAAM,MAAM,GAAG,YAAY,EAAE,EAAE,UAAU,EAAE,UAAU,CAAC;IACtD,IAAI,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1B,OAAO,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;IACvE,CAAC;IAED,IAAI,QAAgB,CAAC;IACrB,IAAI,CAAC;QACH,QAAQ,GAAG,wBAAwB,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IACzD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,0EAA0E;QAC1E,mEAAmE;QACnE,oCAAoC;QACpC,MAAM,CAAC,KAAK,CAAC;YACX,GAAG,EAAE,sBAAsB;YAC3B,MAAM,EAAE,SAAS;YACjB,GAAG,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;SAC5D,CAAC,CAAC;QACH,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,GAAG,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IACnC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IAC1C,MAAM,KAAK,GAAG,GAAG,CAAC,UAAU,CAAC;IAC7B,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAC5C,OAAO,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;AACrE,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,yBAAyB,CACvC,GAAW,EACX,QAA4B,EAC5B,YAAqB;IAErB,MAAM,UAAU,GAAG,oBAAoB,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IAC3D,OAAO,qBAAqB,CAAC;QAC3B,QAAQ;QACR,UAAU;KACX,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* sim-runner — owns the live-view state machine for `opensip sim`
|
|
3
|
+
* (ADR-0016). Before this, sim had NO live view: it ran to completion silently
|
|
4
|
+
* and printed a static envelope-to-table. It now renders the shared
|
|
5
|
+
* <LiveProgress> (pool mode) during the run, so the user sees an animated
|
|
6
|
+
* spinner + scenario `completed/total` — including for parallel recipes, where
|
|
7
|
+
* the counter advances as concurrent scenarios finish.
|
|
8
|
+
*
|
|
9
|
+
* Shared presentational primitives (Banner, RunHeader, RunSummary, LiveProgress)
|
|
10
|
+
* come from @opensip-cli/cli-ui. Effectful egress (cloud + --report-to) stays
|
|
11
|
+
* at the composition root: this runner returns the run's SignalEnvelope and the
|
|
12
|
+
* tool's registerLiveView callback delivers it once the Ink app exits.
|
|
13
|
+
*
|
|
14
|
+
* The live run executes OFF the main process (ADR-0028): it forks the CLI to the
|
|
15
|
+
* internal `sim-run-worker` subcommand and relays progress + result over IPC, so
|
|
16
|
+
* the spinner + 80ms clock never block on a synchronous chunk. It falls back to
|
|
17
|
+
* in-process when forking is disabled/unavailable (OPENSIP_CLI_NO_WORKER).
|
|
18
|
+
*/
|
|
19
|
+
import { type SignalEnvelope, type ToolOptions } from '@opensip-cli/contracts';
|
|
20
|
+
import { type LiveViewContext, type ToolRunCompletion, type ToolSessionContribution } from '@opensip-cli/core';
|
|
21
|
+
import React from 'react';
|
|
22
|
+
/** The sim subcommand's parsed options. `quiet`/`open` are not on the base
|
|
23
|
+
* ToolOptions (they're added by the command's `.option(...)` flags), so the
|
|
24
|
+
* live view widens the type to read `quiet`. */
|
|
25
|
+
type SimLiveArgs = ToolOptions & {
|
|
26
|
+
readonly quiet?: boolean;
|
|
27
|
+
readonly verbose?: boolean;
|
|
28
|
+
};
|
|
29
|
+
/** Props for {@link SimRunner}. Exported so the live-view state machine can be
|
|
30
|
+
* driven directly under ink-testing-library without spinning up the full
|
|
31
|
+
* `render()` host (which needs a TTY stdout). */
|
|
32
|
+
export interface SimRunnerProps {
|
|
33
|
+
readonly args: SimLiveArgs;
|
|
34
|
+
readonly setExitCode?: (code: number) => void;
|
|
35
|
+
readonly onEnvelope?: (envelope: SignalEnvelope) => void;
|
|
36
|
+
/**
|
|
37
|
+
* Surfaces the run's generic-session contribution (host-owned-run-timing
|
|
38
|
+
* Phase 2). The host persists it after the live view exits — the component
|
|
39
|
+
* must NOT write the session itself.
|
|
40
|
+
*/
|
|
41
|
+
readonly onSession?: (contribution: ToolSessionContribution) => void;
|
|
42
|
+
/** From host LiveViewContext — carries the run timer for the RunTimingProvider. */
|
|
43
|
+
readonly liveContext?: LiveViewContext;
|
|
44
|
+
}
|
|
45
|
+
/** The sim live-view component (loading → running → done/error). Exported for
|
|
46
|
+
* testing; production renders it through {@link renderSimLive}. */
|
|
47
|
+
export declare function SimRunner({ args, setExitCode, onEnvelope, onSession, liveContext, }: SimRunnerProps): React.ReactElement;
|
|
48
|
+
export interface RenderSimLiveOptions {
|
|
49
|
+
readonly setExitCode?: (code: number) => void;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Render the live `sim` view. Resolves once the Ink app exits with a
|
|
53
|
+
* {@link ToolRunCompletion} carrying the run's `envelope` (for root-owned
|
|
54
|
+
* egress) and `session` contribution (persisted by the HOST after this
|
|
55
|
+
* resolves — host-owned-run-timing Phase 2; the component no longer writes the
|
|
56
|
+
* session itself).
|
|
57
|
+
*/
|
|
58
|
+
export declare function renderSimLive(args: SimLiveArgs, options?: RenderSimLiveOptions, liveContext?: LiveViewContext): Promise<ToolRunCompletion>;
|
|
59
|
+
export {};
|
|
60
|
+
//# sourceMappingURL=sim-runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sim-runner.d.ts","sourceRoot":"","sources":["../../src/cli/sim-runner.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAyBH,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,WAAW,EAEjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAGL,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,uBAAuB,EAC7B,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAA8B,MAAM,OAAO,CAAC;AAUnD;;iDAEiD;AACjD,KAAK,WAAW,GAAG,WAAW,GAAG;IAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAoC1F;;kDAEkD;AAClD,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,cAAc,KAAK,IAAI,CAAC;IACzD;;;;OAIG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,YAAY,EAAE,uBAAuB,KAAK,IAAI,CAAC;IACrE,mFAAmF;IACnF,QAAQ,CAAC,WAAW,CAAC,EAAE,eAAe,CAAC;CACxC;AAED;oEACoE;AACpE,wBAAgB,SAAS,CAAC,EACxB,IAAI,EACJ,WAAW,EACX,UAAU,EACV,SAAS,EACT,WAAW,GACZ,EAAE,cAAc,GAAG,KAAK,CAAC,YAAY,CA8KrC;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/C;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,WAAW,EACjB,OAAO,CAAC,EAAE,oBAAoB,EAC9B,WAAW,CAAC,EAAE,eAAe,GAC5B,OAAO,CAAC,iBAAiB,CAAC,CAyB5B"}
|