Home | History | Annotate | Download | only in xfstests
      1 # Copyright 2016 The Chromium OS Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 import os, re, glob, logging, shutil
      6 from autotest_lib.client.common_lib import error
      7 from autotest_lib.client.bin import test, utils
      8 
      9 class xfstests(test.test):
     10     """
     11     Runs a single test of the xfstests suite.
     12     """
     13 
     14     XFS_TESTS_PATH='/usr/local/xfstests'
     15     XFS_EXCLUDE_FILENAME = '/tmp/.xfstests.exclude'
     16     version = 2
     17 
     18     PASSED_RE = re.compile(r'Passed all \d+ tests')
     19     FAILED_RE = re.compile(r'Failed \d+ of \d+ tests')
     20     TEST_RE = re.compile(r'(?P<name>\d+)\.out')
     21     NA_RE = re.compile(r'Passed all 0 tests')
     22     NA_DETAIL_RE = re.compile(r'(\d{3})\s*(\[not run\])\s*(.*)')
     23 
     24 
     25     def _get_available_tests(self, fs):
     26         os.chdir(os.path.join(self.XFS_TESTS_PATH, 'tests', fs))
     27         tests = glob.glob('*.out*')
     28         tests_list = []
     29         for t in tests:
     30             t_m = self.TEST_RE.match(t)
     31             if t_m:
     32                 t_name = t_m.group('name')
     33                 if t_name not in tests_list and os.path.exists(t_name):
     34                     tests_list.append(t_name)
     35         tests_list.sort()
     36         return tests_list
     37 
     38 
     39     def _run_sub_test(self, test):
     40         os.chdir(self.XFS_TESTS_PATH)
     41         logging.debug("Environment variables: %s", os.environ)
     42         output = utils.system_output(
     43                 'bash ./check %s' % os.path.join('tests', test),
     44                 ignore_status=True,
     45                 retain_output=True)
     46         lines = output.split('\n')
     47         result_line = lines[-2]
     48         result_full = os.path.join('results', '.'.join([test, 'full']))
     49         result_full_loc = os.path.join(self.XFS_TESTS_PATH, result_full)
     50         if os.path.isfile(result_full_loc):
     51             shutil.copyfile(result_full_loc,
     52                             os.path.join(self.resultsdir, 'full'))
     53 
     54         if self.NA_RE.match(result_line):
     55             detail_line = lines[-3]
     56             match = self.NA_DETAIL_RE.match(detail_line)
     57             if match is not None:
     58                 error_msg = match.groups()[2]
     59             else:
     60                 error_msg = 'Test dependency failed, test not run'
     61             raise error.TestNAError(error_msg)
     62 
     63         elif self.FAILED_RE.match(result_line):
     64             raise error.TestError('Test error, check debug logs for complete '
     65                                   'test output')
     66 
     67         elif self.PASSED_RE.match(result_line):
     68             return
     69 
     70         else:
     71             raise error.TestError('Could not assert test success or failure, '
     72                                   'assuming failure. Please check debug logs')
     73 
     74 
     75     def _run_standalone(self, group):
     76         os.chdir(self.XFS_TESTS_PATH)
     77         logging.debug("Environment variables: %s", os.environ)
     78         output = utils.system_output(
     79                 'bash ./check -E %s -g %s' % (self.XFS_EXCLUDE_FILENAME, group),
     80                 ignore_status=True,
     81                 retain_output=True)
     82         lines = output.split('\n')
     83         result_line = lines[-2]
     84 
     85         if self.NA_RE.match(result_line):
     86             raise error.TestNAError('Test dependency failed, no tests run')
     87 
     88         elif self.FAILED_RE.match(result_line):
     89             failures_line = re.match(r'Failures: (?P<tests>.*)', lines[-3])
     90             if failures_line:
     91                 test_failures = failures_line.group('tests')
     92                 tests = test_failures.split(' ')
     93                 for test in tests:
     94                     result_full = os.path.join('results',
     95                                                '.'.join([test, 'full']))
     96                     result_full_loc = os.path.join(self.XFS_TESTS_PATH,
     97                                                    result_full)
     98                     if os.path.isfile(result_full_loc):
     99                         test_name = test.replace('/','_')
    100                         shutil.copyfile(result_full_loc,
    101                                         os.path.join(self.resultsdir,
    102                                                      '%s.full' % test_name))
    103             raise error.TestError('%s. Check debug logs for complete '
    104                                   'test output' % result_line)
    105 
    106         elif self.PASSED_RE.match(result_line):
    107             return
    108         else:
    109             raise error.TestError('Could not assert success or failure, '
    110                                   'assuming failure. Please check debug logs')
    111 
    112 
    113     def run_once(self, test_dir='generic', test_number='000', group=None,
    114                  exclude=[]):
    115         if group:
    116             excludeFile = open(self.XFS_EXCLUDE_FILENAME, 'w')
    117             for test in exclude:
    118                 excludeFile.write('%s\n' % test)
    119             excludeFile.close()
    120             logging.debug("Running tests: group %s", group )
    121             self._run_standalone(group)
    122             if os.path.exists(self.XFS_EXCLUDE_FILENAME):
    123                 os.remove(self.XFS_EXCLUDE_FILENAME)
    124         else:
    125             if test_number == '000':
    126                 logging.debug('Dummy test to setup xfstests')
    127                 return
    128 
    129             if test_number not in self._get_available_tests(test_dir):
    130                 raise error.TestNAError(
    131                     'test file %s/%s not found' % (test_dir, test_number))
    132 
    133             test_name = os.path.join(test_dir, test_number)
    134             logging.debug("Running test: %s", test_name)
    135             self._run_sub_test(test_name)
    136