172 lines
6.5 KiB
Python
172 lines
6.5 KiB
Python
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()
|