summaryrefslogtreecommitdiff
path: root/common/scripts/dd-speed-test.sh
diff options
context:
space:
mode:
Diffstat (limited to 'common/scripts/dd-speed-test.sh')
-rwxr-xr-xcommon/scripts/dd-speed-test.sh186
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"