summaryrefslogtreecommitdiff
path: root/bin
diff options
authorRod Smith <rod.smith@canonical.com>2016-09-01 11:38:52 -0400
committerRod Smith <rod.smith@canonical.com>2016-09-01 11:38:52 -0400
commitababaa506249728f3b0c5ad62da6eb3b2c3c4652 (patch)
tree39d141d827c6cc4797ad328facba96da0d34356c /bin
parentda93f8eba3b84a5d91857ad8ee60cfdd85e2673b (diff)
Added test for CPU load imposed by disk input operations.
Diffstat (limited to 'bin')
-rwxr-xr-xbin/disk_cpu_load138
1 files changed, 138 insertions, 0 deletions
diff --git a/bin/disk_cpu_load b/bin/disk_cpu_load
new file mode 100755
index 00000000..5e0d0eb8
--- /dev/null
+++ b/bin/disk_cpu_load
@@ -0,0 +1,138 @@
+#!/bin/bash
+
+# Script to test CPU load imposed by a simple disk read operation
+#
+# Copyright (c) 2016 Canonical Ltd.
+#
+# Authors
+# Rod Smith <rod.smith@canonical.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 3,
+# as published by the Free Software Foundation.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# The purpose of this script is to run disk stress tests using the
+# stress-ng program.
+#
+# Usage:
+# disk_cpu_load [ --max-load <load> ] [ --xfer <mebibytes> ]
+# [ <device-filename> ]
+#
+# Parameters:
+# --max-load <load> -- The maximum acceptable CPU load, as a percentage.
+# Defaults to 30.
+# --xfer <mebibytes> -- The amount of data to read from the disk, in
+# mebibytes. Defaults to 4096 (4 GiB).
+# <device-filename> -- This is the WHOLE-DISK device filename (with or
+# without "/dev/"), e.g. "sda" or "/dev/sda". The
+# script finds a filesystem on that device, mounts
+# it if necessary, and runs the tests on that mounted
+# filesystem. Defaults to /dev/sda.
+
+
+set -e
+
+
+get_params() {
+ disk_device="/dev/sda"
+ short_device="sda"
+ max_load=30
+ xfer=4096
+ while [ $# -gt 0 ] ; do
+ case $1 in
+ --max-load) max_load="$2"
+ shift
+ ;;
+ --xfer) xfer="$2"
+ shift
+ ;;
+ *) disk_device="/dev/$1"
+ disk_device=`echo $disk_device | sed "s/\/dev\/\/dev/\/dev/g"`
+ short_device=$(echo $disk_device | sed "s/\/dev//g")
+ if [ ! -b $disk_device ] ; then
+ echo "Unknown block device \"$disk_device\""
+ echo "Usage: $0 [ --max-load <load> ] [ --xfer <mebibytes> ]"
+ echo " [ device-file ]"
+ exit 1
+ fi
+ ;;
+ esac
+ shift
+ done
+} # get_params()
+
+
+# Find the sum of all values in an array
+# Input:
+# $1 - The array whose values are to be summed
+# Output:
+# $total - The sum of the values
+sum_array() {
+ local array=("${@}")
+ total=0
+ for i in ${array[@]}; do
+ let total+=$i
+ done
+} # sum_array()
+
+
+# Compute's CPU load between two points in time.
+# Input:
+# $1 - CPU statistics from /proc/stat from START point, in a string of numbers
+# $2 - CPU statistics from /proc/stat from END point, in a string of numbers
+# These values can be obtained via $(grep "cpu " /proc/stat | tr -s " " | cut -d " " -f 2-)
+# Ouput:
+# $cpu_load - CPU load over the two measurements, as a percentage (0-100)
+compute_cpu_load() {
+ local start_use
+ local end_use
+ IFS=' ' read -r -a start_use <<< $1
+ IFS=' ' read -r -a end_use <<< $2
+ local diff_idle
+ let diff_idle=${end_use[3]}-${start_use[3]}
+
+ sum_array "${start_use[@]}"
+ local start_total=$total
+ sum_array "${end_use[@]}"
+ local end_total=$total
+
+ local diff_total
+ local diff_used
+ let diff_total=${end_total}-${start_total}
+ let diff_used=$diff_total-$diff_idle
+
+ if [ "$diff_total" != "0" ] ; then
+ let cpu_load=($diff_used*100)/$diff_total
+ else
+ cpu_load=0
+ fi
+} # compute_cpu_load()
+
+
+#
+# Main program body....
+#
+
+get_params "$@"
+retval=0
+echo "Testing CPU load when reading $xfer MiB from $disk_device"
+echo "Maximum acceptable CPU load is $max_load"
+blockdev --flushbufs $disk_device
+start_load="$(grep "cpu " /proc/stat | tr -s " " | cut -d " " -f 2-)"
+dd if="$disk_device" of=/dev/null bs=1048576 count="$xfer" &> /dev/null
+end_load="$(grep "cpu " /proc/stat | tr -s " " | cut -d " " -f 2-)"
+compute_cpu_load "$start_load" "$end_load"
+echo "Detected disk read CPU load is $cpu_load"
+if [ "$cpu_load" -gt "$max_load" ] ; then
+ retval=1
+ echo "*** DISK CPU LOAD TEST HAS FAILED! ***"
+fi
+exit $retval