Source code for wlauto.workloads.iozone

#    Copyright 2012-2015 ARM Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# pylint: disable=attribute-defined-outside-init
from collections import OrderedDict
from itertools import izip_longest
import os
import re
import csv


from wlauto import Workload, Parameter, Executable
from wlauto.exceptions import ConfigError
from wlauto.utils.types import list_of_ints


iozone_results_txt = 'iozone_results.txt'


[docs]class Iozone(Workload): name = 'iozone' description = """ Iozone is a filesystem benchmark that runs a series of disk I/O performance tests. Here is a list of tests that you can run in the iozone workload. The descriptions are from the official iozone document. 0 - Write Test Measure performance of writing a new file. Other tests rely on the file written by this, so it must always be enabled (WA will automatically neable this if not specified). 1 - Rewrite Test Measure performance of writing an existing file. 2 - Read Test Measure performance of reading an existing file. 3 - Reread Test Measure performance of rereading an existing file. 4 - Random Read Test Measure performance of reading a file by accessing random locations within the file. 5 - Random Write Test Measure performance of writing a file by accessing random locations within the file. 6 - Backwards Read Test Measure performance of reading a file backwards. 7 - Record Rewrite Test Measure performance of writing and rewriting a particular spot within the file. 8 - Strided Read Test Measure performance of reading a file with strided access behavior. 9 - Fwrite Test Measure performance of writing a file using the library function fwrite() that performances buffered write operations. 10 - Frewrite Test Measure performance of writing a file using the the library function fwrite() that performs buffered and blocked write operations. 11 - Fread Test Measure performance of reading a file using the library function fread() that performs buffered and blocked read operations. 12 - Freread Test Same as the Fread Test except the current file being read was read previously sometime in the past. By default, iozone will run all tests in auto mode. To run specific tests, they must be written in the form of: [0,1,4,5] Please enable classifiers in your agenda or config file in order to display the results properly in the results.csv file. The official website for iozone is at www.iozone.org. """ parameters = [ Parameter('tests', kind=list_of_ints, allowed_values=range(13), description='List of performance tests to run.'), Parameter('auto_mode', kind=bool, default=True, description='Run tests in auto mode.'), Parameter('timeout', kind=int, default=14400, description='Timeout for the workload.'), Parameter('file_size', kind=int, description='Fixed file size.'), Parameter('record_length', kind=int, description='Fixed record length.'), Parameter('threads', kind=int, description='Number of threads'), Parameter('other_params', kind=str, default='', description='Other parameter. Run iozone -h to see' ' list of options.') ] def initialize(self, context): Iozone.host_binary = context.resolver.get(Executable(self, self.device.abi, 'iozone')) Iozone.device_binary = self.device.install(Iozone.host_binary)
[docs] def setup(self, context): self.results = os.path.join(self.device.working_directory, iozone_results_txt) self.command = self._build_command() if self.threads and self.auto_mode: raise ConfigError("You cannot set the number of threads and enable" " auto mode at the same time.")
def _build_command(self): # pylint: disable=access-member-before-definition iozone_command = 'cd {} && {}'.format(self.device.working_directory, self.device_binary) if self.auto_mode: iozone_command += ' -a' if self.tests: if 0 not in self.tests: self.tests = [0] + self.tests iozone_command += ''.join([' -i {}'.format(t) for t in self.tests]) if self.record_length > 0: iozone_command += ' -r {}'.format(self.record_length) if self.threads > 0: iozone_command += ' -t {}'.format(self.threads) if self.file_size > 0: iozone_command += ' -s {}'.format(self.file_size) if self.other_params: iozone_command += ' ' + self.other_params # enable reporting mode for parsing non-thread results iozone_command += ' -R > {}'.format(self.results) # check if -b option is used match = re.search(r'-b (.?\w+.?\w+?\s)', iozone_command) if match: self.user_file = match.group(1) self.device_output_file = os.path.join(self.device.working_directory, self.user_file) return iozone_command
[docs] def run(self, context): self.device.execute(self.command, timeout=self.timeout)
[docs] def update_result(self, context): self.device.pull_file(self.results, context.output_directory) self.outfile = os.path.join(context.output_directory, iozone_results_txt) if '-b' in self.other_params: self.device.pull_file(self.device_output_file, context.output_directory) # if running in thread mode if self.threads: thread_results = self.parse_thread_results() for name, value, units in thread_results: context.add_metric(name, value, units) # for non-thread mode results else: with open(self.outfile, 'r') as iozone_file: iozone_file = (line.replace('\"', '') for line in iozone_file) table_list = [] # begin parsing results for line in iozone_file: if 'Writer report' in line: table_list.append(line.split()) break for line in iozone_file: if 'exiting' in line or 'completed' in line: break else: table_list.append(line.split()) # create csv file self.write_to_csv(context, table_list) # parse metrics self.parse_metrics(context, table_list)
[docs] def write_to_csv(self, context, csv_table_list): self.test_file = os.path.join(context.output_directory, 'table_results.csv') # create csv file for writing csv_file = open(self.test_file, 'w') wr = csv.writer(csv_file, delimiter=',') # shift second row by adding extra element # for "prettier" formatting index = 0 for element in csv_table_list: if element: if index == 1: element.insert(0, '0') index += 1 else: index = 0 # write to csv file for item in csv_table_list: wr.writerow(item) csv_file.close()
# break list of results into smaller groups based on # test name
[docs] def parse_metrics(self, context, plist): # pylint: disable=no-self-use subvalue_list = [] value_list = [] for values in plist: if values: subvalue_list.append(values) else: value_list.append(subvalue_list) subvalue_list = [] # If users run a list of specific tests, make # sure that the results for the last test # executed are appended. if subvalue_list: value_list.append(subvalue_list) for reports in value_list: # grab report name and convert it to a string report_name = reports[0] report_name = report_name[:-1] report_name = '_'.join(report_name).lower() record_sizes = reports[1] values = reports[2:] for v in values: templist = OrderedDict(izip_longest(record_sizes, v)) for reclen, value in templist.items(): if reclen is '0': fs = value if value is None: value = '0' classifiers = {'reclen': reclen, 'file_size': fs} if reclen != '0': context.add_metric(report_name, int(value), 'kb/s', classifiers=classifiers)
# parse thread-mode results
[docs] def parse_thread_results(self): results = [] with open(self.outfile, 'r') as iozone_file: for line in iozone_file: # grab section of data we care about if 'Throughput report' in line: break else: if '=' in line: if 'Time Resolution' not in line: line = line.replace('=', '') line = line.split() # grab headers if len(line) >= 8: header = line[0] subheader = ' '.join(line[-5:-2]) header += ' ' + subheader else: header = ' '.join(line[0:2]) units = line[-1] value = line[-2] tup = (header, value, units) results.append(tup) return results
def finalize(self, context): self.device.uninstall_executable(self.device_binary)