From 1d8e22be826dee5f52d0c2d5ec6ce59ab7b12e1a Mon Sep 17 00:00:00 2001 From: Lars Date: Sat, 4 Jul 2026 19:47:45 +0200 Subject: [PATCH] k6-CI fuer Raspberry Pi: weniger Last, quiet-Modus, nach pytest. Co-authored-by: Cursor --- .gitea/workflows/test.yml | 15 ++++++++++++--- scripts/load/k6-health-baseline.js | 24 +++++++++++++++++++++--- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/.gitea/workflows/test.yml b/.gitea/workflows/test.yml index ed76634..6c30656 100644 --- a/.gitea/workflows/test.yml +++ b/.gitea/workflows/test.yml @@ -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: diff --git a/scripts/load/k6-health-baseline.js b/scripts/load/k6-health-baseline.js index 62e9dd1..cb69d76 100644 --- a/scripts/load/k6-health-baseline.js +++ b/scripts/load/k6-health-baseline.js @@ -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' } +}