diff options
Diffstat (limited to 'common/scripts/dd-speed-test.sh')
-rwxr-xr-x | common/scripts/dd-speed-test.sh | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/common/scripts/dd-speed-test.sh b/common/scripts/dd-speed-test.sh new file mode 100755 index 0000000..9a0e5bd --- /dev/null +++ b/common/scripts/dd-speed-test.sh @@ -0,0 +1,186 @@ +#!/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" |