blob: 9a0e5bd03f237167f3dafd07e50d882c51ef6ca6 [file] [log] [blame] [edit]
#!/bin/sh
#
# Run dd write/read speed test.
#
# Copyright (C) 2010 - 2016, Linaro Limited.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# Author: Chase Qi <chase.qi@linaro.org>
. ./common/scripts/include/sh-test-lib
LANG=C
export LANG
WD="$(pwd)"
RESULT_FILE="${WD}/result.txt"
ITERATION="5"
UNITS="MB/s"
usage() {
echo "Usage: $0 [-p <partition>] [-t <type>] [-i <iteration>]" 1>&2
exit 1
}
while getopts "p:t:i:" o; do
case "$o" in
# The current working directory will be used by default.
# Use '-p' specify partition that used for dd test.
p) PARTITION="${OPTARG}" ;;
# CAUTION: if FS_TYPE not equal to the existing fs type of the partition
# specified with '-p', the partition will be formatted.
t) FS_TYPE="${OPTARG}" ;;
# You may need to run dd test 4-5 times for an accurate evaluation.
i) ITERATION="${OPTARG}" ;;
*) usage ;;
esac
done
prepare_partition() {
if [ -n "${PARTITION}" ]; then
device_attribute="$(blkid | grep "${PARTITION}")"
[ -z "${device_attribute}" ] && error_msg "${PARTITION} NOT found"
fs_type=$(echo "${device_attribute}" \
| grep "TYPE=" \
| awk '{print $3}' \
| awk -F '"' '{print $2}')
# Try to format the partition if it is unformatted or not the same as
# the filesystem type specified with parameter '-t'.
if [ -n "${FS_TYPE}" ]; then
if [ "${FS_TYPE}" != "${fs_type}" ]; then
umount "${PARTITION}" > /dev/null 2>&1
info_msg "Formatting ${PARTITION} to ${FS_TYPE}..."
if [ "${FS_TYPE}" = "fat32" ]; then
echo "y" | mkfs -t vfat -F 32 "${PARTITION}"
else
echo "y" | mkfs -t "${FS_TYPE}" "${PARTITION}"
fi
if [ $? -ne 0 ]; then
error_msg "unable to format ${PARTITION}"
else
info_msg "${PARTITION} formatted to ${FS_TYPE}"
fi
fi
fi
# Mount the partition and enter its mount point.
mount_point="$(df |grep "${PARTITION}" | awk '{print $NF}')"
if [ -z "${mount_point}" ]; then
mount_point="/mnt"
mount "${PARTITION}" "${mount_point}"
if [ $? -ne 0 ]; then
error_msg "Unable to mount ${PARTITIOIN}"
else
info_msg "${PARTITION} mounted to ${mount_point}"
fi
fi
cd "${mount_point}"
fi
}
dd_write() {
echo
echo "--- dd write speed test ---"
rm -f dd-write-output.txt
for i in $(seq "${ITERATION}"); do
echo "Running iteration ${i}..."
rm -f dd.img
echo 3 > /proc/sys/vm/drop_caches
dd if=/dev/zero of=dd.img bs=1048576 count=1024 conv=fsync 2>&1 \
| tee -a "${WD}"/dd-write-output.txt
done
}
dd_read() {
echo
echo "--- dd read speed test ---"
rm -f dd-read-output.txt
for i in $(seq "${ITERATION}"); do
echo "Running iteration ${i}..."
echo 3 > /proc/sys/vm/drop_caches
dd if=dd.img of=/dev/null bs=1048576 count=1024 2>&1 \
| tee -a "${WD}"/dd-read-output.txt
done
rm -f dd.img
}
parse_output() {
local test="$1"
local test_case_id="${test}"
[ -n "${FS_TYPE}" ] && test_case_id="${FS_TYPE}-${test_case_id}"
if [ -n "${PARTITION}" ]; then
partition_no="$(echo "${PARTITION}" |awk -F '/' '{print $NF}')"
test_case_id="${partition_no}-${test_case_id}"
fi
# Parse raw output and add results to result.txt.
itr=1
while read line; do
if echo "${line}" | egrep -q "(M|G)B/s"; then
measurement="$(echo "${line}" | awk '{print $(NF-1)}')"
units="$(echo "${line}" | awk '{print $NF}')"
if [ "${units}" = "GB/s" ]; then
measurement=$(( measurement * 1024 ))
elif [ "${units}" = "KB/s" ]; then
measurement=$(( measurement / 1024 ))
fi
add_metric "${test_case_id}-itr${itr}" "${measurement}" "${UNITS}"
itr=$(( itr + 1 ))
fi
done < "${WD}/${test}"-output.txt
# For mutiple times dd test, calculate the mean, min and max values.
# Save them to result.txt.
if [ "${ITERATION}" -gt 1 ]; then
eval "$(grep "${test}" "${WD}"/result.txt \
| awk '{
if(min=="") {min=max=$3};
if($3>max) {max=$3};
if($3< min) {min=$3};
total+=$3; count+=1;
}
END {
print "mean="total/count, "min="min, "max="max;
}')"
add_metric "${test_case_id}-mean" "${mean}" "${UNITS}"
add_metric "${test_case_id}-min" "${min}" "${UNITS}"
add_metric "${test_case_id}-max" "${max}" "${UNITS}"
fi
}
# Test run.
! check_root && error_msg "This script must be run as root"
pkgs="e2fsprogs dosfstools"
install_deps "${pkgs}"
[ -f "${RESULT_FILE}" ] && \
mv "${RESULT_FILE}" "${RESULT_FILE}_$(date +%Y%m%d%H%M%S)"
echo
info_msg "About to run dd test..."
info_msg "Working directory: ${WD}"
info_msg "Result will be saved to: ${RESULT_FILE}"
prepare_partition
info_msg "dd test directory: $(pwd)"
dd_write
parse_output "dd-write"
dd_read
parse_output "dd-read"