1 """A library of helper functions for the CherryPy test suite.
2
3 The actual script that runs the entire CP test suite is called
4 "test.py" (in this folder); test.py calls this module as a library.
5
6 Usage
7 =====
8 Each individual test_*.py module imports this module (helper),
9 usually to make an instance of CPWebCase, and then call testmain().
10
11 The CP test suite script (test.py) imports this module and calls
12 run_test_suite, possibly more than once. CP applications may also
13 import test.py (to use TestHarness), which then calls helper.py.
14 """
15
16
17
18
19
20
21 import re
22 import sys
23 import thread
24 import warnings
25
26 import cherrypy
27 from cherrypy.lib import http, profiler
28 from cherrypy.test import webtest
29
30
32
33 script_name = ""
34 scheme = "http"
35
38
54
57
60
61 - def getPage(self, url, headers=None, method="GET", body=None, protocol=None):
62 """Open the url. Return status, headers, body."""
63 if self.script_name:
64 url = http.urljoin(self.script_name, url)
65 webtest.WebCase.getPage(self, url, headers, method, body, protocol)
66
67 - def assertErrorPage(self, status, message=None, pattern=''):
68 """Compare the response body with a built in error page.
69
70 The function will optionally look for the regexp pattern,
71 within the exception embedded in the error page."""
72
73
74 page = cherrypy._cperror.get_error_page(status, message=message)
75
76
77
78 esc = re.escape
79 epage = esc(page)
80 epage = epage.replace(esc('<pre id="traceback"></pre>'),
81 esc('<pre id="traceback">') + '(.*)' + esc('</pre>'))
82 m = re.match(epage, self.body, re.DOTALL)
83 if not m:
84 self._handlewebError('Error page does not match\n' + page)
85 return
86
87
88 if pattern is None:
89
90 if m and m.group(1):
91 self._handlewebError('Error page contains traceback')
92 else:
93 if (m is None) or (not re.search(re.escape(pattern), m.group(1))):
94 msg = 'Error page does not contain %s in traceback'
95 self._handlewebError(msg % repr(pattern))
96
97
98 CPTestLoader = webtest.ReloadingTestLoader()
99 CPTestRunner = webtest.TerseTestRunner(verbosity=2)
100
108
109
129
130 -def sync_apps(profile=False, validate=False, conquer=False):
156
158 for testmod in moduleNames:
159
160
161 cherrypy.tree = cherrypy._cptree.Tree()
162 cherrypy.config.reset()
163 setConfig(conf)
164
165 m = __import__(testmod, globals(), locals())
166 setup = getattr(m, "setup_server", None)
167 if setup:
168 setup()
169
170
171
172 sync_apps(profile=conf.get("profiling.on", False),
173 validate=conf.get("validator.on", False),
174 conquer=conf.get("conquer.on", False),
175 )
176
177 suite = CPTestLoader.loadTestsFromName(testmod)
178 result = CPTestRunner.run(suite)
179 cherrypy.engine.test_success &= result.wasSuccessful()
180
181 teardown = getattr(m, "teardown_server", None)
182 if teardown:
183 teardown()
184 thread.interrupt_main()
185
186 -def testmain(conf=None):
187 """Run __main__ as a test module, with webtest debugging."""
188 if conf is None:
189 conf = {'server.socket_host': '127.0.0.1'}
190 setConfig(conf)
191 try:
192 cherrypy.server.quickstart()
193 cherrypy.engine.start_with_callback(_test_main_thread)
194 except KeyboardInterrupt:
195 cherrypy.server.stop()
196 cherrypy.engine.stop()
197
199 try:
200 webtest.WebCase.PORT = cherrypy.server.socket_port
201 webtest.main()
202 finally:
203 thread.interrupt_main()
204