source: rtems/testsuites/rtems-test-check.py

Last change on this file was a06356b, checked in by Chris Johns <chrisj@…>, on Mar 6, 2019 at 9:31:10 AM

testsuite: Add rexclude, rinclude and cflags to test config files.

  • Property mode set to 100755
File size: 8.1 KB
Line 
1#! /usr/bin/env python
2#
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#
30#
31
32#
33# Python version the rtems-test-check script.
34#
35
36from __future__ import print_function
37
38import os
39import os.path
40import re
41import sre_constants
42import sys
43
44def eprint(*args, **kwargs):
45    print(*args, file=sys.stderr, **kwargs)
46
47#
48# Search the include paths for a file.
49#
50def find_testdata(paths, name):
51    for p in paths:
52        fn = os.path.join(p, name)
53        if os.path.exists(fn):
54            return fn
55    return None
56
57#
58# Arguments. Keep it simple.
59#
60sys_args = sys.argv[1:]
61if len(sys_args) < 4:
62    eprint('error: invalid command line')
63    print('INVALID-TEST-DATA')
64    sys.exit(2)
65
66verbose = False
67args = 0
68
69if sys_args[1] == '-v':
70    verbose = True
71    args = 1
72
73mode = sys_args[args + 1]
74bsp = sys_args[args + 2]
75includepaths = sys_args[args + 4].split(os.pathsep)
76testconfig = [find_testdata(includepaths, sys_args[args + 3])]
77tests = sys_args[args + 5:]
78
79if verbose:
80    eprint('cmd: %s' % (' '.join(sys_args)))
81
82#
83# Handle the modes.
84#
85if mode == 'exclude':
86    pass
87elif mode == 'cflags':
88    if len(tests) != 1:
89        eprint('error: test count not 1 for mode: %s' % (mode))
90        print('INVALID-TEST-DATA')
91        sys.exit(1)
92else:
93    eprint('error: invalid mode: %s' % (mode))
94    print('INVALID-TEST-DATA')
95    sys.exit(1)
96
97#
98# Common RTEMS testsuite configuration. Load first.
99#
100rtems_testdata = find_testdata(includepaths, os.path.join('testdata', 'rtems.tcfg'))
101if rtems_testdata is not None:
102    testconfig.insert(0, rtems_testdata)
103
104states = ['exclude',
105          'expected-fail',
106          'user-input',
107          'indeterminate',
108          'benchmark',
109          'rexclude',
110          'rinclude']
111flags = ['cflags']
112defines = { 'expected-fail' : '-DTEST_STATE_EXPECTED_FAIL=1',
113            'user-input'    : '-DTEST_STATE_USER_INPUT=1',
114            'indeterminate' : '-DTEST_STATE_INDETERMINATE=1',
115            'benchmark'     : '-DTEST_STATE_BENCHMARK=1' }
116output = []
117testdata = { 'flags': {} }
118
119for f in flags:
120    testdata['flags'][f] = {}
121
122if verbose:
123    eprint('mode: %s' % (mode))
124    eprint('testconfig: %r' % (testconfig))
125    eprint('testconfig: %s' % (', '.join([x for x in testconfig if x is not None])))
126    eprint('includepaths: %s' % (includepaths))
127    eprint('bsp: %s' % (bsp))
128    eprint('tests: %s' % (', '.join(tests)))
129
130def clean(line):
131    line = line[0:-1]
132    b = line.find('#')
133    if b >= 0:
134        line = line[1:b]
135    return line.strip()
136
137#
138# Load the test data.
139#
140while len(testconfig):
141    tc = testconfig[0]
142    testconfig.remove(tc)
143    if tc is None:
144        continue
145    if verbose:
146        eprint('reading: %s' % (tc))
147    if not os.path.exists(tc):
148        if verbose:
149            eprint('%s: not found' % (tc))
150        continue
151    with open(tc) as f:
152        tdata = [clean(l) for l in f.readlines()]
153    lc = 0
154    for line in tdata:
155        lc += 1
156        if len(line) == 0:
157            continue
158        ls = [s.strip() for s in line.split(':', 1)]
159        if verbose:
160            eprint('%4d: %s' % (lc, line))
161        if len(ls) != 2:
162            eprint('error: syntax error: %s:%d' % (tc, lc))
163            print('INVALID-TEST-DATA')
164            sys.exit(1)
165        state = ls[0]
166        test = ls[1]
167        if state == 'include':
168            td = find_testdata(includepaths, test)
169            if td is None:
170                eprint('error: include not found: %s:%d' % (tc, lc))
171                print('INVALID-TEST-DATA')
172                sys.exit(1)
173            testconfig.insert(0, td)
174            if verbose:
175                eprint('include: %s' % (', '.join(testconfig)))
176        elif state in flags:
177            fs = test.split(':', 1)
178            if len(fs) != 2:
179                eprint('error: syntax error: %s:%d' % (tc, lc))
180                print('INVALID-TEST-DATA')
181                sys.exit(1)
182            ftests = [t.strip() for t in fs[0].split(',')]
183            if verbose:
184                eprint('%4d: %r : %s' % (lc, ftests, fs[1]))
185            for test in ftests:
186                if test not in testdata['flags'][state]:
187                    testdata['flags'][state][test] = [fs[1]]
188                else:
189                    testdata['flags'][state][test] += [fs[1]]
190        elif state in states:
191            stests = [t.strip() for t in test.split(',')]
192            if state not in testdata:
193                testdata[state] = stests
194            else:
195                testdata[state] += stests
196        else:
197            eprint('error: invalid test state: %s in %s:%d' % (state, tc, lc))
198            print('INVALID-TEST-DATA')
199            sys.exit(1)
200
201if mode in flags:
202    for state in ['exclude', 'rexclude', 'rinclude']:
203        states.remove(state)
204
205for test in tests:
206    if mode == 'exclude':
207        #
208        # Exclude is the highest priority, do this first
209        #
210        if 'exclude' in testdata and test in testdata['exclude']:
211            exclude = True
212        else:
213            #
214            # Regx exclude then regx include so you can filter a whole
215            # group and add back some.
216            #
217            exclude = False
218            if 'rexclude' in testdata:
219                for e in testdata['rexclude']:
220                    try:
221                        m = re.compile(e).match(test)
222                    except sre_constants.error as ree:
223                        eprint('error: invalid rexclude regx: %s: %s' % (e, ree))
224                        print('INVALID-TEST-DATA')
225                        sys.exit(1)
226                    if m:
227                        exclude = True
228                        if 'rinclude' in testdata:
229                            for i in testdata['rinclude']:
230                                try:
231                                    m = re.compile(i).match(test)
232                                except sre_constants.error as ree:
233                                    eprint('error: invalid rinclude regx: %s: %s' % (i, ree))
234                                    print('INVALID-TEST-DATA')
235                                    sys.exit(1)
236                                if m:
237                                    exclude = False
238        #
239        # If not excluded add the test to the output
240        #
241        if not exclude:
242            output += [test]
243    elif mode in flags:
244        if mode == 'cflags':
245            for state in states:
246                if state in testdata and test in testdata[state]:
247                    output += [defines[state]]
248        for ftest in testdata['flags'][mode]:
249            try:
250                m = re.compile(ftest).match(test)
251            except sre_constants.error as ref:
252                eprint('error: invalid flags test regx: %s: %s' % (ftest, ref))
253                print('INVALID-TEST-DATA')
254                sys.exit(1)
255            if m:
256                output += testdata['flags'][mode][ftest]
257
258print(' '.join(sorted(set(output))))
259
260sys.exit(0)
Note: See TracBrowser for help on using the repository browser.