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

Changeset 1996

Show
Ignore:
Timestamp:
06/29/08 01:31:48
Author:
fumanchu
Message:

Fix for #828 (CherryPy should exit on SIGHUP if not daemonized). The tests need to be exercised on Unix.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/cherrypy/process/plugins.py

    r1989 r1996  
    5757        # Set default handlers 
    5858        self.handlers = {'SIGTERM': self.bus.exit, 
    59                          'SIGHUP': self.bus.restart
     59                         'SIGHUP': self.handle_SIGHUP
    6060                         'SIGUSR1': self.bus.graceful, 
    6161                         } 
     
    101101        self.bus.log("Caught signal %s." % signame) 
    102102        self.bus.publish(signame) 
    103  
     103     
     104    def handle_SIGHUP(self): 
     105        if os.isatty(sys.stdin.fileno()): 
     106            # not daemonized (may be foreground or background) 
     107            self.bus.log("SIGHUP caught but not daemonized. Exiting.") 
     108            self.bus.exit() 
     109        else: 
     110            self.bus.log("SIGHUP caught while daemonized. Restarting.") 
     111            self.bus.restart() 
    104112 
    105113 
  • trunk/cherrypy/test/test_states.py

    r1995 r1996  
    376376 
    377377 
    378 class DaemonizeTests(helper.CPWebCase): 
     378class PluginTests(helper.CPWebCase): 
    379379     
    380380    def test_daemonize(self): 
     
    386386            return 
    387387         
    388         # Start the demo script in a new process 
    389388        # Spawn the process and wait, when this returns, the original process 
    390389        # is finished.  If it daemonized properly, we should still be able 
     
    415414 
    416415 
     416class SignalHandlingTests(helper.CPWebCase): 
     417     
     418    def test_SIGHUP_tty(self): 
     419        # When not daemonized, SIGHUP should shut down the server. 
     420        if not self.server_class: 
     421            print "skipped (no server) ", 
     422            return 
     423         
     424        try: 
     425            from signal import SIGHUP 
     426        except ImportError: 
     427            print "skipped (no SIGHUP) ", 
     428            return 
     429         
     430        # Spawn the process. 
     431        write_conf(scheme=self.scheme) 
     432        pid = spawn_cp(wait=False, daemonize=False) 
     433        # Send a SIGHUP 
     434        os.kill(pid, signal.SIGHUP) 
     435        # This might hang if things aren't working right, but meh. 
     436        wait(pid) 
     437     
     438    def test_SIGHUP_daemonized(self): 
     439        # When daemonized, SIGHUP should restart the server. 
     440        if not self.server_class: 
     441            print "skipped (no server) ", 
     442            return 
     443         
     444        try: 
     445            from signal import SIGHUP 
     446        except ImportError: 
     447            print "skipped (no SIGHUP) ", 
     448            return 
     449         
     450        if os.name not in ['posix']:  
     451            print "skipped (not on posix) ", 
     452            return 
     453         
     454        # Spawn the process and wait, when this returns, the original process 
     455        # is finished.  If it daemonized properly, we should still be able 
     456        # to access pages. 
     457        write_conf(scheme=self.scheme) 
     458        exit_code = spawn_cp(wait=True, daemonize=True) 
     459         
     460        # Give the server some time to start up 
     461        time.sleep(2) 
     462         
     463        # Get the PID from the file. 
     464        pid = int(open(PID_file_path).read()) 
     465        try: 
     466            # Send a SIGHUP 
     467            os.kill(pid, signal.SIGHUP) 
     468            # Give the server some time to restart 
     469            time.sleep(2) 
     470            self.getPage("/pid") 
     471            self.assertStatus(200) 
     472            new_pid = int(self.body) 
     473            self.assertNotEqual(new_pid, pid) 
     474        finally: 
     475            # Shut down the spawned process 
     476            self.getPage("/exit") 
     477        wait(new_pid) 
     478 
     479 
     480 
     481cases = [v for v in globals().values() 
     482         if isinstance(v, type) and issubclass(v, helper.CPWebCase)] 
     483 
    417484def run(server, conf): 
    418485    helper.setConfig(conf) 
    419     ServerStateTests.server_class = server 
    420     DaemonizeTests.server_class = server 
    421     suite = helper.CPTestLoader.loadTestsFromTestCase(ServerStateTests) 
    422     daemon_suite = helper.CPTestLoader.loadTestsFromTestCase(DaemonizeTests) 
     486    for tc in cases: 
     487        tc.server_class = server 
     488    suites = [helper.CPTestLoader.loadTestsFromTestCase(tc) for tc in 
     489              (ServerStateTests, PluginTests, SignalHandlingTests)] 
    423490    try: 
    424491        try: 
    425492            import pyconquer 
    426493        except ImportError: 
    427             helper.CPTestRunner.run(suite) 
    428             helper.CPTestRunner.run(daemon_suite) 
     494            for suite in suites: 
     495                helper.CPTestRunner.run(suite) 
    429496        else: 
    430497            tr = pyconquer.Logger("cherrypy") 
     
    432499            try: 
    433500                tr.start() 
    434                 helper.CPTestRunner.run(suite) 
    435                 helper.CPTestRunner.run(daemon_suite) 
     501                for suite in suites: 
     502                    helper.CPTestRunner.run(suite) 
    436503            finally: 
    437504                tr.stop() 
     
    449516     
    450517    if host: 
    451         DaemonizeTests.HOST = ServerStateTests.HOST = host 
     518        for tc in cases: 
     519            tc.HOST = host 
    452520     
    453521    if port: 
    454         DaemonizeTests.PORT = ServerStateTests.PORT = port 
     522        for tc in cases: 
     523            tc.PORT = port 
    455524     
    456525    if ssl: 
     
    459528        conf['server.ssl_certificate'] = serverpem 
    460529        conf['server.ssl_private_key'] = serverpem 
    461         DaemonizeTests.scheme = ServerStateTests.scheme = "https" 
    462         DaemonizeTests.HTTP_CONN = ServerStateTests.HTTP_CONN = httplib.HTTPSConnection 
     530        for tc in cases: 
     531            tc.scheme = "https" 
     532            tc.HTTP_CONN = httplib.HTTPSConnection 
    463533     
    464534    def _run(server): 

Hosted by WebFaction

Log in as guest/cpguest to create tickets