# Copyright 2016 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 os, re, glob, logging, shutil from autotest_lib.client.common_lib import error from autotest_lib.client.bin import test, utils class xfstests(test.test): """ Runs a single test of the xfstests suite. """ XFS_TESTS_PATH='/usr/local/xfstests' XFS_EXCLUDE_FILENAME = '/tmp/.xfstests.exclude' version = 2 PASSED_RE = re.compile(r'Passed all \d+ tests') FAILED_RE = re.compile(r'Failed \d+ of \d+ tests') TEST_RE = re.compile(r'(?P\d+)\.out') NA_RE = re.compile(r'Passed all 0 tests') NA_DETAIL_RE = re.compile(r'(\d{3})\s*(\[not run\])\s*(.*)') def _get_available_tests(self, fs): os.chdir(os.path.join(self.XFS_TESTS_PATH, 'tests', fs)) tests = glob.glob('*.out*') tests_list = [] for t in tests: t_m = self.TEST_RE.match(t) if t_m: t_name = t_m.group('name') if t_name not in tests_list and os.path.exists(t_name): tests_list.append(t_name) tests_list.sort() return tests_list def _run_sub_test(self, test): os.chdir(self.XFS_TESTS_PATH) logging.debug("Environment variables: %s", os.environ) output = utils.system_output( 'bash ./check %s' % os.path.join('tests', test), ignore_status=True, retain_output=True) lines = output.split('\n') result_line = lines[-2] result_full = os.path.join('results', '.'.join([test, 'full'])) result_full_loc = os.path.join(self.XFS_TESTS_PATH, result_full) if os.path.isfile(result_full_loc): shutil.copyfile(result_full_loc, os.path.join(self.resultsdir, 'full')) if self.NA_RE.match(result_line): detail_line = lines[-3] match = self.NA_DETAIL_RE.match(detail_line) if match is not None: error_msg = match.groups()[2] else: error_msg = 'Test dependency failed, test not run' raise error.TestNAError(error_msg) elif self.FAILED_RE.match(result_line): raise error.TestError('Test error, check debug logs for complete ' 'test output') elif self.PASSED_RE.match(result_line): return else: raise error.TestError('Could not assert test success or failure, ' 'assuming failure. Please check debug logs') def _run_standalone(self, group): os.chdir(self.XFS_TESTS_PATH) logging.debug("Environment variables: %s", os.environ) output = utils.system_output( 'bash ./check -E %s -g %s' % (self.XFS_EXCLUDE_FILENAME, group), ignore_status=True, retain_output=True) lines = output.split('\n') result_line = lines[-2] if self.NA_RE.match(result_line): raise error.TestNAError('Test dependency failed, no tests run') elif self.FAILED_RE.match(result_line): failures_line = re.match(r'Failures: (?P.*)', lines[-3]) if failures_line: test_failures = failures_line.group('tests') tests = test_failures.split(' ') for test in tests: result_full = os.path.join('results', '.'.join([test, 'full'])) result_full_loc = os.path.join(self.XFS_TESTS_PATH, result_full) if os.path.isfile(result_full_loc): test_name = test.replace('/','_') shutil.copyfile(result_full_loc, os.path.join(self.resultsdir, '%s.full' % test_name)) raise error.TestError('%s. Check debug logs for complete ' 'test output' % result_line) elif self.PASSED_RE.match(result_line): return else: raise error.TestError('Could not assert success or failure, ' 'assuming failure. Please check debug logs') def run_once(self, test_dir='generic', test_number='000', group=None, exclude=[]): if group: excludeFile = open(self.XFS_EXCLUDE_FILENAME, 'w') for test in exclude: excludeFile.write('%s\n' % test) excludeFile.close() logging.debug("Running tests: group %s", group ) self._run_standalone(group) if os.path.exists(self.XFS_EXCLUDE_FILENAME): os.remove(self.XFS_EXCLUDE_FILENAME) else: if test_number == '000': logging.debug('Dummy test to setup xfstests') return if test_number not in self._get_available_tests(test_dir): raise error.TestNAError( 'test file %s/%s not found' % (test_dir, test_number)) test_name = os.path.join(test_dir, test_number) logging.debug("Running test: %s", test_name) self._run_sub_test(test_name)