-
Notifications
You must be signed in to change notification settings - Fork 93
138 lines (120 loc) · 4.54 KB
/
Copy pathloadtest-stress.yml
File metadata and controls
138 lines (120 loc) · 4.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
name: Performance Stress Test (Nightly)
on:
push:
branches: [main]
pull_request:
paths:
- '.github/workflows/loadtest-stress.yml'
schedule:
# Runs at 02:00 UTC every night
- cron: '0 2 * * *'
# Allow manual triggering from the Actions tab
workflow_dispatch:
permissions:
contents: read
jobs:
loadtest-stress:
name: k6 Full Stress Test
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v7
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version-file: 'go.mod'
cache: true
- name: Download dependencies
run: go mod download
- name: Build Maglev
run: make build
- name: Create CI config
run: |
cat > config.ci.json << 'EOF'
{
"port": 4000,
"env": "development",
"api-keys": ["test"],
"rate-limit": 1000,
"log-level": "warn",
"log-format": "json",
"gtfs-static-feed": {
"url": "testdata/raba.zip",
"enable-gtfs-tidy": false
},
"gtfs-rt-feeds": [],
"data-path": "./ci-gtfs.db"
}
EOF
- name: Start Maglev server (with pprof enabled)
run: |
MAGLEV_ENABLE_PPROF=1 ./bin/maglev -f config.ci.json > maglev.log 2>&1 &
echo "MAGLEV_PID=$!" >> $GITHUB_ENV
- name: Wait for server to be ready
run: |
echo "Waiting for Maglev to be ready..."
for i in $(seq 1 60); do
if curl -sf http://localhost:4000/healthz > /dev/null 2>&1; then
echo "Server is ready after ${i} attempts."
exit 0
fi
echo " Attempt $i/60 — not ready yet, waiting 5s..."
tail -1 maglev.log 2>/dev/null || true
sleep 5
done
echo "ERROR: Server did not become ready in time. Dumping logs:"
cat maglev.log
exit 1
- name: Install k6
run: |
sudo gpg -k
sudo gpg --no-default-keyring \
--keyring /usr/share/keyrings/k6-archive-keyring.gpg \
--keyserver hkp://keyserver.ubuntu.com:80 \
--recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" \
| sudo tee /etc/apt/sources.list.d/k6.list
sudo apt-get update -qq
sudo apt-get install -y k6
- name: Capture pprof baseline (before load)
run: |
mkdir -p loadtest/profiles
curl -sf "http://localhost:6060/debug/pprof/heap" -o loadtest/profiles/heap-before.pprof || true
curl -sf "http://localhost:6060/debug/pprof/goroutine" -o loadtest/profiles/goroutine-before.pprof || true
- name: Run k6 full stress test
run: |
# Wait 60s for ramp-up, then capture 30s CPU profile during peak load
(sleep 60 && curl -sf "http://localhost:6060/debug/pprof/profile?seconds=30" -o loadtest/profiles/cpu.pprof) &
PPROF_PID=$!
k6 run \
-e USE_FALLBACKS=true \
loadtest/k6/scenarios.js
# Wait for the background profile to finish and gracefully catch any errors
wait $PPROF_PID || echo "Warning: Background CPU profile capture failed."
continue-on-error: true
id: k6_stress
- name: Capture pprof profiles (after load)
if: always()
run: |
curl -sf "http://localhost:6060/debug/pprof/heap" -o loadtest/profiles/heap-after.pprof || true
curl -sf "http://localhost:6060/debug/pprof/goroutine" -o loadtest/profiles/goroutine-after.pprof || true
curl -sf "http://localhost:6060/debug/pprof/mutex" -o loadtest/profiles/mutex-after.pprof || true
# Note: CPU profile is captured concurrently during the test above
- name: Stop Maglev server
if: always()
run: |
kill $MAGLEV_PID 2>/dev/null || true
- name: Upload stress test results and profiles
if: always()
uses: actions/upload-artifact@v7
with:
name: k6-stress-results-${{ github.sha }}
path: |
loadtest/k6/stress-summary.json
loadtest/profiles/
maglev.log
- name: Fail job if k6 thresholds were exceeded
if: steps.k6_stress.outcome == 'failure'
run: |
echo "k6 stress test thresholds were exceeded. Download the k6-stress-results artifact for pprof profiles."
exit 1