271 lines
8.5 KiB
Bash
Executable File
271 lines
8.5 KiB
Bash
Executable File
#!/bin/bash
|
||
# Bulk Event Retrieval Performance Test
|
||
# Tests retrieving hundreds of events to measure JSON reconstruction performance
|
||
|
||
# Load test keys
|
||
source tests/.test_keys.txt
|
||
|
||
RELAY_URL="${RELAY_URL:-ws://localhost:8888}"
|
||
NUM_EVENTS=500
|
||
|
||
# Use test secret keys for creating valid events
|
||
SECRET_KEYS=(
|
||
"3fdd8227a920c2385559400b2b14e464f22e80df312a73cc7a86e1d7e91d608f"
|
||
"a156011cd65b71f84b4a488ac81687f2aed57e490b31c28f58195d787030db60"
|
||
"1618aaa21f5bd45c5ffede0d9a60556db67d4a046900e5f66b0bae5c01c801fb"
|
||
)
|
||
|
||
echo "=========================================="
|
||
echo "Bulk Event Retrieval Performance Test"
|
||
echo "=========================================="
|
||
echo "Relay: $RELAY_URL"
|
||
echo "Target: Retrieve $NUM_EVENTS events"
|
||
echo ""
|
||
|
||
# Check if relay is running
|
||
echo "Checking if relay is running..."
|
||
if ! nc -z localhost 8888 2>/dev/null; then
|
||
echo "ERROR: Relay is not running on port 8888"
|
||
exit 1
|
||
fi
|
||
echo "✓ Relay is running"
|
||
echo ""
|
||
|
||
# Check if nak is installed
|
||
if ! command -v nak &> /dev/null; then
|
||
echo "ERROR: 'nak' command not found. Please install nak:"
|
||
echo " go install github.com/fiatjaf/nak@latest"
|
||
exit 1
|
||
fi
|
||
|
||
# Check current event count in database
|
||
DB_FILE=$(ls build/*.db 2>/dev/null | head -1)
|
||
if [ -n "$DB_FILE" ]; then
|
||
CURRENT_COUNT=$(sqlite3 "$DB_FILE" "SELECT COUNT(*) FROM events WHERE kind=1;" 2>/dev/null || echo "0")
|
||
echo "Current kind 1 events in database: $CURRENT_COUNT"
|
||
|
||
if [ "$CURRENT_COUNT" -ge "$NUM_EVENTS" ]; then
|
||
echo "✓ Database already has $CURRENT_COUNT events (>= $NUM_EVENTS required)"
|
||
echo " Skipping event posting..."
|
||
echo ""
|
||
else
|
||
EVENTS_TO_POST=$((NUM_EVENTS - CURRENT_COUNT))
|
||
echo "Need to post $EVENTS_TO_POST more events..."
|
||
echo ""
|
||
|
||
# Post additional events
|
||
echo "Posting $EVENTS_TO_POST test events using nak..."
|
||
for i in $(seq 1 $EVENTS_TO_POST); do
|
||
# Cycle through secret keys
|
||
KEY_INDEX=$(( (i - 1) % ${#SECRET_KEYS[@]} ))
|
||
CURRENT_KEY=${SECRET_KEYS[$KEY_INDEX]}
|
||
|
||
# Create content
|
||
CONTENT="Bulk test event $i/$EVENTS_TO_POST for performance testing"
|
||
|
||
# Post event using nak (properly signed)
|
||
nak event -c "$CONTENT" --sec "$CURRENT_KEY" "$RELAY_URL" >/dev/null 2>&1
|
||
|
||
# Progress indicator
|
||
if [ $((i % 50)) -eq 0 ]; then
|
||
echo " Posted $i/$EVENTS_TO_POST events..."
|
||
fi
|
||
done
|
||
echo "✓ Posted $EVENTS_TO_POST test events"
|
||
echo ""
|
||
fi
|
||
else
|
||
echo "WARNING: Could not find database file"
|
||
echo "Posting $NUM_EVENTS events anyway..."
|
||
echo ""
|
||
|
||
# Post events
|
||
echo "Posting $NUM_EVENTS test events using nak..."
|
||
for i in $(seq 1 $NUM_EVENTS); do
|
||
KEY_INDEX=$(( (i - 1) % ${#SECRET_KEYS[@]} ))
|
||
CURRENT_KEY=${SECRET_KEYS[$KEY_INDEX]}
|
||
CONTENT="Bulk test event $i/$NUM_EVENTS for performance testing"
|
||
nak event -c "$CONTENT" --sec "$CURRENT_KEY" "$RELAY_URL" >/dev/null 2>&1
|
||
|
||
if [ $((i % 50)) -eq 0 ]; then
|
||
echo " Posted $i/$NUM_EVENTS events..."
|
||
fi
|
||
done
|
||
echo "✓ Posted $NUM_EVENTS test events"
|
||
echo ""
|
||
fi
|
||
|
||
# Wait for events to be stored
|
||
echo "Waiting 2 seconds for events to be stored..."
|
||
sleep 2
|
||
echo ""
|
||
|
||
# Test 1: Retrieve 500 events using nak req
|
||
echo "=========================================="
|
||
echo "TEST 1: Retrieve $NUM_EVENTS events"
|
||
echo "=========================================="
|
||
echo "Sending REQ with limit=$NUM_EVENTS..."
|
||
echo ""
|
||
|
||
START_TIME=$(date +%s%N)
|
||
|
||
# Use nak req to retrieve events (properly handles subscription protocol)
|
||
RESPONSE=$(nak req -k 1 -l $NUM_EVENTS "$RELAY_URL" 2>/dev/null)
|
||
|
||
END_TIME=$(date +%s%N)
|
||
ELAPSED_MS=$(( (END_TIME - START_TIME) / 1000000 ))
|
||
|
||
# Count events received (each line is one event)
|
||
EVENT_COUNT=$(echo "$RESPONSE" | grep -c '^{')
|
||
|
||
echo "Results:"
|
||
echo " Time elapsed: ${ELAPSED_MS}ms"
|
||
echo " Events received: $EVENT_COUNT"
|
||
echo ""
|
||
|
||
if [ $EVENT_COUNT -ge $((NUM_EVENTS - 10)) ]; then
|
||
echo "✓ TEST 1 PASSED: Retrieved $EVENT_COUNT events in ${ELAPSED_MS}ms"
|
||
if [ $ELAPSED_MS -lt 100 ]; then
|
||
echo " ⚡ EXCELLENT: <100ms for $EVENT_COUNT events!"
|
||
elif [ $ELAPSED_MS -lt 500 ]; then
|
||
echo " ✓ GOOD: <500ms for $EVENT_COUNT events"
|
||
elif [ $ELAPSED_MS -lt 2000 ]; then
|
||
echo " ⚠ ACCEPTABLE: <2s for $EVENT_COUNT events"
|
||
else
|
||
echo " ⚠ SLOW: ${ELAPSED_MS}ms for $EVENT_COUNT events (expected <100ms)"
|
||
fi
|
||
else
|
||
echo "✗ TEST 1 FAILED: Only retrieved $EVENT_COUNT events (expected ~$NUM_EVENTS)"
|
||
fi
|
||
echo ""
|
||
|
||
# Test 2: Retrieve events by author (use first test key's pubkey)
|
||
echo "=========================================="
|
||
echo "TEST 2: Retrieve events by author"
|
||
echo "=========================================="
|
||
echo "Sending REQ with authors filter..."
|
||
echo ""
|
||
|
||
# Get pubkey from first secret key
|
||
TEST_PUBKEY=$(nak key public ${SECRET_KEYS[0]})
|
||
|
||
START_TIME=$(date +%s%N)
|
||
|
||
RESPONSE=$(nak req -k 1 -a "$TEST_PUBKEY" -l $NUM_EVENTS "$RELAY_URL" 2>/dev/null)
|
||
|
||
END_TIME=$(date +%s%N)
|
||
ELAPSED_MS=$(( (END_TIME - START_TIME) / 1000000 ))
|
||
|
||
EVENT_COUNT=$(echo "$RESPONSE" | grep -c '^{')
|
||
|
||
echo "Results:"
|
||
echo " Time elapsed: ${ELAPSED_MS}ms"
|
||
echo " Events received: $EVENT_COUNT"
|
||
echo " (Note: Only events from first test key, ~1/3 of total)"
|
||
echo ""
|
||
|
||
if [ $EVENT_COUNT -ge $((NUM_EVENTS / 3 - 20)) ]; then
|
||
echo "✓ TEST 2 PASSED: Retrieved $EVENT_COUNT events in ${ELAPSED_MS}ms"
|
||
else
|
||
echo "⚠ TEST 2 WARNING: Only retrieved $EVENT_COUNT events (expected ~$((NUM_EVENTS / 3)))"
|
||
fi
|
||
echo ""
|
||
|
||
# Test 3: Retrieve events with time filter
|
||
echo "=========================================="
|
||
echo "TEST 3: Retrieve events with time filter"
|
||
echo "=========================================="
|
||
echo "Sending REQ with since filter (last hour)..."
|
||
echo ""
|
||
|
||
SINCE_TIME=$(($(date +%s) - 3600))
|
||
|
||
START_TIME=$(date +%s%N)
|
||
|
||
RESPONSE=$(nak req -k 1 --since "$SINCE_TIME" -l $NUM_EVENTS "$RELAY_URL" 2>/dev/null)
|
||
|
||
END_TIME=$(date +%s%N)
|
||
ELAPSED_MS=$(( (END_TIME - START_TIME) / 1000000 ))
|
||
|
||
EVENT_COUNT=$(echo "$RESPONSE" | grep -c '^{')
|
||
|
||
echo "Results:"
|
||
echo " Time elapsed: ${ELAPSED_MS}ms"
|
||
echo " Events received: $EVENT_COUNT"
|
||
echo ""
|
||
|
||
if [ $EVENT_COUNT -ge $((NUM_EVENTS - 10)) ]; then
|
||
echo "✓ TEST 3 PASSED: Retrieved $EVENT_COUNT events in ${ELAPSED_MS}ms"
|
||
else
|
||
echo "⚠ TEST 3 WARNING: Only retrieved $EVENT_COUNT events (expected ~$NUM_EVENTS)"
|
||
fi
|
||
echo ""
|
||
|
||
# Test 4: Multiple small retrievals (simulating real-world usage)
|
||
echo "=========================================="
|
||
echo "TEST 4: Multiple small retrievals (50 events × 10 times)"
|
||
echo "=========================================="
|
||
echo "Simulating real-world client behavior..."
|
||
echo ""
|
||
|
||
TOTAL_TIME=0
|
||
TOTAL_EVENTS=0
|
||
for i in $(seq 1 10); do
|
||
START_TIME=$(date +%s%N)
|
||
|
||
RESPONSE=$(nak req -k 1 -l 50 "$RELAY_URL" 2>/dev/null)
|
||
|
||
END_TIME=$(date +%s%N)
|
||
ELAPSED_MS=$(( (END_TIME - START_TIME) / 1000000 ))
|
||
TOTAL_TIME=$((TOTAL_TIME + ELAPSED_MS))
|
||
|
||
EVENT_COUNT=$(echo "$RESPONSE" | grep -c '^{')
|
||
TOTAL_EVENTS=$((TOTAL_EVENTS + EVENT_COUNT))
|
||
echo " Request $i: ${ELAPSED_MS}ms ($EVENT_COUNT events)"
|
||
done
|
||
|
||
AVG_TIME=$((TOTAL_TIME / 10))
|
||
|
||
echo ""
|
||
echo "Results:"
|
||
echo " Total time: ${TOTAL_TIME}ms"
|
||
echo " Total events: $TOTAL_EVENTS"
|
||
echo " Average time per request: ${AVG_TIME}ms"
|
||
echo ""
|
||
|
||
if [ $AVG_TIME -lt 50 ]; then
|
||
echo "✓ TEST 4 PASSED: Average retrieval time ${AVG_TIME}ms (excellent)"
|
||
elif [ $AVG_TIME -lt 200 ]; then
|
||
echo "✓ TEST 4 PASSED: Average retrieval time ${AVG_TIME}ms (good)"
|
||
else
|
||
echo "⚠ TEST 4 WARNING: Average retrieval time ${AVG_TIME}ms (slow)"
|
||
fi
|
||
echo ""
|
||
|
||
# Performance Summary
|
||
echo "=========================================="
|
||
echo "PERFORMANCE SUMMARY"
|
||
echo "=========================================="
|
||
echo ""
|
||
echo "Expected performance with event_json optimization:"
|
||
echo " - 366 events: <10ms (previously 18 seconds)"
|
||
echo " - 500 events: <15ms"
|
||
echo " - Per-event overhead: ~0.02ms (vs 50ms before)"
|
||
echo ""
|
||
|
||
if [ -n "$DB_FILE" ]; then
|
||
FINAL_COUNT=$(sqlite3 "$DB_FILE" "SELECT COUNT(*) FROM events WHERE kind=1;" 2>/dev/null || echo "0")
|
||
echo "Final database stats:"
|
||
echo " Total kind 1 events: $FINAL_COUNT"
|
||
echo " Database file: $DB_FILE"
|
||
echo ""
|
||
fi
|
||
|
||
echo "Check relay logs for [QUERY] entries to see actual query times:"
|
||
echo " journalctl -u c-relay -n 100 | grep QUERY"
|
||
echo ""
|
||
|
||
echo "=========================================="
|
||
echo "Test Complete"
|
||
echo "=========================================="
|