xref: /aosp_15_r20/external/autotest/client/tests/disktest/disktest.py (revision 9c5db1993ded3edbeafc8092d69fe5de2ee02df7)
1*9c5db199SXin Liimport os, sys, subprocess, logging
2*9c5db199SXin Lifrom autotest_lib.client.bin import test, utils
3*9c5db199SXin Lifrom autotest_lib.client.common_lib import error
4*9c5db199SXin Li
5*9c5db199SXin Li
6*9c5db199SXin Liclass disktest(test.test):
7*9c5db199SXin Li    """
8*9c5db199SXin Li    Autotest module for disktest.
9*9c5db199SXin Li
10*9c5db199SXin Li    Pattern test of the disk, using unique signatures for each block and each
11*9c5db199SXin Li    iteration of the test. Designed to check for data corruption issues in the
12*9c5db199SXin Li    disk and disk controller.
13*9c5db199SXin Li
14*9c5db199SXin Li    It writes 50MB/s of 500KB size ops.
15*9c5db199SXin Li
16*9c5db199SXin Li    @author: Martin Bligh ([email protected])
17*9c5db199SXin Li    """
18*9c5db199SXin Li    version = 2
19*9c5db199SXin Li    preserve_srcdir = True
20*9c5db199SXin Li
21*9c5db199SXin Li    def setup(self):
22*9c5db199SXin Li        """
23*9c5db199SXin Li        Compiles disktest.
24*9c5db199SXin Li        """
25*9c5db199SXin Li        os.chdir(self.srcdir)
26*9c5db199SXin Li        utils.make('clean')
27*9c5db199SXin Li        utils.make()
28*9c5db199SXin Li
29*9c5db199SXin Li
30*9c5db199SXin Li    def initialize(self):
31*9c5db199SXin Li        """
32*9c5db199SXin Li        Verifies if we have gcc to compile disktest.
33*9c5db199SXin Li        """
34*9c5db199SXin Li        self.job.require_gcc()
35*9c5db199SXin Li
36*9c5db199SXin Li
37*9c5db199SXin Li    def test_one_disk_chunk(self, disk, chunk):
38*9c5db199SXin Li        """
39*9c5db199SXin Li        Tests one part of the disk by spawning a disktest instance.
40*9c5db199SXin Li
41*9c5db199SXin Li        @param disk: Directory (usually a mountpoint).
42*9c5db199SXin Li        @param chunk: Portion of the disk used.
43*9c5db199SXin Li        """
44*9c5db199SXin Li        logging.info("Testing %d MB files on %s in %d MB memory, chunk %s",
45*9c5db199SXin Li                     self.chunk_mb, disk, self.memory_mb, chunk)
46*9c5db199SXin Li        cmd = ("%s/disktest -m %d -f %s/testfile.%d -i -S" %
47*9c5db199SXin Li               (self.srcdir, self.chunk_mb, disk, chunk))
48*9c5db199SXin Li        logging.debug("Running '%s'", cmd)
49*9c5db199SXin Li        p = subprocess.Popen(cmd, shell=True)
50*9c5db199SXin Li        return(p.pid)
51*9c5db199SXin Li
52*9c5db199SXin Li
53*9c5db199SXin Li    def run_once(self, disks=None, gigabytes=None, chunk_mb=None):
54*9c5db199SXin Li        """
55*9c5db199SXin Li        Runs one iteration of disktest.
56*9c5db199SXin Li
57*9c5db199SXin Li        @param disks: List of directories (usually mountpoints) to be passed
58*9c5db199SXin Li                to the test.
59*9c5db199SXin Li        @param gigabytes: Disk space that will be used for the test to run.
60*9c5db199SXin Li        @param chunk_mb: Size of the portion of the disk used to run the test.
61*9c5db199SXin Li                Cannot be larger than the total amount of free RAM.
62*9c5db199SXin Li        """
63*9c5db199SXin Li        os.chdir(self.srcdir)
64*9c5db199SXin Li        if chunk_mb is None:
65*9c5db199SXin Li            chunk_mb = utils.memtotal() / 1024
66*9c5db199SXin Li        if disks is None:
67*9c5db199SXin Li            disks = [self.tmpdir]
68*9c5db199SXin Li        if gigabytes is None:
69*9c5db199SXin Li            free = 100 # cap it at 100GB by default
70*9c5db199SXin Li            for disk in disks:
71*9c5db199SXin Li                free = min(utils.freespace(disk) / 1024**3, free)
72*9c5db199SXin Li            gigabytes = free
73*9c5db199SXin Li            logging.info("Resizing to %s GB", gigabytes)
74*9c5db199SXin Li            sys.stdout.flush()
75*9c5db199SXin Li
76*9c5db199SXin Li        self.chunk_mb = chunk_mb
77*9c5db199SXin Li        self.memory_mb = utils.memtotal()/1024
78*9c5db199SXin Li        if self.memory_mb > chunk_mb:
79*9c5db199SXin Li            raise error.TestError("Too much RAM (%dMB) for this test to work" %
80*9c5db199SXin Li                                  self.memory_mb)
81*9c5db199SXin Li
82*9c5db199SXin Li        chunks = (1024 * gigabytes) / chunk_mb
83*9c5db199SXin Li
84*9c5db199SXin Li        logging.info("Total of disk chunks that will be used: %s", chunks)
85*9c5db199SXin Li        for i in range(chunks):
86*9c5db199SXin Li            pids = []
87*9c5db199SXin Li            for disk in disks:
88*9c5db199SXin Li                pid = self.test_one_disk_chunk(disk, i)
89*9c5db199SXin Li                pids.append(pid)
90*9c5db199SXin Li            errors = []
91*9c5db199SXin Li            for pid in pids:
92*9c5db199SXin Li                (junk, retval) = os.waitpid(pid, 0)
93*9c5db199SXin Li                if (retval != 0):
94*9c5db199SXin Li                    errors.append(retval)
95*9c5db199SXin Li            if errors:
96*9c5db199SXin Li                raise error.TestError("Errors from children: %s" % errors)
97