1# Lint as: python2, python3 2# Copyright 2017 The Chromium OS Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6import logging 7import re 8 9from autotest_lib.client.bin import test, utils 10from autotest_lib.client.common_lib import error 11 12_RESULT_STRING = 'Average page access speed: (\d+)' 13 14class hardware_MemoryZRAMThroughput(test.test): 15 """ 16 This test uses a large buffer to measure the page access throughput with 17 and without ZRAM. 18 """ 19 version = 1 20 21 def initialize(self): 22 utils.system('stop ui', ignore_status=True) 23 self._PATTERN = re.compile(_RESULT_STRING) 24 25 def _log_results(self, key, out): 26 logging.info("test output: %s", out) 27 pages_per_second = 0 28 data_points = 0 29 for line in out.splitlines(): 30 result = self._PATTERN.match(line) 31 if result: 32 pages_per_second += float(result.group(1)) 33 data_points += 1 34 continue 35 36 if data_points == 0: 37 raise error.TestError('Test results not found') 38 39 # Take the average of all data points. Currently when --fork is 40 # passed to memory-eater, there will be two data points from two 41 # processes. 42 average_pages_per_second = pages_per_second / data_points 43 self.output_perf_value(description=key, 44 value=average_pages_per_second, 45 higher_is_better=True, 46 units='pages_per_sec') 47 48 return average_pages_per_second 49 50 def run_once(self): 51 mem_size = utils.memtotal() 52 swap_size = utils.swaptotal() 53 logging.info("MemTotal: %.0f KB", mem_size) 54 logging.info("SwapTotal: %.0f KB", swap_size) 55 56 # First run memory-eater wth 60% of total memory size to measure the 57 # page access throughput 58 cmd = ("memory-eater --size %d --speed --repeat 4 --chunk 500 " 59 "--wait 0" % int(mem_size * 0.60 / 1024)) 60 logging.debug('cmd: %s', cmd) 61 out = utils.system_output(cmd) 62 self._log_results("60_Percent_RAM", out) 63 64 # Then run memory-eater wth total memory + 30% swap size to measure the 65 # page access throughput. On 32-bit system with 4GB of RAM, the memory 66 # footprint needed to generate enough memory pressure is larger than 67 # a single user-space process can own. So we divide the memory usage 68 # by half and the test itself will fork a child process to double the 69 # memory usage. Each process will take turns to access 500 pages 70 # (via --chunk) until all pages are accessed 4 times (via --repeat). 71 half_mem_pressure_size = int((mem_size+swap_size * 0.3) / 1024) / 2; 72 cmd = ("memory-eater --size %d --speed --fork --repeat 4 --chunk 500" 73 "--wait 0" % half_mem_pressure_size) 74 logging.debug('cmd: %s', cmd) 75 out = utils.system_output(cmd) 76 self._log_results("30_Percent_SWAP", out) 77 78 def cleanup(self): 79 utils.system('start ui') 80