import os, re
from autotest_lib.client.bin import test, utils
import postprocessing
class iozone(test.test):
"""
This autotest module runs the IOzone filesystem benchmark. The benchmark
generates and measures a variety of file operations. Iozone has been ported
to many machines and runs under many operating systems.
Iozone is useful for performing a broad filesystem analysis of a vendor's
computer platform. The benchmark tests file I/O performance for the
following operations:
Read, write, re-read, re-write, read backwards, read strided, fread, fwrite,
random read, pread ,mmap, aio_read, aio_write
@author: Ying Tao (yingtao@cn.ibm.com)
@see: http://www.iozone.org
"""
version = 3
def initialize(self):
self.job.require_gcc()
def setup(self, tarball='iozone3_347.tar'):
"""
Builds the given version of IOzone from a tarball.
@param tarball: Tarball with IOzone
@see: http://www.iozone.org/src/current/iozone3_347.tar
"""
tarball = utils.unmap_url(self.bindir, tarball, self.tmpdir)
utils.extract_tarball_to_dir(tarball, self.srcdir)
os.chdir(os.path.join(self.srcdir, 'src/current'))
utils.system('patch -p3 < ../../../makefile.patch')
utils.system('patch -p3 < ../../../clang_fortify.patch')
ctarget = os.getenv('CTARGET_default')
if (ctarget == 'armv7a-cros-linux-gnueabihf'):
utils.make('linux-arm')
elif (ctarget == 'i686-pc-linux-gnu'):
utils.make('linux')
elif (ctarget == 'x86_64-cros-linux-gnu'):
utils.make('linux-AMD64')
else:
utils.make('linux')
def run_once(self, dir=None, args=None):
"""
Runs IOzone with appropriate parameters, record raw results in a per
iteration raw output file as well as in the results attribute
@param dir: IOzone file generation dir.
@param args: Arguments to the iozone program.
"""
if not dir:
dir = self.tmpdir
os.chdir(dir)
if not args:
args = '-a'
cmd = os.path.join(self.srcdir, 'src', 'current', 'iozone')
self.results = utils.system_output('%s %s' % (cmd, args))
self.auto_mode = ("-a" in args)
self.results_path = os.path.join(self.resultsdir,
'raw_output_%s' % self.iteration)
self.analysisdir = os.path.join(self.resultsdir,
'analysis_%s' % self.iteration)
utils.open_write_close(self.results_path, self.results)
def __get_section_name(self, desc):
return desc.strip().replace(' ', '_')
def generate_keyval(self):
"""
Generates a keylist.
"""
keylist = {}
if self.auto_mode:
labels = ('write', 'rewrite', 'read', 'reread', 'randread',
'randwrite', 'bkwdread', 'recordrewrite',
'strideread', 'fwrite', 'frewrite', 'fread', 'freread')
for line in self.results.splitlines():
fields = line.split()
if len(fields) != 15:
continue
try:
fields = tuple([int(i) for i in fields])
except ValueError:
continue
for l, v in zip(labels, fields[2:]):
key_name = "%d-%d-%s" % (fields[0], fields[1], l)
keylist[key_name] = v
else:
child_regexp = re.compile('Children see throughput for[\s]+'
'([\d]+)\s+([-\w]+[-\w\s]*)\=[\s]+([\d\.]*) KB/sec')
parent_regexp = re.compile('Parent sees throughput for[\s]+'
'([\d]+)\s+([-\w]+[-\w\s]*)\=[\s]+([\d\.]*) KB/sec')
KBsec_regexp = re.compile('\=[\s]+([\d\.]*) KB/sec')
KBval_regexp = re.compile('\=[\s]+([\d\.]*) KB')
section = None
w_count = 0
for line in self.results.splitlines():
line = line.strip()
# Check for the beginning of a new result section
match = child_regexp.search(line)
if match:
# Extract the section name and the worker count
w_count = int(match.group(1))
section = self.__get_section_name(match.group(2))
# Output the appropriate keyval pair
key_name = '%s-%d-kids' % (section, w_count)
keylist[key_name] = match.group(3)
continue
# Check for any other interesting lines
if '=' in line:
# Is it something we recognize? First check for parent.
match = parent_regexp.search(line)
if match:
# The section name and the worker count better match
p_count = int(match.group(1))
p_secnt = self.__get_section_name(match.group(2))
if p_secnt != section or p_count != w_count:
continue
# Set the base name for the keyval
basekey = 'parent'
else:
# Check for the various 'throughput' values
if line[3:26] == ' throughput per thread ':
basekey = line[0:3]
match_x = KBsec_regexp
else:
# The only other thing we expect is 'Min xfer'
if not line.startswith('Min xfer '):
continue
basekey = 'MinXfer'
match_x = KBval_regexp
match = match_x.search(line)
if match:
result = match.group(1)
key_name = "%s-%d-%s" % (section, w_count, basekey)
keylist[key_name] = result
self.write_perf_keyval(keylist)
def postprocess_iteration(self):
self.generate_keyval()
if self.auto_mode:
a = postprocessing.IOzoneAnalyzer(list_files=[self.results_path],
output_dir=self.analysisdir)
a.analyze()
p = postprocessing.IOzonePlotter(results_file=self.results_path,
output_dir=self.analysisdir)
p.plot_all()