Changeset 1627
- Timestamp:
- 03/05/07 15:22:13
- Files:
-
- trunk/cherrypy/__init__.py (modified) (6 diffs)
- trunk/cherrypy/_cpchecker.py (modified) (2 diffs)
- trunk/cherrypy/_cpconfig.py (modified) (5 diffs)
- trunk/cherrypy/_cpengine.py (deleted)
- trunk/cherrypy/_cpmodpy.py (modified) (6 diffs)
- trunk/cherrypy/_cprequest.py (modified) (2 diffs)
- trunk/cherrypy/_cpserver.py (modified) (5 diffs)
- trunk/cherrypy/_cptools.py (modified) (1 diff)
- trunk/cherrypy/_cptree.py (modified) (4 diffs)
- trunk/cherrypy/_cpwsgi.py (modified) (4 diffs)
- trunk/cherrypy/lib/covercp.py (modified) (2 diffs)
- trunk/cherrypy/lib/sessions.py (modified) (4 diffs)
- trunk/cherrypy/pywebd (added)
- trunk/cherrypy/pywebd/__init__.py (added)
- trunk/cherrypy/pywebd/base.py (added)
- trunk/cherrypy/pywebd/plugins.py (added)
- trunk/cherrypy/pywebd/win32.py (added)
- trunk/cherrypy/test/benchmark.py (modified) (2 diffs)
- trunk/cherrypy/test/helper.py (modified) (4 diffs)
- trunk/cherrypy/test/modpy.py (modified) (1 diff)
- trunk/cherrypy/test/test.py (modified) (2 diffs)
- trunk/cherrypy/test/test_config.py (modified) (2 diffs)
- trunk/cherrypy/test/test_states.py (modified) (18 diffs)
- trunk/cherrypy/test/test_states_demo.py (modified) (3 diffs)
- trunk/cherrypy/test/test_tools.py (modified) (1 diff)
- trunk/cherrypy/tutorial/tut02_expose_methods.py (modified) (1 diff)
- trunk/cherrypy/tutorial/tut03_get_and_post.py (modified) (1 diff)
- trunk/cherrypy/tutorial/tut04_complex_site.py (modified) (1 diff)
- trunk/cherrypy/tutorial/tut05_derived_objects.py (modified) (1 diff)
- trunk/cherrypy/tutorial/tut06_default_method.py (modified) (1 diff)
- trunk/cherrypy/tutorial/tut07_sessions.py (modified) (1 diff)
- trunk/cherrypy/tutorial/tut08_generators_and_yield.py (modified) (1 diff)
- trunk/cherrypy/tutorial/tut09_files.py (modified) (1 diff)
- trunk/cherrypy/tutorial/tut10_http_errors.py (modified) (1 diff)
- trunk/cherrypy/wsgiserver/__init__.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/cherrypy/__init__.py
r1622 r1627 58 58 """ 59 59 60 __version__ = "3. 0.1"60 __version__ = "3.1alpha" 61 61 62 62 from urlparse import urljoin as _urljoin … … 77 77 popped from the class dict and folded into the class docstring. 78 78 79 The naming convention for attribute docstrings is: <attrname> + "__doc". 79 The naming convention for attribute docstrings is: 80 <attrname> + "__doc". 80 81 For example: 81 82 … … 158 159 159 160 from cherrypy import _cpdispatch as dispatch 160 from cherrypy import _cprequest161 from cherrypy.lib import http as _http162 from cherrypy import _cpengine163 engine = _cpengine.Engine()164 161 165 162 from cherrypy import _cptools 166 163 tools = _cptools.default_toolbox 167 164 Tool = _cptools.Tool 165 166 from cherrypy import _cprequest 167 from cherrypy.lib import http as _http 168 168 169 169 from cherrypy import _cptree … … 174 174 server = _cpserver.Server() 175 175 176 from cherrypy import pywebd 177 engine = pywebd.engine 178 179 # Timeout monitor 180 class _TimeoutMonitor(pywebd.plugins.Monitor): 181 182 def __init__(self, engine, channel=None): 183 self.servings = [] 184 pywebd.plugins.Monitor.__init__(self, engine, self.run, channel) 185 186 def acquire(self): 187 self.servings.append((serving.request, serving.response)) 188 189 def release(self): 190 try: 191 self.servings.remove((serving.request, serving.response)) 192 except ValueError: 193 pass 194 195 def run(self): 196 """Check timeout on all responses. (Internal)""" 197 for req, resp in self.servings: 198 resp.check_timeout() 199 _timeout_monitor = _TimeoutMonitor(engine, "CherryPy Timeout Monitor") 200 201 # Add an autoreloader (the 'engine' config namespace may detach/attach it). 202 engine.autoreload = pywebd.plugins.Autoreloader(engine) 203 pywebd.plugins.Reexec(engine) 204 _thread_manager = pywebd.plugins.ThreadManager(engine) 205 206 176 207 def quickstart(root, script_name="", config=None): 177 """Mount the given root, start the engine and builtin server, then block."""208 """Mount the given root, start the builtin server (and engine), then block.""" 178 209 if config: 179 210 _global_conf_alias.update(config) 180 211 tree.mount(root, script_name, config) 181 server.quickstart() 212 213 engine.subscribe('start', server.quickstart) 214 215 s = pywebd.plugins.SignalHandler(engine) 216 s.set_handler('SIGTERM', engine.stop) 217 s.set_handler('SIGHUP', engine.restart) 218 182 219 engine.start() 220 engine.block() 183 221 184 222 … … 324 362 # Using an access file makes CP about 10% slower. Leave off by default. 325 363 log.access_file = '' 326 364 engine.log = lambda msg, traceback=False: log.error(msg, 'ENGINE', 365 traceback=traceback) 327 366 328 367 # Helper functions for CP apps # … … 454 493 from cherrypy import _cpchecker 455 494 checker = _cpchecker.Checker() 495 engine.subscribe('start', checker) trunk/cherrypy/_cpchecker.py
r1575 r1627 143 143 extra_config_namespaces = [] 144 144 145 def _known_ns(self, config):145 def _known_ns(self, app): 146 146 ns = ["wsgi"] 147 ns.extend(cherrypy.engine.request_class.namespaces.keys()) 147 ns.extend(app.toolboxes.keys()) 148 ns.extend(app.request_class.namespaces.keys()) 148 149 ns.extend(cherrypy.config.namespaces.keys()) 149 150 ns += self.extra_config_namespaces 150 151 151 for section, conf in config.iteritems():152 for section, conf in app.config.iteritems(): 152 153 is_path_section = section.startswith("/") 153 154 if is_path_section and isinstance(conf, dict): … … 169 170 """Process config and warn on each unknown config namespace.""" 170 171 for sn, app in cherrypy.tree.apps.iteritems(): 171 self._known_ns(app .config)172 self._known_ns(app) 172 173 173 174 trunk/cherrypy/_cpconfig.py
r1612 r1627 87 87 You can define your own namespaces to be called at the Global, Application, 88 88 or Request level, by adding a named handler to cherrypy.config.namespaces, 89 app.namespaces, or cherrypy.engine.request_class.namespaces. The name can89 app.namespaces, or app.request_class.namespaces. The name can 90 90 be any string, and the handler must be either a callable or a (Python 2.5 91 91 style) context manager. … … 144 144 145 145 If the given config is a filename, it will be appended to 146 cherrypy.engine.reload_files and monitored forchanges.146 the list of files to monitor for "autoreload" changes. 147 147 """ 148 148 if isinstance(other, basestring): 149 if other not in cherrypy.engine.reload_files: 150 cherrypy.engine.reload_files.append(other) 149 cherrypy.engine.publish('Autoreloader', 'add()', other) 151 150 152 151 # Load other into base … … 240 239 namespaces = NamespaceSet( 241 240 **{"server": lambda k, v: setattr(cherrypy.server, k, v), 242 "engine": lambda k, v: setattr(cherrypy.engine, k, v),243 241 "log": lambda k, v: setattr(cherrypy.log, k, v), 244 242 "checker": lambda k, v: setattr(cherrypy.checker, k, v), … … 257 255 if isinstance(config, basestring): 258 256 # Filename 259 if config not in cherrypy.engine.reload_files: 260 cherrypy.engine.reload_files.append(config) 257 cherrypy.engine.publish('Autoreloader', 'add()', config) 261 258 config = _Parser().dict_from_file(config) 262 259 elif hasattr(config, 'read'): … … 287 284 self.namespaces({k: v}) 288 285 286 287 # Backward compatibility handler for the "engine" namespace. 288 def _engine_namespace_handler(k, v): 289 engine = cherrypy.engine 290 if k == 'autoreload_on': 291 if v: 292 engine.autoreload.attach() 293 else: 294 engine.autoreload.detach() 295 elif k == 'autoreload_frequency': 296 engine.publish('Autoreloader', 'frequency', v) 297 elif k == 'autoreload_match': 298 engine.publish('Autoreloader', 'match', v) 299 elif k == 'reload_files': 300 engine.publish('Autoreloader', 'files', v) 301 elif k == 'deadlock_poll_freq': 302 engine.publish('CherryPy Timeout Monitor', 'frequency', v) 303 elif k == 'reexec_retry': 304 engine.publish('reexec', 'retry', v) 305 elif k == 'SIGHUP': 306 engine.listeners['SIGHUP'] = set([v]) 307 elif k == 'SIGTERM': 308 engine.listeners['SIGTERM'] = set([v]) 309 Config.namespaces["engine"] = _engine_namespace_handler 289 310 290 311 trunk/cherrypy/_cpmodpy.py
r1608 r1627 16 16 17 17 # We will use this method from the mod_python configuration 18 # as the ent yrpoint to our application18 # as the entry point to our application 19 19 def setup_server(): 20 20 cherrypy.tree.mount(Root()) … … 24 24 # You must start the engine in a non-blocking fashion 25 25 # so that mod_python can proceed 26 cherrypy.engine.start( blocking=False)26 cherrypy.engine.start() 27 27 28 28 ########################################## … … 84 84 }) 85 85 86 if cherrypy.engine.state == cherrypy._cpengine.STOPPED: 87 cherrypy.engine.start(blocking=False) 88 elif cherrypy.engine.state == cherrypy._cpengine.STARTING: 89 cherrypy.engine.wait() 86 cherrypy.engine.start() 87 cherrypy.engine.wait() 90 88 91 89 def cherrypy_cleanup(data): … … 167 165 redirections = [] 168 166 while True: 169 request = cherrypy.engine.request(local, remote, scheme)167 request = app.get_serving(local, remote, scheme) 170 168 request.login = req.user 171 169 request.multithread = bool(threaded) … … 179 177 break 180 178 except cherrypy.InternalRedirect, ir: 181 cherrypy.engine.release()179 app.release_serving() 182 180 prev = request 183 181 … … 199 197 200 198 send_response(req, response.status, response.header_list, response.body) 201 cherrypy.engine.release()199 app.release_serving() 202 200 except: 203 201 tb = format_exc() trunk/cherrypy/_cprequest.py
r1616 r1627 394 394 "response": response_namespace, 395 395 "error_page": error_page_namespace, 396 # "tools": See _cptools.Toolbox396 "tools": cherrypy.tools, 397 397 }) 398 398 … … 550 550 if self.handler: 551 551 cherrypy.response.body = self.handler() 552 552 553 self.hooks.run('before_finalize') 553 554 cherrypy.response.finalize() trunk/cherrypy/_cpserver.py
r1608 r1627 94 94 for httpserver in self.httpservers: 95 95 self._start_http(httpserver) 96 cherrypy.engine.subscribe('stop', self.stop) 96 97 97 98 def _start_http(self, httpserver): … … 121 122 main thread persists to receive KeyboardInterrupt's. If an 122 123 exception is raised in the httpserver's thread then it's 123 trapped here, and the httpserver(s) and engine are shut down. 124 trapped here, and the engine (and therefore our httpservers) 125 are shut down. 124 126 """ 125 127 try: … … 128 130 cherrypy.log("<Ctrl-C> hit: shutting down HTTP servers", "SERVER") 129 131 self.interrupt = exc 130 self.stop()131 132 cherrypy.engine.stop() 132 133 except SystemExit, exc: 133 134 cherrypy.log("SystemExit raised: shutting down HTTP servers", "SERVER") 134 135 self.interrupt = exc 135 self.stop()136 136 cherrypy.engine.stop() 137 137 raise … … 155 155 # Wait for port to be occupied 156 156 if isinstance(bind_addr, tuple): 157 wait_for_occupied_port(*bind_addr) 157 host, port = bind_addr 158 if not host or host == '0.0.0.0': 159 host = socket.gethostname() 160 wait_for_occupied_port(host, port) 158 161 159 162 def stop(self): … … 182 185 183 186 host = self.socket_host 184 if not host :187 if not host or host == '0.0.0.0': 185 188 # The empty string signifies INADDR_ANY. Look up the host name, 186 189 # which should be the safest thing to spit out in a URL. trunk/cherrypy/_cptools.py
r1621 r1627 330 330 331 331 This object also functions as a config namespace handler for itself. 332 Custom toolboxes should be added to each Application's toolboxes dict. 332 333 """ 333 334 334 335 def __init__(self, namespace): 335 336 self.namespace = namespace 336 cherrypy.engine.request_class.namespaces[namespace] = self337 337 338 338 def __setattr__(self, name, value): trunk/cherrypy/_cptree.py
r1612 r1627 3 3 import os 4 4 import cherrypy 5 from cherrypy import _cpconfig, _cplogging, _cp wsgi, tools5 from cherrypy import _cpconfig, _cplogging, _cprequest, _cpwsgi, tools 6 6 7 7 8 8 class Application(object): 9 9 """A CherryPy Application. 10 11 Servers and gateways should not instantiate Request objects directly. 12 Instead, they should ask an Application object for a request object. 10 13 11 14 An instance of this class may also be used as a WSGI callable … … 29 32 30 33 namespaces = _cpconfig.NamespaceSet() 34 toolboxes = {'tools': cherrypy.tools} 31 35 32 36 log = None … … 35 39 wsgiapp = None 36 40 wsgiapp__doc = """A CPWSGIApp instance. See _cpwsgi.""" 41 42 request_class = _cprequest.Request 43 response_class = _cprequest.Response 37 44 38 45 def __init__(self, root, script_name=""): … … 70 77 # Handle namespaces specified in config. 71 78 self.namespaces(self.config.get("/", {})) 79 80 def get_serving(self, local, remote, scheme, sproto): 81 """Create and return a Request and Response object.""" 82 req = self.request_class(local, remote, scheme, sproto) 83 req.app = self 84 85 for name, toolbox in self.toolboxes.iteritems(): 86 req.namespaces[name] = toolbox 87 88 resp = self.response_class() 89 cherrypy.serving.load(req, resp) 90 cherrypy.engine.publish('CherryPy Timeout Monitor', 'acquire()') 91 cherrypy.engine.publish('acquire_thread') 92 93 return req, resp 94 95 def release_serving(self): 96 """Release the current serving (request and response).""" 97 req = cherrypy.serving.request 98 99 cherrypy.engine.publish('CherryPy Timeout Monitor', 'release()') 100 101 try: 102 req.close() 103 except: 104 cherrypy.log(traceback=True) 105 106 cherrypy.serving.clear() 72 107 73 108 def __call__(self, environ, start_response): trunk/cherrypy/_cpwsgi.py
r1608 r1627 114 114 115 115 def __init__(self, environ, start_response, cpapp): 116 try: 117 self.request = self.get_engine_request(environ, cpapp) 116 self.cpapp = cpapp 117 118 try: 119 self.request = self.get_request(environ) 118 120 119 121 meth = environ['REQUEST_METHOD'] … … 193 195 194 196 def close(self): 195 _cherrypy.engine.release() 196 197 def get_engine_request(self, environ, cpapp): 198 """Return a Request object from the CherryPy Engine using environ.""" 197 """Close and de-reference the current request and response. (Core)""" 198 self.cpapp.release_serving() 199 200 def get_request(self, environ): 201 """Create a Request object using environ.""" 199 202 env = environ.get 200 203 … … 206 209 scheme = env('wsgi.url_scheme') 207 210 sproto = env('ACTUAL_SERVER_PROTOCOL', "HTTP/1.1") 208 request = _cherrypy.engine.request(local, remote, scheme, sproto)211 request, resp = self.cpapp.get_serving(local, remote, scheme, sproto) 209 212 210 213 # LOGON_USER is served by IIS, and is the name of the … … 215 218 request.multiprocess = environ['wsgi.multiprocess'] 216 219 request.wsgi_environ = environ 217 request.app = cpapp218 220 request.prev = env('cherrypy.request') 219 221 environ['cherrypy.request'] = request trunk/cherrypy/lib/covercp.py
r1219 r1627 11 11 To turn on coverage tracing, use the following code: 12 12 13 cherrypy.engine. on_start_engine_list.insert(0, covercp.start)14 cherrypy.engine. on_start_thread_list.insert(0, covercp.start)13 cherrypy.engine.subscribe('start', covercp.start) 14 cherrypy.engine.subscribe('start_thread', covercp.start) 15 15 16 16 Run your code, then use the covercp.serve() function to browse the … … 45 45 def start(threadid=None): 46 46 pass 47 start.priority = 20 47 48 48 49 # Guess initial depth to hide FIXME this doesn't work for non-cherrypy stuff trunk/cherrypy/lib/sessions.py
r1611 r1627 24 24 25 25 26 class PerpetualTimer(threading._Timer):27 28 def run(self):29 while True:30 self.finished.wait(self.interval)31 if self.finished.isSet():32 return33 self.function(*self.args, **self.kwargs)34 35 36 26 missing = object() 37 27 … … 58 48 59 49 clean_thread = None 60 clean_thread__doc = "Class-level PerpetualTimer which calls self.clean_up."50 clean_thread__doc = "Class-level Monitor which calls self.clean_up." 61 51 62 52 clean_freq = 5 … … 75 65 if self._load() is not None: 76 66 self.id = None 77 78 def clean_interrupt(cls):79 """Stop the expired-session cleaning timer."""80 if cls.clean_thread:81 cls.clean_thread.cancel()82 cls.clean_thread.join()83 cls.clean_thread = None84 clean_interrupt = classmethod(clean_interrupt)85 67 86 68 def clean_up(self): … … 130 112 cls = self.__class__ 131 113 if not cls.clean_thread: 132 cherrypy.engine.on_stop_engine_list.append(cls.clean_interrupt)133 114 # clean_up is in instancemethod and not a classmethod, 134 115 # so tool config can be accessed inside the method. 135 t = PerpetualTimer(self.clean_freq, self.clean_up) 136 t.setName("CP Session Cleanup") 116 from cherrypy import pywebd 117 t = pywebd.plugins.Monitor(cherrypy.engine, self.clean_up, 118 "CP Session Cleanup") 119 t.frequency = self.clean_freq 137 120 cls.clean_thread = t 138 121 t.start() trunk/cherrypy/test/benchmark.py
r1589 r1627 150 150 151 151 152 Server Software: CherryPy/3. 0.1alpha152 Server Software: CherryPy/3.1alpha 153 153 Server Hostname: localhost 154 154 Server Port: 8080 … … 309 309 global AB_PATH 310 310 AB_PATH = ab_opt 311 cherrypy.engine.start( blocking=False)311 cherrypy.engine.start() 312 312 if cherrypy.engine.state == cherrypy._cpengine.STARTING: 313 313 cherrypy.engine.wait() trunk/cherrypy/test/helper.py
r1528 r1627 122 122 cherrypy.engine.start_with_callback(_run_test_suite_thread, 123 123 args=(moduleNames, conf)) 124 cherrypy.engine.block() 124 125 if cherrypy.engine.test_success: 125 126 return 0 … … 181 182 if teardown: 182 183 teardown() 183 thread.interrupt_main()184 cherrypy.engine.stop() 184 185 185 186 def testmain(conf=None): … … 188 189 conf = {'server.socket_host': '127.0.0.1'} 189 190 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() 191 cherrypy.server.quickstart() 192 cherrypy.engine.start_with_callback(_test_main_thread) 193 cherrypy.engine.block() 196 194 197 195 def _test_main_thread(): … … 200 198 webtest.main() 201 199 finally: 202 thread.interrupt_main()203 200 cherrypy.engine.stop() 201 trunk/cherrypy/test/modpy.py
r1568 r1627 119 119 "environment": "production", 120 120 }) 121 cherrypy.engine.start( blocking=False)121 cherrypy.engine.start() 122 122 from mod_python import apache 123 123 return apache.OK trunk/cherrypy/test/test.py
r1528 r1627 227 227 import cherrypy 228 228 from cherrypy.lib import covercp 229 cherrypy.engine. on_start_engine_list.insert(0, covercp.start)230 cherrypy.engine. on_start_thread_list.insert(0, covercp.start)229 cherrypy.engine.hooks['start_process'].insert(0, covercp.start) 230 cherrypy.engine.hooks['start_thread'].insert(0, covercp.start) 231 231 except ImportError: 232 232 coverage = None … … 237 237 import cherrypy 238 238 from cherrypy.lib import covercp 239 while covercp.start in cherrypy.engine. on_start_engine_list:240 cherrypy.engine. on_start_engine_list.remove(covercp.start)241 while covercp.start in cherrypy.engine. on_start_thread_list:242 cherrypy.engine. on_start_thread_list.remove(covercp.start)239 while covercp.start in cherrypy.engine.hooks['start_process']: 240 cherrypy.engine.hooks['start_process'].remove(covercp.start) 241 while covercp.start in cherrypy.engine.hooks['start_thread']: 242 cherrypy.engine.hooks['start_thread'].remove(covercp.start) 243 243 if self.coverage: 244 244 self.coverage.save() trunk/cherrypy/test/test_config.py
r1620 r1627 61 61 return value(handler()) 62 62 cherrypy.request.handler = wrapper 63 cherrypy.engine.request_class.namespaces['raw'] = raw_namespace64 63 65 64 class Raw: … … 81 80 root.foo = Foo() 82 81 root.raw = Raw() 83 cherrypy.tree.mount(root, config=ioconf) 82 app = cherrypy.tree.mount(root, config=ioconf) 83 app.request_class.namespaces['raw'] = raw_namespace 84 84 85 cherrypy.tree.mount(Another(), "/another") 85 86 cherrypy.config.update({'environment': 'test_suite'}) trunk/cherrypy/test/test_states.py
r1475 r1627 22 22 ctrlc.exposed = True 23 23 24 def restart(self):25 cherrypy.engine. restart()26 return "app was restarted succesfully"27 restart.exposed = True24 def graceful(self): 25 cherrypy.engine.graceful() 26 return "app was (gracefully) restarted succesfully" 27 graceful.exposed = True 28 28 29 29 def block_explicit(self): … … 52 52 self.running = False 53 53 self.startcount = 0 54 self.gracecount = 0 54 55 self.threads = {} 55 56 … … 60 61 def stop(self): 61 62 self.running = False 63 64 def graceful(self): 65 self.gracecount += 1 62 66 63 67 def startthread(self, thread_id): … … 86 90 # Test server start 87 91 cherrypy.server.quickstart(self.server_class) 88 cherrypy.engine.start( blocking=False)92 cherrypy.engine.start() 89 93 self.assertEqual(cherrypy.engine.state, 1) 90 94 … … 103 107 self.assertEqual(len(db_connection.threads), 1) 104 108 105 # Test engine stop 109 # Test engine stop. This will also stop the HTTP server. 106 110 cherrypy.engine.stop() 107 111 self.assertEqual(cherrypy.engine.state, 0) 108 112 109 # Verify that the on_stop_enginefunction was called113 # Verify that our custom stop function was called 110 114 self.assertEqual(db_connection.running, False) 111 115 self.assertEqual(len(db_connection.threads), 0) … … 123 127 self.assertBody("Hello World") 124 128 cherrypy.engine.stop() 129 cherrypy.server.start() 125 130 cherrypy.engine.start_with_callback(stoptest) 131 cherrypy.engine.block() 126 132 self.assertEqual(cherrypy.engine.state, 0) 127 cherrypy.server.stop()128 133 129 134 def test_1_Restart(self): 130 135 cherrypy.server.start() 131 cherrypy.engine.start( blocking=False)136 cherrypy.engine.start() 132 137 133 138 # The db_connection should be running now 134 139 self.assertEqual(db_connection.running, True) 135 sc = db_connection.startcount140 grace = db_connection.gracecount 136 141 137 142 self.getPage("/") … … 140 145 141 146 # Test server restart from this thread 142 cherrypy.engine. restart()147 cherrypy.engine.graceful() 143 148 self.assertEqual(cherrypy.engine.state, 1) 144 149 self.getPage("/") 145 150 self.assertBody("Hello World") 146 151 self.assertEqual(db_connection.running, True) 147 self.assertEqual(db_connection. startcount, sc+ 1)152 self.assertEqual(db_connection.gracecount, grace + 1) 148 153 self.assertEqual(len(db_connection.threads), 1) 149 154 150 155 # Test server restart from inside a page handler 151 self.getPage("/ restart")156 self.getPage("/graceful") 152 157 self.assertEqual(cherrypy.engine.state, 1) 153 self.assertBody("app was restarted succesfully")158 self.assertBody("app was (gracefully) restarted succesfully") 154 159 self.assertEqual(db_connection.running, True) 155 self.assertEqual(db_connection. startcount, sc+ 2)160 self.assertEqual(db_connection.gracecount, grace + 2) 156 161 # Since we are requesting synchronously, is only one thread used? 157 # Note that the "/ restart" request has been flushed.162 # Note that the "/graceful" request has been flushed. 158 163 self.assertEqual(len(db_connection.threads), 0) 159 164 … … 162 167 self.assertEqual(db_connection.running, False) 163 168 self.assertEqual(len(db_connection.threads), 0) 164 cherrypy.server.stop()165 169 166 170 def test_2_KeyboardInterrupt(self): … … 169 173 # Raise a keyboard interrupt in the HTTP server's main thread. 170 174 # We must start the server in this, the main thread 171 cherrypy.engine.start( blocking=False)175 cherrypy.engine.start() 172 176 cherrypy.server.start() 173 177 … … 194 198 # This should raise a BadStatusLine error, since the worker 195 199 # thread will just die without writing a response. 196 cherrypy.engine.start( blocking=False)200 cherrypy.engine.start() 197 201 cherrypy.server.start() 198 202 … … 211 215 212 216 def test_3_Deadlocks(self): 213 cherrypy.engine.start( blocking=False)217 cherrypy.engine.start() 214 218 cherrypy.server.start() 215 219 try: 216 self.assertNotEqual(cherrypy. engine.monitor_thread, None)220 self.assertNotEqual(cherrypy._timeout_monitor.thread, None) 217 221 218 222 # Request a "normal" page. 219 self.assertEqual(cherrypy. engine.servings, [])223 self.assertEqual(cherrypy._timeout_monitor.servings, []) 220 224 self.getPage("/") 221 225 self.assertBody("Hello World") 222 226 # request.close is called async. 223 while cherrypy.engine.servings: 227 while cherrypy._timeout_monitor.servings: 228 print ".", 224 229 time.sleep(0.01) 225 230 … … 237 242 finally: 238 243 cherrypy.engine.stop() 239 cherrypy.server.stop()240 244 241 245 def test_4_Autoreload(self): … … 255 259 args.append('-ssl') 256 260 pid = os.spawnl(os.P_NOWAIT, sys.executable, *args) 257 pid = str(pid)258 261 cherrypy._cpserver.wait_for_occupied_port(host, port) 259 262 260 263 try: 261 self.getPage("/pid") 262 assert self.body.isdigit(), self.body 263 pid = self.body 264 self.getPage("/start") 265 start = float(self.body) 264 266 265 267 # Give the autoreloader time to cache the file time. … … 267 269 268 270 # Touch the file 269 f = open(demoscript, 'ab') 270 f.write(" ") 271 f.close() 271 os.utime(demoscript, None) 272 272 273 273 # Give the autoreloader time to re-exec the process … … 276 276 277 277 self.getPage("/pid") 278 assert self.body.isdigit(), self.body 279 self.assertNotEqual(self.body, pid) 280 pid = self.body 278 pid = int(self.body) 279 280 self.getPage("/start") 281 self.assert_(float(self.body) > start) 281 282 finally: 282 283 # Shut down the spawned process … … 289 290 except AttributeError: 290 291 # Windows 291 print os.waitpid( int(pid), 0)292 print os.waitpid(pid, 0) 292 293 except OSError, x: 293 294 if x.args != (10, 'No child processes'): … … 300 301 ServerStateTests.server_class = server 301 302 suite = helper.CPTestLoader.loadTestsFromTestCase(ServerStateTests) 303 engine = cherrypy.engine 302 304 try: 303 305 global db_connection 304 306 db_connection = Dependency() 305 cherrypy.engine.on_start_engine_list.append(db_connection.start) 306 cherrypy.engine.on_stop_engine_list.append(db_connection.stop) 307 cherrypy.engine.on_start_thread_list.append(db_connection.startthread) 308 cherrypy.engine.on_stop_thread_list.append(db_connection.stopthread) 307 engine.subscribe('start', db_connection.start) 308 engine.subscribe('stop', db_connection.stop) 309 engine.subscribe('graceful', db_connection.graceful) 310 engine.subscribe('start_thread', db_connection.startthread) 311 engine.subscribe('stop_thread', db_connection.stopthread) 309 312 310 313 try: … … 322 325 tr.out.close() 323 326 finally: 324 cherrypy.server.stop() 325 cherrypy.engine.stop() 327 engine.stop() 326 328 327 329 trunk/cherrypy/test/test_states_demo.py
r1476 r1627 1 1 import os 2 2 import sys 3 import time 4 starttime = time.time() 3 5 4 6 import cherrypy … … 11 13 index.exposed = True 12 14 15 def mtimes(self): 16 return repr(cherrypy.engine.publish("Autoreloader", "mtimes")) 17 mtimes.exposed = True 18 13 19 def pid(self): 14 20 return str(os.getpid()) 15 21 pid.exposed = True 16 22 23 def start(self): 24 return repr(starttime) 25 start.exposed = True 26 17 27 def stop(self): 18 28 cherrypy.engine.stop() 19 cherrypy.server.stop()20 29 stop.exposed = True 21 30 … … 38 47 cherrypy.config.update(conf) 39 48 cherrypy.tree.mount(Root(), config={'global': conf}) 40 cherrypy.engine.start( blocking=False)49 cherrypy.engine.start() 41 50 cherrypy.server.quickstart() 42 51 cherrypy.engine.block() 43 trunk/cherrypy/test/test_tools.py
r1621 r1627 208 208 }, 209 209 } 210 cherrypy.tree.mount(root, config=conf) 210 app = cherrypy.tree.mount(root, config=conf) 211 app.request_class.namespaces['myauth'] = myauthtools 211 212 212 213
