synapse-hub 0.0.0-stage → 2.0.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/.agents/agents/failure-analyst.md +47 -0
- package/.agents/agents/live-explorer.md +41 -0
- package/.agents/agents/orchestrator.md +43 -0
- package/.agents/agents/pom-crafter.md +81 -0
- package/.agents/agents/quality-gatekeeper.md +47 -0
- package/.agents/agents/test-runner.md +43 -0
- package/.agents/rules/context-engineering.md +88 -0
- package/.agents/rules/git-push-protocol.md +101 -0
- package/.agents/rules/graphify.md +14 -0
- package/.agents/rules/lessons-learned.md +23 -0
- package/.agents/rules/mandatory-playwright-live.md +29 -0
- package/.agents/rules/skill-precedence.md +42 -0
- package/.agents/rules/systematic-debugging.md +99 -0
- package/.agents/skills/agent-orchestration-multi-agent-optimize/SKILL.md +239 -0
- package/.agents/skills/antigravity-test-sentinel/SKILL.md +64 -0
- package/.agents/skills/api-network-mocking-interception/SKILL.md +142 -0
- package/.agents/skills/api-spec-to-e2e-matrix/SKILL.md +70 -0
- package/.agents/skills/architecture-decision-records/SKILL.md +441 -0
- package/.agents/skills/auth-session-and-cookie-manager/SKILL.md +72 -0
- package/.agents/skills/backend-load-and-stress-patterns/SKILL.md +214 -0
- package/.agents/skills/bats-testing-patterns/SKILL.md +100 -0
- package/.agents/skills/bats-testing-patterns/resources/implementation-playbook.md +614 -0
- package/.agents/skills/clean-pom-crafter/SKILL.md +75 -0
- package/.agents/skills/clean-pom-crafter/examples/standard_test_case.groovy +28 -0
- package/.agents/skills/clean-pom-crafter/references/pom_patterns.groovy +138 -0
- package/.agents/skills/code-refactoring-refactor-clean/SKILL.md +64 -0
- package/.agents/skills/code-refactoring-refactor-clean/resources/implementation-playbook.md +879 -0
- package/.agents/skills/db-state-verifier-and-seeder/SKILL.md +123 -0
- package/.agents/skills/e2e-testing-patterns/SKILL.md +103 -0
- package/.agents/skills/e2e-testing-patterns/resources/implementation-playbook.md +522 -0
- package/.agents/skills/failure-autopsy-and-healing/SKILL.md +54 -0
- package/.agents/skills/failure-autopsy-and-healing/references/healing_matrix.md +64 -0
- package/.agents/skills/failure-autopsy-and-healing/references/qa_investigation_protocol.md +56 -0
- package/.agents/skills/failure-autopsy-and-healing/scripts/triage_failures.sh +98 -0
- package/.agents/skills/file-and-report-validator/SKILL.md +90 -0
- package/.agents/skills/flaky-test-sentinel-and-quarantine/SKILL.md +114 -0
- package/.agents/skills/github-actions-templates/SKILL.md +334 -0
- package/.agents/skills/graphify-impact-analyzer/SKILL.md +78 -0
- package/.agents/skills/katalon-cli-runner/SKILL.md +76 -0
- package/.agents/skills/katalon-cli-runner/references/groovy-patterns.md +209 -0
- package/.agents/skills/katalon-cli-runner/references/katalon-api.md +155 -0
- package/.agents/skills/katalon-cli-runner/references/runner_commands.md +67 -0
- package/.agents/skills/lam-script-generator/SKILL.md +83 -0
- package/.agents/skills/playwright-live-interaction/SKILL.md +86 -0
- package/.agents/skills/playwright-live-interaction/references/advanced_superpowers.md +160 -0
- package/.agents/skills/playwright-live-interaction/references/compact_accessibility_snapshots.md +75 -0
- package/.agents/skills/playwright-live-interaction/references/recipes.md +388 -0
- package/.agents/skills/playwright-live-interaction/references/swarm_orchestration.md +134 -0
- package/.agents/skills/security-dast-sentinel/SKILL.md +176 -0
- package/.agents/skills/self-healing-locator/SKILL.md +73 -0
- package/.agents/skills/synthetic-test-data-generator/SKILL.md +135 -0
- package/.agents/skills/token-and-context-optimizer/SKILL.md +70 -0
- package/.agents/skills/visual-regression-sentinel/SKILL.md +62 -0
- package/.agents/skills/wcag-audit-patterns/SKILL.md +77 -0
- package/.agents/skills/wcag-audit-patterns/resources/implementation-playbook.md +541 -0
- package/.agents/skills/web-vitals-and-performance-profiler/SKILL.md +65 -0
- package/.agents/templates/completion_report.md +57 -0
- package/.agents/workflows/graphify.md +10 -0
- package/.agents/workflows/test-impact.md +15 -0
- package/.agents/workflows/verify.md +34 -0
- package/AGENTS.md +115 -0
- package/README.md +394 -2
- package/bin/agent-qa.js +90 -0
- package/package.json +59 -4
- package/skills_manifest.json +262 -0
- package/templates/PROJECT_AI_GUIDE_TEMPLATE.md +97 -0
- package/templates/PROJECT_STATE_TEMPLATE.md +20 -0
- package/tools/TOOLS_RUNBOOK.md +298 -0
- package/tools/agent_canary.py +501 -0
- package/tools/analyze_project.py +242 -0
- package/tools/api_drift_sentinel.py +208 -0
- package/tools/auto_heal.py +189 -0
- package/tools/browser_helpers.js +593 -0
- package/tools/bug_reporter.py +224 -0
- package/tools/cache_resolver.py +846 -0
- package/tools/check_env.py +288 -0
- package/tools/ci_healing_hook.py +128 -0
- package/tools/cli.py +402 -0
- package/tools/config_decoupler.py +253 -0
- package/tools/db_sandbox.py +341 -0
- package/tools/distill_log.py +152 -0
- package/tools/e2e_flow_prober.ps1 +65 -0
- package/tools/flaky_detector.py +222 -0
- package/tools/fuzz_payloads.py +197 -0
- package/tools/generate_allure_report.ps1 +30 -0
- package/tools/generate_api_matrix.py +193 -0
- package/tools/generate_tc_from_story.py +182 -0
- package/tools/generate_test_reports.ps1 +135 -0
- package/tools/git_pre_commit_guard.py +203 -0
- package/tools/heal_pr_automator.py +195 -0
- package/tools/heuristic_locator_matcher.py +202 -0
- package/tools/infer_linter.py +238 -0
- package/tools/lint_ai_docs.py +254 -0
- package/tools/lookup_tc.py +165 -0
- package/tools/lookup_xpath.py +167 -0
- package/tools/matrix_sharder.py +146 -0
- package/tools/mcp_excel_server.ps1 +251 -0
- package/tools/mcp_server.py +490 -0
- package/tools/micro_mutator.py +309 -0
- package/tools/network_mock_shield.py +170 -0
- package/tools/omni_emitter.py +500 -0
- package/tools/omni_parser.py +435 -0
- package/tools/omni_transpiler.py +168 -0
- package/tools/pinpoint_failure.py +88 -0
- package/tools/project_state.py +169 -0
- package/tools/repo_map.json +12 -0
- package/tools/repo_map.py +277 -0
- package/tools/repo_map.txt +7 -0
- package/tools/safety_firewall.py +245 -0
- package/tools/setup_project.py +265 -0
- package/tools/smart_visual_masker.py +134 -0
- package/tools/test_impact.py +321 -0
- package/tools/tms_sync_bridge.py +342 -0
- package/tools/trace_data_flow.py +240 -0
- package/tools/traffic_session_converter.py +256 -0
- package/tools/universal_ir.py +480 -0
- package/tools/validate_groovy_scripts.py +173 -0
- package/tools/verify_all.py +496 -0
- package/tools/verify_all.sh +4 -0
- package/tools/visual_diff_canvas.py +142 -0
- package/tools/visual_som_helper.py +418 -0
- package/tools/wcag_audit.py +214 -0
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: backend-load-and-stress-patterns
|
|
3
|
+
description: Enterprise backend load, stress, and endurance test orchestration using k6 and Locust. Directs AI agents in modeling concurrent Virtual Users (VUs), establishing SLA threshold assertions (P95/P99 latency, throughput/RPS, error rate < 0.1%), executing stress break-point tests, and soak/endurance validation.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Backend Load & Stress Testing Patterns (k6 & Locust Orchestrator)
|
|
7
|
+
|
|
8
|
+
> **Purpose:** Master backend performance, throughput, and scalability engineering. Directs AI agents to model concurrent Virtual User (VU) traffic, execute stress/soak test profiles, and enforce automated SLA gates (P95/P99 latency, error rate < 0.1%) to detect bottlenecks before production release.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 1. Five Core Performance Test Archetypes
|
|
13
|
+
|
|
14
|
+
```mermaid
|
|
15
|
+
flowchart LR
|
|
16
|
+
A["<b>1. Smoke Test</b><br/>1-5 VUs / 1 min<br/>Sanity check"] --> B["<b>2. Load Test</b><br/>50-200 VUs / 15m<br/>Expected daily peak"]
|
|
17
|
+
B --> C["<b>3. Stress Test</b><br/>500-2000+ VUs<br/>Find breaking point"]
|
|
18
|
+
C --> D["<b>4. Spike Test</b><br/>Instant surge 10->1000<br/>Traffic shocks"]
|
|
19
|
+
D --> E["<b>5. Soak / Endurance</b><br/>Stable load / 2-12 hrs<br/>Memory leaks & OOM"]
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
| Test Archetype | Virtual Users (VUs) | Duration | Primary Objective | Failure Indicator |
|
|
23
|
+
| :--- | :--- | :--- | :--- | :--- |
|
|
24
|
+
| **Smoke Test** | 1 - 5 VUs | 1 - 2 mins | Script syntax & endpoint health sanity | Any HTTP 5xx or unhandled exceptions |
|
|
25
|
+
| **Load Test** | 50 - 200 VUs | 15 - 30 mins | Verify system SLA under standard peak traffic | P95 latency > 500ms or error rate > 0.1% |
|
|
26
|
+
| **Stress Test** | 200 -> 2,000+ VUs | 30 - 60 mins | Identify maximum throughput and degradation cliff | DB connection pool exhaustion, 503/504 errors |
|
|
27
|
+
| **Spike Test** | 10 -> 1,000 VUs in 10s | 5 - 10 mins | Test autoscaling latency and rate limiters | Gateway timeout (504), service unresponsiveness |
|
|
28
|
+
| **Soak Test** | 50 - 100 VUs | 2 - 12 hours | Detect slow memory leaks, disk fill, thread locks | Degraded throughput over time, JVM OOM |
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## 2. Automated SLA Threshold Assertions
|
|
33
|
+
|
|
34
|
+
Every performance test execution must assert measurable SLA criteria. If thresholds fail, the CI/CD pipeline returns a non-zero exit code.
|
|
35
|
+
|
|
36
|
+
```javascript
|
|
37
|
+
// Enterprise SLA Gates (k6)
|
|
38
|
+
export const options = {
|
|
39
|
+
thresholds: {
|
|
40
|
+
// 95% of requests must complete under 500ms
|
|
41
|
+
http_req_duration: ['p(95)<500', 'p(99)<1000'],
|
|
42
|
+
// Request failure rate must stay under 0.1%
|
|
43
|
+
http_req_failed: ['rate<0.001'],
|
|
44
|
+
// Functional checks must maintain > 99.9% success
|
|
45
|
+
checks: ['rate>0.999'],
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## 3. Production-Ready k6 Load Script (TypeScript / JavaScript)
|
|
53
|
+
|
|
54
|
+
```javascript
|
|
55
|
+
import http from 'k6/http';
|
|
56
|
+
import { check, sleep } from 'k6';
|
|
57
|
+
import { Counter, Rate, Trend } from 'k6/metrics';
|
|
58
|
+
|
|
59
|
+
// Custom Enterprise Metrics
|
|
60
|
+
const errorRate = new Rate('custom_error_rate');
|
|
61
|
+
const searchLatency = new Trend('search_latency');
|
|
62
|
+
|
|
63
|
+
export const options = {
|
|
64
|
+
scenarios: {
|
|
65
|
+
enterprise_workload: {
|
|
66
|
+
executor: 'ramping-vus',
|
|
67
|
+
startVUs: 0,
|
|
68
|
+
stages: [
|
|
69
|
+
{ duration: '2m', target: 50 }, // Ramp-up to 50 users
|
|
70
|
+
{ duration: '5m', target: 50 }, // Steady state peak
|
|
71
|
+
{ duration: '2m', target: 150 }, // Surge stress load
|
|
72
|
+
{ duration: '3m', target: 150 }, // Sustained stress
|
|
73
|
+
{ duration: '2m', target: 0 }, // Ramp-down to 0
|
|
74
|
+
],
|
|
75
|
+
gracefulRampDown: '30s',
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
thresholds: {
|
|
79
|
+
http_req_duration: ['p(95)<400', 'p(99)<800'],
|
|
80
|
+
custom_error_rate: ['rate<0.005'], // < 0.5% errors under stress
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const BASE_URL = __ENV.TARGET_URL || 'https://api.staging.enterprise.local';
|
|
85
|
+
|
|
86
|
+
export function setup() {
|
|
87
|
+
// Pre-test Authentication & Seeding (Executed once)
|
|
88
|
+
const authRes = http.post(`${BASE_URL}/api/v1/auth/login`, JSON.stringify({
|
|
89
|
+
username: __ENV.PERF_USER || 'perf_agent_01',
|
|
90
|
+
password: __ENV.PERF_PASSWORD || 'SecretVault#2026',
|
|
91
|
+
}), { headers: { 'Content-Type': 'application/json' } });
|
|
92
|
+
|
|
93
|
+
check(authRes, { 'Auth 200 OK': (r) => r.status === 200 });
|
|
94
|
+
const token = authRes.json('token');
|
|
95
|
+
return { token };
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export default function (data) {
|
|
99
|
+
const params = {
|
|
100
|
+
headers: {
|
|
101
|
+
'Authorization': `Bearer ${data.token}`,
|
|
102
|
+
'Content-Type': 'application/json',
|
|
103
|
+
'X-Correlation-ID': `PERF-${__VU}-${__ITER}-${Date.now()}`,
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
// 1. Transaction A: Fast Read API
|
|
108
|
+
const resGet = http.get(`${BASE_URL}/api/v1/catalogs?limit=20`, params);
|
|
109
|
+
const getOk = check(resGet, {
|
|
110
|
+
'Catalog GET 200': (r) => r.status === 200,
|
|
111
|
+
'Catalog Payload Valid': (r) => r.json('data.items') !== undefined,
|
|
112
|
+
});
|
|
113
|
+
errorRate.add(!getOk);
|
|
114
|
+
searchLatency.add(resGet.timings.duration);
|
|
115
|
+
|
|
116
|
+
sleep(1);
|
|
117
|
+
|
|
118
|
+
// 2. Transaction B: Dynamic Mutation API
|
|
119
|
+
const payload = JSON.stringify({
|
|
120
|
+
code: `AUTO_PERF_${__VU}_${__ITER}_${Date.now()}`,
|
|
121
|
+
name: 'Dynamic Synthetic Benchmark Item',
|
|
122
|
+
active: true,
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
const resPost = http.post(`${BASE_URL}/api/v1/catalogs`, payload, params);
|
|
126
|
+
const postOk = check(resPost, {
|
|
127
|
+
'Catalog POST 201': (r) => r.status === 201 || r.status === 200,
|
|
128
|
+
});
|
|
129
|
+
errorRate.add(!postOk);
|
|
130
|
+
|
|
131
|
+
sleep(2);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export function teardown(data) {
|
|
135
|
+
// Clean up benchmark markers if required
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## 4. Production-Ready Locust Load Script (Python)
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
import os
|
|
145
|
+
import time
|
|
146
|
+
from locust import HttpUser, task, between, events
|
|
147
|
+
|
|
148
|
+
class EnterpriseBackendUser(HttpUser):
|
|
149
|
+
wait_time = between(1.0, 2.5) # Realistic user think-time
|
|
150
|
+
|
|
151
|
+
def on_start(self):
|
|
152
|
+
"""Initial authentication handshake per Virtual User."""
|
|
153
|
+
res = self.client.post("/api/v1/auth/login", json={
|
|
154
|
+
"username": os.getenv("PERF_USER", "perf_tester"),
|
|
155
|
+
"password": os.getenv("PERF_PWD", "SecretPass2026")
|
|
156
|
+
})
|
|
157
|
+
if res.status_code == 200:
|
|
158
|
+
token = res.json().get("token")
|
|
159
|
+
self.client.headers.update({"Authorization": f"Bearer {token}"})
|
|
160
|
+
|
|
161
|
+
@task(3)
|
|
162
|
+
def query_search_index(self):
|
|
163
|
+
"""High-frequency read query."""
|
|
164
|
+
with self.client.get("/api/v1/search?q=enterprise&page=1", catch_response=True) as response:
|
|
165
|
+
if response.status_code != 200:
|
|
166
|
+
response.failure(f"Search API failed with HTTP {response.status_code}")
|
|
167
|
+
elif response.elapsed.total_seconds() > 0.5:
|
|
168
|
+
response.failure(f"Search API SLA breached (>500ms): {response.elapsed.total_seconds():.3f}s")
|
|
169
|
+
|
|
170
|
+
@task(1)
|
|
171
|
+
def submit_order_transaction(self):
|
|
172
|
+
"""Mutation transaction with dynamic unique identifier."""
|
|
173
|
+
order_id = f"ORDER_PERF_{time.time_ns()}"
|
|
174
|
+
with self.client.post("/api/v1/orders", json={
|
|
175
|
+
"orderCode": order_id,
|
|
176
|
+
"items": [{"sku": "SKU-990", "quantity": 1}],
|
|
177
|
+
"totalAmount": 150000
|
|
178
|
+
}, catch_response=True) as response:
|
|
179
|
+
if response.status_code not in (200, 201):
|
|
180
|
+
response.failure(f"Order submission failed: {response.text}")
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## 5. Execution Runbook & CI/CD Integration
|
|
186
|
+
|
|
187
|
+
### Run k6 Headless with JSON Summary
|
|
188
|
+
```bash
|
|
189
|
+
# Execute 100-user load test and export raw metrics
|
|
190
|
+
k6 run --out json=reports/k6_metrics.json tests/load/k6_catalog_load.js
|
|
191
|
+
|
|
192
|
+
# Assert exit code in CI/CD pipeline
|
|
193
|
+
if [ $? -ne 0 ]; then
|
|
194
|
+
echo "❌ Performance SLA threshold breached!"
|
|
195
|
+
exit 1
|
|
196
|
+
fi
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### Run Locust Headless in CI/CD
|
|
200
|
+
```bash
|
|
201
|
+
locust -f tests/load/locustfile.py --headless -u 100 -r 10 --run-time 5m \
|
|
202
|
+
--host https://api.staging.enterprise.local \
|
|
203
|
+
--html reports/locust_report.html \
|
|
204
|
+
--exit-code-on-error 1
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## 6. Performance Engineering Checklist
|
|
210
|
+
- [ ] Authentication executed once per VU in `setup()` or `on_start()`, never in tight loops.
|
|
211
|
+
- [ ] Synthetic transactions use dynamic unique codes to eliminate DB primary key collisions.
|
|
212
|
+
- [ ] SLA thresholds include both latency (P95/P99) and availability (`error_rate < 0.1%`).
|
|
213
|
+
- [ ] Soak tests executed against isolated staging environments with active APM/DB monitoring.
|
|
214
|
+
- [ ] Teardown removes temporary benchmark data to prevent DB bloat.
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bats-testing-patterns
|
|
3
|
+
description: Master Bash Automated Testing System (Bats) for testing bash/sh scripts, CI/CD pipelines, exit codes, and mock CLI execution.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Bats Testing Patterns (Bash Automated Testing System)
|
|
7
|
+
|
|
8
|
+
Comprehensive test engineering standard for validating shell scripts, CI/CD scripts (`.sh`), CLI wrappers, and DevOps automation using Bats-core.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 1. Core Principles
|
|
13
|
+
|
|
14
|
+
1. **Deterministic Exit Codes:** Every script assertion must explicitly assert `$status` (0 for success, non-zero for explicit failure vectors).
|
|
15
|
+
2. **Standard Output & Error Isolation:** Assert exact error strings in `${lines[@]}` or `$output`.
|
|
16
|
+
3. **Sandbox Filesystem:** Never mutate user home or production directories. Use `$BATS_TEST_TMPDIR` for all temporary files and fixtures.
|
|
17
|
+
4. **Mock External CLI Commands:** Intercept destructive CLI commands (`curl`, `docker`, `kubectl`, `git push`) by prepending a mock binary directory to `$PATH`.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 2. Standard Test Architecture & Setup
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
#!/usr/bin/env bats
|
|
25
|
+
|
|
26
|
+
setup() {
|
|
27
|
+
# Load bats helper libraries if available
|
|
28
|
+
load 'test_helper/bats-support/load' || true
|
|
29
|
+
load 'test_helper/bats-assert/load' || true
|
|
30
|
+
|
|
31
|
+
# Create an isolated sandbox directory per test
|
|
32
|
+
TEST_DIR="$(mktemp -d "${BATS_TMPDIR}/bats_test.XXXXXX")"
|
|
33
|
+
export TEST_DIR
|
|
34
|
+
cd "$TEST_DIR"
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
teardown() {
|
|
38
|
+
# Ensure clean sandbox teardown
|
|
39
|
+
rm -rf "$TEST_DIR"
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## 3. Production Test Patterns
|
|
46
|
+
|
|
47
|
+
### Pattern A: Exit Code and Output Verification
|
|
48
|
+
```bash
|
|
49
|
+
@test "script fails gracefully when required parameter is missing" {
|
|
50
|
+
run ./scripts/deploy.sh
|
|
51
|
+
[ "$status" -eq 1 ]
|
|
52
|
+
[[ "$output" =~ "ERROR: Missing --target environment" ]]
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
@test "script outputs version correctly on --version flag" {
|
|
56
|
+
run ./scripts/deploy.sh --version
|
|
57
|
+
[ "$status" -eq 0 ]
|
|
58
|
+
[ "${lines[0]}" = "deploy.sh version 2.4.0" ]
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Pattern B: Mocking Destructive CLI Tools
|
|
63
|
+
```bash
|
|
64
|
+
@test "mock curl API failure triggers automatic retry loop" {
|
|
65
|
+
MOCK_DIR="${TEST_DIR}/bin"
|
|
66
|
+
mkdir -p "$MOCK_DIR"
|
|
67
|
+
|
|
68
|
+
# Create mock curl returning HTTP 503
|
|
69
|
+
cat << 'EOF' > "${MOCK_DIR}/curl"
|
|
70
|
+
#!/bin/bash
|
|
71
|
+
echo "HTTP/1.1 503 Service Unavailable" >&2
|
|
72
|
+
exit 22
|
|
73
|
+
EOF
|
|
74
|
+
chmod +x "${MOCK_DIR}/curl"
|
|
75
|
+
|
|
76
|
+
# Prepend mock path
|
|
77
|
+
PATH="${MOCK_DIR}:${PATH}" run ./scripts/sync_data.sh --retries 2
|
|
78
|
+
[ "$status" -ne 0 ]
|
|
79
|
+
[[ "$output" =~ "Retry attempt 2 failed" ]]
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Pattern C: File Creation & Mutation Verification
|
|
84
|
+
```bash
|
|
85
|
+
@test "script generates valid JSON report on completion" {
|
|
86
|
+
run ./scripts/generate_report.sh --output "${TEST_DIR}/summary.json"
|
|
87
|
+
[ "$status" -eq 0 ]
|
|
88
|
+
[ -f "${TEST_DIR}/summary.json" ]
|
|
89
|
+
run jq '.status' "${TEST_DIR}/summary.json"
|
|
90
|
+
[ "$output" = '"SUCCESS"' ]
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## 4. CI/CD Pipeline Execution
|
|
97
|
+
```bash
|
|
98
|
+
# Execute full Bats test suite with JUnit report output for CI
|
|
99
|
+
bats test/*.bats --formatter junit > test-results.xml
|
|
100
|
+
```
|