File size: 6,211 Bytes
1a9e2c2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#!/bin/bash

# Grok2API ๅนถๅ‘ๆต‹่ฏ•่„šๆœฌ๏ผˆShell็‰ˆๆœฌ๏ผ‰
# ไฝฟ็”จ curl ๅ’Œ GNU parallel ่ฟ›่กŒๅนถๅ‘ๆต‹่ฏ•

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' # No Color

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}"
}

# ๅฏผๅ‡บๅ‡ฝๆ•ฐไพ› parallel ไฝฟ็”จ
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)

# ไฝฟ็”จ GNU parallel๏ผˆๅฆ‚ๆžœๅฏ็”จ๏ผ‰๏ผŒๅฆๅˆ™ไฝฟ็”จ็ฎ€ๅ•ๅพช็Žฏ
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
    P50_LINE=$((SUCCESS_COUNT / 2))
    P50=$(sed -n "${P50_LINE}p" "$TMP_DIR/latencies.txt" | awk '{printf "%.0f", $1*1000}')
    
    # P95
    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
    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}"