initial base setup #1

Merged
Lars merged 10 commits from develop into main 2026-07-04 19:56:36 +02:00
2 changed files with 33 additions and 6 deletions
Showing only changes of commit 1d8e22be82 - Show all commits

View File

@ -115,6 +115,7 @@ jobs:
k6-health-baseline:
name: k6 /api/health Baseline
needs: [pytest-backend]
if: ${{ github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success' }}
runs-on: ubuntu-latest
steps:
@ -160,11 +161,19 @@ jobs:
sudo mv "/tmp/k6-${K6_VER}-linux-${K6_ARCH}/k6" /usr/local/bin/k6
- name: k6 Health-Baseline
env:
BASE_URL: ${{ steps.k6.outputs.base_url }}
run: k6 run scripts/load/k6-health-baseline.js
run: |
set -e
BASE_URL="${{ steps.k6.outputs.base_url }}"
if [ -z "$BASE_URL" ]; then
echo "BASE_URL leer — steps.k6.outputs.base_url prüfen"
exit 1
fi
echo "k6 gegen BASE_URL=$BASE_URL (K6_CI=1, quiet)"
BASE_URL="$BASE_URL" K6_CI=1 k6 run --quiet scripts/load/k6-health-baseline.js
echo "✓ k6 Health-Baseline OK"
playwright-smoke:
needs: [pytest-backend]
if: ${{ github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success' }}
runs-on: ubuntu-latest
steps:

View File

@ -1,16 +1,23 @@
/**
* Phase-0-Baseline: parallele GET /api/health (kein Auth).
* BASE_URL optional, z. B. https://dev.kairo.jinkendo.de
*
* K6_CI=1: leichtere Last für Self-hosted Runner (Raspberry Pi).
*/
import http from 'k6/http'
import { check } from 'k6'
const isCi = __ENV.K6_CI === '1' || __ENV.K6_CI === 'true'
const vus = parseInt(__ENV.K6_VUS || (isCi ? '5' : '10'), 10)
const duration = __ENV.K6_DURATION || (isCi ? '15s' : '30s')
const p95Ms = parseInt(__ENV.K6_P95_MS || (isCi ? '5000' : '3000'), 10)
export const options = {
scenarios: {
health: {
executor: 'constant-vus',
vus: 10,
duration: '30s',
vus,
duration,
gracefulStop: '5s',
tags: { scenario: 'health' },
exec: 'health',
@ -18,8 +25,9 @@ export const options = {
},
thresholds: {
http_req_failed: ['rate<0.05'],
'http_req_duration{scenario:health}': ['p(95)<3000'],
'http_req_duration{scenario:health}': [`p(95)<${p95Ms}`],
},
summaryTrendStats: ['avg', 'min', 'med', 'max', 'p(90)', 'p(95)'],
}
const BASE = (__ENV.BASE_URL || 'https://dev.kairo.jinkendo.de').replace(/\/$/, '')
@ -30,3 +38,13 @@ export function health() {
'health 2xx': (r) => r.status >= 200 && r.status < 300,
})
}
export function handleSummary(data) {
const failed = data.metrics.http_req_failed?.values?.rate ?? 0
const p95 = data.metrics.http_req_duration?.values?.['p(95)'] ?? 0
const lines = [
`k6 summary: BASE=${BASE} vus=${vus} duration=${duration}`,
` http_req_failed=${(failed * 100).toFixed(2)}% p(95)=${p95.toFixed(1)}ms (limit ${p95Ms}ms)`,
]
return { stdout: lines.join('\n') + '\n' }
}