source: trunk/anuga_core/source/anuga/test_all.py @ 9516

Last change on this file since 9516 was 9503, checked in by steve, 10 years ago

Moved anuga_parallel to anuga.parallel. Now the compile_all and test_all
scripts should work

File size: 8.5 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
7Usage: test_all.py [<options>]
8
9where <options> is zero or more of:
10      -q         be quiet, minimal output to screen, write to ./.temp
11      --quiet    same as above
12      -v         be verbose to screen, more '-v's makes more verbose
13      --verbose  same as above
14You may do things like "test_all.py -q -v -v".
15"""
16
17# Author: Mark Pilgrim
18# Modified by Ole Nielsen
19
20import unittest
21import os
22import sys
23import tempfile
24import time
25import anuga.config as config
26from anuga.utilities.terminal_width import terminal_width
27import anuga.utilities.system_tools as aust
28
29
30#List files that should be excluded from the testing process.
31#E.g. if they are known to fail and under development
32exclude_files = []
33
34# Directories that should not be searched for test files.
35exclude_dirs = ['shallow_water_balanced' , 'parallel', # Special requirements
36                '.svn',          # subversion
37                'props', 'wcprops', 'prop-base', 'text-base', 'tmp']
38
39# name of file to capture stdout in
40CaptureFilename = '.temp'
41
42
43def list_names(names, func=None, col_width=None, page_width=None):
44    # set defaults
45    p_width = page_width - 1            # set page width
46    if p_width is None:
47        p_width = 132                   # default page width
48
49    c_width = col_width                 # set column width
50    if c_width is None:
51        c_width = 0
52        for name in names:
53            if func:
54                name = func(name)
55            c_width = max(c_width, len(name))
56    c_width += 2                        # 2 column padding
57
58    # calculate number of columns allowed
59    max_columns = int(p_width / c_width)
60
61    # print columns
62    column = 0
63    for name in names:
64        if func:
65            name = func(name)
66        print '%-*s' % (c_width-1, name),
67        column += 1
68        if column >= max_columns:
69            column = 0
70            print
71
72    # if last line not finished, end it here
73    if column > 0:
74        print
75
76
77def get_test_files(path):
78    """ Get 'test_*.py' files and paths to directories.
79    param path Path to directory to start walk in.
80    @return A tuple (<files>, <dirs>).
81    Don't include any files in and below forbidden directories.
82
83    """
84    walk = os.walk(path)
85
86    test_files = []
87    path_files = []
88
89    for (dirpath, dirnames, filenames) in walk:
90        # exclude forbidden directories
91        for e_dir in exclude_dirs:
92            try:
93                dirnames.remove(e_dir)
94            except ValueError:
95                pass
96
97        # check for test_*.py files
98        for filename in filenames:
99            if filename.startswith('test_') and filename.endswith('.py'):
100                test_files.append(filename)
101                if dirpath not in path_files:
102                    path_files.append(dirpath)
103
104    return test_files, path_files
105
106
107def regressionTest(test_verbose=False):
108    # start off with where we are
109    path = os.getcwd()
110    print
111    print 'Testing path: %s' % path
112   
113    common_dir = os.path.dirname(path)
114    common_dir_length = len(common_dir)
115    #print common_dir, common_dir_length
116   
117    # get the terminal width
118    term_width = terminal_width()
119
120    # explain what we are doing
121    print
122    print "The following directories will be skipped over:"
123    exclude_dirs.sort()
124    list_names(exclude_dirs, page_width=term_width)
125
126    # get all test_*.py and enclosing directories
127    test_files, path_files = get_test_files(path)
128    #print path_files
129    path_files.sort()
130
131    files = [x for x in test_files if not x == 'test_all.py']
132    files.sort()        # Ensure same order on all platforms
133
134    def my_filter(pathname):
135       
136        return pathname[common_dir_length+1:]
137   
138    print
139    print 'Paths searched:'
140    list_names(path_files, my_filter, page_width=term_width)
141
142    print   
143    print 'Files tested:'
144    list_names(files, page_width=term_width)
145    print
146
147    # update system path with found paths
148    for path in path_files:
149        sys.path.append(path)
150   
151    # exclude files that we can't handle
152    for file in exclude_files:
153        print 'WARNING: File '+ file + ' to be excluded from testing'
154        try:
155            files.remove(file)
156        except ValueError, e:
157            msg = 'File "%s" was not found in test suite.\n' % file
158            msg += 'Original error is "%s"\n' % e
159            msg += 'Perhaps it should be removed from exclude list?'
160            raise Exception, msg
161
162    # import all test_*.py files
163    # NOTE: This implies that test_*.py files MUST HAVE UNIQUE NAMES!
164    filenameToModuleName = lambda f: os.path.splitext(f)[0]
165    moduleNames = map(filenameToModuleName, files)
166    modules = map(__import__, moduleNames)
167
168    # Fix up the system path
169    for file in path_files:
170        sys.path.remove(file)
171
172    # bundle up all the tests
173    load = unittest.defaultTestLoader.loadTestsFromModule
174    testCaseClasses = map(load, modules)
175
176    if test_verbose is True:
177        # Test the code by setting verbose to True.
178        # The test cases have to be set up for this to work.
179        # See test data manager for an example.
180        for test_suite in testCaseClasses:
181            for tests in test_suite._tests:
182                # tests is of class TestSuite
183                if len(tests._tests) > 1:
184                    # these are the test functions
185                    try:
186                        # Calls class method set_verbose in test case classes
187                        tests._tests[0].set_verbose()
188                    except:
189                        pass                # No all classes have set_verbose
190
191    return unittest.TestSuite(testCaseClasses)
192
193
194def check_anuga_import():
195    try:
196        # importing something that loads quickly
197        import anuga.anuga_exceptions
198    except ImportError:
199        print "Python cannot import ANUGA module."
200        print "Check you have followed all steps of its installation."
201        import sys
202        sys.exit()
203
204
205if __name__ == '__main__':
206    from optparse import OptionParser
207
208    import os
209    for file in os.listdir('.'):
210        if file.endswith('.sww') or\
211                file.endswith('.msh') or\
212                file.endswith('.csv') or\
213                file.endswith('.asc') or\
214                file.endswith('.prj') or\
215                file.endswith('.tsh') or\
216                file.endswith('.sts') or\
217                file.endswith('.tms') or\
218                file.endswith('.pickle'):
219            try:
220                os.remove(file)
221            except:
222                pass
223
224    check_anuga_import()
225
226    # check the commandline params
227    usage = "usage: %prog [-h|-q|-v]"
228    parser = OptionParser(usage)
229    parser.add_option("-v", "--verbose",
230                      action="count", dest="verbosity", default=1,
231                      help='make the ouput even more verbose')
232    parser.add_option("-q", "--quiet",
233                      action="store_true", dest="quiet",
234                      help="capture statistics output in file '%s'"
235                           % CaptureFilename)
236    (options, args) = parser.parse_args()
237
238    if len(args) > 0:
239        parser.error("test_all.py doesn't take any parameters.  "
240                     "Do 'test_all.py -h' to see the help.")
241
242    if options.quiet:
243        saveout = sys.stdout
244        filename = CaptureFilename
245        fid = open(filename, 'w')
246        sys.stdout = fid
247
248    # run the tests
249    suite = regressionTest(options.quiet)
250    runner = unittest.TextTestRunner(verbosity=options.verbosity)
251    runner.run(suite)
252
253    # timestamp at the end
254    timestamp = time.asctime()
255    major_revision = config.major_revision
256    minor_revision = aust.get_revision_number()
257    print '\nFinished at %s, version %s %s' % (timestamp, major_revision, minor_revision)
258
259    # Cleaning up
260    if options.verbosity < 1:
261        sys.stdout = saveout
262        #fid.close() # This was causing an error in windows
263        #os.remove(filename)
264   
265
266
267    import os
268    for file in os.listdir('.'):
269        if file.endswith('.sww') or\
270                file.endswith('.msh') or\
271                file.endswith('.csv') or\
272                file.endswith('.asc') or\
273                file.endswith('.prj') or\
274                file.endswith('.tsh') or\
275                file.endswith('.sts') or\
276                file.endswith('.tms') or\
277                file.endswith('.pickle'):
278            try:
279                os.remove(file)
280            except Exception as inst:
281                pass
282           
Note: See TracBrowser for help on using the repository browser.