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