From 3d1bc8474e38b17ae4ee1660c2a2fc0edf023961 Mon Sep 17 00:00:00 2001 From: Chase Qi Date: Fri, 26 Aug 2016 14:47:16 +0800 Subject: v2: linux: add dd write/read speed test - Added Linux dd write/read speed test - Optimized sh-test-lib Change-Id: I3bccfda212535e9a36b8e231b69c0dd2367a88f6 Signed-off-by: Chase Qi --- automated/bin/setenv.sh | 2 +- automated/lib/sh-test-lib | 51 ++++---- automated/linux/dd-wr-speed/dd-wr-speed.sh | 171 +++++++++++++++++++++++++++ automated/linux/dd-wr-speed/dd-wr-speed.yaml | 35 ++++++ plans/linux-example.yaml | 7 ++ 5 files changed, 237 insertions(+), 29 deletions(-) create mode 100755 automated/linux/dd-wr-speed/dd-wr-speed.sh create mode 100644 automated/linux/dd-wr-speed/dd-wr-speed.yaml diff --git a/automated/bin/setenv.sh b/automated/bin/setenv.sh index c0a3f79..1449fc6 100755 --- a/automated/bin/setenv.sh +++ b/automated/bin/setenv.sh @@ -4,7 +4,7 @@ export REPO_PATH="$(pwd)" echo "REPO_PATH: ${REPO_PATH}" if ! [ -d "${REPO_PATH}/automated/bin" ]; then - echo "ERROR: Please execute the below command from test-definitions DIR" + echo "ERROR: Please execute the below command from 'test-definitions' DIR" echo " . ./automated/bin/setenv.sh" exit 1 fi diff --git a/automated/lib/sh-test-lib b/automated/lib/sh-test-lib index 15ef4e0..fca1153 100755 --- a/automated/lib/sh-test-lib +++ b/automated/lib/sh-test-lib @@ -5,55 +5,47 @@ export LANG error_msg() { local msg="$1" - test -z "${msg}" && msg="Unknown error" + [ -z "${msg}" ] && msg="Unknown error" printf "ERROR: %s\n" "${msg}" >&2 exit 1 } warn_msg() { local msg="$1" - test -z "${msg}" && msg="Unknown error" + [ -z "${msg}" ] && msg="Unknown error" printf "WARNING: %s\n" "${msg}" >&2 } info_msg() { local msg="$1" - test -z "${msg}" && msg="Unknown info" + [ -z "${msg}" ] && msg="Unknown info" printf "INFO: %s\n" "${msg}" >&1 } -check_return_fail() { - if [ $? -ne 0 ]; then - fail_test "$1" +check_root() { + if [ "$(id -ru)" -eq 0 ]; then return 0 else return 1 fi } -fail_test() { - local reason="$1" - echo "${test}: fail - ${reason}" -} - -pass_test() { - echo "${test}: pass" -} +exit_on_fail() { + local exit_code="$?" + [ "$#" -ne 1 ] && error_msg "Usage: exit_on_fail test" + local test="$1" -check_root() { - if [ "$(id -ru)" -eq 0 ]; then - return 0 - else - return 1 + if [ "${exit_code}" -ne 0 ]; then + echo "${test} fail" | tee -a "${RESULT_FILE}" + exit 1 fi } check_return() { local exit_code="$?" + [ "$#" -ne 1 ] && error_msg "Usage: check_return test" local test="$1" - test -z "${test}" && warn_msg "Test name is empty" - if [ "${exit_code}" -ne 0 ]; then echo "${test} fail" | tee -a "${RESULT_FILE}" return "${exit_code}" @@ -64,15 +56,16 @@ check_return() { } add_metric() { + if [ "$#" -ne 4 ]; then + warn_msg "The number of parameters less then 4" + error_msg "Usage: add_metric test result measurement units" + fi local test="$1" - local measurement="$2" - local units="$3" - - test -z "${test}" && warn_msg "Test name is empty" - test -z "${measurement}" && warn_msg "Test measurement is empty" - test -z "${units}" && warn_msg "Test units is empty" + local result="$2" + local measurement="$3" + local units="$4" - echo "${test} pass ${measurement} ${units}" | tee -a "${RESULT_FILE}" + echo "${test} ${result} ${measurement} ${units}" | tee -a "${RESULT_FILE}" } dist_name() { @@ -95,6 +88,8 @@ dist_name() { install_deps() { local pkgs="$1" + [ -z "${pkgs}" ] && error_msg "Usage: install_deps pkgs" + # skip_install parmater is optional. local skip_install="$2" if [ "${skip_install}" = "True" ] || [ "${skip_install}" = "true" ]; then diff --git a/automated/linux/dd-wr-speed/dd-wr-speed.sh b/automated/linux/dd-wr-speed/dd-wr-speed.sh new file mode 100755 index 0000000..5ba35ea --- /dev/null +++ b/automated/linux/dd-wr-speed/dd-wr-speed.sh @@ -0,0 +1,171 @@ +#!/bin/sh + +. ../../lib/sh-test-lib +OUTPUT="$(pwd)/output" +RESULT_FILE="${OUTPUT}/result.txt" +ITERATION="5" +UNITS="MB/s" + +usage() { + echo "Usage: $0 [-p ] [-t ] [-i ] [-s ]" 1>&2 + exit 1 +} + +while getopts "p:t:i:s:" 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}" ;; + s) SKIP_INSTALL="${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}') + + # If PARTITION specified, its FS_TYPE needs to be specified explicitly. + [ -z "${FS_TYPE}" ] && error_msg "Please specify ${FS_TYPE} explicitly" + + # 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 "${OUTPUT}"/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 "${OUTPUT}"/dd-read-output.txt + done + rm -f dd.img +} + +parse_output() { + local test="$1" + local test_case_id="${test}" + if ! [ -f "${OUTPUT}/${test}-output.txt" ]; then + warn_msg "output file is missing" + return 1 + fi + + # Fixup test-case-id with filesystem type and partion name. + [ -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 + + 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}" "pass" "${measurement}" "${UNITS}" + itr=$(( itr + 1 )) + fi + done < "${OUTPUT}/${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}" "${OUTPUT}"/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" "pass" "${mean}" "${UNITS}" + add_metric "${test_case_id}-min" "pass" "${min}" "${UNITS}" + add_metric "${test_case_id}-max" "pass" "${max}" "${UNITS}" + fi +} + +# Test run. +! check_root && error_msg "This script must be run as root" +[ -d "${OUTPUT}" ] && mv "${OUTPUT}" "${OUTPUT}_$(date +%Y%m%d%H%M%S)" +mkdir -p "${OUTPUT}" + +info_msg "About to run dd test..." +info_msg "Output directory: ${OUTPUT}" + +pkgs="e2fsprogs dosfstools" +install_deps "${pkgs}" "${SKIP_INSTALL}" + +prepare_partition +info_msg "dd test directory: $(pwd)" +dd_write +parse_output "dd-write" +dd_read +parse_output "dd-read" diff --git a/automated/linux/dd-wr-speed/dd-wr-speed.yaml b/automated/linux/dd-wr-speed/dd-wr-speed.yaml new file mode 100644 index 0000000..ae9a1d2 --- /dev/null +++ b/automated/linux/dd-wr-speed/dd-wr-speed.yaml @@ -0,0 +1,35 @@ +metadata: + name: dd-speed-test + format: "Lava-Test-Shell Test Definition 1.0" + description: "dd write/read speed test." + maintainer: + - chase.qi@linaro.org + os: + - debian + - fedora + devices: + - mustang + - hi6220-hikey + - apq8016-sbc + scope: + - performance + environment: + - lava-test-shell + +params: + # The currenty working directory will be used by default. + # Use '-p' specify partition that used for dd test. + # Example: /dev/sdb1 + PARTITION: "" + # CAUTION: if FS_TYPE not equal to the existing fs type of the partition + # specified with '-p', the partition will be formatted. + FS_TYPE: "" + # You may need to run dd test 4-5 times for an accurate evaluation. + ITERATION: "5" + SKIP_INSTALL: "false" + +run: + steps: + - cd ./automated/linux/dd-wr-speed + - ./dd-wr-speed.sh -p "${PARTITION}" -t "${FS_TYPE}" -i "${ITERATION}" -s "${SKIP_INSTALL}" + - ../../utils/send-to-lava.sh ./output/result.txt diff --git a/plans/linux-example.yaml b/plans/linux-example.yaml index 26b10f4..d79af77 100644 --- a/plans/linux-example.yaml +++ b/plans/linux-example.yaml @@ -21,3 +21,10 @@ requirements: timeout: 1800 params: SKIP_INSTALL: True + - path: automated/linux/dd-wr-speed/dd-wr-speed.yaml + timeout: 1800 + - path: automated/linux/dd-wr-speed/dd-wr-speed.yaml + timeout: 1800 + params: + SKIP_INSTALL: True + ITERATION: 3 -- cgit v1.2.3