| # Copyright (c) 2014 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import logging |
| import os |
| import shutil |
| |
| from autotest_lib.client.bin import test |
| from autotest_lib.client.bin import utils |
| from autotest_lib.client.common_lib import error |
| from autotest_lib.client.cros import service_stopper |
| |
| |
| class hardware_RamFio(test.test): |
| """ |
| Create ram disk and use FIO to test for ram throughput |
| """ |
| |
| version = 1 |
| |
| _MB = 1024 * 1024 |
| _DEFAULT_SIZE = 1024 * _MB |
| _RESERVED_RAM_SIZE = 200 * _MB |
| _RAMDISK = '/tmp/ramdisk' |
| _RAMFS_OVERHEAD = 0.2 |
| |
| def initialize(self): |
| # This test grabs a lot of system memory. Lets move Chrome out of the |
| # picture to avoid interference with OOM killer. |
| self._services = service_stopper.ServiceStopper(['ui']) |
| self._services.stop_services() |
| |
| def cleanup(self): |
| if self._services: |
| self._services.restore_services() |
| |
| def run_once(self, size=_DEFAULT_SIZE, requirements=None, dry_run=False): |
| """Call hardware_StorageFio to test on ram drive |
| |
| @param size: size to test in byte |
| 0 means all usable memory |
| @param requirements: requirement to pass to hardware_StorageFio |
| """ |
| usable_mem = utils.usable_memtotal() * 1024 |
| logging.info('Found %d bytes of usable memory.', usable_mem) |
| # Assume 20% overhead with ramfs. |
| usable_mem *= 1 - self._RAMFS_OVERHEAD |
| |
| # crbug.com/762315 Reserved 200 MiB to prevent OOM error. |
| if usable_mem <= self._RESERVED_RAM_SIZE: |
| raise error.TestNAError( |
| 'Usable memory (%d MiB) is less than reserved size (%d MiB).' % |
| (usable_mem / self._MB, self._RESERVED_RAM_SIZE / self._MB)) |
| usable_mem -= self._RESERVED_RAM_SIZE |
| |
| if size == 0: |
| size = usable_mem |
| elif usable_mem < size: |
| logging.info('Not enough memory. Want: %d, Usable: %d', size, |
| usable_mem) |
| size = usable_mem |
| self.write_perf_keyval({'Size': size}) |
| |
| if dry_run: |
| return |
| |
| utils.run('mkdir -p %s' % self._RAMDISK) |
| # Don't throw an exception on errors. |
| result = utils.run('mount -t ramfs -o context=u:object_r:tmpfs:s0 ' |
| 'ramfs %s' % self._RAMDISK, ignore_status = True) |
| if result.exit_status: |
| logging.info('cannot mount ramfs with context=u:object_r:tmpfs:s0,' |
| ' trying plain mount') |
| # Try again without selinux options. This time fail on error. |
| utils.run('mount -t ramfs ramfs %s' % self._RAMDISK) |
| |
| self.job.run_test('hardware_StorageFio', |
| dev='%s/test_file' % self._RAMDISK, |
| size=size, |
| requirements=requirements) |
| |
| utils.run('umount %s' % self._RAMDISK) |
| |
| dst = os.path.join(self.resultsdir, 'results-chart.json') |
| src = dst.replace('hardware_RamFio', 'hardware_StorageFio') |
| shutil.copyfile(src, dst) |