xref: /aosp_15_r20/external/autotest/client/site_tests/hardware_RamFio/hardware_RamFio.py (revision 9c5db1993ded3edbeafc8092d69fe5de2ee02df7)
1# Lint as: python2, python3
2# # Copyright (c) 2014 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
7
8from autotest_lib.client.bin import test
9from autotest_lib.client.bin import utils
10from autotest_lib.client.common_lib import error
11from autotest_lib.client.cros import service_stopper
12
13
14class hardware_RamFio(test.test):
15    """
16    Create ram disk and use FIO to test for ram throughput
17    """
18
19    version = 1
20
21    _MB = 1024 * 1024
22    _DEFAULT_SIZE = 1024 * _MB
23    _RESERVED_RAM_SIZE = 200 * _MB
24    _RAMDISK = '/tmp/ramdisk'
25    _RAMFS_OVERHEAD = 0.2
26
27    def initialize(self):
28        # This test grabs a lot of system memory. Lets move Chrome out of the
29        # picture to avoid interference with OOM killer.
30        self._services = service_stopper.ServiceStopper(['ui'])
31        self._services.stop_services()
32
33    def cleanup(self):
34        if self._services:
35            self._services.restore_services()
36
37    def run_once(self, size=_DEFAULT_SIZE, requirements=None, dry_run=False):
38        """Call hardware_StorageFio to test on ram drive
39
40        @param size: size to test in byte
41                     0 means all usable memory
42        @param requirements: requirement to pass to hardware_StorageFio
43        """
44        usable_mem = utils.usable_memtotal() * 1024
45        logging.info('Found %d bytes of usable memory.', usable_mem)
46        # Assume 20% overhead with ramfs.
47        usable_mem *= 1 - self._RAMFS_OVERHEAD
48
49        # crbug.com/762315 Reserved 200 MiB to prevent OOM error.
50        if usable_mem <= self._RESERVED_RAM_SIZE:
51            raise error.TestNAError(
52                'Usable memory (%d MiB) is less than reserved size (%d MiB).' %
53                (usable_mem / self._MB, self._RESERVED_RAM_SIZE / self._MB))
54        usable_mem -= self._RESERVED_RAM_SIZE
55
56        if size == 0:
57            size = usable_mem
58        elif usable_mem < size:
59            logging.info('Not enough memory. Want: %d, Usable: %d', size,
60                         usable_mem)
61            size = usable_mem
62        self.write_perf_keyval({'Size': size})
63
64        if dry_run:
65            return
66
67        utils.run('mkdir -p %s' % self._RAMDISK)
68        # Don't throw an exception on errors.
69        result = utils.run('mount -t ramfs -o context=u:object_r:tmpfs:s0 '
70                           'ramfs %s' % self._RAMDISK, ignore_status = True)
71        if result.exit_status:
72            logging.info('cannot mount ramfs with context=u:object_r:tmpfs:s0,'
73                         ' trying plain mount')
74            # Try again without selinux options.  This time fail on error.
75            utils.run('mount -t ramfs ramfs %s' % self._RAMDISK)
76
77        self.job.run_test('hardware_StorageFio',
78                          dev='%s/test_file' % self._RAMDISK,
79                          size=size,
80                          requirements=requirements)
81
82        utils.run('umount %s' % self._RAMDISK)
83