@assertrx/dino 1.0.10 → 1.0.12

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.
Files changed (38) hide show
  1. package/package.json +1 -1
  2. package/prompts/generate-k6-test-from-endpoint.md +68 -0
  3. package/prompts/generate-k6-test-from-openapi.md +85 -0
  4. package/prompts/setup-k6.md +130 -0
  5. package/prompts/setup-promptfoo.md +103 -0
  6. package/scripts/api-server.mjs +28 -0
  7. package/skills/analyzing-test-results/SKILL.md +150 -0
  8. package/skills/analyzing-test-results/reference/bottleneck-patterns.md +130 -0
  9. package/skills/analyzing-test-results/reference/metrics.md +134 -0
  10. package/skills/analyzing-test-results/reference/visualization.md +152 -0
  11. package/skills/designing-test-scenarios/SKILL.md +247 -0
  12. package/skills/designing-test-scenarios/reference/executors.md +215 -0
  13. package/skills/designing-test-scenarios/reference/test-types.md +215 -0
  14. package/skills/designing-test-scenarios/reference/thresholds.md +208 -0
  15. package/skills/generating-api-load-tests/SKILL.md +199 -0
  16. package/skills/generating-api-load-tests/reference/data-parameterization.md +343 -0
  17. package/skills/generating-api-load-tests/reference/grpc.md +315 -0
  18. package/skills/generating-api-load-tests/reference/http.md +380 -0
  19. package/skills/generating-api-load-tests/reference/websocket.md +369 -0
  20. package/skills/generating-browser-tests/SKILL.md +269 -0
  21. package/skills/generating-browser-tests/reference/browser-api.md +251 -0
  22. package/skills/generating-browser-tests/reference/web-vitals.md +148 -0
  23. package/skills/generating-tests-from-code/SKILL.md +142 -0
  24. package/skills/generating-tests-from-code/reference/auth-analysis.md +220 -0
  25. package/skills/generating-tests-from-code/reference/framework-patterns.md +242 -0
  26. package/skills/generating-tests-from-openapi/SKILL.md +234 -0
  27. package/skills/generating-tests-from-openapi/reference/openapi-auth-mapping.md +247 -0
  28. package/skills/generating-tests-from-openapi/reference/openapi-parsing.md +194 -0
  29. package/skills/operating-k6-in-ci-cd/SKILL.md +98 -0
  30. package/skills/operating-k6-in-ci-cd/reference/ci-cd-pipelines.md +265 -0
  31. package/skills/operating-k6-in-ci-cd/reference/extensions.md +144 -0
  32. package/skills/operating-k6-in-ci-cd/reference/k6-operator.md +214 -0
  33. package/skills/promptfoo/SKILL.md +121 -0
  34. package/skills/promptfoo/reference/assert-types.md +74 -0
  35. package/skills/promptfoo/reference/providers.md +70 -0
  36. package/skills/testing-resilience/SKILL.md +230 -0
  37. package/skills/testing-resilience/reference/fault-injection.md +153 -0
  38. package/skills/testing-resilience/reference/resilience-patterns.md +500 -0
@@ -0,0 +1,121 @@
1
+ ---
2
+ name: promptfoo
3
+ description: Use when writing, running, or debugging promptfoo AI evaluations — promptfooconfig.yaml structure, providers (OpenAI/Anthropic/HTTP/echo), test cases with vars, assert types (contains, is-json, javascript, similar, llm-rubric), CLI usage (eval, view, JSON output), thresholds, and CI integration. Use when the user asks about LLM evals, prompt evaluation, model output testing, or setting up a promptfoo project.
4
+ ---
5
+
6
+ # Promptfoo — LLM / Prompt Evaluations
7
+
8
+ Author, run, and interpret [promptfoo](https://www.promptfoo.dev/) evaluations. Promptfoo evaluates LLM prompts, agents, and model-backed endpoints against test cases with deterministic and model-graded assertions, producing a pass/fail result like a test runner.
9
+
10
+ ## When to Use Promptfoo
11
+
12
+ | Goal | Approach |
13
+ |------|----------|
14
+ | Verify prompt/model changes don't regress outputs | Eval suite with deterministic asserts on known inputs |
15
+ | Compare prompts or models side by side | Multiple `prompts` or `providers` in one config — promptfoo renders a matrix |
16
+ | Test subjective quality (tone, faithfulness) | `llm-rubric` assert (author it with the **write-judge-prompt** skill) |
17
+ | Test an HTTP endpoint that wraps a model | `http` provider hitting the real endpoint |
18
+ | Sanity-check the harness itself, no API needed | `echo` provider — instant, offline, zero cost |
19
+ | Find vulnerable/unsafe outputs | `npx promptfoo redteam` (separate command, own config) |
20
+
21
+ ## Project Layout
22
+
23
+ ```
24
+ promptfoo/
25
+ promptfooconfig.yaml # the eval config: prompts + providers + tests
26
+ prompts/
27
+ system.txt # prompt templates ({{var}} placeholders) — or inline
28
+ tests/ # optional: split test cases into YAML/CSV/JSON files
29
+ README.md # how to run, env vars needed
30
+ ```
31
+
32
+ A single `promptfooconfig.yaml` is enough for a skeleton project; split prompts/tests into files only when the config grows.
33
+
34
+ ## Config Anatomy (promptfooconfig.yaml)
35
+
36
+ ```yaml
37
+ description: "Customer support agent — smoke evals"
38
+
39
+ # What to evaluate. One or more prompt templates; {{vars}} come from tests.
40
+ prompts:
41
+ - file://promptfoo/prompts/system.txt
42
+ # or inline:
43
+ # - "Translate the following to French: {{text}}"
44
+
45
+ # Who answers. Multiple providers = comparison matrix.
46
+ providers:
47
+ - openai:gpt-4o-mini # needs OPENAI_API_KEY
48
+ - anthropic:claude-3-5-haiku-latest # needs ANTHROPIC_API_KEY
49
+ # Local/zero-cost provider for harness checks:
50
+ # - echo
51
+
52
+ # Test cases: inputs + expected behavior.
53
+ tests:
54
+ - description: "Greeting is friendly"
55
+ vars:
56
+ message: "hi there"
57
+ assert:
58
+ - type: contains
59
+ value: "hello"
60
+ - type: llm-rubric
61
+ value: "The reply is polite and offers help"
62
+
63
+ # Assertions applied to every test (defaults; per-test asserts extend these).
64
+ defaultTest:
65
+ assert:
66
+ - type: latency
67
+ threshold: 5000 # ms
68
+ ```
69
+
70
+ Full assert reference: [reference/assert-types.md](reference/assert-types.md). Provider reference: [reference/providers.md](reference/providers.md).
71
+
72
+ ## Running Evals
73
+
74
+ ```bash
75
+ # Run the default config (promptfooconfig.yaml in cwd)
76
+ npx promptfoo@latest eval
77
+
78
+ # Run a specific config, fail the command on failed asserts (default)
79
+ npx promptfoo@latest eval -c promptfoo/promptfooconfig.yaml
80
+
81
+ # Machine-readable results (for CI or parsing)
82
+ npx promptfoo@latest eval -c promptfoo/promptfooconfig.yaml --output json
83
+
84
+ # Interactive web viewer of the last results
85
+ npx promptfoo@latest view
86
+ ```
87
+
88
+ - **Exit code**: `0` when all asserts pass, non-zero when any test fails or the config is invalid — safe for CI.
89
+ - **Cost control**: `--repeat 1` (default), keep test counts small, prefer cheap models while iterating.
90
+ - **Concurrency**: defaults are conservative; raise via `--max-concurrency N` for larger suites.
91
+
92
+ ## Test-Design Rules
93
+
94
+ 1. **Deterministic first.** Use `contains`, `is-json`, `javascript`, and `similar` before model-graded asserts — they are reproducible, free, and debuggable.
95
+ 2. **Rubric only for the subjective.** For `llm-rubric`, write the judge criteria with the **write-judge-prompt** skill, and calibrate it with **validate-evaluator** before trusting results.
96
+ 3. **Small, sharp suites.** 5–20 targeted cases beat 200 vague ones. Generate bulk synthetic variants with **generate-synthetic-data** only when you need coverage/robustness checks.
97
+ 4. **No secrets in configs.** API keys come from env (`OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, …) — never commit them.
98
+ 5. **Thresholds over vibes.** Set `defaultTest` latency/cost guards so regressions fail loudly even when content asserts pass.
99
+
100
+ ## CI Integration (GitHub Actions)
101
+
102
+ ```yaml
103
+ - name: Run prompt evals
104
+ env:
105
+ OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
106
+ run: npx promptfoo@latest eval -c promptfoo/promptfooconfig.yaml --output json > results.json
107
+ ```
108
+
109
+ ## Interpreting Results
110
+
111
+ - Each row = one test × (prompt × provider). Red cells list the exact assert that failed with actual vs expected — read that first.
112
+ - For `llm-rubric` failures, inspect the judge's reason in the viewer before assuming the model is wrong; a mis-calibrated judge is a common failure mode (see **eval-audit** skill).
113
+ - Flaky content asserts (`contains` on chatty models) → relax to `contains-any`, `similar` with a threshold, or a better-scoped rubric.
114
+
115
+ ## Related Skills in This Package
116
+
117
+ - **write-judge-prompt** — author the `llm-rubric` criteria.
118
+ - **validate-evaluator** — calibrate judges against human labels before trusting scores.
119
+ - **eval-audit** — audit an existing eval suite for missing error analysis, vanity metrics, etc.
120
+ - **generate-synthetic-data** — bulk-generate test inputs across behavioral dimensions.
121
+ - **error-analysis** — categorize failures after a run to decide what to fix first.
@@ -0,0 +1,74 @@
1
+ # Promptfoo Assert Types Reference
2
+
3
+ Assertions live under each test's `assert:` list (and `defaultTest.assert:` for suite-wide defaults). Every assert evaluates to pass/fail against the provider output. Prefer deterministic types; use model-graded types only for subjective criteria.
4
+
5
+ ## Deterministic (reproducible, free)
6
+
7
+ | Type | What it checks | Key fields |
8
+ |------|----------------|-----------|
9
+ | `contains` | Output includes a substring | `value` |
10
+ | `not-contains` | Output must not include a substring | `value` |
11
+ | `contains-any` | Output includes at least one of several substrings | `value: [..]` |
12
+ | `contains-all` | Output includes all of several substrings | `value: [..]` |
13
+ | `regex` | Output matches a pattern | `value` (regex string) |
14
+ | `equals` | Exact match (trim/normalize first) | `value` |
15
+ | `is-json` | Output parses as JSON; optionally validates a JSON schema | `value` (JSON schema) |
16
+ | `javascript` | Custom predicate over output/context | `value` (JS expression returning boolean/number; `output`, `context` available) |
17
+ | `python` | Same, in Python | `value` (code) |
18
+ | `similar` | Embedding similarity to expected text | `value`, `threshold` (0–1, default 0.75) |
19
+ | `latency` | Response time guard | `threshold` (ms) |
20
+ | `cost` | Per-call cost guard | `threshold` (USD) |
21
+ | `contains-sql` / `is-valid-sql` / `is-valid-function-call` / `is-valid-openai-function-call` / `is-valid-url` / `no-refusal` / `perplexity` / `perplexity-score` | Domain-specific structural checks | varies |
22
+
23
+ ## Model-graded (subjective criteria — judge LLM involved)
24
+
25
+ | Type | What it checks | Notes |
26
+ |------|----------------|-------|
27
+ | `llm-rubric` | Output satisfies natural-language criteria | Judge prompt in `value`; author it with the **write-judge-prompt** skill. Optional `rubricPrompt` to override the default judge prompt template |
28
+ | `factuality` | Output is factually consistent with a reference | `value` = ground truth, `subject` = original input |
29
+ | `answer-relevance` | Output addresses the input | no extra fields |
30
+ | `context-recall` / `context-relevance` / `context-faithfulness` | RAG quality: retrieved context vs question/answer | see **evaluate-rag** skill |
31
+ | `classifier` | Label the output with a model-chosen category | `value` = list of allowed labels |
32
+
33
+ ## Grading Model
34
+
35
+ Model-graded asserts run on a grader LLM. Configure it suite-wide:
36
+
37
+ ```yaml
38
+ # Use a different model for judging than for the system under test
39
+ evaluateOptions:
40
+ # or per-assert via the assert's own provider field
41
+ providers: []
42
+ ```
43
+
44
+ Simplest per-assert override:
45
+
46
+ ```yaml
47
+ - type: llm-rubric
48
+ value: "Answer states the refund window and cites the policy doc."
49
+ # provider: anthropic:claude-3-5-haiku-latest # optional judge override
50
+ ```
51
+
52
+ ## Weighted & Threshold Asserts
53
+
54
+ ```yaml
55
+ tests:
56
+ - description: "Balanced checks"
57
+ vars: { q: "what is your return policy" }
58
+ assert:
59
+ - type: contains
60
+ value: "30 days"
61
+ weight: 2 # counts double in the score
62
+ - type: llm-rubric
63
+ value: "Polite and on-topic"
64
+ weight: 1
65
+ threshold: 0.8 # test passes only if score >= 0.8
66
+ ```
67
+
68
+ ## Suite-wide Pass Threshold
69
+
70
+ ```yaml
71
+ # Fail the whole eval if less than 90% of tests pass
72
+ tests:
73
+ - threshold: 0.9
74
+ ```
@@ -0,0 +1,70 @@
1
+ # Promptfoo Providers Reference
2
+
3
+ Providers answer prompts. List one or more under `providers:` — multiple entries render a comparison matrix across all tests.
4
+
5
+ ## Model Providers
6
+
7
+ ```yaml
8
+ providers:
9
+ - openai:gpt-4o-mini # needs OPENAI_API_KEY
10
+ - anthropic:claude-3-5-haiku-latest # needs ANTHROPIC_API_KEY
11
+ - bedrock:us.anthropic.claude-3-5-sonnet-20241022-v2:0
12
+ - azureopenai:gpt-4o:my-deployment # needs AZURE_OPENAI_API_BASE etc.
13
+ - google:gemini-1.5-flash # needs GOOGLE_API_KEY
14
+ - ollama:chat:llama3.1 # local, no key
15
+ ```
16
+
17
+ Custom model params (temperature, max tokens) use the long form:
18
+
19
+ ```yaml
20
+ providers:
21
+ - id: anthropic:claude-3-5-haiku-latest
22
+ config:
23
+ temperature: 0
24
+ max_tokens: 512
25
+ ```
26
+
27
+ ## HTTP Provider (test any endpoint that wraps an LLM)
28
+
29
+ ```yaml
30
+ providers:
31
+ - id: http
32
+ config:
33
+ url: https://api.example.com/v1/answer
34
+ method: POST
35
+ headers:
36
+ Content-Type: application/json
37
+ Authorization: Bearer {{ENV.API_TOKEN}}
38
+ body:
39
+ model: support-agent
40
+ messages: [{ role: user, content: "{{prompt}}" }]
41
+ transformResponse: json.response # JSONPath-ish pick of the text to assert on
42
+ ```
43
+
44
+ `{{prompt}}` is the rendered prompt template; `{{ENV.NAME}` reads environment variables — no secrets in the config file.
45
+
46
+ ## Echo Provider (offline harness checks)
47
+
48
+ Returns the rendered prompt verbatim — no network, no cost. Use it to validate the config, wiring, and deterministic asserts before spending tokens (note: plain `- echo`, not `- echo:text` — the colon shorthand was removed in recent versions):
49
+
50
+ ```yaml
51
+ providers:
52
+ - echo
53
+ ```
54
+
55
+ ## File/Script Providers
56
+
57
+ - `file://path/to/provider.py` or `.js` — full control (custom agent, chain, RAG pipeline); export a `CallApi(prompt, context)` function.
58
+ - Python file providers let you wrap internal SDKs not reachable over HTTP.
59
+
60
+ ## Environment Variables
61
+
62
+ | Provider | Variable(s) |
63
+ |----------|-------------|
64
+ | OpenAI | `OPENAI_API_KEY` |
65
+ | Anthropic | `ANTHROPIC_API_KEY` |
66
+ | Google | `GOOGLE_API_KEY` / `GEMINI_API_KEY` |
67
+ | Azure OpenAI | `AZURE_OPENAI_API_BASE`, `AZURE_OPENAI_API_KEY`, `AZURE_OPENAI_DEPLOYMENT_NAME` |
68
+ | HTTP | anything referenced via `{{ENV.*}}` |
69
+
70
+ Load from `.env` files or the shell; never commit keys.
@@ -0,0 +1,230 @@
1
+ ---
2
+ name: testing-resilience
3
+ description: Use when creating chaos engineering or resilience tests with k6 and xk6-disruptor. Use when the user wants to inject faults (pod failures, network delays, HTTP errors) into Kubernetes services during load tests, validate circuit breakers, or test system recovery behavior.
4
+ ---
5
+
6
+ # Testing Resilience with k6
7
+
8
+ Create chaos and resilience tests using xk6-disruptor to inject faults into Kubernetes services during k6 load tests. Validates system behavior under failure conditions.
9
+
10
+ ## Overview
11
+
12
+ xk6-disruptor injects faults into Kubernetes pods and services while k6 generates load, allowing you to verify:
13
+ - System survives pod failures
14
+ - Graceful degradation under network issues
15
+ - Circuit breaker behavior
16
+ - Recovery time after fault removal
17
+ - Auto-scaling response to failures
18
+
19
+ ## Quick Start
20
+
21
+ ```javascript
22
+ import http from 'k6/http';
23
+ import { check, sleep } from 'k6';
24
+ import { ServiceDisruptor } from 'k6/x/disruptor';
25
+
26
+ export const options = {
27
+ scenarios: {
28
+ load: {
29
+ executor: 'constant-arrival-rate',
30
+ rate: 100,
31
+ timeUnit: '1s',
32
+ duration: '2m',
33
+ preAllocatedVUs: 50,
34
+ },
35
+ },
36
+ thresholds: {
37
+ http_req_failed: ['rate<0.3'], // Allow up to 30% errors during chaos
38
+ http_req_duration: ['p(95)<3000'], // Relaxed threshold during chaos
39
+ },
40
+ };
41
+
42
+ export function setup() {
43
+ // Inject fault: Add 500ms delay to 50% of requests
44
+ const disruptor = new ServiceDisruptor('my-service', 'default');
45
+ const fault = {
46
+ averageDelay: '500ms',
47
+ errorRate: 0.1, // 10% of requests return errors
48
+ errorCode: 503,
49
+ };
50
+ disruptor.injectHTTPFaults(fault, '60s');
51
+ }
52
+
53
+ export default function () {
54
+ const res = http.get('http://my-service.default.svc.cluster.local:8080/api');
55
+ check(res, {
56
+ 'not server error': (r) => r.status < 500 || r.status === 503,
57
+ });
58
+ sleep(0.1); // Intentional: adds backpressure per VU to avoid overwhelming the disrupted service
59
+ }
60
+ ```
61
+
62
+ ## Prerequisites
63
+
64
+ - **Kubernetes cluster** with target services deployed
65
+ - **k6 with xk6-disruptor** extension (or use automatic resolution)
66
+ - **RBAC permissions** for the k6 pod to manage target pods
67
+
68
+ ## Disruptor Types
69
+
70
+ ### ServiceDisruptor
71
+
72
+ Targets all pods behind a Kubernetes Service:
73
+
74
+ ```javascript
75
+ import { ServiceDisruptor } from 'k6/x/disruptor';
76
+
77
+ const disruptor = new ServiceDisruptor('service-name', 'namespace');
78
+ ```
79
+
80
+ ### PodDisruptor
81
+
82
+ Targets specific pods by label selector:
83
+
84
+ ```javascript
85
+ import { PodDisruptor } from 'k6/x/disruptor';
86
+
87
+ const disruptor = new PodDisruptor({
88
+ namespace: 'default',
89
+ select: { labels: { app: 'my-app' } },
90
+ });
91
+ ```
92
+
93
+ ## Fault Types
94
+
95
+ ### HTTP Faults
96
+
97
+ Inject delays and errors into HTTP responses:
98
+
99
+ ```javascript
100
+ disruptor.injectHTTPFaults(
101
+ {
102
+ averageDelay: '500ms', // Add delay to responses
103
+ delayVariation: '100ms', // Delay jitter
104
+ errorRate: 0.1, // 10% error rate
105
+ errorCode: 503, // Error HTTP status code
106
+ port: 8080, // Target port
107
+ exclude: '/health', // Exclude health check endpoint
108
+ },
109
+ '60s' // Fault duration
110
+ );
111
+ ```
112
+
113
+ ### gRPC Faults
114
+
115
+ Inject faults into gRPC services:
116
+
117
+ ```javascript
118
+ disruptor.injectGrpcFaults(
119
+ {
120
+ averageDelay: '500ms',
121
+ errorRate: 0.2,
122
+ statusCode: 14, // UNAVAILABLE
123
+ statusMessage: 'service overloaded',
124
+ },
125
+ '60s'
126
+ );
127
+ ```
128
+
129
+ ### Pod Termination
130
+
131
+ Kill pods to test recovery:
132
+
133
+ ```javascript
134
+ disruptor.terminatePods({
135
+ count: 1, // Number of pods to terminate
136
+ interval: '30s', // Wait between terminations
137
+ });
138
+ ```
139
+
140
+ See [reference/fault-injection.md](reference/fault-injection.md) for detailed fault configuration.
141
+
142
+ ## Resilience Test Patterns
143
+
144
+ ### Pattern 1: Graceful Degradation
145
+
146
+ Verify system degrades gracefully under partial failure:
147
+
148
+ ```javascript
149
+ export function setup() {
150
+ const disruptor = new ServiceDisruptor('backend-service', 'default');
151
+ disruptor.injectHTTPFaults({
152
+ averageDelay: '1000ms',
153
+ errorRate: 0.2,
154
+ errorCode: 503,
155
+ }, '90s');
156
+ }
157
+ ```
158
+
159
+ **Success criteria:** System returns degraded responses instead of cascading failures.
160
+
161
+ ### Pattern 2: Circuit Breaker Validation
162
+
163
+ Verify circuit breaker activates under error conditions:
164
+
165
+ ```javascript
166
+ export function setup() {
167
+ const disruptor = new ServiceDisruptor('downstream-service', 'default');
168
+ disruptor.injectHTTPFaults({
169
+ errorRate: 0.8, // 80% errors to trigger circuit breaker
170
+ errorCode: 500,
171
+ }, '60s');
172
+ }
173
+ ```
174
+
175
+ **Success criteria:** Upstream service returns fallback responses quickly (circuit open).
176
+
177
+ ### Pattern 3: Recovery Test
178
+
179
+ Verify system recovers after fault is removed:
180
+
181
+ ```javascript
182
+ export const options = {
183
+ scenarios: {
184
+ load: {
185
+ executor: 'constant-arrival-rate',
186
+ rate: 50,
187
+ timeUnit: '1s',
188
+ duration: '5m', // Total test: 5 minutes
189
+ preAllocatedVUs: 30,
190
+ },
191
+ },
192
+ };
193
+
194
+ export function setup() {
195
+ const disruptor = new ServiceDisruptor('my-service', 'default');
196
+ // Inject fault for only 2 minutes (test runs 5 minutes)
197
+ disruptor.injectHTTPFaults({
198
+ averageDelay: '2000ms',
199
+ errorRate: 0.5,
200
+ errorCode: 503,
201
+ }, '120s'); // Fault active for 2m, then 3m of recovery
202
+ }
203
+ ```
204
+
205
+ **Success criteria:** Metrics return to baseline within acceptable time after fault removal.
206
+
207
+ See [reference/resilience-patterns.md](reference/resilience-patterns.md) for more patterns.
208
+
209
+ ## Thresholds for Resilience Tests
210
+
211
+ Resilience tests need relaxed thresholds compared to normal load tests. Use tag-based thresholds to set different criteria for chaos and recovery phases:
212
+
213
+ ```javascript
214
+ export const options = {
215
+ thresholds: {
216
+ // During chaos: accept higher error rates
217
+ http_req_failed: ['rate<0.5'], // Up to 50% errors acceptable
218
+ // Overall response time upper bound (includes chaos phase)
219
+ http_req_duration: ['p(95)<5000'], // 5s max even during chaos
220
+ // Strict threshold for recovery phase only (tagged requests)
221
+ 'http_req_duration{phase:recovery}': ['p(95)<500'], // After recovery, back to normal
222
+ },
223
+ };
224
+ ```
225
+
226
+ ## Related Skills
227
+
228
+ - For generating load test scripts: `/k6:generating-api-load-tests`
229
+ - For CI/CD and Kubernetes setup: `/k6:operating-k6-in-ci-cd`
230
+ - For scenario design: `/k6:designing-test-scenarios`
@@ -0,0 +1,153 @@
1
+ # Fault Injection Reference
2
+
3
+ ## ServiceDisruptor
4
+
5
+ Targets all pods behind a Kubernetes Service.
6
+
7
+ ```javascript
8
+ import { ServiceDisruptor } from 'k6/x/disruptor';
9
+
10
+ const disruptor = new ServiceDisruptor('service-name', 'namespace');
11
+ ```
12
+
13
+ ### injectHTTPFaults(fault, duration)
14
+
15
+ | Parameter | Type | Description |
16
+ |-----------|------|-------------|
17
+ | `averageDelay` | string | Average delay added to responses (e.g., `'500ms'`) |
18
+ | `delayVariation` | string | Variation around averageDelay (e.g., `'100ms'`) |
19
+ | `errorRate` | float | Fraction of requests returning errors (0.0-1.0) |
20
+ | `errorCode` | integer | HTTP status code for injected errors |
21
+ | `errorBody` | string | Response body for injected errors |
22
+ | `port` | integer | Target port (required if service has multiple ports) |
23
+ | `exclude` | string | URL path prefix to exclude from faults |
24
+
25
+ ```javascript
26
+ disruptor.injectHTTPFaults({
27
+ averageDelay: '500ms',
28
+ delayVariation: '100ms',
29
+ errorRate: 0.1,
30
+ errorCode: 503,
31
+ errorBody: '{"error": "service unavailable"}',
32
+ port: 8080,
33
+ exclude: '/health',
34
+ }, '60s');
35
+ ```
36
+
37
+ ### injectGrpcFaults(fault, duration)
38
+
39
+ | Parameter | Type | Description |
40
+ |-----------|------|-------------|
41
+ | `averageDelay` | string | Average delay added to responses |
42
+ | `delayVariation` | string | Variation around averageDelay |
43
+ | `errorRate` | float | Fraction of requests returning errors (0.0-1.0) |
44
+ | `statusCode` | integer | gRPC status code for errors |
45
+ | `statusMessage` | string | gRPC status message for errors |
46
+ | `port` | integer | Target port |
47
+ | `exclude` | string | Service method to exclude |
48
+
49
+ ```javascript
50
+ disruptor.injectGrpcFaults({
51
+ averageDelay: '500ms',
52
+ errorRate: 0.2,
53
+ statusCode: 14, // UNAVAILABLE
54
+ statusMessage: 'injected fault',
55
+ }, '60s');
56
+ ```
57
+
58
+ ### terminatePods(options)
59
+
60
+ | Parameter | Type | Description |
61
+ |-----------|------|-------------|
62
+ | `count` | integer | Number of pods to terminate |
63
+ | `interval` | string | Wait time between terminations |
64
+
65
+ ```javascript
66
+ disruptor.terminatePods({
67
+ count: 1,
68
+ interval: '30s',
69
+ });
70
+ ```
71
+
72
+ ## PodDisruptor
73
+
74
+ Targets pods by label selector.
75
+
76
+ ```javascript
77
+ import { PodDisruptor } from 'k6/x/disruptor';
78
+
79
+ const disruptor = new PodDisruptor({
80
+ namespace: 'default',
81
+ select: {
82
+ labels: { app: 'my-app', version: 'v1' },
83
+ },
84
+ });
85
+ ```
86
+
87
+ Same methods as ServiceDisruptor: `injectHTTPFaults()`, `injectGrpcFaults()`, `terminatePods()`.
88
+
89
+ Additional method:
90
+
91
+ ### targets()
92
+
93
+ Returns list of target pod names:
94
+
95
+ ```javascript
96
+ const pods = disruptor.targets();
97
+ console.log(`Targeting ${pods.length} pods:`, pods);
98
+ ```
99
+
100
+ ## Kubernetes Requirements
101
+
102
+ ### RBAC
103
+
104
+ The k6 pod needs permissions to manage target pods:
105
+
106
+ ```yaml
107
+ apiVersion: rbac.authorization.k8s.io/v1
108
+ kind: ClusterRole
109
+ metadata:
110
+ name: k6-disruptor
111
+ rules:
112
+ - apiGroups: [""]
113
+ resources: ["pods", "pods/ephemeralcontainers"]
114
+ verbs: ["get", "list", "patch", "update", "delete"]
115
+ - apiGroups: [""]
116
+ resources: ["services"]
117
+ verbs: ["get", "list"]
118
+ - apiGroups: ["apps"]
119
+ resources: ["deployments"]
120
+ verbs: ["get", "list"]
121
+ ---
122
+ apiVersion: rbac.authorization.k8s.io/v1
123
+ kind: ClusterRoleBinding
124
+ metadata:
125
+ name: k6-disruptor-binding
126
+ roleRef:
127
+ apiGroup: rbac.authorization.k8s.io
128
+ kind: ClusterRole
129
+ name: k6-disruptor
130
+ subjects:
131
+ - kind: ServiceAccount
132
+ name: default
133
+ namespace: k6-test
134
+ ```
135
+
136
+ ### Running in Cluster
137
+
138
+ For xk6-disruptor to work, k6 must run **inside the Kubernetes cluster** (not locally). Options:
139
+ - k6-operator TestRun
140
+ - Pod with k6 + xk6-disruptor image
141
+ - CI/CD runner with cluster access
142
+
143
+ ## Fault Duration vs Test Duration
144
+
145
+ ```
146
+ Test Duration: |========================== 5 min ============================|
147
+ Fault Duration: |======== 2 min ========|
148
+ ↑ Fault injected ↑ Fault removed ↑ Test ends
149
+
150
+ Phases: |--- Chaos Phase ------|--- Recovery Phase ---|
151
+ ```
152
+
153
+ Set fault duration shorter than test duration to observe both degradation and recovery.