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
25 import cherrypy
26 from cherrypy.lib import http, profiler
27 from cherrypy.test import webtest
28
29
31
32 script_name = ""
33 scheme = "http"
34
37
53
56
59
60 - def getPage(self, url, headers=None, method="GET", body=None, protocol=None):
61 """Open the url. Return status, headers, body."""
62 if self.script_name:
63 url = http.urljoin(self.script_name, url)
64 webtest.WebCase.getPage(self, url, headers, method, body, protocol)
65
66 - def assertErrorPage(self, status, message=None, pattern=''):
67 """Compare the response body with a built in error page.
68
69 The function will optionally look for the regexp pattern,
70 within the exception embedded in the error page."""
71
72
73 page = cherrypy._cperror.get_error_page(status, message=message)
74
75
76
77 esc = re.escape
78 epage = esc(page)
79 epage = epage.replace(esc('<pre id="traceback"></pre>'),
80 esc('<pre id="traceback">') + '(.*)' + esc('</pre>'))
81 m = re.match(epage, self.body, re.DOTALL)
82 if not m:
83 self._handlewebError('Error page does not match\n' + page)
84 return
85
86
87 if pattern is None:
88
89 if m and m.group(1):
90 self._handlewebError('Error page contains traceback')
91 else:
92 if (m is None) or (not re.search(re.escape(pattern), m.group(1))):
93 msg = 'Error page does not contain %s in traceback'
94 self._handlewebError(msg % repr(pattern))
95
96
97 CPTestLoader = webtest.ReloadingTestLoader()
98 CPTestRunner = webtest.TerseTestRunner(verbosity=2)
99
107
108
128
129 -def sync_apps(profile=False, validate=False, conquer=False):
155
157 for testmod in moduleNames:
158
159
160 cherrypy.tree = cherrypy._cptree.Tree()
161 cherrypy.config.reset()
162 setConfig(conf)
163
164 m = __import__(testmod, globals(), locals())
165 setup = getattr(m, "setup_server", None)
166 if setup:
167 setup()
168
169
170
171 sync_apps(profile=conf.get("profiling.on", False),
172 validate=conf.get("validator.on", False),
173 conquer=conf.get("conquer.on", False),
174 )
175
176 suite = CPTestLoader.loadTestsFromName(testmod)
177 result = CPTestRunner.run(suite)
178 cherrypy.engine.test_success &= result.wasSuccessful()
179
180 teardown = getattr(m, "teardown_server", None)
181 if teardown:
182 teardown()
183 thread.interrupt_main()
184
185 -def testmain(conf=None):
186 """Run __main__ as a test module, with webtest debugging."""
187 if conf is None:
188 conf = {'server.socket_host': '127.0.0.1'}
189 setConfig(conf)
190 try:
191 cherrypy.server.quickstart()
192 cherrypy.engine.start_with_callback(_test_main_thread)
193 except KeyboardInterrupt:
194 cherrypy.server.stop()
195 cherrypy.engine.stop()
196
198 try:
199 webtest.WebCase.PORT = cherrypy.server.socket_port
200 webtest.main()
201 finally:
202 thread.interrupt_main()
203