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

Last change on this file since 9737 was 9734, checked in by steve, 10 years ago

Adding in multiple git commit

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