#!/bin/sh
# shellcheck disable=SC1091
#执行脚本后,就可以调用脚本中定义的函数
. ../../lib/sh-test-lib
#定义常量,这里的常量都是用双引号。
OUTPUT="$(pwd)/output"
RESULT_FILE="${OUTPUT}/result.txt"
export RESULT_FILE
# Set default values.
TESTS="stress_ng stress_oom stress_network"
#定义一个常数
DURATION=$((60 * 60 * 6))
INTERFACE="eth0"
# An valid link should be specified. Here is an example.
LINK="http://192.168.3.1/testdata/stress-network.img"
MD5="e5c834fbdaa6bfd8eac5eb9404eefdd4"
NPROC=$(nproc)
#应以一个usage函数说明调用这个脚本个个参数的作用
usage()
{
echo "Usage: $0 [-h] [-t tests] [-d duration] [-i interface] [-l link] [-m md5]"
echo
echo "Options"
echo " -h, --help Print this help message"
echo " -t, --test Run only specified test from the following:"
echo " stress_ng"
echo " stress_oom"
echo " stress_network"
echo " -d, --duration Set test duration in seconds for each stress test"
echo " -i, --interface Run network stress on the specified interface."
echo " -l, --link Specify file link for download test."
echo " -m, --md5 Set md5 value of the file used for download test."
echo
echo "Examples"
echo " Run all stress tests with defualt settings:"
echo " $0"
echo " Set test duration for each test to 1 hour:"
echo " $0 -d 3600"
echo " Run network stress test on eth0:"
echo " $0 -t stress_network -i eth0"
echo " Run stress_ng and stress_oom:"
echo " $0 -t 'stress_ng stress_oom'"
echo
}
# Parse command line arguments.
#下面这个case中的参数可以同时指定,这里用while循环分别parse.
while [ $# -gt 0 ]
do
case $1 in
-t|--test)
TESTS="$2"
;;
-d|--DURATION)
DURATION="$2"
;;
-i|--INTERFACE)
INTERFACE="$2"
;;
-l|--LINK)
LINK="$2"
;;
-m|--MD5)
MD5=$2
;;
-h|--help)
usage
exit 1
;;
*)
echo "Unknown option $*"
usage
exit 1
;;
esac
shift 2
done
stress_ng()
{
workloads="cpu io fork switch vm pipe yield hdd cache sock fallocate flock affinity timer dentry urandom sem open sigq poll"
#通过wc -w 统计有多少个单词
workload_number=$(echo "$workloads" | wc -w)
sub_duration=$(( DURATION / workload_number ))
echo "CPU(s): $NPROC"
echo "Workloads to run: $workloads"
echo "Total stress_ng test duration: $DURATION seconds"
echo "Test duration for each workload: $sub_duration seconds"
count=1
for i in $workloads
do
echo
echo "[$count/$workload_number] Running $i workload..."
#如果测试的vm的话,stress-ng这个函数的参数有所不同
if [ "$i" = "vm" ]; then
# mmap 64M per vm process to avoid OOM, the default is 256M.
stress-ng --"$i" "$NPROC" --vm-bytes 64m --timeout "$sub_duration" --metrics-brief --verbose
else
stress-ng --"$i" "$NPROC" --timeout "$sub_duration" --metrics-brief --verbose
fi
check_return stress-ng-"$i"
#count子加1
count=$(( count + 1 ))
done
}
#定义测试oom的函数
stress_oom()
{
#通过free命令输出的计算mem和swap
mem=$(free | grep Mem | awk '{print $2}')
swap=$(free | grep Swap | awk '{print $2}')
total_mem=$(( mem + swap ))
vm_bytes=$(( total_mem / NPROC ))
echo
echo "CPU(s): $NPROC"
echo "Total Memory: $total_mem"
echo "Stress OOM test duration: $DURATION seconds"
echo "About to run $NPROC stress-ng-vm instances"
# Clear dmesg and save new output continuously to a log file.
#清掉dmesg的输出,并把输出重定向到一个文件中
dmesg --clear
dmesg --follow > "${OUTPUT}/stress_oom_kern.log" 2>&1 & # -w, --follow wait for new messages
#这里$!表示最后运行的后台,这里就上面重定向log的process
kernel_log=$!
# Disable oom-killer on the log collecting process.
# shellcheck disable=SC2039
#修改oom的值
echo -17 > "/proc/${kernel_log}/oom_score_adj"
# Disables timeout message.
#禁止hung_task_timeout_secs
echo 0 > /proc/sys/kernel/hung_task_timeout_secs
# Run stress-ng-vm test to trigger oom-killer.
# In stress-vm.c file, NO_MEM_RETRIES_MAX has been increased to 1000000000 for OOM stress test.
echo "mmap ${vm_bytes}KB per vm process to occupy all memory to trigger oom-killer."
#开始测试
stress-ng --vm "$NPROC" --vm-bytes "${vm_bytes}k" --timeout "$DURATION" --metrics-brief --verbose
# Check if oom-killer triggered.
#杀掉之前重定向log的进程以触发oom
kill $kernel_log
oom_number=$(grep -c "Out of memory: Kill process" "$OUTPUT/stress_oom_kern.log")
#通过查找输出文件中是否有"Out of memory: Kill process"的字符串还确定是否发生oom
#-gt 表示不等于o的话,说明查找到了.
if [ "$oom_number" -gt 0 ]; then
echo "oom-killer activated $oom_number times within $DURATION seconds"
#输出log,表示oom成功
report_pass "stress-oom-test"
else
echo "Failed to active oom-killer."
report_fail "stress-oom-test"
fi
}
stress_network()
{
echo "Stress network test duration: $DURATION"
echo "Test interface: $INTERFACE"
echo "File link: $LINK"
echo "md5: $MD5"
# Check if network set on the interface.
#执行ip route show default 后得到ip地址
gateway=$(ip route show default | grep -m 1 default | awk '{print $3}')
#指定gateway,并且ping 10次.
if ! ping -c 10 -I "$INTERFACE" "$gateway"; then
echo "Please check network connection and rerun this script"
exit 1
fi
# Check if $LINK set properly.
#curl -O --remote-name Write output to a file named as the remote file
if curl -O "$LINK"; then
echo "LINK is accessable."
#测试成功后,删除这个文件
rm -f stress-network.img
else
echo "Please download stress-network.img with the following link:"
echo "http://testdata.validation.linaro.org/stress/stress-network.img"
echo "And place the file on local http server, then modify 'LINK' pramater:"
echo " with '-l $LINK' when using script directly."
echo " by defining LINK paramter in definition file or test plan."
exit 1
fi
# Run 'stress-ng hdd' stress in the background.
echo "About to run 'stress-ng --hdd 1' in background"
#在后台进程测试hdd。
stress-ng --hdd 1 > /dev/null 2>&1 &
#保存执行的结果到stress_ng_hdd
stress_ng_hdd=$!
#睡眠10s
sleep 10
#测试结束的时间
end=$(( $(date +%s) + DURATION ))
iteration=0
#现在的时间小于结束的时间,则执行while循环
while [ "$(date +%s)" -lt "$end" ]
do
echo
echo "Running stress_network iteration $iteration"
#如果没有找到stress-ng-hdd 这个进程,则重新开始这个进程的执行,pgrep 用于查找进程.
if ! pgrep -l "stress-ng-hdd"; then
echo "'stress-ng --hdd 1' is dead, restarting..."
stress-ng --hdd 1 > /dev/null 2>&1 &
stress_ng_hdd=$!
else
echo "'stress-ng --hdd 1' is running in background"
fi
# Network enable/disable test.
#down掉网口
ip link set "$INTERFACE" down
sleep 15
#查询网口是否已经给down了
ip link show dev "$INTERFACE" | grep "state DOWN"
check_return "network-disable-$iteration"
#up 网口
ip link set "$INTERFACE" up
sleep 15
ip link show dev "$INTERFACE" | grep "state UP"
check_return "network-enable-$iteration"
# Check if IP obtained.
#检查是否可以获取ip 地址
dhclient "$INTERFACE" > /dev/null 2>&1 || true
ip=$(ip addr show "$INTERFACE" | grep -w inet | awk '{print $2}' | awk -F'/' '{print $1}')
#test -n 用于检查后面的字符串是否为null.
test -n "$ip"
#调用函数
check_return "network-ip-check-$iteration"
# File download test.
#test -e 表示检查文件是否存在,如果存在的话,则删除
test -e stress-network.img && rm -rf stress-network.img
#指定ip地址下载
curl -O --interface "$ip" "$LINK"
check_return "file-download-$iteration"
#计算md5的值
local_md5=$(md5sum stress-network.img | awk '{print $1}')
#判断这两个md5值是否相等
test "$local_md5" = "$MD5"
check_return "file-md5-check-$iteration"
#删除这个文件
rm -rf stress-network.img
#计数变量自加1
iteration=$(( iteration + 1 ))
done
#结束掉这个进程
kill "$stress_ng_hdd"
}
## Setup environment and run tests.
#检查是否root 用户,如果不是root用户输出错误日志
! check_root && error_msg "You need to be root to run this test!"
#如果已经存在目录的话,则把这个命令移动到李哥新的命令中,如果不存在就新建目录
[ -d "${OUTPUT}" ] && mv "${OUTPUT}" "${OUTPUT}_$(date +%Y%m%d%H%M%S)"
mkdir -p "${OUTPUT}"
#如果没有安装curl的话,按照那个curl
which curl || install_deps "curl"
#如果不存在stress-ng的话
if ! which stress-ng; then
echo "stress-ng not found, installing it ..."
#执行dist_name函数输出发行版的名字
dist_name
# shellcheck disable=SC2154
case "${dist}" in
#如果发行版是Ubuntu 或者debian的话,则看庄下面这些包
debian|ubuntu)
install_deps "git build-essential libaio-dev libapparmor-dev libattr1-dev libbsd-dev libcap-dev libgcrypt11-dev libkeyutils-dev libsctp-dev zlib1g-dev"
#clone git仓库
git clone git://kernel.ubuntu.com/cking/stress-ng.git
(
cd stress-ng || exit
# Use a known good release.
#切换到具体的岑智
git checkout V0.05.21 -b V0.05.21
# Set NO_MEM_RETRIES_MAX to 1000000000 for long time stress OOM test.
#在stress-vm.c 中通过sed -i 插入两个宏定义
sed -i "s/#define NO_MEM_RETRIES_MAX$(printf '\t')(100)/#define NO_MEM_RETRIES_MAX$(printf '\t')(1000000000)/" stress-vm.c
#build 并安装
make && make install
)
;;
*)
warn_msg "Unsupported distro: ${dist}! Package installation skipped."
;;
esac
fi
# Run tests.
for i in $TESTS
do
#分别执行TEST中定义的三个函数.
"$i" 2>&1 | tee "${OUTPUT}/${i}.log"
done
test-definitions/blob/master/auto-test/24h-stress-test/24h-stress-test.sh
最新推荐文章于 2022-10-13 12:32:23 发布