af6e25876b29a171b48171959ba0b5207d1aeecd
[scons.git] / runtest.py
1 #!/usr/bin/env python
2 #
3 # runtests.py - wrapper script for running SCons tests
4 #
5 # This script mainly exists to set PYTHONPATH to the right list of
6 # directories to test the SCons modules.
7 #
8 # By default, it directly uses the modules in the local tree:
9 # ./src/ (source files we ship) and ./etc/ (other modules we don't)
10 #
11 # When "-b aegis" is specified, it assumes it's in a directory
12 # in which an Aegis build (aeb) has been performed, and sets
13 # PYTHONPATH so that it *only* references the modules that have
14 # unpacked from the built packages, to test whether the packages
15 # are good.
16 #
17 # Options:
18 #
19 #       -a              Run all tests; does a virtual 'find' for
20 #                       all SCons tests under the current directory.
21 #
22 #       -d              Debug.  Runs the script under the Python
23 #                       debugger (pdb.py) so you don't have to
24 #                       muck with PYTHONPATH yourself.
25 #
26 #       -q              Quiet.  By default, runtest.py prints the
27 #                       command line it will execute before
28 #                       executing it.  This suppresses that print.
29 #
30 #       -p package      Test against the specified package.
31 #
32 # (Note:  There used to be a -v option that specified the SCons
33 # version to be tested, when we were installing in a version-specific
34 # library directory.  If we ever resurrect that as the default, then
35 # you can find the appropriate code in the 0.04 version of this script,
36 # rather than reinventing that wheel.)
37 #
38
39 import getopt
40 import os
41 import os.path
42 import re
43 import string
44 import sys
45
46 all = 0
47 debug = ''
48 tests = []
49 printcmd = 1
50 package = None
51
52 if sys.platform == 'win32':
53     lib_dir = os.path.join(sys.exec_prefix, "lib")
54 else:
55     lib_dir = os.path.join(sys.exec_prefix, "lib", "python" + sys.version[0:3])
56
57 opts, tests = getopt.getopt(sys.argv[1:], "adqp:",
58                             ['all', 'debug', 'quiet', 'package='])
59
60 for o, a in opts:
61     if o == '-a' or o == '--all': all = 1
62     elif o == '-d' or o == '--debug': debug = os.path.join(lib_dir, "pdb.py")
63     elif o == '-q' or o == '--quiet': printcmd = 0
64     elif o == '-p' or o == '--package': package = a
65
66 cwd = os.getcwd()
67
68 if tests:
69     map(os.path.abspath, tests)
70 elif all:
71     def find_Test_py(arg, dirname, names):
72         global tests
73         n = filter(lambda n: n[-8:] == "Tests.py", names)
74         tests.extend(map(lambda x,d=dirname: os.path.join(d, x), n))
75     os.path.walk('src', find_Test_py, 0)
76
77     def find_py(arg, dirname, names):
78         global tests
79         n = filter(lambda n: n[-3:] == ".py", names)
80         tests.extend(map(lambda x,d=dirname: os.path.join(d, x), n))
81     os.path.walk('test', find_py, 0)
82
83     tests.sort()
84
85 if package:
86
87     dir = {
88         'deb'        : 'usr',
89         'rpm'        : 'usr',
90         'src-tar-gz' : '',
91         'tar-gz'     : '',
92     }
93
94     if not dir.has_key(package):
95         sys.stderr.write("Unknown package '%s'\n" % package)
96         sys.exit(2)
97
98     test_dir = os.path.join(cwd, 'build', 'test-%s' % package)
99
100     scons_dir = os.path.join(test_dir, dir[package], 'bin')
101
102     lib_dir = os.path.join(test_dir, dir[package], 'lib', 'scons')
103
104 else:
105
106     scons_dir = os.path.join(cwd, 'src', 'script')
107
108     lib_dir = os.path.join(cwd, 'src', 'engine')
109
110 os.environ['PYTHONPATH'] = lib_dir + \
111                            os.pathsep + \
112                            os.path.join(cwd, 'build', 'etc') + \
113                            os.pathsep + \
114                            os.path.join(cwd, 'etc')
115
116 os.chdir(scons_dir)
117
118 fail = []
119 no_result = []
120
121 for path in tests:
122     if os.path.isabs(path):
123         abs = path
124     else:
125         abs = os.path.join(cwd, path)
126     cmd = string.join(["python", debug, abs], " ")
127     if printcmd:
128         print cmd
129     s = os.system(cmd)
130     if s == 1 or s == 256:
131         fail.append(path)
132     elif s == 2 or s == 512:
133         no_result.append(path)
134     elif s != 0:
135         print "Unexpected exit status %d" % s
136
137 if len(tests) != 1:
138     if fail:
139         if len(fail) == 1:
140             str = "test"
141         else:
142             str = "%d tests" % len(fail)
143         print "\nFailed the following %s:" % str
144         print "\t", string.join(fail, "\n\t")
145     if no_result:
146         if len(no_result) == 1:
147             str = "test"
148         else:
149             str = "%d tests" % len(no_result)
150         print "\nNO RESULT from the following %s:" % str
151         print "\t", string.join(no_result, "\n\t")
152
153 sys.exit(len(fail) + len(no_result))