This commit is contained in:
12600k-rog-d4
2026-08-24 00:35:30 +08:00
parent 32b308bc08
commit b673ed62f9
24 changed files with 483 additions and 393 deletions

View File

@@ -0,0 +1,59 @@
echo "===TEST:cpu==="
# 读取温度sensors 不可用时输出空)
read_temp() {
sensors 2>/dev/null | grep -oP '\+?\d+(\.\d+)?(?=°C)' | head -1
}
# 后台采样 CPU 使用率 + 温度
SAMPLE_LOG=/tmp/auto-check-cpu-sample.log
: > "$SAMPLE_LOG"
(
while true; do
TS=$(date +%H:%M:%S)
CPU=$(top -bn1 2>/dev/null | grep "Cpu(s)" | sed -n 's/.*,\s*\([0-9.]*\)%*\s*id.*/\1/p' | awk '{printf "%.1f", 100-$1}' 2>/dev/null)
TEMP=$(read_temp)
echo "${TS},${CPU},${TEMP}" >> "$SAMPLE_LOG"
sleep "${AUTOCHECK_SAMPLE_INTERVAL:-2}"
done
) &
SAMPLE_PID=$!
START_TIME=$(date +%s%N)
set +e
OUTPUT=$(stress-ng --cpu "${AUTOCHECK_THREADS:-4}" --cpu-method all --timeout "${AUTOCHECK_DURATION:-30}s" --temp-path /tmp --metrics-brief 2>&1)
EXIT_CODE=$?
set -e
END_TIME=$(date +%s%N)
kill $SAMPLE_PID 2>/dev/null || true
wait $SAMPLE_PID 2>/dev/null || true
DURATION_MS=$(( (END_TIME - START_TIME) / 1000000 ))
if [ "$EXIT_CODE" -eq 0 ]; then echo 'status:pass'; else echo 'status:fail'; fi
echo "duration:${DURATION_MS}ms"
# 跑分:各 stressor 的 bogo ops/s 之和
SCORE=$(echo "$OUTPUT" | awk '
/^stress-ng:/ && ($4=="cpu" || $4=="vm" || $4=="iomix" || $4=="memrate") {
v=$(NF-1)+0; if (v>0) s+=v
}
END { printf "%.1f", s+0 }')
echo "score:${SCORE}"
# 关键指标
AVG_CPU=$(awk -F',' '$2!="" {s+=$2; n++} END{printf "%.1f", (n?s/n:0)}' "$SAMPLE_LOG")
echo "metric:avg_cpu=${AVG_CPU}"
MAX_TEMP=$(awk -F',' '$3!="" && $3+0>m {m=$3} END{printf "%.1f", m+0}' "$SAMPLE_LOG")
HAS_TEMP=$(awk -F',' '$3!="" && $3+0>0{f=1} END{print f+0}' "$SAMPLE_LOG")
if [ "$HAS_TEMP" = "1" ]; then echo "metric:max_temp=${MAX_TEMP}"; fi
echo "output:${OUTPUT}"
# 采样数据(首行表头)
echo "===SAMPLES==="
echo "time,cpu,temp"
cat "$SAMPLE_LOG"
echo "===END_SAMPLES==="
echo ''

View File

@@ -0,0 +1,77 @@
echo "===TEST:disk==="
TEST_DIR=${AUTOCHECK_DISK_DIR:-/tmp/auto-check-disk}
mkdir -p "$TEST_DIR"
START_TIME=$(date +%s%N)
if command -v fio >/dev/null 2>&1; then
FIO_IMG="$TEST_DIR/fio.img"
BW_LOG="$TEST_DIR/ac-bw"
IOPS_LOG="$TEST_DIR/ac-iops"
rm -f "$BW_LOG"*.log "$IOPS_LOG"*.log "$FIO_IMG"
set +e
OUTPUT=$(fio --name=autocheck --rw=randrw --rwmixread=70 --bs=4k \
--size="${AUTOCHECK_DISK_SIZE_MB:-512}M" --iodepth=32 --numjobs=1 \
--runtime="${AUTOCHECK_DURATION:-30}" --time_based --direct=1 \
--group_reporting --output-format=normal \
--write_bw_log="$BW_LOG" --write_iops_log="$IOPS_LOG" \
--log_avg_msec=1000 --filename="$FIO_IMG" 2>&1)
EXIT_CODE=$?
set -e
READ_LINE=$(echo "$OUTPUT" | grep -E '^[[:space:]]*read:' | head -1)
WRITE_LINE=$(echo "$OUTPUT" | grep -E '^[[:space:]]*write:' | head -1)
READ_IOPS=$(echo "$READ_LINE" | grep -oP 'IOPS=\K[0-9.]+' | head -1)
READ_BW=$(echo "$READ_LINE" | grep -oP 'BW=\K[0-9.]+' | head -1)
WRITE_IOPS=$(echo "$WRITE_LINE" | grep -oP 'IOPS=\K[0-9.]+' | head -1)
WRITE_BW=$(echo "$WRITE_LINE" | grep -oP 'BW=\K[0-9.]+' | head -1)
SCORE=$(awk -v r="${READ_BW:-0}" -v w="${WRITE_BW:-0}" 'BEGIN{printf "%.1f", r+w}')
IOPS_TOTAL=$(awk -v r="${READ_IOPS:-0}" -v w="${WRITE_IOPS:-0}" 'BEGIN{printf "%.1f", r+w}')
END_TIME=$(date +%s%N)
DURATION_MS=$(( (END_TIME - START_TIME) / 1000000 ))
if [ "$EXIT_CODE" -eq 0 ]; then echo 'status:pass'; else echo 'status:fail'; fi
echo "duration:${DURATION_MS}ms"
echo "score:${SCORE}"
echo "metric:iops_total=${IOPS_TOTAL}"
[ -n "$READ_IOPS" ] && echo "metric:read_iops=${READ_IOPS}"
[ -n "$WRITE_IOPS" ] && echo "metric:write_iops=${WRITE_IOPS}"
[ -n "$READ_BW" ] && echo "metric:read_bw=${READ_BW}"
[ -n "$WRITE_BW" ] && echo "metric:write_bw=${WRITE_BW}"
[ -n "$READ_BW" ] && [ -n "$WRITE_BW" ] && echo "metric:bw_total=${SCORE}"
echo "output:${OUTPUT}"
# IOPS / 吞吐 曲线(按秒聚合)
BW_LOG_FILE=$(ls "$BW_LOG"*.log 2>/dev/null | head -1)
IOPS_LOG_FILE=$(ls "$IOPS_LOG"*.log 2>/dev/null | head -1)
echo "===SAMPLES==="
echo "time,iops_total,bw_total"
if [ -n "$BW_LOG_FILE" ] && [ -n "$IOPS_LOG_FILE" ]; then
awk -F',' '
FNR==NR { t=int($1/1000); if($3==0) ri[t]=$2; else wi[t]=$2; seen[t]=1; next }
{ t=int($1/1000); if($3==0) rb[t]=$2; else wb[t]=$2; seen[t]=1 }
END { for (k in seen) printf "%d,%.0f,%.1f\n", k, ri[k]+wi[k], (rb[k]+wb[k])/1024 }
' "$IOPS_LOG_FILE" "$BW_LOG_FILE" | sort -n
fi
echo "===END_SAMPLES==="
rm -f "$FIO_IMG" "$BW_LOG"*.log "$IOPS_LOG"*.log
else
# 无 fio降级为 stress-ng 磁盘 IO 压测(无 IOPS/吞吐曲线)
set +e
OUTPUT=$(stress-ng --iomix "${AUTOCHECK_THREADS:-2}" --iomix-bytes "${AUTOCHECK_DISK_MB:-512}M" --timeout "${AUTOCHECK_DURATION:-30}s" --temp-path /tmp --metrics-brief 2>&1)
EXIT_CODE=$?
set -e
SCORE=$(echo "$OUTPUT" | awk '/^stress-ng:/ && $4=="iomix" { v=$(NF-1)+0; if(v>0) s+=v } END{printf "%.1f", s+0}')
END_TIME=$(date +%s%N)
DURATION_MS=$(( (END_TIME - START_TIME) / 1000000 ))
if [ "$EXIT_CODE" -eq 0 ]; then echo 'status:pass'; else echo 'status:fail'; fi
echo "duration:${DURATION_MS}ms"
echo "score:${SCORE}"
echo "output:${OUTPUT}"
fi
echo ''

View File

@@ -0,0 +1,11 @@
echo '===MONITOR:dmesg==='
DMESG_ERR=$(dmesg --level=err,crit,alert,emerg 2>/dev/null | tail -30 || true)
if [ -n "$DMESG_ERR" ]; then
echo 'status:fail'
echo "output:${DMESG_ERR}"
else
echo 'status:pass'
echo 'output:无硬件相关内核报错'
fi
echo ''
echo '===END==='

View File

@@ -0,0 +1,71 @@
echo "===TEST:full==="
# 读取温度sensors 不可用时输出空)
read_temp() {
sensors 2>/dev/null | grep -oP '\+?\d+(\.\d+)?(?=°C)' | head -1
}
# 后台采样 CPU + 内存 + 温度
SAMPLE_LOG=/tmp/auto-check-full-sample.log
: > "$SAMPLE_LOG"
(
while true; do
TS=$(date +%H:%M:%S)
CPU=$(top -bn1 2>/dev/null | grep "Cpu(s)" | sed -n 's/.*,\s*\([0-9.]*\)%*\s*id.*/\1/p' | awk '{printf "%.1f", 100-$1}' 2>/dev/null)
MEM_TOTAL=$(awk '/^MemTotal:/{print $2}' /proc/meminfo)
MEM_AVAIL=$(awk '/^MemAvailable:/{print $2}' /proc/meminfo)
if [ -z "$MEM_AVAIL" ] || [ "$MEM_AVAIL" = "0" ]; then
MEM_AVAIL=$(awk '/^MemFree:/{print $2}' /proc/meminfo)
fi
MEM_PCT=$(awk -v t="$MEM_TOTAL" -v a="$MEM_AVAIL" 'BEGIN{if(t>0) printf "%.1f", (t-a)/t*100}')
TEMP=$(read_temp)
echo "${TS},${CPU},${MEM_PCT},${TEMP}" >> "$SAMPLE_LOG"
sleep "${AUTOCHECK_SAMPLE_INTERVAL:-2}"
done
) &
SAMPLE_PID=$!
START_TIME=$(date +%s%N)
set +e
OUTPUT=$(stress-ng \
--cpu "${AUTOCHECK_THREADS:-4}" --cpu-method all \
--vm "${AUTOCHECK_THREADS:-4}" --vm-bytes "${AUTOCHECK_MEM_MB:-256}M" --vm-method all \
--iomix 2 --iomix-bytes "${AUTOCHECK_DISK_SIZE_MB:-512}M" \
--timeout "${AUTOCHECK_DURATION:-30}s" --temp-path /tmp --metrics-brief 2>&1)
EXIT_CODE=$?
set -e
END_TIME=$(date +%s%N)
kill $SAMPLE_PID 2>/dev/null || true
wait $SAMPLE_PID 2>/dev/null || true
DURATION_MS=$(( (END_TIME - START_TIME) / 1000000 ))
if [ "$EXIT_CODE" -eq 0 ]; then echo 'status:pass'; else echo 'status:fail'; fi
echo "duration:${DURATION_MS}ms"
# 跑分:各 stressor 的 bogo ops/s 之和
SCORE=$(echo "$OUTPUT" | awk '
/^stress-ng:/ && ($4=="cpu" || $4=="vm" || $4=="iomix" || $4=="memrate") {
v=$(NF-1)+0; if (v>0) s+=v
}
END { printf "%.1f", s+0 }')
echo "score:${SCORE}"
# 关键指标
AVG_CPU=$(awk -F',' '$2!="" {s+=$2; n++} END{printf "%.1f", (n?s/n:0)}' "$SAMPLE_LOG")
echo "metric:avg_cpu=${AVG_CPU}"
MAX_MEM=$(awk -F',' '$3!="" && $3+0>m {m=$3} END{printf "%.1f", m+0}' "$SAMPLE_LOG")
echo "metric:mem_used_pct=${MAX_MEM}"
MAX_TEMP=$(awk -F',' '$4!="" && $4+0>m {m=$4} END{printf "%.1f", m+0}' "$SAMPLE_LOG")
HAS_TEMP=$(awk -F',' '$4!="" && $4+0>0{f=1} END{print f+0}' "$SAMPLE_LOG")
if [ "$HAS_TEMP" = "1" ]; then echo "metric:max_temp=${MAX_TEMP}"; fi
echo "output:${OUTPUT}"
# 采样数据(首行表头)
echo "===SAMPLES==="
echo "time,cpu,mem_used_pct,temp"
cat "$SAMPLE_LOG"
echo "===END_SAMPLES==="
echo ''

View File

@@ -0,0 +1,19 @@
echo "===TEST:memnative==="
MEM_SIZE_MB=${AUTOCHECK_MEM_SIZE_MB:-0}
if [ "$MEM_SIZE_MB" -gt 0 ]; then
MEM_ARG="-M ${MEM_SIZE_MB}"
else
M=$(free -m 2>/dev/null | awk '/Mem:/{print int($7*0.6)}' || echo 512)
MEM_ARG="-M ${M}"
fi
START_TIME=$(date +%s%N)
set +e
OUTPUT=$(stressapptest -s "${AUTOCHECK_DURATION:-30}" ${MEM_ARG} -f 0 -v 2>&1)
EXIT_CODE=$?
set -e
END_TIME=$(date +%s%N)
DURATION_MS=$(( (END_TIME - START_TIME) / 1000000 ))
if [ "$EXIT_CODE" -eq 0 ]; then echo 'status:pass'; else echo 'status:fail'; fi
echo "duration:${DURATION_MS}ms"
echo "output:${OUTPUT}"
echo ''

View File

@@ -0,0 +1,64 @@
echo "===TEST:memory==="
# 读取温度sensors 不可用时输出空)
read_temp() {
sensors 2>/dev/null | grep -oP '\+?\d+(\.\d+)?(?=°C)' | head -1
}
# 后台采样内存使用率 + 温度
SAMPLE_LOG=/tmp/auto-check-memory-sample.log
: > "$SAMPLE_LOG"
(
while true; do
TS=$(date +%H:%M:%S)
MEM_TOTAL=$(awk '/^MemTotal:/{print $2}' /proc/meminfo)
MEM_AVAIL=$(awk '/^MemAvailable:/{print $2}' /proc/meminfo)
if [ -z "$MEM_AVAIL" ] || [ "$MEM_AVAIL" = "0" ]; then
MEM_AVAIL=$(awk '/^MemFree:/{print $2}' /proc/meminfo)
fi
MEM_PCT=$(awk -v t="$MEM_TOTAL" -v a="$MEM_AVAIL" 'BEGIN{if(t>0) printf "%.1f", (t-a)/t*100}')
TEMP=$(read_temp)
echo "${TS},${MEM_PCT},${TEMP}" >> "$SAMPLE_LOG"
sleep "${AUTOCHECK_SAMPLE_INTERVAL:-2}"
done
) &
SAMPLE_PID=$!
START_TIME=$(date +%s%N)
set +e
OUTPUT=$(stress-ng --vm "${AUTOCHECK_THREADS:-4}" --vm-bytes "${AUTOCHECK_MEM_MB:-256}M" --vm-method all --timeout "${AUTOCHECK_DURATION:-30}s" --temp-path /tmp --metrics-brief 2>&1)
EXIT_CODE=$?
set -e
END_TIME=$(date +%s%N)
kill $SAMPLE_PID 2>/dev/null || true
wait $SAMPLE_PID 2>/dev/null || true
DURATION_MS=$(( (END_TIME - START_TIME) / 1000000 ))
if [ "$EXIT_CODE" -eq 0 ]; then echo 'status:pass'; else echo 'status:fail'; fi
echo "duration:${DURATION_MS}ms"
# 跑分:各 stressor 的 bogo ops/s 之和
SCORE=$(echo "$OUTPUT" | awk '
/^stress-ng:/ && ($4=="cpu" || $4=="vm" || $4=="iomix" || $4=="memrate") {
v=$(NF-1)+0; if (v>0) s+=v
}
END { printf "%.1f", s+0 }')
echo "score:${SCORE}"
# 关键指标
MAX_MEM=$(awk -F',' '$2!="" && $2+0>m {m=$2} END{printf "%.1f", m+0}' "$SAMPLE_LOG")
echo "metric:mem_used_pct=${MAX_MEM}"
MAX_TEMP=$(awk -F',' '$3!="" && $3+0>m {m=$3} END{printf "%.1f", m+0}' "$SAMPLE_LOG")
HAS_TEMP=$(awk -F',' '$3!="" && $3+0>0{f=1} END{print f+0}' "$SAMPLE_LOG")
if [ "$HAS_TEMP" = "1" ]; then echo "metric:max_temp=${MAX_TEMP}"; fi
echo "output:${OUTPUT}"
# 采样数据(首行表头)
echo "===SAMPLES==="
echo "time,mem_used_pct,temp"
cat "$SAMPLE_LOG"
echo "===END_SAMPLES==="
echo ''

View File

@@ -0,0 +1,48 @@
#!/bin/bash
# 压力测试入口脚本(打包在镜像内)
# auto-check 启动容器时通过环境变量传参,执行完整测试流程:
# 系统信息 → 温度监控启动 → 各项压测(先单项、后综合)→ 温度监控收尾 → 内核日志
set -e
# 默认值docker -e 传入时覆盖)
export AUTOCHECK_TYPES="${AUTOCHECK_TYPES:-cpu,memory}"
export AUTOCHECK_DURATION="${AUTOCHECK_DURATION:-30}"
export AUTOCHECK_THREADS="${AUTOCHECK_THREADS:-4}"
export AUTOCHECK_MEM_SIZE_MB="${AUTOCHECK_MEM_SIZE_MB:-0}"
export AUTOCHECK_DISK_SIZE_MB="${AUTOCHECK_DISK_SIZE_MB:-1024}"
export AUTOCHECK_TEMP_INTERVAL="${AUTOCHECK_TEMP_INTERVAL:-10}"
export AUTOCHECK_SAMPLE_INTERVAL="${AUTOCHECK_SAMPLE_INTERVAL:-2}"
if [ -n "$AUTOCHECK_DISK_DIR" ]; then export AUTOCHECK_DISK_DIR; fi
# 1. 系统信息
source /scripts/sysinfo.sh
# 2. 温度监控(后台周期采样)
source /scripts/temp_start.sh
# 未知类型输出 skip保证报告完整
for T in $(echo "$AUTOCHECK_TYPES" | tr ',' ' '); do
case "$T" in
cpu|memory|disk|memnative|full) ;;
*)
echo "===TEST:$T==="
echo "status:skip"
echo "output:未知测试类型"
echo ""
;;
esac
done
# 3. 按固定顺序执行请求的测试(先单项、综合 full 最后)
REQ_TYPES=",${AUTOCHECK_TYPES// /},"
for TYPE in cpu memory disk memnative full; do
case "$REQ_TYPES" in
*",$TYPE,"*) source "/scripts/$TYPE.sh" ;;
esac
done
# 4. 温度监控收尾
source /scripts/temp_end.sh
# 5. 内核日志 + 结束标记
source /scripts/dmesg.sh

View File

@@ -0,0 +1,8 @@
echo '===SYSTEM_INFO==='
echo "hostname:$(hostname)"
echo "cpu:$(lscpu 2>/dev/null | grep 'Model name' | sed 's/Model name:\s*//' || echo unknown)"
echo "cores:$(nproc 2>/dev/null || echo 0)"
echo "memory:$(free -h 2>/dev/null | awk '/Mem:/{print $2}' || echo unknown)"
echo "kernel:$(uname -r 2>/dev/null || echo unknown)"
echo "disk:$(lsblk -d -o NAME,SIZE 2>/dev/null | head -3 | tr '\n' ' ')"
echo ''

View File

@@ -0,0 +1,15 @@
echo '===MONITOR:temp==='
if [ -f "$TEMP_LOG" ] && [ -s "$TEMP_LOG" ]; then
MAX_T=$(sort -n "$TEMP_LOG" | tail -1)
AVG_T=$(awk '{s+=$1; n++} END{printf "%.1f", (n?s/n:0)}' "$TEMP_LOG")
CNT=$(wc -l < "$TEMP_LOG")
echo 'status:pass'
echo "metric:max_temp=${MAX_T}"
echo "metric:avg_temp=${AVG_T}"
echo "output:采样 ${CNT} 次, 最高 ${MAX_T}°C, 平均 ${AVG_T}°C"
else
echo 'status:skip'
echo 'output:未采集到温度数据'
fi
echo ''
kill $TEMP_PID 2>/dev/null || true

View File

@@ -0,0 +1,8 @@
TEMP_LOG=/tmp/auto-check-temp.log
> "$TEMP_LOG"
(while true; do
T=$(sensors 2>/dev/null | grep -oP '\+?\d+(\.\d+)?(?=°C)' | head -1)
[ -n "$T" ] && echo "$T" >> "$TEMP_LOG"
sleep "${AUTOCHECK_TEMP_INTERVAL:-10}"
done) &
TEMP_PID=$!