diff --git a/deluge/tests/common.py b/deluge/tests/common.py index ce5d83656..13701b8d9 100644 --- a/deluge/tests/common.py +++ b/deluge/tests/common.py @@ -19,7 +19,9 @@ from twisted.trial import unittest import deluge.configmanager import deluge.core.preferencesmanager import deluge.log +from deluge.common import get_localhost_auth from deluge.error import DelugeError +from deluge.ui.client import client # This sets log level to critical, so use log.critical() to debug while running unit tests deluge.log.setup_logger('none') @@ -94,12 +96,19 @@ class ReactorOverride: class ProcessOutputHandler(protocol.ProcessProtocol): def __init__( - self, script, callbacks, logfile=None, print_stdout=True, print_stderr=True + self, + script, + shutdown_func, + callbacks, + logfile=None, + print_stdout=True, + print_stderr=True, ): """Executes a script and handle the process' output to stdout and stderr. Args: script (str): The script to execute. + shutdown_func (func): A function which will gracefully stop the called script. callbacks (list): Callbacks to trigger if the expected output if found. logfile (str, optional): Filename to wrote the process' output. print_stderr (bool): Print the process' stderr output to stdout. @@ -108,6 +117,7 @@ class ProcessOutputHandler(protocol.ProcessProtocol): """ self.callbacks = callbacks self.script = script + self.shutdown_func = shutdown_func self.log_output = '' self.stderr_out = '' self.logfile = logfile @@ -127,6 +137,7 @@ class ProcessOutputHandler(protocol.ProcessProtocol): with open(self.logfile, 'w') as f: f.write(self.log_output) + @defer.inlineCallbacks def kill(self): """Kill the running process. @@ -139,8 +150,13 @@ class ProcessOutputHandler(protocol.ProcessProtocol): self.killed = True self._kill_watchdogs() self.quit_d = Deferred() - self.transport.signalProcess('INT') - return self.quit_d + shutdown = self.shutdown_func() + shutdown.addTimeout(5, reactor) + try: + yield shutdown + except Exception: + self.transport.signalProcess('TERM') + yield self.quit_d def _kill_watchdogs(self): """"Cancel all watchdogs""" @@ -216,7 +232,7 @@ def start_core( Args: listen_port (int, optional): The port the daemon listens for client connections. logfile (str, optional): Logfile name to write the output from the process. - timeout (int): If none of the callbacks have been triggered before the imeout, the process is killed. + timeout (int): If none of the callbacks have been triggered before the timeout, the process is killed. timeout_msg (str): The message to print when the timeout expires. custom_script (str): Extra python code to insert into the daemon process script. print_stderr (bool): If the output from the process' stderr should be printed to stdout. @@ -251,7 +267,7 @@ except Exception: import traceback sys.stderr.write('Exception raised:\\n %%s' %% traceback.format_exc()) """ % { - 'dir': config_directory, + 'dir': config_directory.replace('\\', '\\\\'), 'port': listen_port, 'script': custom_script, } @@ -286,20 +302,29 @@ except Exception: if extra_callbacks: callbacks.extend(extra_callbacks) + @defer.inlineCallbacks + def shutdown_daemon(): + username, password = get_localhost_auth() + yield client.connect( + 'localhost', listen_port, username=username, password=password + ) + yield client.daemon.shutdown() + process_protocol = start_process( - daemon_script, callbacks, logfile, print_stdout, print_stderr + daemon_script, shutdown_daemon, callbacks, logfile, print_stdout, print_stderr ) return default_core_cb['deferred'], process_protocol def start_process( - script, callbacks, logfile=None, print_stdout=True, print_stderr=True + script, shutdown_func, callbacks, logfile=None, print_stdout=True, print_stderr=True ): """ Starts an external python process which executes the given script. Args: script (str): The content of the script to execute. + shutdown_func (func): A function which will gracefully end the called script. callbacks (list): list of dictionaries specifying callbacks. logfile (str, optional): Logfile name to write the output from the process. print_stderr (bool): If the output from the process' stderr should be printed to stdout. @@ -321,7 +346,12 @@ def start_process( """ cwd = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) process_protocol = ProcessOutputHandler( - script.encode('utf8'), callbacks, logfile, print_stdout, print_stderr + script.encode('utf8'), + shutdown_func, + callbacks, + logfile, + print_stdout, + print_stderr, ) # Add timeouts to deferreds