[258bda3] | 1 | #! /usr/bin/env python |
---|
| 2 | # |
---|
[06ced25] | 3 | # Copyright 2018 Chris Johns (chrisj@rtems.org) |
---|
| 4 | # All rights reserved. |
---|
| 5 | # |
---|
| 6 | # This file is part of the RTEMS Tools package in 'rtems-tools'. |
---|
| 7 | # |
---|
| 8 | # Redistribution and use in source and binary forms, with or without |
---|
| 9 | # modification, are permitted provided that the following conditions are met: |
---|
| 10 | # |
---|
| 11 | # 1. Redistributions of source code must retain the above copyright notice, |
---|
| 12 | # this list of conditions and the following disclaimer. |
---|
| 13 | # |
---|
| 14 | # 2. Redistributions in binary form must reproduce the above copyright notice, |
---|
| 15 | # this list of conditions and the following disclaimer in the documentation |
---|
| 16 | # and/or other materials provided with the distribution. |
---|
| 17 | # |
---|
| 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
---|
| 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
---|
| 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
---|
| 21 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
---|
| 22 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
---|
| 23 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
---|
| 24 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
---|
| 25 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
---|
| 26 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
---|
| 27 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
---|
| 28 | # POSSIBILITY OF SUCH DAMAGE. |
---|
| 29 | # |
---|
[258bda3] | 30 | # |
---|
| 31 | |
---|
| 32 | # |
---|
| 33 | # Python version the rtems-test-check script. |
---|
| 34 | # |
---|
| 35 | |
---|
| 36 | from __future__ import print_function |
---|
[06ced25] | 37 | |
---|
[258bda3] | 38 | import os.path |
---|
| 39 | import sys |
---|
| 40 | |
---|
| 41 | def eprint(*args, **kwargs): |
---|
| 42 | print(*args, file=sys.stderr, **kwargs) |
---|
| 43 | |
---|
[18f63c0] | 44 | # |
---|
| 45 | # Search the include paths for a file. |
---|
| 46 | # |
---|
| 47 | def find_testdata(paths, name): |
---|
| 48 | for p in paths: |
---|
| 49 | fn = os.path.join(p, name) |
---|
| 50 | if os.path.exists(fn): |
---|
| 51 | return fn |
---|
| 52 | return None |
---|
| 53 | |
---|
[258bda3] | 54 | # |
---|
| 55 | # Arguments. Keep it simple. |
---|
| 56 | # |
---|
[06ced25] | 57 | sys_args = sys.argv[1:] |
---|
| 58 | if len(sys_args) < 4: |
---|
[258bda3] | 59 | eprint('error: invalid command line') |
---|
| 60 | print('INVALID-TEST-DATA') |
---|
| 61 | sys.exit(2) |
---|
| 62 | |
---|
[18f63c0] | 63 | verbose = False |
---|
| 64 | args = 0 |
---|
| 65 | |
---|
[06ced25] | 66 | if sys_args[1] == '-v': |
---|
[18f63c0] | 67 | verbose = True |
---|
| 68 | args = 1 |
---|
| 69 | |
---|
[06ced25] | 70 | mode = sys_args[args + 1] |
---|
| 71 | bsp = sys_args[args + 2] |
---|
| 72 | includepaths = sys_args[args + 4].split(':') |
---|
| 73 | testconfig = [find_testdata(includepaths, sys_args[args + 3])] |
---|
| 74 | tests = sys_args[args + 5:] |
---|
[258bda3] | 75 | |
---|
[3d803af] | 76 | if verbose: |
---|
[06ced25] | 77 | eprint('cmd: %s' % (' '.join(sys_args))) |
---|
[3d803af] | 78 | |
---|
[258bda3] | 79 | # |
---|
| 80 | # Handle the modes. |
---|
| 81 | # |
---|
| 82 | if mode == 'exclude': |
---|
| 83 | pass |
---|
| 84 | elif mode == 'flags': |
---|
| 85 | if len(tests) != 1: |
---|
| 86 | eprint('error: test count not 1 for mode: %s' % (mode)) |
---|
| 87 | print('INVALID-TEST-DATA') |
---|
| 88 | sys.exit(1) |
---|
| 89 | else: |
---|
| 90 | eprint('error: invalid mode: %s' % (mode)) |
---|
| 91 | print('INVALID-TEST-DATA') |
---|
| 92 | sys.exit(1) |
---|
| 93 | |
---|
| 94 | # |
---|
| 95 | # Common RTEMS testsuite configuration. Load first. |
---|
| 96 | # |
---|
[18f63c0] | 97 | rtems_testdata = find_testdata(includepaths, os.path.join('testdata', 'rtems.tcfg')) |
---|
| 98 | if rtems_testdata is not None: |
---|
[258bda3] | 99 | testconfig.insert(0, rtems_testdata) |
---|
| 100 | |
---|
| 101 | states = ['exclude', |
---|
| 102 | 'expected-fail', |
---|
| 103 | 'user-input', |
---|
| 104 | 'indeterminate', |
---|
| 105 | 'benchmark'] |
---|
| 106 | defines = { 'expected-fail' : '-DTEST_STATE_EXPECTED_FAIL=1', |
---|
| 107 | 'user-input' : '-DTEST_STATE_USER_INPUT=1', |
---|
| 108 | 'indeterminate' : '-DTEST_STATE_INDETERMINATE=1', |
---|
| 109 | 'benchmark' : '-DTEST_STATE_BENCHMARK=1' } |
---|
| 110 | output = [] |
---|
| 111 | testdata = {} |
---|
| 112 | |
---|
[18f63c0] | 113 | if verbose: |
---|
| 114 | eprint('mode: %s' % (mode)) |
---|
[3d803af] | 115 | eprint('testconfig: %r' % (testconfig)) |
---|
| 116 | eprint('testconfig: %s' % (', '.join([x for x in testconfig if x is not None]))) |
---|
[18f63c0] | 117 | eprint('includepaths: %s' % (includepaths)) |
---|
| 118 | eprint('bsp: %s' % (bsp)) |
---|
| 119 | eprint('tests: %s' % (', '.join(tests))) |
---|
| 120 | |
---|
[258bda3] | 121 | def clean(line): |
---|
| 122 | line = line[0:-1] |
---|
| 123 | b = line.find('#') |
---|
| 124 | if b >= 0: |
---|
| 125 | line = line[1:b] |
---|
| 126 | return line.strip() |
---|
| 127 | |
---|
| 128 | # |
---|
| 129 | # Load the test data. |
---|
| 130 | # |
---|
[18f63c0] | 131 | while len(testconfig): |
---|
| 132 | tc = testconfig[0] |
---|
| 133 | testconfig.remove(tc) |
---|
[3d803af] | 134 | if tc is None: |
---|
| 135 | continue |
---|
[18f63c0] | 136 | if verbose: |
---|
| 137 | eprint('reading: %s' % (tc)) |
---|
| 138 | if not os.path.exists(tc): |
---|
| 139 | if verbose: |
---|
| 140 | eprint('%s: not found' % (tc)) |
---|
[258bda3] | 141 | continue |
---|
[18f63c0] | 142 | with open(tc) as f: |
---|
[258bda3] | 143 | tdata = [clean(l) for l in f.readlines()] |
---|
| 144 | lc = 0 |
---|
| 145 | for line in tdata: |
---|
| 146 | lc += 1 |
---|
| 147 | ls = [s.strip() for s in line.split(':')] |
---|
| 148 | if len(line) == 0: |
---|
| 149 | continue |
---|
[18f63c0] | 150 | if verbose: |
---|
| 151 | eprint('%4d: %s' % (lc, line)) |
---|
[258bda3] | 152 | if len(ls) != 2: |
---|
| 153 | eprint('error: syntax error: %s:%d' % (tc, lc)) |
---|
| 154 | print('INVALID-TEST-DATA') |
---|
| 155 | sys.exit(1) |
---|
| 156 | state = ls[0] |
---|
| 157 | test = ls[1] |
---|
| 158 | if state == 'include': |
---|
[18f63c0] | 159 | td = find_testdata(includepaths, test) |
---|
| 160 | if td is None: |
---|
| 161 | eprint('error: include not found: %s:%d' % (tc, lc)) |
---|
| 162 | print('INVALID-TEST-DATA') |
---|
| 163 | testconfig.insert(0, td) |
---|
| 164 | if verbose: |
---|
| 165 | eprint('include: %s' % (', '.join(testconfig))) |
---|
[258bda3] | 166 | elif state in states: |
---|
| 167 | if state not in testdata: |
---|
| 168 | testdata[state] = [test] |
---|
| 169 | else: |
---|
| 170 | testdata[state] += [test] |
---|
| 171 | else: |
---|
| 172 | eprint('error: invalid test state: %s in %s:%d' % (state, tc, lc)) |
---|
| 173 | print('INVALID-TEST-DATA') |
---|
| 174 | sys.exit(1) |
---|
| 175 | |
---|
| 176 | for test in tests: |
---|
| 177 | if mode == 'exclude': |
---|
| 178 | if 'exclude' not in testdata or test not in testdata['exclude']: |
---|
| 179 | output += [test] |
---|
| 180 | elif mode == 'flags': |
---|
| 181 | for state in states: |
---|
| 182 | if state != 'exclude' and state in testdata and test in testdata[state]: |
---|
| 183 | output += [defines[state]] |
---|
| 184 | |
---|
| 185 | print(' '.join(sorted(set(output)))) |
---|
| 186 | |
---|
| 187 | sys.exit(0) |
---|