source: trunk/anuga_core/source/anuga_parallel/test_all.py @ 9336

Last change on this file since 9336 was 9122, checked in by steve, 11 years ago

Small changes to parallel code

File size: 6.8 KB
Line 
1"""Regression testing framework
2This module will search for scripts in the same directory named
3test_*.py.  Each such script should be a test suite that tests a
4module through PyUnit. This script will aggregate all
5found test suites into one big test suite and run them all at once.
6"""
7
8# Author: Mark Pilgrim
9# Modified by Ole Nielsen
10
11import unittest
12import os
13import sys
14import tempfile
15import time
16import anuga.utilities.system_tools as aust
17from anuga.utilities.terminal_width import terminal_width
18
19
20
21
22
23#List files that should be excluded from the testing process.
24#E.g. if they are known to fail and under development
25exclude_files = ['test_failure.py', 'test_parallel_boyd_pipe_operator.py', 'test_parallel_boyd_box_op_apron.py']
26
27# Directories that should not be searched for test files.
28exclude_dirs = ['documentation',               # Special requirements
29                '.svn',                              # subversion
30                'props', 'wcprops', 'prop-base', 'text-base', 'tmp']
31
32
33##
34# @brief List a string sequence on the screen in columns.
35# @param names Sequence of strings to list.
36# @param func Function to apply to each string in sequence.
37# @param col_width Force columns to this width (default calculated).
38# @param page_width Set displayable page width to this (default 132).
39def list_names(names, func=None, col_width=None, page_width=None):
40    # set defaults
41    p_width = page_width - 1            # set page width
42    if p_width is None:
43        p_width = 132                   # default page width
44
45    c_width = col_width                 # set column width
46    if c_width is None:
47        c_width = 0
48        for name in names:
49            if func:
50                name = func(name)
51            c_width = max(c_width, len(name))
52    c_width += 2                        # 2 column padding
53
54    # calculate number of columns allowed
55    max_columns = int(p_width / c_width)
56
57    # print columns
58    column = 0
59    for name in names:
60        if func:
61            name = func(name)
62        print '%-*s' % (c_width-1, name),
63        column += 1
64        if column >= max_columns:
65            column = 0
66            print
67
68    # if last line not finished, end it here
69    if column > 0:
70        print
71
72
73##
74# @brief Get 'test_*.py' files and paths to directories.
75# @param path Path to directory to start walk in.
76# @return A tuple (<files>, <dirs>).
77# @note Don't include any files in and below forbidden directories.
78def get_test_files(path):
79    walk = os.walk(path)
80
81    test_files = []
82    path_files = []
83
84    for (dirpath, dirnames, filenames) in walk:
85        # exclude forbidden directories
86        for e_dir in exclude_dirs:
87            try:
88                dirnames.remove(e_dir)
89            except ValueError:
90                pass
91
92        # check for test_*.py files
93        for filename in filenames:
94            if filename.startswith('test_') and filename.endswith('.py'):
95                test_files.append(filename)
96                if dirpath not in path_files:
97                    path_files.append(dirpath)
98
99    return test_files, path_files
100
101
102def regressionTest(test_verbose=False):
103    # start off with where we are
104    path = os.getcwd()
105    print
106    print 'Testing path: %s' % path
107
108    # get the terminal width
109    term_width = terminal_width()
110
111    # explain what we are doing
112    print
113    print "The following directories will be skipped over:"
114    exclude_dirs.sort()
115    list_names(exclude_dirs, page_width=term_width)
116
117    # get all test_*.py and enclosing directories
118    test_files, path_files = get_test_files(path)
119    path_files.sort()
120
121    files = [x for x in test_files if not x == 'test_all.py']
122    files.sort()        # Ensure same order on all platforms
123
124    print
125    print 'Paths searched:'
126    list_names(path_files, os.path.basename, page_width=term_width)
127
128    print   
129    print 'Files tested:'
130    list_names(files, page_width=term_width)
131    print
132
133    # update system path with found paths
134    for path in path_files:
135        sys.path.append(path)
136   
137    # exclude files that we can't handle
138    for file in exclude_files:
139        print 'WARNING: File '+ file + ' to be excluded from testing'
140        try:
141            files.remove(file)
142        except ValueError, e:
143            msg = 'File "%s" was not found in test suite.\n' % file
144            msg += 'Original error is "%s"\n' % e
145            msg += 'Perhaps it should be removed from exclude list?'
146            raise Exception, msg
147
148    # import all test_*.py files
149    # NOTE: This implies that test_*.py files MUST HAVE UNIQUE NAMES!
150    filenameToModuleName = lambda f: os.path.splitext(f)[0]
151    moduleNames = map(filenameToModuleName, files)
152    modules = map(__import__, moduleNames)
153
154    # Fix up the system path
155    for file in path_files:
156        sys.path.remove(file)
157
158    # bundle up all the tests
159    load = unittest.defaultTestLoader.loadTestsFromModule
160    testCaseClasses = map(load, modules)
161
162    if test_verbose is True:
163        # Test the code by setting verbose to True.
164        # The test cases have to be set up for this to work.
165        # See test data manager for an example.
166        for test_suite in testCaseClasses:
167            for tests in test_suite._tests:
168                # tests is of class TestSuite
169                if len(tests._tests) > 1:
170                    # these are the test functions
171                    try:
172                        # Calls class method set_verbose in test case classes
173                        tests._tests[0].set_verbose()
174                    except:
175                        pass                # No all classes have set_verbose
176
177    return unittest.TestSuite(testCaseClasses)
178
179
180##
181# @brief Check that the environment is sane.
182# @note Stops here if there is an error.
183def check_anuga_import():
184    try:
185        # importing something that loads quickly
186        import anuga.anuga_exceptions
187    except ImportError:
188        print "Python cannot import ANUGA module."
189        print "Check you have followed all steps of its installation."
190        import sys
191        sys.exit()
192
193
194if __name__ == '__main__':
195    check_anuga_import()
196
197    if len(sys.argv) > 1 and sys.argv[1][0].upper() == 'V':
198        test_verbose = True
199        saveout = sys.stdout
200        filename = ".temp"
201        fid = open(filename, 'w')
202        sys.stdout = fid
203    else:
204        test_verbose = False
205    suite = regressionTest(test_verbose)
206    runner = unittest.TextTestRunner(verbosity=1)
207    runner.run(suite)
208
209    # timestamp at the end
210    timestamp = time.asctime()
211    version = aust.get_revision_number()
212    print
213    print 'Finished at %s, version %s' % (timestamp, version)
214
215    # Cleaning up
216    if len(sys.argv) > 1 and sys.argv[1][0].upper() == 'V':
217        sys.stdout = saveout
218        #fid.close() # This was causing an error in windows
219        #os.remove(filename)
220
221   
222    if sys.platform == 'win32':
223        raw_input('Press the RETURN key')
Note: See TracBrowser for help on using the repository browser.