| | #!/bin/bash |
| |
|
| | |
| | |
| |
|
| | set -e |
| |
|
| | |
| | BASE_URL="${BASE_URL:-http://localhost:8000}" |
| | API_KEY="${API_KEY:-}" |
| | CONCURRENCY="${CONCURRENCY:-10}" |
| | TOTAL_REQUESTS="${TOTAL_REQUESTS:-50}" |
| |
|
| | |
| | RED='\033[0;31m' |
| | GREEN='\033[0;32m' |
| | YELLOW='\033[1;33m' |
| | BLUE='\033[0;34m' |
| | NC='\033[0m' |
| |
|
| | echo -e "${BLUE}โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ${NC}" |
| | echo -e "${BLUE}โ Grok2API ๅนถๅๆง่ฝๆต่ฏๅทฅๅ
ท (Shell็) โ${NC}" |
| | echo -e "${BLUE}โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ${NC}" |
| | echo "" |
| | echo -e "${GREEN}๐ ๆต่ฏ็ฎๆ :${NC} $BASE_URL" |
| | echo -e "${GREEN}๐ API Key:${NC} ${API_KEY:-(ๆช่ฎพ็ฝฎ)}" |
| | echo -e "${GREEN}๐ ๅนถๅๆฐ:${NC} $CONCURRENCY" |
| | echo -e "${GREEN}๐ ๆป่ฏทๆฑๆฐ:${NC} $TOTAL_REQUESTS" |
| | echo "" |
| |
|
| | |
| | if ! command -v curl &> /dev/null; then |
| | echo -e "${RED}โ ้่ฏฏ: ้่ฆๅฎ่ฃ
curl${NC}" |
| | exit 1 |
| | fi |
| |
|
| | |
| | TMP_DIR=$(mktemp -d) |
| | trap "rm -rf $TMP_DIR" EXIT |
| |
|
| | |
| | test_request() { |
| | local request_id=$1 |
| | local start_time=$(date +%s.%N) |
| | |
| | |
| | local headers="Content-Type: application/json" |
| | if [ -n "$API_KEY" ]; then |
| | headers="${headers}\nAuthorization: Bearer ${API_KEY}" |
| | fi |
| | |
| | local response=$(curl -s -w "\n%{http_code}\n%{time_total}" \ |
| | -X POST "${BASE_URL}/v1/chat/completions" \ |
| | -H "Content-Type: application/json" \ |
| | ${API_KEY:+-H "Authorization: Bearer $API_KEY"} \ |
| | -d "{ |
| | \"model\": \"grok-3-fast\", |
| | \"messages\": [{\"role\": \"user\", \"content\": \"ๆต่ฏ่ฏทๆฑ #${request_id}๏ผ่ฏท็ฎ็ญๅๅคOK\"}], |
| | \"stream\": false, |
| | \"max_tokens\": 10 |
| | }" 2>&1) |
| | |
| | local http_code=$(echo "$response" | tail -n 2 | head -n 1) |
| | local time_total=$(echo "$response" | tail -n 1) |
| | |
| | |
| | echo "${request_id},${http_code},${time_total}" >> "$TMP_DIR/results.csv" |
| | |
| | |
| | echo -ne "\r ่ฟๅบฆ: ${request_id}/${TOTAL_REQUESTS}" |
| | } |
| |
|
| | |
| | export -f test_request |
| | export BASE_URL API_KEY TMP_DIR |
| |
|
| | |
| | echo "id,status,time" > "$TMP_DIR/results.csv" |
| |
|
| | echo -e "${YELLOW}๐ ๅผๅงๅนถๅๆต่ฏ...${NC}" |
| | START_TIME=$(date +%s.%N) |
| |
|
| | |
| | if command -v parallel &> /dev/null; then |
| | seq 1 $TOTAL_REQUESTS | parallel -j $CONCURRENCY test_request {} |
| | else |
| | |
| | for i in $(seq 1 $TOTAL_REQUESTS); do |
| | test_request $i & |
| | |
| | |
| | if (( i % CONCURRENCY == 0 )); then |
| | wait |
| | fi |
| | done |
| | wait |
| | fi |
| |
|
| | END_TIME=$(date +%s.%N) |
| | TOTAL_TIME=$(echo "$END_TIME - $START_TIME" | bc) |
| |
|
| | echo -e "\n" |
| |
|
| | |
| | echo -e "${BLUE}โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ${NC}" |
| | echo -e "${BLUE}๐ ๆต่ฏ็ปๆ็ป่ฎก${NC}" |
| | echo -e "${BLUE}โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ${NC}" |
| |
|
| | |
| | SUCCESS_COUNT=$(awk -F',' '$2 == 200 {count++} END {print count+0}' "$TMP_DIR/results.csv") |
| | ERROR_COUNT=$((TOTAL_REQUESTS - SUCCESS_COUNT)) |
| |
|
| | echo -e " ๆต่ฏๆถ้ด: ${TOTAL_TIME}s" |
| | echo -e " ๆป่ฏทๆฑๆฐ: ${TOTAL_REQUESTS}" |
| | echo -e " ๅนถๅๆฐ: ${CONCURRENCY}" |
| | echo "" |
| | echo -e " ๆๅ่ฏทๆฑ: ${GREEN}${SUCCESS_COUNT}${NC} ($(echo "scale=1; $SUCCESS_COUNT * 100 / $TOTAL_REQUESTS" | bc)%)" |
| | echo -e " ๅคฑ่ดฅ่ฏทๆฑ: ${RED}${ERROR_COUNT}${NC} ($(echo "scale=1; $ERROR_COUNT * 100 / $TOTAL_REQUESTS" | bc)%)" |
| | echo "" |
| |
|
| | |
| | THROUGHPUT=$(echo "scale=2; $TOTAL_REQUESTS / $TOTAL_TIME" | bc) |
| | echo -e " ๅๅ้: ${GREEN}${THROUGHPUT}${NC} req/s" |
| | echo "" |
| |
|
| | |
| | if [ $SUCCESS_COUNT -gt 0 ]; then |
| | echo -e " ๅปถ่ฟ็ป่ฎก:" |
| | |
| | |
| | awk -F',' '$2 == 200 {print $3}' "$TMP_DIR/results.csv" | sort -n > "$TMP_DIR/latencies.txt" |
| | |
| | MIN=$(head -n 1 "$TMP_DIR/latencies.txt" | awk '{printf "%.0f", $1*1000}') |
| | MAX=$(tail -n 1 "$TMP_DIR/latencies.txt" | awk '{printf "%.0f", $1*1000}') |
| | AVG=$(awk '{sum+=$1; count++} END {printf "%.0f", sum/count*1000}' "$TMP_DIR/latencies.txt") |
| | |
| | |
| | P50_LINE=$((SUCCESS_COUNT / 2)) |
| | P50=$(sed -n "${P50_LINE}p" "$TMP_DIR/latencies.txt" | awk '{printf "%.0f", $1*1000}') |
| | |
| | |
| | P95_LINE=$(echo "scale=0; $SUCCESS_COUNT * 0.95 / 1" | bc) |
| | P95=$(sed -n "${P95_LINE}p" "$TMP_DIR/latencies.txt" | awk '{printf "%.0f", $1*1000}') |
| | |
| | |
| | P99_LINE=$(echo "scale=0; $SUCCESS_COUNT * 0.99 / 1" | bc) |
| | P99=$(sed -n "${P99_LINE}p" "$TMP_DIR/latencies.txt" | awk '{printf "%.0f", $1*1000}') |
| | |
| | echo -e " ๆๅฐ: ${MIN}ms" |
| | echo -e " ๅนณๅ: ${AVG}ms" |
| | echo -e " ๆๅคง: ${MAX}ms" |
| | echo -e " P50: ${P50}ms" |
| | echo -e " P95: ${P95}ms" |
| | echo -e " P99: ${P99}ms" |
| | fi |
| |
|
| | echo -e "${BLUE}โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ${NC}" |
| |
|
| | |
| | echo -e "${YELLOW}๐ฏ ๆง่ฝ่ฏ็บง:${NC}" |
| |
|
| | if (( $(echo "$THROUGHPUT >= 100" | bc -l) )); then |
| | RATING="โญโญโญโญโญ ไผ็ง" |
| | elif (( $(echo "$THROUGHPUT >= 60" | bc -l) )); then |
| | RATING="โญโญโญโญ ่ฏๅฅฝ" |
| | elif (( $(echo "$THROUGHPUT >= 30" | bc -l) )); then |
| | RATING="โญโญโญ ไธญ็ญ" |
| | elif (( $(echo "$THROUGHPUT >= 10" | bc -l) )); then |
| | RATING="โญโญ ่พไฝ" |
| | else |
| | RATING="โญ ้ไผๅ" |
| | fi |
| |
|
| | echo -e " ๅๅ้ (${THROUGHPUT} req/s): ${RATING}" |
| |
|
| | echo "" |
| | echo -e "${GREEN}โ
ๆต่ฏๅฎๆ๏ผ${NC}" |
| |
|