summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--samples/fio.yaml43
-rw-r--r--tests/unit/benchmark/scenarios/storage/fio_sample_output.json1
-rw-r--r--tests/unit/benchmark/scenarios/storage/test_fio.py23
-rw-r--r--yardstick/benchmark/scenarios/storage/fio.py39
-rw-r--r--yardstick/benchmark/scenarios/storage/fio_benchmark.bash43
-rw-r--r--yardstick/dispatcher/file.py3
-rw-r--r--yardstick/plot/plotter.py16
7 files changed, 60 insertions, 108 deletions
diff --git a/samples/fio.yaml b/samples/fio.yaml
index 44444c7cc..083c57549 100644
--- a/samples/fio.yaml
+++ b/samples/fio.yaml
@@ -2,48 +2,13 @@
# Sample benchmark task config file
# measure storage performance using fio
#
-# For this sample just like running the command below on the test vm and
+# For this sample just like running the command below on the test vm and
# getting benchmark info back to the yardstick.
#
-# sudo fio -filename=/home/ec2-user/data.raw -bs=4k -ipdepth=1 -rw=write \
+# sudo fio -filename=/home/ec2-user/data.raw -bs=4k -ipdepth=1 -rw=rw \
# -ramp_time=10 -runtime=60 -name=yardstick-fio -ioengine=libaio \
# -direct=1 -group_reporting -numjobs=1 -time_based \
-# --output=yardstick-fio.log
-#
-# When the above fio command done, the yardstick-fio.log file will contain
-# information like below and the benchmark script will take iops, throughput
-# and latency info marked with "" to create json style output.
-#
-# yardstick-fio: (g=0): rw=write, bs=4K-4K/4K-4K/4K-4K, ioengine=libaio, iodepth=1
-# fio-2.1.3
-# Starting 1 process
-#
-# yardstick-fio: (groupid=0, jobs=1): err= 0: pid=1421: Mon Jul 6 01:25:41 2015
-# write: io=1985.4MB, bw=33882KB/s, iops="8470", runt= 60001msec
-# slat (usec): min=6, max=15049, avg=10.29, stdev=19.42
-# clat (usec): min=1, max=18517, avg=105.68, stdev=37.76
-# lat ("usec"): min=85, max=18528, avg="116.30", stdev=43.57
-# clat percentiles (usec):
-# | 1.00th=[ 83], 5.00th=[ 85], 10.00th=[ 87], 20.00th=[ 88],
-# | 30.00th=[ 90], 40.00th=[ 93], 50.00th=[ 98], 60.00th=[ 102],
-# | 70.00th=[ 110], 80.00th=[ 124], 90.00th=[ 137], 95.00th=[ 149],
-# | 99.00th=[ 173], 99.50th=[ 181], 99.90th=[ 203], 99.95th=[ 290],
-# | 99.99th=[ 604]
-# bw (KB /s): min= 0, max=39816, per=99.26%, avg=33631.46, stdev=4369.58
-# lat (usec) : 2=0.01%, 50=0.01%, 100=55.44%, 250=44.50%, 500=0.02%
-# lat (usec) : 750=0.04%, 1000=0.01%
-# lat (msec) : 2=0.01%, 4=0.01%, 10=0.01%, 20=0.01%
-# cpu : usr=4.09%, sys=16.38%, ctx=604931, majf=0, minf=27
-# IO depths : 1=118.9%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
-# submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
-# complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
-# issued : total=r=0/w=508237/d=0, short=r=0/w=0/d=0
-#
-# Run status group 0 (all jobs):
-# WRITE: io=1985.4MB, aggrb="33881KB/s", minb=33881KB/s, maxb=33881KB/s, mint=60001msec, maxt=60001msec
-#
-# Disk stats (read/write):
-# vda: ios=0/604235, merge=0/211, ticks=0/61964, in_queue=61804, util=86.25%
+# --output-format=json
schema: "yardstick:task:0.1"
@@ -54,7 +19,7 @@ scenarios:
filename: /home/ec2-user/data.raw
bs: 4k
iodepth: 1
- rw: write
+ rw: rw
ramp_time: 10
host: fio.demo
runner:
diff --git a/tests/unit/benchmark/scenarios/storage/fio_sample_output.json b/tests/unit/benchmark/scenarios/storage/fio_sample_output.json
new file mode 100644
index 000000000..4c7501818
--- /dev/null
+++ b/tests/unit/benchmark/scenarios/storage/fio_sample_output.json
@@ -0,0 +1 @@
+{"jobs": [{"trim": {"io_bytes": 0, "slat": {"max": 0, "mean": 0.0, "stddev": 0.0, "min": 0}, "bw_max": 0, "bw_mean": 0.0, "iops": 0, "bw": 0, "lat": {"max": 0, "mean": 0.0, "stddev": 0.0, "min": 0}, "bw_agg": 0.0, "clat": {"max": 0, "mean": 0.0, "percentile": {"70.000000": 0, "5.000000": 0, "50.000000": 0, "99.990000": 0, "30.000000": 0, "10.000000": 0, "99.000000": 0, "0.00": 0, "90.000000": 0, "95.000000": 0, "60.000000": 0, "40.000000": 0, "20.000000": 0, "99.900000": 0, "99.950000": 0, "1.000000": 0, "99.500000": 0, "80.000000": 0}, "stddev": 0.0, "min": 0}, "runtime": 0, "bw_min": 0, "bw_dev": 0.0}, "latency_us": {"10": 0.01, "750": 0.03, "20": 0.0, "50": 0.02, "2": 0.01, "4": 0.01, "100": 0.75, "250": 88.37, "500": 10.72, "1000": 0.01}, "latency_ms": {"10": 0.01, "750": 0.0, "20": 0.01, ">=2000": 0.0, "50": 0.01, "2000": 0.0, "2": 0.07, "4": 0.01, "100": 0.0, "250": 0.01, "500": 0.0, "1000": 0.01}, "read": {"io_bytes": 839056, "slat": {"max": 1990, "mean": 18.14, "stddev": 15.4, "min": 0}, "bw_max": 10328, "bw_mean": 8721.27, "iops": 20972, "bw": 83888, "lat": {"max": 776676, "mean": 236.8, "stddev": 4668.12, "min": 45}, "bw_agg": 8721.27, "clat": {"max": 776663, "mean": 217.79, "percentile": {"70.000000": 199, "5.000000": 119, "50.000000": 175, "99.990000": 15168, "30.000000": 155, "10.000000": 131, "99.000000": 342, "0.00": 0, "90.000000": 247, "95.000000": 278, "60.000000": 185, "40.000000": 165, "20.000000": 145, "99.900000": 820, "99.950000": 1272, "1.000000": 96, "99.500000": 370, "80.000000": 217}, "stddev": 4667.79, "min": 0}, "runtime": 10002, "bw_min": 4, "bw_dev": 2178.08}, "majf": 0, "ctx": 490590, "minf": 87, "jobname": "yardstick-fio", "write": {"io_bytes": 841992, "slat": {"max": 2594, "mean": 19.78, "stddev": 16.25, "min": 0}, "bw_max": 10472, "bw_mean": 8464.0, "iops": 21045, "bw": 84182, "lat": {"max": 776709, "mean": 233.55, "stddev": 3115.46, "min": 64}, "bw_agg": 8464.0, "clat": {"max": 776685, "mean": 212.87, "percentile": {"70.000000": 211, "5.000000": 135, "50.000000": 187, "99.990000": 3536, "30.000000": 169, "10.000000": 145, "99.000000": 358, "0.00": 0, "90.000000": 258, "95.000000": 290, "60.000000": 197, "40.000000": 177, "20.000000": 159, "99.900000": 756, "99.950000": 1288, "1.000000": 114, "99.500000": 382, "80.000000": 229}, "stddev": 3115.23, "min": 0}, "runtime": 10002, "bw_min": 4, "bw_dev": 2584.23}, "iodepth_level": {"16": 0.0, "32": 0.0, "1": 111.92, "2": 0.0, "4": 0.0, ">=64": 0.0, "8": 0.0}, "usr_cp": 2.87, "error": 0, "sys_cp": 12.37, "groupid": 0}], "fio version": "fio-2.1.3", "disk_util": [{"aggr_write_ticks": 42020, "read_merges": 0, "name": "dm-0", "write_ios": 233547, "aggr_write_ios": 235129, "aggr_read_ticks": 42576, "read_ios": 233492, "util": 97.22, "read_ticks": 42096, "aggr_write_merge": 0, "write_merges": 0, "aggr_in_queue": 84524, "aggr_read_ios": 235224, "aggr_util": 96.96, "aggr_read_merges": 0, "in_queue": 83732, "write_ticks": 41468}, {"read_merges": 0, "name": "vda", "write_ios": 235129, "read_ios": 235224, "util": 96.96, "read_ticks": 42576, "write_merges": 0, "in_queue": 84524, "write_ticks": 42020}]}
diff --git a/tests/unit/benchmark/scenarios/storage/test_fio.py b/tests/unit/benchmark/scenarios/storage/test_fio.py
index 54f493ee6..45e8a9429 100644
--- a/tests/unit/benchmark/scenarios/storage/test_fio.py
+++ b/tests/unit/benchmark/scenarios/storage/test_fio.py
@@ -14,6 +14,7 @@
import mock
import unittest
import json
+import os
from yardstick.benchmark.scenarios.storage import fio
@@ -34,7 +35,7 @@ class FioTestCase(unittest.TestCase):
options = {
'filename': "/home/ec2-user/data.raw",
'bs': "4k",
- 'rw': "write",
+ 'rw': "rw",
'ramp_time': 10
}
args = {'options': options}
@@ -50,19 +51,21 @@ class FioTestCase(unittest.TestCase):
options = {
'filename': "/home/ec2-user/data.raw",
'bs': "4k",
- 'rw': "write",
+ 'rw': "rw",
'ramp_time': 10
}
args = {'options': options}
p.client = mock_ssh.SSH()
- sample_output = '{"read_bw": "N/A", "write_lat": "407.08usec", \
- "read_iops": "N/A", "write_bw": "9507KB/s", \
- "write_iops": "2376", "read_lat": "N/A"}'
+ sample_output = self._read_sample_output()
mock_ssh.SSH().execute.return_value = (0, sample_output, '')
result = p.run(args)
- expected_result = json.loads(sample_output)
+
+ expected_result = '{"read_bw": 83888, "read_iops": 20972,' \
+ '"read_lat": 236.8, "write_bw": 84182, "write_iops": 21045,'\
+ '"write_lat": 233.55}'
+ expected_result = json.loads(expected_result)
self.assertEqual(result, expected_result)
def test_fio_unsuccessful_script_error(self, mock_ssh):
@@ -71,7 +74,7 @@ class FioTestCase(unittest.TestCase):
options = {
'filename': "/home/ec2-user/data.raw",
'bs': "4k",
- 'rw': "write",
+ 'rw': "rw",
'ramp_time': 10
}
args = {'options': options}
@@ -80,6 +83,12 @@ class FioTestCase(unittest.TestCase):
mock_ssh.SSH().execute.return_value = (1, '', 'FOOBAR')
self.assertRaises(RuntimeError, p.run, args)
+ def _read_sample_output(self):
+ curr_path = os.path.dirname(os.path.abspath(__file__))
+ output = os.path.join(curr_path, 'fio_sample_output.json')
+ with open(output) as f:
+ sample_output = f.read()
+ return sample_output
def main():
unittest.main()
diff --git a/yardstick/benchmark/scenarios/storage/fio.py b/yardstick/benchmark/scenarios/storage/fio.py
index d3695165f..42f159164 100644
--- a/yardstick/benchmark/scenarios/storage/fio.py
+++ b/yardstick/benchmark/scenarios/storage/fio.py
@@ -17,7 +17,7 @@ LOG = logging.getLogger(__name__)
class Fio(base.Scenario):
- """Execute fio benchmark on host
+ """Execute fio benchmark in a host
Parameters
filename - file name for fio workload
@@ -73,8 +73,9 @@ class Fio(base.Scenario):
def run(self, args):
"""execute the benchmark"""
- default_args = "-ioengine=libaio -direct=1 " \
- "-group_reporting -numjobs=1 -time_based"
+ default_args = "-ioengine=libaio -direct=1 -group_reporting " \
+ "-numjobs=1 -time_based --output-format=json"
+ result = {}
if not self.setup_done:
self.setup()
@@ -97,21 +98,32 @@ class Fio(base.Scenario):
else:
runtime = 30
- args = "-filename=%s -bs=%s -iodepth=%s -rw=%s -ramp_time=%s " \
- "-runtime=%s -name=%s" \
- % (filename, bs, iodepth, rw, ramp_time, runtime, name)
- cmd = "sudo bash fio.sh %s %s %s" \
- % (filename, args, default_args)
+ cmd_args = "-filename=%s -bs=%s -iodepth=%s -rw=%s -ramp_time=%s " \
+ "-runtime=%s -name=%s %s" \
+ % (filename, bs, iodepth, rw, ramp_time, runtime, name,
+ default_args)
+ cmd = "sudo bash fio.sh %s %s" % (filename, cmd_args)
LOG.debug("Executing command: %s", cmd)
- status, stdout, stderr = self.client.execute(cmd)
+ # Set timeout, so that the cmd execution does not exit incorrectly
+ # when the test run time is last long
+ timeout = int(ramp_time) + int(runtime) + 600
+ status, stdout, stderr = self.client.execute(cmd, timeout=timeout)
if status:
raise RuntimeError(stderr)
- data = json.loads(stdout)
+ raw_data = json.loads(stdout)
+
+ # The bandwidth unit is KB/s, and latency unit is us
+ result["read_bw"] = raw_data["jobs"][0]["read"]["bw"]
+ result["read_iops"] = raw_data["jobs"][0]["read"]["iops"]
+ result["read_lat"] = raw_data["jobs"][0]["read"]["lat"]["mean"]
+ result["write_bw"] = raw_data["jobs"][0]["write"]["bw"]
+ result["write_iops"] = raw_data["jobs"][0]["write"]["iops"]
+ result["write_lat"] = raw_data["jobs"][0]["write"]["lat"]["mean"]
# TODO: add sla check
- return data
+ return result
def _test():
@@ -133,8 +145,9 @@ def _test():
"filename": "/home/ec2-user/data.raw",
"bs": "4k",
"iodepth": "1",
- "rw": "write",
- "ramp_time": 10,
+ "rw": "rw",
+ "ramp_time": 1,
+ "duration": 10
}
args = {"options": options}
diff --git a/yardstick/benchmark/scenarios/storage/fio_benchmark.bash b/yardstick/benchmark/scenarios/storage/fio_benchmark.bash
index 0fa319dd4..2ef7f4949 100644
--- a/yardstick/benchmark/scenarios/storage/fio_benchmark.bash
+++ b/yardstick/benchmark/scenarios/storage/fio_benchmark.bash
@@ -15,7 +15,6 @@ set -e
FIO_FILENAME=$1
shift
OPTIONS="$@"
-OUTPUT_FILE="yardstick-fio.log"
# setup data file for fio
setup()
@@ -25,43 +24,10 @@ setup()
fi
}
-# run fio test
+# run fio test and write json format result to stdout
run_test()
{
- fio $OPTIONS --output=$OUTPUT_FILE
-}
-
-# write the result to stdout in json format
-output_json()
-{
- read_bw=$(grep "READ.*aggrb" $OUTPUT_FILE | awk -F [=\ ,] '{printf $9}')
- write_bw=$(grep "WRITE.*aggrb" $OUTPUT_FILE | awk -F [=\ ,] '{printf $8}')
- eval $(grep -e '\ lat.*stdev' -e "read.*iops" -e "write.*iops" -e "trim.*iops" $OUTPUT_FILE | sed 'N;s/\n/ /g' | grep read | awk -F [=\ ,\(\)] '{printf("read_iops=%s; read_lat_unit=%s; read_lat=%s", $12, $24, $33)}')
- eval $(grep -e '\ lat.*stdev' -e "read.*iops" -e "write.*iops" -e "trim.*iops" $OUTPUT_FILE | sed 'N;s/\n/ /g' | grep write | awk -F [=\ ,\(\)] '{printf("write_iops=%s; write_lat_unit=%s; write_lat=%s", $11, $23, $32)}')
-
- read_bw=${read_bw:-N/A}
- write_bw=${write_bw:-N/A}
- read_iops=${read_iops:-N/A}
- write_iops=${write_iops:-N/A}
- if [ "x$read_lat" = "x" ]; then
- read_lat="N/A"
- else
- read_lat=$read_lat$read_lat_unit
- fi
- if [ "x$write_lat" = "x" ]; then
- write_lat="N/A"
- else
- write_lat=$write_lat$write_lat_unit
- fi
-
- echo -e "{ \
- \"read_bw\":\"$read_bw\", \
- \"write_bw\":\"$write_bw\", \
- \"read_iops\":\"$read_iops\", \
- \"write_iops\":\"$write_iops\", \
- \"read_lat\":\"$read_lat\", \
- \"write_lat\":\"$write_lat\" \
- }"
+ fio $OPTIONS
}
# main entry
@@ -71,10 +37,7 @@ main()
setup
# run the test
- run_test >/dev/null
-
- # output result
- output_json
+ run_test
}
main
diff --git a/yardstick/dispatcher/file.py b/yardstick/dispatcher/file.py
index 7c644f82f..dc39f152e 100644
--- a/yardstick/dispatcher/file.py
+++ b/yardstick/dispatcher/file.py
@@ -8,6 +8,7 @@
##############################################################################
import logging
+import json
from yardstick.dispatcher.base import Base as DispatchBase
@@ -50,4 +51,4 @@ class FileDispatcher(DispatchBase):
def record_result_data(self, data):
if self.log:
- self.log.info(data)
+ self.log.info(json.dumps(data))
diff --git a/yardstick/plot/plotter.py b/yardstick/plot/plotter.py
index f3fb75d3e..0455386b5 100644
--- a/yardstick/plot/plotter.py
+++ b/yardstick/plot/plotter.py
@@ -213,16 +213,16 @@ class Plotter(object):
is_rw_type = rw_types[i] == "rw" or rw_types[i] == "randrw"
if is_r_type or is_rw_type:
- # Remove trailing 'usec' and convert to float
+ # Convert to float
data['read_lat'] = \
- [r['benchmark']['data']['read_lat'][:-4] for r in records]
+ [r['benchmark']['data']['read_lat'] for r in records]
data['read_lat'] = \
[float(i) for i in data['read_lat']]
- # Remove trailing 'KB/s' and convert to float
+ # Convert to int
data['read_bw'] = \
- [r['benchmark']['data']['read_bw'][:-4] for r in records]
+ [r['benchmark']['data']['read_bw'] for r in records]
data['read_bw'] = \
- [float(i) for i in data['read_bw']]
+ [int(i) for i in data['read_bw']]
# Convert to int
data['read_iops'] = \
[r['benchmark']['data']['read_iops'] for r in records]
@@ -231,14 +231,14 @@ class Plotter(object):
if is_w_type or is_rw_type:
data['write_lat'] = \
- [r['benchmark']['data']['write_lat'][:-4] for r in records]
+ [r['benchmark']['data']['write_lat'] for r in records]
data['write_lat'] = \
[float(i) for i in data['write_lat']]
data['write_bw'] = \
- [r['benchmark']['data']['write_bw'][:-4] for r in records]
+ [r['benchmark']['data']['write_bw'] for r in records]
data['write_bw'] = \
- [float(i) for i in data['write_bw']]
+ [int(i) for i in data['write_bw']]
data['write_iops'] = \
[r['benchmark']['data']['write_iops'] for r in records]