5.3 KiB
5.3 KiB
0. Pre-flight (non-negotiable)
- 0.1 Confirm clean working tree (
git statusreports nothing) and no in-flight worktrees with uncommitted work (git worktree listthengit statusin each) - 0.2 If any worktrees exist under
.claude/worktrees/, account for each one: still-active agent, work-pending-merge, or stale-and-prune. Stale worktrees MUST be removed (git worktree remove) before opening a new one — code that has been lost twice on main is the failure mode this guards against. - 0.3 Confirm the package set in
MANIFEST.mdmatchesfind packages -maxdepth 3 -name package.jsoncount. Drift here means a prior change archived without regenerating the manifest.
1. Catalog setup
- 1.1 Add
autocannonto rootpackage.jsoncatalogs.testing(k6 runs via thegrafana/k6container; no npm entry needed) - 1.2 Run
bun install; confirm lockfile updates cleanly
2. Package skeleton — @suaveplan/testing-load
- 2.1 Create
packages/testing/testing-load/withpackage.json(version0.1.0,type: "module",sideEffects: false,@suaveplan/typesworkspace dep, external catalog deps only) - 2.2 Create
tsconfig.lib.jsonextending@suaveplan/typescript-config/library.json - 2.3 Create
vite.config.ts(preserveModules, ESM only) - 2.4 Create
vitest.config.tsconsuming@suaveplan/testing/configonce available; thresholds at 100/100/100/100 (istanbul) - 2.5 Create
README.mdwith purpose, install, quick-start, error-code index, links to module.mdfiles - 2.6 Subpath exports in
package.jsonfor every feature module peropenspec/AGENTS.md§6
3. Public API — scenario, driver, runner
- 3.1
src/scenario/scenario.ts—defineLoadScenario,LoadScenario,LoadScenarioSpec; Zod schemas inscenario.schemas.ts - 3.2
src/scenario/presets.ts—smoke,load,stress,spikeconstants composing vus/stages/duration - 3.3
src/driver/driver.ts—LoadDriverinterface,LoadSummarynormalised shape - 3.4
src/driver/k6-driver.ts— k6 implementation; injectableexec(testcontainers) +fetchfor self-testability - 3.5
src/driver/autocannon-driver.ts— autocannon implementation; in-process Node fallback - 3.6
src/runner/run-load-scenario.ts—runLoadScenario(scenario, opts); resolves driver default to k6 if reachable, autocannon otherwise; honoursAbortSignal - 3.7
src/thresholds/assert-thresholds.ts—assertThresholds(summary); throwsTestingLoadError("TESTING_LOAD.THRESHOLD_VIOLATION", …)listing every failed predicate
4. Errors and observability
- 4.1
src/errors/testing-load-error.ts—TestingLoadError extends Errorwith{ code, cause?, context? } - 4.2
src/errors/codes.ts—TESTING_LOAD.THRESHOLD_VIOLATION,TESTING_LOAD.DRIVER_FAILED,TESTING_LOAD.CONFIG_INVALID,TESTING_LOAD.DRIVER_UNAVAILABLE,TESTING_LOAD.ABORTED - 4.3 OTel counters/histograms via
@opentelemetry/apiper existingtesting/spec.mdpattern; spans forrunLoadScenarioonly
5. Tests, docs, schemas
- 5.1 Co-locate
*.test.tsper implementation file; 100% Istanbul coverage (statements / branches / functions / lines) - 5.2 Co-locate
*.mdper implementation file (≥ 200 words, simple + advanced examples, API reference, implementation notes) peropenspec/AGENTS.md§4 - 5.3 Co-locate
*.schemas.tsper implementation file; tree-shake test proving schemas don't bloat functional bundle - 5.4 Property tests (fast-check) for
assertThresholdspredicate evaluation, scenario merge associativity - 5.5 Mitata benchmarks under
src/__benchmarks__/for scenario-build and threshold-evaluation hot paths
6. App integration — *.smoke.load.ts
- 6.1
apps/testbed/tests/load/healthz.smoke.load.ts— smoke scenario forGET /healthz - 6.2 One
*.smoke.load.tsper route declared inapps/testbed/src/routes.ts - 6.3
apps/websocket-gateway/tests/load/connection.smoke.load.ts— websocket-fan-out smoke scenario - 6.4 Each app's
package.jsonexposestest:load:smokeinvoking its smoke files via the package's own runner
7. CI integration
- 7.1 Nightly job: run every
*.smoke.load.tsagainst the app's Docker staging stack - 7.2 Failure on any threshold violation breaks the build
- 7.3 Weekly job (or manual workflow_dispatch): run
load,stress,spikemodes against staging - 7.4 Cross-link smoke result into the release-readiness gate (audit §7) once that gate lands
8. Spec deltas and validation
- 8.1
openspec validate enterprise-testing-load-perf --type changepasses - 8.2 Fold
specs/testing-load/spec.mdADDED Requirements into a newopenspec/specs/testing-load/spec.md - 8.3 Fold
specs/testing/spec.mdADDED Requirement into the existingopenspec/specs/testing/spec.md - 8.4 Move this change folder to
openspec/archive/<yyyy-mm-dd>-enterprise-testing-load-perf/
9. Pre-publish gate and publish
- 9.1
bunx turbo lint typecheck test --filter=@suaveplan/testing-loadgreen - 9.2
bunx turbo test:coverage --filter=@suaveplan/testing-loadreports 100% statements / branches / functions / lines - 9.3
bun scripts/publish.ts --package @suaveplan/testing-load --dry-runproduces a sane diff - 9.4
bun scripts/publish.ts --package @suaveplan/testing-load— publish0.1.0to Verdaccio