Skip to content

Commit c56198b

Browse files
committed
Add e2e perf test script with report generation
1 parent 42084db commit c56198b

1 file changed

Lines changed: 242 additions & 0 deletions

File tree

tools/run_perf_e2e.sh

Lines changed: 242 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,242 @@
1+
#!/bin/bash
2+
set -euo pipefail
3+
4+
# Usage: ./run_perf_e2e.sh <pub_subs> <pure_subs> [top_n] [duration_sec] [output_dir]
5+
# Example: ./run_perf_e2e.sh 80 720 45 120 ./perf-results
6+
7+
PUB_SUBS=${1:?Usage: $0 <pub_subs> <pure_subs> [top_n] [duration_sec] [output_dir]}
8+
PURE_SUBS=${2:?Usage: $0 <pub_subs> <pure_subs> [top_n] [duration_sec] [output_dir]}
9+
TOP_N=${3:-45}
10+
DURATION=${4:-120}
11+
OUTPUT_DIR=${5:-./perf-results}
12+
13+
TOTAL_SUBS=$((PUB_SUBS + PURE_SUBS))
14+
REMOTE="admin@snk-dev-1.m10x.org"
15+
SSH_KEY="$HOME/.ssh/keys/snk-dev-server.pem"
16+
SSH="ssh -i $SSH_KEY $REMOTE"
17+
SCP="scp -i $SSH_KEY"
18+
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
19+
REMOTE_DIR="/tmp/moq-rs-perf-$TIMESTAMP"
20+
LOCAL_DIR="$OUTPUT_DIR/$TIMESTAMP"
21+
22+
mkdir -p "$LOCAL_DIR"
23+
24+
echo "=== MOQ-RS E2E Performance Test ==="
25+
echo " Publishers (pub-sub): $PUB_SUBS"
26+
echo " Pure subscribers: $PURE_SUBS"
27+
echo " Total subscribers: $TOTAL_SUBS"
28+
echo " Top-N filter: $TOP_N"
29+
echo " Duration: ${DURATION}s"
30+
echo " Remote: $REMOTE"
31+
echo " Remote dir: $REMOTE_DIR"
32+
echo " Local output: $LOCAL_DIR"
33+
echo ""
34+
35+
# Step 1: Collect system info
36+
echo "[1/7] Collecting system configuration..."
37+
$SSH "bash -s" > "$LOCAL_DIR/sysinfo.txt" <<'SYSINFO'
38+
echo "=== System Configuration ==="
39+
echo "Hostname: $(hostname)"
40+
echo "Date: $(date -u)"
41+
echo "Kernel: $(uname -r)"
42+
echo "Arch: $(uname -m)"
43+
echo "CPU:"
44+
lscpu | grep -E "^(Model name|CPU\(s\)|Thread|Core|Socket|CPU max)"
45+
echo ""
46+
echo "Memory:"
47+
free -h | head -2
48+
echo ""
49+
echo "OS:"
50+
cat /etc/os-release 2>/dev/null | grep -E "^(NAME|VERSION)" || true
51+
echo ""
52+
echo "Rust:"
53+
source ~/.cargo/env 2>/dev/null
54+
rustc --version 2>/dev/null || echo "unknown"
55+
echo ""
56+
echo "Git commit:"
57+
cd ~/moq-rs-top-n && git log --oneline -1
58+
echo "Git branch:"
59+
cd ~/moq-rs-top-n && git branch --show-current
60+
SYSINFO
61+
62+
echo " Done."
63+
64+
# Step 2: Build on remote
65+
echo "[2/7] Building on remote..."
66+
$SSH "cd ~/moq-rs-top-n && source ~/.cargo/env && cargo build --release --bin moq-relay-ietf --bin moq-topn-test 2>&1 | tail -3"
67+
echo " Done."
68+
69+
# Step 3: Run perf test
70+
echo "[3/7] Running perf test (${DURATION}s + overhead)..."
71+
$SSH "bash -s" <<PERF_SCRIPT
72+
set -e
73+
cd ~/moq-rs-top-n
74+
source ~/.cargo/env
75+
mkdir -p $REMOTE_DIR
76+
77+
pkill -f moq-relay-ietf 2>/dev/null || true
78+
sleep 1
79+
80+
# Start relay
81+
./target/release/moq-relay-ietf --bind "[::]:4443" --tls-cert cert.pem --tls-key key.pem > $REMOTE_DIR/relay.log 2>&1 &
82+
RELAY_PID=\$!
83+
sleep 2
84+
85+
# Capture memory baseline
86+
ps -o rss= -p \$RELAY_PID > $REMOTE_DIR/mem_before.txt
87+
88+
# Start perf recording
89+
perf record -F 999 -p \$RELAY_PID -g -o $REMOTE_DIR/perf.data -- sleep $((DURATION + 15)) &
90+
PERF_PID=\$!
91+
92+
# Run e2e test
93+
./target/release/moq-topn-test -m e2e \\
94+
--relay https://localhost:4443 \\
95+
--tls-disable-verify \\
96+
-x $PUB_SUBS \\
97+
-y $TOTAL_SUBS \\
98+
-n $TOP_N \\
99+
-d $DURATION \\
100+
--group-interval-ms 33 \\
101+
--connection-batch-size 50 \\
102+
> $REMOTE_DIR/test_output.txt 2>&1 || true
103+
104+
# Capture memory after test
105+
ps -o rss= -p \$RELAY_PID > $REMOTE_DIR/mem_after.txt 2>/dev/null || echo "0" > $REMOTE_DIR/mem_after.txt
106+
107+
wait \$PERF_PID 2>/dev/null || true
108+
109+
# Generate flamegraph
110+
perf script -i $REMOTE_DIR/perf.data | ~/FlameGraph/stackcollapse-perf.pl > $REMOTE_DIR/collapsed.txt
111+
~/FlameGraph/flamegraph.pl $REMOTE_DIR/collapsed.txt > $REMOTE_DIR/flamegraph.svg
112+
113+
# Run analysis
114+
python3 ~/moq-rs-top-n/tools/analyze_flamegraph.py $REMOTE_DIR/collapsed.txt $REMOTE_DIR/analysis.txt
115+
116+
kill \$RELAY_PID 2>/dev/null || true
117+
echo "DONE" > $REMOTE_DIR/status.txt
118+
PERF_SCRIPT
119+
120+
echo " Done."
121+
122+
# Step 4: Wait for completion and verify
123+
echo "[4/7] Verifying completion..."
124+
STATUS=$($SSH "cat $REMOTE_DIR/status.txt 2>/dev/null || echo FAILED")
125+
if [ "$STATUS" != "DONE" ]; then
126+
echo " ERROR: Test did not complete successfully"
127+
exit 1
128+
fi
129+
echo " Done."
130+
131+
# Step 5: Collect results
132+
echo "[5/7] Collecting results from remote..."
133+
$SCP "$REMOTE:$REMOTE_DIR/flamegraph.svg" "$LOCAL_DIR/flamegraph.svg"
134+
$SCP "$REMOTE:$REMOTE_DIR/collapsed.txt" "$LOCAL_DIR/collapsed.txt"
135+
$SCP "$REMOTE:$REMOTE_DIR/analysis.txt" "$LOCAL_DIR/analysis.txt"
136+
$SCP "$REMOTE:$REMOTE_DIR/test_output.txt" "$LOCAL_DIR/test_output.txt"
137+
$SCP "$REMOTE:$REMOTE_DIR/relay.log" "$LOCAL_DIR/relay.log"
138+
$SCP "$REMOTE:$REMOTE_DIR/mem_before.txt" "$LOCAL_DIR/mem_before.txt"
139+
$SCP "$REMOTE:$REMOTE_DIR/mem_after.txt" "$LOCAL_DIR/mem_after.txt"
140+
echo " Done."
141+
142+
# Step 6: Extract test metrics from output
143+
echo "[6/7] Extracting metrics..."
144+
TEST_OUTPUT="$LOCAL_DIR/test_output.txt"
145+
146+
# Extract key metrics from test output
147+
OBJECTS_SENT=$(grep -o "objects_sent\":[0-9]*" "$TEST_OUTPUT" | tail -1 | cut -d: -f2 || echo "N/A")
148+
OBJECTS_RECV=$(grep -o "objects_received\":[0-9]*" "$TEST_OUTPUT" | tail -1 | cut -d: -f2 || echo "N/A")
149+
FILTER_PASS=$(grep -c "TOPN_EVENT.*filter_pass" "$TEST_OUTPUT" 2>/dev/null || echo "0")
150+
FILTER_DROP=$(grep -c "TOPN_EVENT.*filter_drop" "$TEST_OUTPUT" 2>/dev/null || echo "0")
151+
152+
# Memory
153+
MEM_BEFORE=$(cat "$LOCAL_DIR/mem_before.txt" | tr -d ' ')
154+
MEM_AFTER=$(cat "$LOCAL_DIR/mem_after.txt" | tr -d ' ')
155+
MEM_BEFORE_MB=$(echo "scale=1; $MEM_BEFORE / 1024" | bc 2>/dev/null || echo "N/A")
156+
MEM_AFTER_MB=$(echo "scale=1; $MEM_AFTER / 1024" | bc 2>/dev/null || echo "N/A")
157+
158+
# Extract from analysis
159+
TOPN_SELF=$(grep "Total Top-N self time" "$LOCAL_DIR/analysis.txt" | grep -o "[0-9.]*%" | head -1 || echo "N/A")
160+
TOPN_INCLUSIVE=$(grep "Top-N compute (inclusive)" "$LOCAL_DIR/analysis.txt" | grep -o "[0-9.]*%" | head -1 || echo "N/A")
161+
QUIC_SELF=$(grep "QUIC transport (self)" "$LOCAL_DIR/analysis.txt" | grep -o "[0-9.]*%" | head -1 || echo "N/A")
162+
QUIC_INCLUSIVE=$(grep "QUIC Transport" "$LOCAL_DIR/analysis.txt" | head -1 | grep -o "[0-9.]*%" | head -1 || echo "N/A")
163+
MOQ_INCLUSIVE=$(grep "MOQ protocol (inclusive)" "$LOCAL_DIR/analysis.txt" | grep -o "[0-9.]*%" | head -1 || echo "N/A")
164+
ALLOC_SELF=$(grep "Memory Allocation" "$LOCAL_DIR/analysis.txt" | tail -1 | grep -o "[0-9.]*%" | head -1 || echo "N/A")
165+
166+
echo " Done."
167+
168+
# Step 7: Generate report
169+
echo "[7/7] Generating report..."
170+
REPORT="$LOCAL_DIR/report.md"
171+
SYSINFO=$(cat "$LOCAL_DIR/sysinfo.txt")
172+
ANALYSIS=$(cat "$LOCAL_DIR/analysis.txt")
173+
174+
cat > "$REPORT" <<EOF
175+
# MOQ-RS Relay Performance Report
176+
177+
**Date:** $(date -u '+%Y-%m-%d %H:%M:%S UTC')
178+
**Commit:** $(grep "Git commit:" "$LOCAL_DIR/sysinfo.txt" | cut -d: -f2- | xargs)
179+
**Branch:** $(grep "Git branch:" "$LOCAL_DIR/sysinfo.txt" | cut -d: -f2- | xargs)
180+
181+
## Test Parameters
182+
183+
| Parameter | Value |
184+
|-----------|-------|
185+
| Publishers (pub-sub) | $PUB_SUBS |
186+
| Pure subscribers | $PURE_SUBS |
187+
| Total subscribers | $TOTAL_SUBS |
188+
| Top-N filter | $TOP_N |
189+
| Duration | ${DURATION}s |
190+
| Group interval | 33ms (~30 fps) |
191+
| Connection batch size | 50 |
192+
193+
## System Configuration
194+
195+
\`\`\`
196+
$SYSINFO
197+
\`\`\`
198+
199+
## Results Summary
200+
201+
### CPU Profile
202+
203+
| Component | Self Time | Inclusive Time |
204+
|-----------|-----------|----------------|
205+
| **Top-N** | $TOPN_SELF | $TOPN_INCLUSIVE |
206+
| QUIC Transport | $QUIC_SELF | $QUIC_INCLUSIVE |
207+
| MOQ Protocol | — | $MOQ_INCLUSIVE |
208+
| Memory Allocation | $ALLOC_SELF | — |
209+
210+
### Memory Usage
211+
212+
| Metric | Value |
213+
|--------|-------|
214+
| RSS before test | ${MEM_BEFORE_MB} MB |
215+
| RSS after test | ${MEM_AFTER_MB} MB |
216+
| Growth | $(echo "scale=1; ($MEM_AFTER - $MEM_BEFORE) / 1024" | bc 2>/dev/null || echo "N/A") MB |
217+
218+
### Top-N vs QUIC Relative Cost
219+
220+
- Self vs self: Top-N $TOPN_SELF vs QUIC $QUIC_SELF
221+
- Inclusive vs inclusive: Top-N $TOPN_INCLUSIVE vs QUIC $QUIC_INCLUSIVE
222+
223+
## Detailed Flamegraph Analysis
224+
225+
\`\`\`
226+
$ANALYSIS
227+
\`\`\`
228+
229+
## Artifacts
230+
231+
- \`flamegraph.svg\` — Interactive flamegraph
232+
- \`collapsed.txt\` — Collapsed stacks for custom analysis
233+
- \`test_output.txt\` — Full test driver output
234+
- \`relay.log\` — Relay server logs
235+
- \`analysis.txt\` — Raw flamegraph analysis
236+
237+
EOF
238+
239+
echo " Done."
240+
echo ""
241+
echo "=== Report generated: $REPORT ==="
242+
echo "=== Flamegraph: $LOCAL_DIR/flamegraph.svg ==="

0 commit comments

Comments
 (0)