Win32 portability in runtest.py tests after disabling QMTest by default.
[scons.git] / QMTest / TestRuntest.py
1 """
2 TestRuntest.py:  a testing framework for the runtest.py command used to
3 invoke SCons tests.
4
5 A TestRuntest environment object is created via the usual invocation:
6
7     test = TestRuntest()
8
9 TestRuntest is a subclass of TestCommon, which is in turn is a subclass
10 of TestCmd), and hence has available all of the methods and attributes
11 from those classes, as well as any overridden or additional methods or
12 attributes defined in this subclass.
13 """
14
15 # __COPYRIGHT__
16
17 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
18
19 import os
20 import os.path
21 import re
22 import string
23 import shutil
24 import sys
25
26 from TestCommon import *
27 from TestCommon import __all__
28
29 __all__.extend([ 'TestRuntest',
30                  'python',
31                  'pythonstring',
32                  '_python_',
33                ])
34
35 python = python_executable
36 _python_ = '"' + python_executable + '"'
37
38 if re.search('\s', python):
39     pythonstring = _python_
40 else:
41     pythonstring = python
42 pythonstring = string.replace(pythonstring, '\\', '\\\\')
43
44
45 failing_test_template = """\
46 import sys
47 sys.stdout.write('FAILING TEST STDOUT\\n')
48 sys.stderr.write('FAILING TEST STDERR\\n')
49 sys.exit(1)
50 """
51
52 no_result_test_template = """\
53 import sys
54 sys.stdout.write('NO RESULT TEST STDOUT\\n')
55 sys.stderr.write('NO RESULT TEST STDERR\\n')
56 sys.exit(2)
57 """
58
59 passing_test_template = """\
60 import sys
61 sys.stdout.write('PASSING TEST STDOUT\\n')
62 sys.stderr.write('PASSING TEST STDERR\\n')
63 sys.exit(0)
64 """
65
66 fake_scons_py = """
67 __version__ = '1.2.3'
68 __build__ = 'D123'
69 __buildsys__ = 'fake_system'
70 __date__ = 'Jan 1 1970'
71 __developer__ = 'Anonymous'
72 """
73
74 fake___init___py = """
75 __version__ = '4.5.6'
76 __build__ = 'D456'
77 __buildsys__ = 'another_fake_system'
78 __date__ = 'Dec 31 1999'
79 __developer__ = 'John Doe'
80 """
81
82 class TestRuntest(TestCommon):
83     """Class for testing the runtest.py script.
84
85     This provides a common place for initializing Runtest tests,
86     eliminating the need to begin every test with the same repeated
87     initializations.
88     """
89
90     def __init__(self, **kw):
91         """Initialize a Runtest testing object.
92
93         If they're not overridden by keyword arguments, this
94         initializes the object with the following default values:
95
96                 program = 'runtest.py'
97                 interpreter = ['python', '-tt']
98                 match = match_exact
99                 workdir = ''
100
101         The workdir value means that, by default, a temporary
102         workspace directory is created for a TestRuntest environment.
103         The superclass TestCommon.__init__() will change directory (chdir)
104         to the workspace directory, so an explicit "chdir = '.'" on all
105         of the run() method calls is not necessary.  This initialization
106         also copies the runtest.py and QMTest/ subdirectory tree to the
107         temporary directory, duplicating how this test infrastructure
108         appears in a normal workspace.
109         """
110         set_workpath_runtest = None
111         if not kw.has_key('program'):
112             kw['program'] = 'runtest.py'
113             set_workpath_runtest = 1
114         if not kw.has_key('interpreter'):
115             kw['interpreter'] = [python, '-tt']
116         if not kw.has_key('match'):
117             kw['match'] = match_exact
118         if not kw.has_key('workdir'):
119             kw['workdir'] = ''
120
121         try:
122             noqmtest = kw['noqmtest']
123         except KeyError:
124             noqmtest = 0
125         else:
126             del kw['noqmtest']
127
128         orig_cwd = os.getcwd()
129         apply(TestCommon.__init__, [self], kw)
130   
131         if not noqmtest:
132             qmtest = self.where_is('qmtest')
133             if not qmtest:
134                 self.skip_test("Could not find 'qmtest'; skipping test(s).\n")
135
136         things_to_copy = [
137             'runtest.py',
138             'QMTest',
139         ]
140
141         dirs = [os.environ.get('SCONS_RUNTEST_DIR', orig_cwd)]
142         
143         spe = os.environ.get('SCONS_SOURCE_PATH_EXECUTABLE', orig_cwd)
144         for d in string.split(spe, os.pathsep):
145             dirs.append(os.path.join(d, 'build'))
146             dirs.append(d)
147
148         for thing in things_to_copy:
149             for dir in dirs:
150                 t = os.path.join(dir, thing)
151                 if os.path.exists(t):
152                     if os.path.isdir(t):
153                         copy_func = shutil.copytree
154                     else:
155                         copy_func = shutil.copyfile
156                     copy_func(t, self.workpath(thing))
157                     break
158
159         if set_workpath_runtest:
160             self.program_set(self.workpath('runtest.py'))
161
162         for key in os.environ.keys():
163             if key[:5] == 'AEGIS':
164                 os.environ[key] = ''
165
166         os.environ['PYTHONPATH'] = ''
167         os.environ['SCONS_SOURCE_PATH_EXECUTABLE'] = ''
168
169     def write_fake_scons_source_tree(self):
170         os.mkdir('src')
171         os.mkdir('src/script')
172         self.write('src/script/scons.py', fake_scons_py)
173
174         os.mkdir('src/engine')
175         os.mkdir('src/engine/SCons')
176         self.write('src/engine/SCons/__init__.py', fake___init___py)
177         os.mkdir('src/engine/SCons/Script')
178         self.write('src/engine/SCons/Script/__init__.py', fake___init___py)
179
180     def write_failing_test(self, name):
181         self.write(name, failing_test_template)
182
183     def write_no_result_test(self, name):
184         self.write(name, no_result_test_template)
185
186     def write_passing_test(self, name):
187         self.write(name, passing_test_template)
188
189 # Local Variables:
190 # tab-width:4
191 # indent-tabs-mode:nil
192 # End:
193 # vim: set expandtab tabstop=4 shiftwidth=4: