1# Copyright 2018 The Chromium Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import logging 6import os 7from autotest_lib.client.common_lib import file_utils 8from autotest_lib.client.cros import chrome_binary_test 9from autotest_lib.client.cros.video import helper_logger 10 11DOWNLOAD_BASE = ('http://commondatastorage.googleapis.com/' 12 'chromiumos-test-assets-public/') 13TEST_LOG = 'test_log' 14REPEAT_TIMES = 100 15TIME_UNIT = 'millisecond' 16HW_ENCODE_LABEL = 'hw_encode_time' 17SW_ENCODE_LABEL = 'sw_encode_time' 18LATENCY_50_SUFFIX = '.encode_latency.50_percentile' 19LATENCY_75_SUFFIX = '.encode_latency.75_percentile' 20LATENCY_95_SUFFIX = '.encode_latency.95_percentile' 21HW_PREFIX = 'hw_' 22SW_PREFIX = 'sw_' 23 24class video_JEAPerf(chrome_binary_test.ChromeBinaryTest): 25 """ 26 This test monitors performance metrics reported by Chrome test binary, 27 jpeg_encode_accelerator_unittest. 28 """ 29 30 version = 1 31 binary = 'jpeg_encode_accelerator_unittest' 32 33 def report_perf_results(self, test_name, output_path): 34 hw_times = [] 35 sw_times = [] 36 with open(output_path, 'r') as f: 37 lines = f.readlines() 38 lines = [line.strip() for line in lines] 39 for line in lines: 40 key_value = line.split(':') 41 if len(key_value) != 2: 42 continue 43 (key, value) = (key_value[0].strip(), key_value[1].strip()) 44 if key == HW_ENCODE_LABEL: 45 hw_times.append(int(value)) 46 if key == SW_ENCODE_LABEL: 47 sw_times.append(int(value)) 48 hw_times.sort() 49 sw_times.sort() 50 51 if len(hw_times) > 0: 52 percentile_50 = len(hw_times) / 2 53 percentile_75 = len(hw_times) * 3 / 4 54 percentile_95 = len(hw_times) * 95 / 100 55 test_title = HW_PREFIX + test_name 56 self.output_perf_value(description=(test_title + LATENCY_50_SUFFIX), 57 value=hw_times[percentile_50], 58 units=TIME_UNIT, higher_is_better=False) 59 self.output_perf_value(description=(test_title + LATENCY_75_SUFFIX), 60 value=hw_times[percentile_75], 61 units=TIME_UNIT, higher_is_better=False) 62 self.output_perf_value(description=(test_title + LATENCY_95_SUFFIX), 63 value=hw_times[percentile_95], 64 units=TIME_UNIT, higher_is_better=False) 65 66 if len(sw_times) > 0: 67 percentile_50 = len(sw_times) / 2 68 percentile_75 = len(sw_times) * 3 / 4 69 percentile_95 = len(sw_times) * 95 / 100 70 test_title = SW_PREFIX + test_name 71 self.output_perf_value(description=(test_title + LATENCY_50_SUFFIX), 72 value=sw_times[percentile_50], 73 units=TIME_UNIT, higher_is_better=False) 74 self.output_perf_value(description=(test_title + LATENCY_75_SUFFIX), 75 value=sw_times[percentile_75], 76 units=TIME_UNIT, higher_is_better=False) 77 self.output_perf_value(description=(test_title + LATENCY_95_SUFFIX), 78 value=sw_times[percentile_95], 79 units=TIME_UNIT, higher_is_better=False) 80 81 def remove_if_exists(self, file_path): 82 try: 83 os.remove(file_path) 84 except OSError as e: 85 if e.errno != errno.ENOENT: # no such file 86 raise 87 88 @helper_logger.video_log_wrapper 89 @chrome_binary_test.nuke_chrome 90 def run_once(self, test_cases): 91 """ 92 Runs JpegEncodeAcceleratorTest.SimpleEncode on the device and reports 93 latency values for HW and SW. 94 """ 95 96 for (image_path, width, height) in test_cases: 97 url = DOWNLOAD_BASE + image_path 98 file_name = os.path.basename(image_path) 99 input_path = os.path.join(self.bindir, file_name) 100 file_utils.download_file(url, input_path) 101 test_name = ('%s_%dx%d' % (file_name, width, height)) 102 output_path = os.path.join(self.tmpdir, TEST_LOG) 103 104 cmd_line_list = [helper_logger.chrome_vmodule_flag()] + [ 105 '--gtest_filter=JpegEncodeAcceleratorTest.SimpleEncode', 106 ('--output_log=%s' % output_path), 107 ('--repeat=%d' % REPEAT_TIMES), 108 ('--yuv_filenames="%s:%dx%d"' % (input_path, width, height)) 109 ] 110 cmd_line = ' '.join(cmd_line_list) 111 try: 112 self.run_chrome_test_binary(self.binary, cmd_line) 113 self.report_perf_results(test_name, output_path) 114 except Exception as last_error: 115 # Log the error and continue to the next test case. 116 logging.exception(last_error) 117 finally: 118 self.remove_if_exists(input_path) 119 self.remove_if_exists(output_path) 120 121