Gwendal Grignou | 7a80494 | 2016-01-25 12:38:49 -0800 | [diff] [blame] | 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 |
Dale Curtis | 456d3c1 | 2011-07-19 11:42:51 -0700 | [diff] [blame] | 6 | from autotest_lib.client.common_lib import error |
Gwendal Grignou | 7a80494 | 2016-01-25 12:38:49 -0800 | [diff] [blame] | 7 | from autotest_lib.client.bin import test, utils |
Dale Curtis | 456d3c1 | 2011-07-19 11:42:51 -0700 | [diff] [blame] | 8 | |
| 9 | class xfstests(test.test): |
Gwendal Grignou | 7a80494 | 2016-01-25 12:38:49 -0800 | [diff] [blame] | 10 | """ |
| 11 | Runs a single test of the xfstests suite. |
| 12 | """ |
Dale Curtis | 456d3c1 | 2011-07-19 11:42:51 -0700 | [diff] [blame] | 13 | |
Gwendal Grignou | 7a80494 | 2016-01-25 12:38:49 -0800 | [diff] [blame] | 14 | XFS_TESTS_PATH='/usr/local/xfstests' |
Alexis Savery | 08b9b41 | 2017-10-30 16:25:25 -0700 | [diff] [blame] | 15 | XFS_EXCLUDE_FILENAME = '/tmp/.xfstests.exclude' |
Gwendal Grignou | 7a80494 | 2016-01-25 12:38:49 -0800 | [diff] [blame] | 16 | version = 2 |
Dale Curtis | 456d3c1 | 2011-07-19 11:42:51 -0700 | [diff] [blame] | 17 | |
| 18 | PASSED_RE = re.compile(r'Passed all \d+ tests') |
| 19 | FAILED_RE = re.compile(r'Failed \d+ of \d+ tests') |
Gwendal Grignou | 7a80494 | 2016-01-25 12:38:49 -0800 | [diff] [blame] | 20 | TEST_RE = re.compile(r'(?P<name>\d+)\.out') |
Dale Curtis | 456d3c1 | 2011-07-19 11:42:51 -0700 | [diff] [blame] | 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 | |
Gwendal Grignou | 7a80494 | 2016-01-25 12:38:49 -0800 | [diff] [blame] | 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) |
Dale Curtis | 456d3c1 | 2011-07-19 11:42:51 -0700 | [diff] [blame] | 35 | tests_list.sort() |
| 36 | return tests_list |
| 37 | |
| 38 | |
Gwendal Grignou | 6cf7d07 | 2018-05-25 10:05:51 -0700 | [diff] [blame] | 39 | def _copy_result_test(self, t): |
Gwendal Grignou | 0a30db5 | 2018-05-25 08:58:31 -0700 | [diff] [blame] | 40 | for ext in ('full', 'dmesg'): |
Gwendal Grignou | 6cf7d07 | 2018-05-25 10:05:51 -0700 | [diff] [blame] | 41 | result_file = os.path.join('results', '.'.join([t, ext])) |
Gwendal Grignou | 0a30db5 | 2018-05-25 08:58:31 -0700 | [diff] [blame] | 42 | result_file_loc = os.path.join(self.XFS_TESTS_PATH, result_file) |
Gwendal Grignou | 6cf7d07 | 2018-05-25 10:05:51 -0700 | [diff] [blame] | 43 | test_name = t.replace('/','_') |
Gwendal Grignou | 0a30db5 | 2018-05-25 08:58:31 -0700 | [diff] [blame] | 44 | result_file_dest = os.path.join( |
| 45 | self.resultsdir, '.'.join([test_name, ext])) |
| 46 | if os.path.isfile(result_file_loc): |
| 47 | shutil.copyfile(result_file_loc, result_file_dest) |
| 48 | |
| 49 | |
Gwendal Grignou | 6cf7d07 | 2018-05-25 10:05:51 -0700 | [diff] [blame] | 50 | def _run_sub_test(self, t): |
Gwendal Grignou | 7a80494 | 2016-01-25 12:38:49 -0800 | [diff] [blame] | 51 | os.chdir(self.XFS_TESTS_PATH) |
| 52 | logging.debug("Environment variables: %s", os.environ) |
| 53 | output = utils.system_output( |
Gwendal Grignou | 6cf7d07 | 2018-05-25 10:05:51 -0700 | [diff] [blame] | 54 | 'bash ./check %s' % os.path.join('tests', t), |
Gwendal Grignou | 7a80494 | 2016-01-25 12:38:49 -0800 | [diff] [blame] | 55 | ignore_status=True, |
| 56 | retain_output=True) |
Dale Curtis | 456d3c1 | 2011-07-19 11:42:51 -0700 | [diff] [blame] | 57 | lines = output.split('\n') |
Gwendal Grignou | 7a80494 | 2016-01-25 12:38:49 -0800 | [diff] [blame] | 58 | result_line = lines[-2] |
Gwendal Grignou | 6cf7d07 | 2018-05-25 10:05:51 -0700 | [diff] [blame] | 59 | self._copy_result_test(t) |
Dale Curtis | 456d3c1 | 2011-07-19 11:42:51 -0700 | [diff] [blame] | 60 | |
| 61 | if self.NA_RE.match(result_line): |
| 62 | detail_line = lines[-3] |
| 63 | match = self.NA_DETAIL_RE.match(detail_line) |
| 64 | if match is not None: |
| 65 | error_msg = match.groups()[2] |
| 66 | else: |
| 67 | error_msg = 'Test dependency failed, test not run' |
| 68 | raise error.TestNAError(error_msg) |
| 69 | |
| 70 | elif self.FAILED_RE.match(result_line): |
| 71 | raise error.TestError('Test error, check debug logs for complete ' |
| 72 | 'test output') |
| 73 | |
| 74 | elif self.PASSED_RE.match(result_line): |
| 75 | return |
| 76 | |
| 77 | else: |
| 78 | raise error.TestError('Could not assert test success or failure, ' |
| 79 | 'assuming failure. Please check debug logs') |
| 80 | |
| 81 | |
Alexis Savery | 08b9b41 | 2017-10-30 16:25:25 -0700 | [diff] [blame] | 82 | def _run_standalone(self, group): |
| 83 | os.chdir(self.XFS_TESTS_PATH) |
| 84 | logging.debug("Environment variables: %s", os.environ) |
| 85 | output = utils.system_output( |
| 86 | 'bash ./check -E %s -g %s' % (self.XFS_EXCLUDE_FILENAME, group), |
| 87 | ignore_status=True, |
| 88 | retain_output=True) |
| 89 | lines = output.split('\n') |
| 90 | result_line = lines[-2] |
Dale Curtis | 456d3c1 | 2011-07-19 11:42:51 -0700 | [diff] [blame] | 91 | |
Alexis Savery | 08b9b41 | 2017-10-30 16:25:25 -0700 | [diff] [blame] | 92 | if self.NA_RE.match(result_line): |
| 93 | raise error.TestNAError('Test dependency failed, no tests run') |
| 94 | |
| 95 | elif self.FAILED_RE.match(result_line): |
| 96 | failures_line = re.match(r'Failures: (?P<tests>.*)', lines[-3]) |
| 97 | if failures_line: |
| 98 | test_failures = failures_line.group('tests') |
| 99 | tests = test_failures.split(' ') |
Gwendal Grignou | 6cf7d07 | 2018-05-25 10:05:51 -0700 | [diff] [blame] | 100 | for t in tests: |
| 101 | self._copy_result_test(t) |
Gwendal Grignou | 0a30db5 | 2018-05-25 08:58:31 -0700 | [diff] [blame] | 102 | |
Alexis Savery | 08b9b41 | 2017-10-30 16:25:25 -0700 | [diff] [blame] | 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, |
Gwendal Grignou | 6cf7d07 | 2018-05-25 10:05:51 -0700 | [diff] [blame] | 114 | exclude=None): |
Alexis Savery | 08b9b41 | 2017-10-30 16:25:25 -0700 | [diff] [blame] | 115 | if group: |
| 116 | excludeFile = open(self.XFS_EXCLUDE_FILENAME, 'w') |
Gwendal Grignou | 6cf7d07 | 2018-05-25 10:05:51 -0700 | [diff] [blame] | 117 | for t in exclude or []: |
| 118 | excludeFile.write('%s\n' % t) |
Alexis Savery | 08b9b41 | 2017-10-30 16:25:25 -0700 | [diff] [blame] | 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( |
Gwendal Grignou | 7a80494 | 2016-01-25 12:38:49 -0800 | [diff] [blame] | 131 | 'test file %s/%s not found' % (test_dir, test_number)) |
Dale Curtis | 456d3c1 | 2011-07-19 11:42:51 -0700 | [diff] [blame] | 132 | |
Alexis Savery | 08b9b41 | 2017-10-30 16:25:25 -0700 | [diff] [blame] | 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) |