mirror of
				https://github.com/ARM-software/workload-automation.git
				synced 2025-10-30 14:44:09 +00:00 
			
		
		
		
	iozone: Add functions and rewrite update_result()
Added functions to parse thread-mode results and non-thread mode results accordingly, in addition to rewriting the update_result() function. Signed-off-by: Lisa Nguyen <lisa.nguyen@linaro.org>
This commit is contained in:
		| @@ -17,26 +17,22 @@ from wlauto.exceptions import ConfigError | ||||
| from wlauto.utils.types import list_of_strs | ||||
| import os | ||||
| import re | ||||
| import csv | ||||
|  | ||||
| iozone_results_txt = 'iozone_results.txt' | ||||
|  | ||||
| time_res_regex = re.compile(r'Time Resolution = (\d+.\d+) (\w+)') | ||||
| cache_size_regex = re.compile(r'Processor cache size set to (\d+) (\w+)') | ||||
| cache_line_regex = re.compile(r'Processor cache line size set to (\d+) (\w+)') | ||||
|  | ||||
|  | ||||
| class Iozone(Workload): | ||||
|  | ||||
|     name = 'iozone' | ||||
|     description = """ | ||||
|     Iozone runs a series of disk I/O performance tests. | ||||
|     Iozone is a filesystem benchmark that runs a series of disk | ||||
|     I/O performance tests. | ||||
|  | ||||
|     To run specific tests, they must be written in the form of: | ||||
|     By default, iozone will run all tests in auto mode. To run | ||||
|     specific tests, they must be written in the form of: | ||||
|  | ||||
|     ['0', '1', '5', '6'] | ||||
|  | ||||
|     By default, iozone will run all tests in auto mode. | ||||
|  | ||||
|     The official website for iozone is at www.iozone.org. | ||||
|     """ | ||||
|  | ||||
| @@ -48,7 +44,7 @@ class Iozone(Workload): | ||||
|         Parameter('timeout', kind=int, default=14400, | ||||
|                   description='Timeout for the workload.'), | ||||
|         Parameter('file_size', kind=int, default=0, | ||||
|                   description='Fixed file size to run tests with.'), | ||||
|                   description='Fixed file size.'), | ||||
|         Parameter('record_length', kind=int, default=0, | ||||
|                   description='Fixed record length.'), | ||||
|         Parameter('threads', kind=int, default=0, | ||||
| @@ -74,34 +70,37 @@ class Iozone(Workload): | ||||
|                               " auto mode at the same time.") | ||||
|  | ||||
|     def _build_command(self): | ||||
|         iozone_command = '{}'.format(self.device_binary) | ||||
|         iozone_command = 'cd {} && {}'.format(self.device.working_directory, | ||||
|                                               self.device_binary) | ||||
|  | ||||
|         if self.auto_mode: | ||||
|             self.auto_option = ' -a' | ||||
|             iozone_command += self.auto_option | ||||
|             iozone_command += ' -a' | ||||
|  | ||||
|         if self.tests: | ||||
|             self.test_string = ''.join([' -i {}'.format(t) for t in self.tests]) | ||||
|             iozone_command += self.test_string | ||||
|             iozone_command += ''.join([' -i {}'.format(t) for t in self.tests]) | ||||
|  | ||||
|         if self.record_length > 0: | ||||
|             self.record_option = ' -r {}'.format(self.record_length) | ||||
|             iozone_command += self.record_option | ||||
|             iozone_command += ' -r {}'.format(self.record_length) | ||||
|  | ||||
|         if self.threads > 0: | ||||
|             self.threads_option = ' -t {}'.format(self.threads) | ||||
|             iozone_command += self.threads_option | ||||
|             iozone_command += ' -t {}'.format(self.threads) | ||||
|  | ||||
|         if self.file_size > 0: | ||||
|             self.file_size_option = ' -s {}'.format(self.file_size) | ||||
|             iozone_command += self.file_size_option | ||||
|             iozone_command += ' -s {}'.format(self.file_size) | ||||
|  | ||||
|         if self.other_params: | ||||
|             other_params_string = ' ' + self.other_params | ||||
|             iozone_command += other_params_string | ||||
|             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) | ||||
|  | ||||
|         self.log_string = ' > {}'.format(self.results) | ||||
|         iozone_command += self.log_string | ||||
|  | ||||
|         return iozone_command | ||||
|  | ||||
| @@ -110,27 +109,120 @@ class Iozone(Workload): | ||||
|  | ||||
|     def update_result(self, context): | ||||
|         self.device.pull_file(self.results, context.output_directory) | ||||
|         outfile = os.path.join(context.output_directory, iozone_results_txt) | ||||
|         self.outfile = os.path.join(context.output_directory, | ||||
|                                     iozone_results_txt) | ||||
|  | ||||
|         with open(outfile, 'r') as iozone_file: | ||||
|         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) | ||||
|  | ||||
|     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 | ||||
|     # I/O operation | ||||
|     def parse_metrics(self, context, plist): | ||||
|         subvalue_list = [] | ||||
|         value_list = [] | ||||
|         for values in plist: | ||||
|             if values: | ||||
|                 subvalue_list.append(values) | ||||
|             else: | ||||
|                 value_list.append(subvalue_list) | ||||
|                 subvalue_list = [] | ||||
|  | ||||
|         for group in value_list: | ||||
|             classifier = {'header': group[0]} | ||||
|             record_lens = group[2:] | ||||
|             for rec in record_lens: | ||||
|                 context.add_metric('reclen', int(rec[0]), 'kb', | ||||
|                                    classifiers=classifier) | ||||
|                 values = rec[1:] | ||||
|                 for v in values: | ||||
|                     context.add_metric('bytes', int(v), 'kb', | ||||
|                                        classifiers=classifier) | ||||
|  | ||||
|     # parse thread-mode results | ||||
|     def parse_thread_results(self): | ||||
|         results = [] | ||||
|         with open(self.outfile, 'r') as iozone_file: | ||||
|             for line in iozone_file: | ||||
|                 time_res_match = time_res_regex.search(line) | ||||
|                 if time_res_match: | ||||
|                     context.result.add_metric("time_resolution", | ||||
|                                               float(time_res_match.group(1)), | ||||
|                                               time_res_match.group(2)) | ||||
|                 # 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() | ||||
|  | ||||
|                 cache_size_match = cache_size_regex.search(line) | ||||
|                 if cache_size_match: | ||||
|                     context.result.add_metric("processor_cache_size", | ||||
|                                               float(cache_size_match.group(1)), | ||||
|                                               cache_size_match.group(2)) | ||||
|                             # grab headers | ||||
|                             if len(line) >= 8: | ||||
|                                 header = line[0] | ||||
|                                 subheader = ' '.join(line[-5:-2]) | ||||
|                                 header += ' ' + subheader | ||||
|                             else: | ||||
|                                 header = ' '.join(line[0:2]) | ||||
|  | ||||
|                 cache_line_match = cache_line_regex.search(line) | ||||
|                 if cache_line_match: | ||||
|                     context.result.add_metric("processor_cache_line_size", | ||||
|                                               float(cache_line_match.group(1)), | ||||
|                                               cache_line_match.group(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) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user