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

Changeset 1995

Show
Ignore:
Timestamp:
06/29/08 01:12:27
Author:
fumanchu
Message:

Some test_states love. Also, cherryd grew an --import option.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/cherrypy/cherryd

    r1989 r1995  
    11#! /usr/bin/env python 
    22"""The CherryPy daemon.""" 
     3 
     4import sys 
    35 
    46import cherrypy 
     
    79 
    810def start(configfiles=None, daemonize=False, environment=None, 
    9           fastcgi=False, pidfile=None): 
     11          fastcgi=False, pidfile=None, imports=None): 
    1012    """Subscribe all engine plugins and start the engine.""" 
     13    for i in imports: 
     14        exec "import %s" % i 
     15     
    1116    for c in configfiles or []: 
    1217        cherrypy.config.update(c) 
     
    4550     
    4651    # Always start the engine; this will start all other services 
    47     engine.start() 
    48     engine.block() 
     52    try: 
     53        engine.start() 
     54    except: 
     55        # Assume the error has been logged already via bus.log. 
     56        sys.exit(1) 
     57    else: 
     58        engine.block() 
    4959 
    5060 
     
    6171    p.add_option('-f', action="store_true", dest='fastcgi', 
    6272                 help="start a fastcgi server instead of the default HTTP server") 
     73    p.add_option('-i', '--import', action="append", dest='imports', 
     74                 help="specify modules to import") 
    6375    p.add_option('-p', '--pidfile', dest='pidfile', default=None, 
    6476                 help="store the process id in the given file") 
     
    6678     
    6779    start(options.config, options.daemonize, 
    68           options.environment, options.fastcgi, options.pidfile) 
     80          options.environment, options.fastcgi, options.pidfile, 
     81          options.imports) 
    6982 
  • trunk/cherrypy/test/test_states.py

    r1989 r1995  
    1414thisdir = os.path.join(os.getcwd(), os.path.dirname(__file__)) 
    1515PID_file_path = os.path.join(thisdir, 'pid_for_test_daemonize') 
     16 
     17 
     18def write_conf(scheme='http', starterror=False): 
     19    if scheme.lower() == 'https': 
     20        serverpem = os.path.join(thisdir, 'test.pem') 
     21        ssl = """ 
     22server.ssl_certificate: r'%s' 
     23server.ssl_private_key: r'%s' 
     24""" % (serverpem, serverpem) 
     25    else: 
     26        ssl = "" 
     27     
     28    if starterror: 
     29        starterror = "starterror: True" 
     30    else: 
     31        starterror = "" 
     32     
     33    conffile = open(os.path.join(thisdir, 'test_states.conf'), 'wb') 
     34    conffile.write("""[global] 
     35server.socket_host: '%(host)s' 
     36server.socket_port: %(port)s 
     37log.screen: False 
     38log.error_file: r'%(error_log)s' 
     39log.access_file: r'%(access_log)s' 
     40%(ssl)s 
     41%(starterror)s 
     42""" % {'host': host, 
     43       'port': port, 
     44       'error_log': os.path.join(thisdir, 'test_states_demo.error.log'), 
     45       'access_log': os.path.join(thisdir, 'test_states_demo.access.log'), 
     46       'ssl': ssl, 
     47       'starterror': starterror, 
     48       }) 
     49    conffile.close() 
     50 
     51 
     52def spawn_cp(configfile=os.path.join(thisdir, 'test_states.conf'), 
     53             wait=False, daemonize=False): 
     54    """Start cherryd in a subprocess.""" 
     55    host = cherrypy.server.socket_host 
     56    port = cherrypy.server.socket_port 
     57    cherrypy._cpserver.wait_for_free_port(host, port) 
     58     
     59    args = [sys.executable, os.path.join(thisdir, '..', 'cherryd'), 
     60            '-c', configfile, '-i', 'cherrypy.test.test_states_demo'] 
     61     
     62    if sys.platform != 'win32': 
     63        args.append('-p') 
     64        args.append(PID_file_path) 
     65     
     66    # Spawn the process and wait, when this returns, the original process 
     67    # is finished.  If it daemonized properly, we should still be able 
     68    # to access pages. 
     69    if daemonize: 
     70        args.append('-d') 
     71     
     72    if wait: 
     73        result = os.spawnl(os.P_WAIT, sys.executable, *args) 
     74    else: 
     75        result = os.spawnl(os.P_NOWAIT, sys.executable, *args) 
     76        cherrypy._cpserver.wait_for_occupied_port(host, port) 
     77     
     78    return result 
     79 
     80def wait(pid): 
     81    """Wait for the process with the given pid to exit.""" 
     82    try: 
     83        try: 
     84            # Mac, UNIX 
     85            os.wait() 
     86        except AttributeError: 
     87            # Windows 
     88            os.waitpid(pid, 0) 
     89    except OSError, x: 
     90        if x.args != (10, 'No child processes'): 
     91            raise 
    1692 
    1793 
     
    261337         
    262338        # Start the demo script in a new process 
    263         demoscript = os.path.join(os.getcwd(), os.path.dirname(__file__), 
    264                                   "test_states_demo.py") 
    265         host = cherrypy.server.socket_host 
    266         port = cherrypy.server.socket_port 
    267         cherrypy._cpserver.wait_for_free_port(host, port) 
    268          
    269         args = [sys.executable, demoscript, host, str(port)] 
    270         if self.scheme == "https": 
    271             args.append('-ssl') 
    272         pid = os.spawnl(os.P_NOWAIT, sys.executable, *args) 
    273         cherrypy._cpserver.wait_for_occupied_port(host, port) 
    274          
     339        write_conf(scheme=self.scheme) 
     340        pid = spawn_cp() 
    275341        try: 
    276342            self.getPage("/start") 
     
    281347             
    282348            # Touch the file 
    283             os.utime(demoscript, None) 
     349            os.utime(os.path.join(thisdir, "test_states_demo.py"), None) 
    284350             
    285351            # Give the autoreloader time to re-exec the process 
     
    295361            # Shut down the spawned process 
    296362            self.getPage("/exit") 
    297          
    298         try: 
    299             try: 
    300                 # Mac, UNIX 
    301                 print os.wait() 
    302             except AttributeError: 
    303                 # Windows 
    304                 print os.waitpid(pid, 0) 
    305         except OSError, x: 
    306             if x.args != (10, 'No child processes'): 
    307                 raise 
     363        wait(pid) 
    308364     
    309365    def test_5_Start_Error(self): 
     
    312368            return 
    313369         
    314         # Start the demo script in a new process 
    315         demoscript = os.path.join(os.getcwd(), os.path.dirname(__file__), 
    316                                   "test_states_demo.py") 
    317         host = cherrypy.server.socket_host 
    318         port = cherrypy.server.socket_port 
    319          
    320370        # If a process errors during start, it should stop the engine 
    321371        # and exit with a non-zero exit code. 
    322         args = [sys.executable, demoscript, host, str(port), '-starterror'] 
    323         if self.scheme == "https": 
    324             args.append('-ssl') 
    325         exit_code = os.spawnl(os.P_WAIT, sys.executable, *args) 
     372        write_conf(scheme=self.scheme, starterror=True) 
     373        exit_code = spawn_cp(wait=True) 
    326374        if exit_code == 0: 
    327375            self.fail("Process failed to return nonzero exit code.") 
     
    330378class DaemonizeTests(helper.CPWebCase): 
    331379     
    332     def test_1_Daemonize(self): 
     380    def test_daemonize(self): 
    333381        if not self.server_class: 
    334382            print "skipped (no server) ", 
     
    339387         
    340388        # Start the demo script in a new process 
    341         demoscript = os.path.join(os.getcwd(), os.path.dirname(__file__), 
    342                                   "test_states_demo.py") 
    343         host = cherrypy.server.socket_host 
    344         port = cherrypy.server.socket_port 
    345         cherrypy._cpserver.wait_for_free_port(host, port) 
    346          
    347         args = [sys.executable, demoscript, host, str(port), '-daemonize'] 
    348         if self.scheme == "https": 
    349             args.append('-ssl') 
    350389        # Spawn the process and wait, when this returns, the original process 
    351390        # is finished.  If it daemonized properly, we should still be able 
    352391        # to access pages. 
    353         exit_code = os.spawnl(os.P_WAIT, sys.executable, *args
    354         cherrypy._cpserver.wait_for_occupied_port(host, port
     392        write_conf(scheme=self.scheme
     393        exit_code = spawn_cp(wait=True, daemonize=True
    355394         
    356395        # Give the server some time to start up 
     
    368407            # Shut down the spawned process 
    369408            self.getPage("/exit") 
    370          
    371         try: 
    372             print os.waitpid(pid, 0) 
    373         except OSError, x: 
    374             if x.args != (10, 'No child processes'): 
    375                 raise 
     409        wait(pid) 
    376410         
    377411        # Wait until here to test the exit code because we want to ensure 
    378412        # that we wait for the daemon to finish running before we fail. 
    379413        if exit_code != 0: 
    380             self.fail("Daemonized process failed to exit cleanly") 
     414            self.fail("Daemonized parent process failed to exit cleanly.") 
    381415 
    382416 
  • trunk/cherrypy/test/test_states_demo.py

    r1926 r1995  
    55 
    66import cherrypy 
    7 from cherrypy.process import plugins 
    8 thisdir = os.path.join(os.getcwd(), os.path.dirname(__file__)) 
    9 PID_file_path = os.path.join(thisdir, 'pid_for_test_daemonize') 
    107 
    118 
     
    3734    exit.exposed = True 
    3835 
     36def starterror(): 
     37    if cherrypy.config.get('starterror', False): 
     38        zerodiv = 1 / 0 
     39cherrypy.engine.subscribe('start', starterror, priority=6) 
    3940 
    40 if __name__ == '__main__': 
    41     conf = {"server.socket_host": sys.argv[1], 
    42             "server.socket_port": int(sys.argv[2]), 
    43             "log.screen": False, 
    44             "log.error_file": os.path.join(thisdir, 'test_states_demo.error.log'), 
    45             "log.access_file": os.path.join(thisdir, 'test_states_demo.access.log'), 
    46             } 
    47      
    48     if '-ssl' in sys.argv[3:]: 
    49         localDir = os.path.dirname(__file__) 
    50         serverpem = os.path.join(os.getcwd(), localDir, 'test.pem') 
    51         conf['server.ssl_certificate'] = serverpem 
    52         conf['server.ssl_private_key'] = serverpem 
    53      
    54     if '-daemonize' in sys.argv[3:]: 
    55         # Sometimes an exception happens during exit; 
    56         # try to make sure we get a non_zero exit code. 
    57         old_exitfunc = sys.exitfunc 
    58         def exitfunc(): 
    59             try: 
    60                 old_exitfunc() 
    61             except SystemExit: 
    62                 raise 
    63             except: 
    64                 raise SystemExit(1) 
    65         sys.exitfunc = exitfunc 
    66          
    67         plugins.Daemonizer(cherrypy.engine).subscribe() 
    68         plugins.PIDFile(cherrypy.engine, PID_file_path).subscribe() 
    69      
    70     if '-starterror' in sys.argv[3:]: 
    71         cherrypy.engine.subscribe('start', lambda: 1/0, priority=6) 
    72      
    73     # This is in a special order for a reason: 
    74     # it allows test_states to wait_for_occupied_port 
    75     # and then immediately call getPage without getting 503. 
    76     cherrypy.config.update(conf) 
    77     cherrypy.tree.mount(Root(), config={'global': conf}) 
    78     try: 
    79         cherrypy.engine.start() 
    80     except ZeroDivisionError: 
    81         sys.exit(1) 
    82     cherrypy.engine.block() 
     41cherrypy.tree.mount(Root(), '/', {'/': {}}) 

Hosted by WebFaction

Log in as guest/cpguest to create tickets