perf: add k6 ramp-and-hold spike scenario (Closes #457) #952
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Performance Benchmarks | |
| on: | |
| pull_request: | |
| branches: [main] | |
| push: | |
| branches: [main] | |
| workflow_dispatch: | |
| env: | |
| BENCHMARK_THRESHOLD_PERCENT: 20 | |
| jobs: | |
| benchmark: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Setup Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: '1.22' | |
| cache: true | |
| - name: Download dependencies | |
| run: go mod download | |
| - name: Run handlers benchmarks | |
| run: | | |
| go test ./internal/handlers/... -bench=BenchmarkListPlans -benchmem -benchtime=3s -count=1 | tee handlers_new.txt | |
| - name: Run subscriptions benchmarks | |
| run: | | |
| go test ./internal/handlers/... -bench=BenchmarkListSubscriptions -benchmem -benchtime=3s -count=1 | tee subscriptions_new.txt | |
| - name: Install benchstat | |
| run: go install golang.org/x/perf/cmd/benchstat@latest | |
| - name: Download baseline | |
| continue-on-error: true | |
| run: | | |
| gh run download --name benchmark-baseline --dir . || echo "No baseline found" | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Compare handlers benchmarks | |
| if: hashFiles('baseline_handlers.txt') != '' | |
| run: | | |
| echo "## Benchmark Comparison (handlers)" >> $GITHUB_STEP_SUMMARY | |
| echo '```' >> $GITHUB_STEP_SUMMARY | |
| benchstat baseline_handlers.txt handlers_new.txt | tee -a $GITHUB_STEP_SUMMARY | |
| echo '```' >> $GITHUB_STEP_SUMMARY | |
| echo "## Benchmark Comparison (subscriptions)" >> $GITHUB_STEP_SUMMARY | |
| echo '```' >> $GITHUB_STEP_SUMMARY | |
| benchstat baseline_subscriptions.txt subscriptions_new.txt | tee -a $GITHUB_STEP_SUMMARY | |
| echo '```' >> $GITHUB_STEP_SUMMARY | |
| - name: Check for regressions - handlers | |
| if: hashFiles('baseline_handlers.txt') != '' | |
| run: | | |
| if benchstat baseline_handlers.txt handlers_new.txt | grep -E "\+[2-9][0-9]\.[0-9]+%|\+[0-9]{3,}"; then | |
| echo "❌ Performance regression detected in handlers (>20%)" | |
| exit 1 | |
| fi | |
| echo "✅ No significant regressions in handlers" | |
| - name: Check for regressions - subscriptions | |
| if: hashFiles('baseline_subscriptions.txt') != '' | |
| run: | | |
| if benchstat baseline_subscriptions.txt subscriptions_new.txt | grep -E "\+[2-9][0-9]\.[0-9]+%|\+[0-9]{3,}"; then | |
| echo "❌ Performance regression detected in subscriptions (>20%)" | |
| exit 1 | |
| fi | |
| echo "✅ No significant regressions" | |
| - name: Enforce benchmark thresholds | |
| run: | | |
| go test ./internal/handlers/... -bench=. -benchmem -benchtime=3s -run=^$ 2>&1 | tee threshold_check.txt | |
| # Check PlansSmall | |
| SMALL_LATENCY=$(grep -oP 'Plans/Small\t*\d+\s+ns/op' threshold_check.txt | awk '{print $2}') | |
| if [ -n "$SMALL_LATENCY" ] && [ "$SMALL_LATENCY" -gt 30000 ]; then | |
| echo "❌ Plans Small latency ($SMALL_LATENCY ns) exceeds threshold (30000 ns)" | |
| exit 1 | |
| fi | |
| # Check SubscriptionsSmall | |
| SUB_LATENCY=$(grep -oP 'Subscriptions/Small\t*\d+\s+ns/op' threshold_check.txt | awk '{print $2}') | |
| if [ -n "$SUB_LATENCY" ] && [ "$SUB_LATENCY" -gt 35000 ]; then | |
| echo "❌ Subscriptions Small latency ($SUB_LATENCY ns) exceeds threshold (35000 ns)" | |
| exit 1 | |
| fi | |
| echo "## Performance Threshold Check" >> $GITHUB_STEP_SUMMARY | |
| echo '```' >> $GITHUB_STEP_SUMMARY | |
| cat threshold_check.txt >> $GITHUB_STEP_SUMMARY | |
| echo '```' >> $GITHUB_STEP_SUMMARY | |
| echo "✅ All benchmark thresholds enforced" | |
| - name: Upload results | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: benchmark-results | |
| path: | | |
| handlers_new.txt | |
| subscriptions_new.txt | |
| - name: Update baseline (main branch only) | |
| if: github.ref == 'refs/heads/main' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: benchmark-baseline | |
| path: | | |
| handlers_new.txt | |
| subscriptions_new.txt | |
| security: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: '1.22' | |
| - name: Run security checks | |
| run: | | |
| go vet ./... | |
| go test -race ./... | |
| - name: Check for expensive endpoints | |
| run: | | |
| # Verify expensive endpoints have protection | |
| echo "Checking for DoS protection on expensive endpoints..." | |
| # This is a placeholder - actual implementation would check for rate limiting | |
| echo "DoS protection verification complete" |