Download Install Tutorial Docs FAQ Tools WikiLicense Team IRC Planet Involvement Shop Book

root/branches/cherrypy-2.x/cherrypy/test/helper.py

Revision 1582 (checked in by dowski, 2 years ago)

2.x backport of fixes in [1388] and [1530] (safer WSGI and request close). See #567.

Also buglet fixes in test.py and helper.py.

  • Property svn:eol-style set to native
Line 
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 # GREAT CARE has been taken to separate this module from test.py,
17 # because different consumers of each have mutually-exclusive import
18 # requirements. So don't go moving functions from here into test.py,
19 # or vice-versa, unless you *really* know what you're doing.
20
21 import re
22 import sys
23 import thread
24
25 import cherrypy
26 from cherrypy.lib import httptools
27 import webtest
28
29
30 class CPWebCase(webtest.WebCase):
31    
32     mount_point = ""
33     scheme = "http"
34    
35     def prefix(self):
36         return self.mount_point.rstrip("/")
37    
38     def exit(self):
39         sys.exit()
40    
41     def tearDown(self):
42         pass
43    
44     def getPage(self, url, headers=None, method="GET", body=None, protocol="HTTP/1.1"):
45         """Open the url. Return status, headers, body."""
46         if self.mount_point:
47             url = httptools.urljoin(self.mount_point, url)
48        
49         webtest.WebCase.getPage(self, url, headers, method, body, protocol)
50    
51     def assertErrorPage(self, status, message=None, pattern=''):
52         """ Compare the response body with a built in error page.
53             The function will optionally look for the regexp pattern,
54             within the exception embedded in the error page.
55         """
56        
57         # This will never contain a traceback:
58         page = cherrypy._cputil.getErrorPage(status, message=message)
59        
60         # First, test the response body without checking the traceback.
61         # Stick a match-all group (.*) in to grab the traceback.
62         esc = re.escape
63         epage = esc(page)
64         epage = epage.replace(esc('<pre id="traceback"></pre>'),
65                               esc('<pre id="traceback">')
66                               + '(.*)' + esc('</pre>'))
67         m = re.match(epage, self.body, re.DOTALL)
68         if not m:
69             self._handlewebError('Error page does not match\n' + page)
70             return
71        
72         # Now test the pattern against the traceback
73         if pattern is None:
74             # Special-case None to mean that there should be *no* traceback.
75             if m and m.group(1):
76                 self._handlewebError('Error page contains traceback')
77         else:
78             if (m is None) or (not re.search(re.escape(pattern), m.group(1))):
79                 msg = 'Error page does not contain %s in traceback'
80                 self._handlewebError(msg % repr(pattern))
81
82
83 CPTestLoader = webtest.ReloadingTestLoader()
84 CPTestRunner = webtest.TerseTestRunner(verbosity=2)
85
86 def setConfig(conf):
87     """Set the config using a copy of conf."""
88     if isinstance(conf, basestring):
89         # assume it's a filename
90         cherrypy.config.update(file=conf)
91     else:
92         cherrypy.config.update(conf.copy())
93
94
95 def run_test_suite(moduleNames, server, conf):
96     """Run the given test modules using the given server and conf.
97     
98     The server is started and stopped once, regardless of the number
99     of test modules. The config, however, is reset for each module.
100     """
101     setConfig(conf)
102     # The Pybots automatic testing system needs the suite to exit
103     # with a non-zero value if there were any problems.
104     # Might as well stick it in the server... :/
105     cherrypy.server.test_success = True
106     cherrypy.server.start_with_callback(_run_test_suite_thread,
107                                         args = (moduleNames, conf),
108                                         server_class = server)
109     if cherrypy.server.test_success:
110         return 0
111     else:
112         return 1
113
114 def _run_test_suite_thread(moduleNames, conf):
115     for testmod in moduleNames:
116         # Must run each module in a separate suite,
117         # because each module uses/overwrites cherrypy globals.
118         cherrypy.root = None
119         cherrypy.tree = cherrypy._cptree.Tree()
120         cherrypy.config.reset()
121         setConfig(conf)
122        
123         m = __import__(testmod, globals(), locals())
124         setup = getattr(m, "setup_server", None)
125         if setup:
126             setup()
127        
128         suite = CPTestLoader.loadTestsFromName(testmod)
129         result = CPTestRunner.run(suite)
130         cherrypy.server.test_success &= result.wasSuccessful()
131        
132         teardown = getattr(m, "teardown_server", None)
133         if teardown:
134             teardown()
135        
136     thread.interrupt_main()
137
138 def testmain(conf=None, *args, **kwargs):
139     """Run __main__ as a test module, with webtest debugging."""
140     if conf is None:
141         conf = {}
142     setConfig(conf)
143     try:
144         cherrypy.server.start_with_callback(_test_main_thread, *args, **kwargs)
145     except KeyboardInterrupt:
146         cherrypy.server.stop()
147
148 def _test_main_thread():
149     try:
150         webtest.WebCase.PORT = cherrypy.config.get('server.socket_port')
151         webtest.main()
152     finally:
153         thread.interrupt_main()
154
Note: See TracBrowser for help on using the browser.

Hosted by WebFaction

Log in as guest/cpguest to create tickets