def test_with_stdout(self): stdout = """ Lo, praise of the prowess of people-kings of spear-armed Danes, in days long sped, we have heard, and what honot the athelings won! Oft Scyld the Scefing from squadroned foes, from many a tribe, the mead-bench tore, awing the earls. Since erse he lay friendless, a foundling, fate repaid him: for he waxed under welkin, in wealth he trove, till before him the folk, both far and near, who house by the whale-path, heard his mandate, gabe him gits: a good king he! To him an heir was afterward born, a son in his halls, whom heaven sent to favor the fol, feeling their woe that erst they had lacked an earl for leader so long a while; the Lord endowed him, the Wielder of Wonder, with world's renown. """.strip() err = exception.ProcessExecutionError(stdout=stdout) print err.message self.assertTrue('people-kings' in err.message)
def execute(*cmd, **kwargs): """ Helper method to execute command with optional retry. :cmd Passed to subprocess.Popen. :process_input Send to opened process. :check_exit_code Defaults to 0. Raise exception.ProcessExecutionError unless program exits with this code. :delay_on_retry True | False. Defaults to True. If set to True, wait a short amount of time before retrying. :attempts How many times to retry cmd. :run_as_root True | False. Defaults to False. If set to True, the command is prefixed by the command specified in the root_helper kwarg. :root_helper command to prefix all cmd's with :raises exception.Error on receiving unknown arguments :raises exception.ProcessExecutionError """ process_input = kwargs.pop('process_input', None) check_exit_code = kwargs.pop('check_exit_code', 0) delay_on_retry = kwargs.pop('delay_on_retry', True) attempts = kwargs.pop('attempts', 1) run_as_root = kwargs.pop('run_as_root', False) root_helper = kwargs.pop('root_helper', '') if len(kwargs): raise exception.Error( _('Got unknown keyword args ' 'to utils.execute: %r') % kwargs) if run_as_root: cmd = shlex.split(root_helper) + list(cmd) cmd = map(str, cmd) while attempts > 0: attempts -= 1 try: LOG.debug(_('Running cmd (subprocess): %s'), ' '.join(cmd)) _PIPE = subprocess.PIPE # pylint: disable=E1101 obj = subprocess.Popen(cmd, stdin=_PIPE, stdout=_PIPE, stderr=_PIPE, close_fds=True) result = None if process_input is not None: result = obj.communicate(process_input) else: result = obj.communicate() obj.stdin.close() # pylint: disable=E1101 _returncode = obj.returncode # pylint: disable=E1101 if _returncode: LOG.debug(_('Result was %s') % _returncode) if (isinstance(check_exit_code, int) and not isinstance(check_exit_code, bool) and _returncode != check_exit_code): (stdout, stderr) = result raise exception.ProcessExecutionError( exit_code=_returncode, stdout=stdout, stderr=stderr, cmd=' '.join(cmd)) return result except exception.ProcessExecutionError: if not attempts: raise else: LOG.debug(_('%r failed. Retrying.'), cmd) if delay_on_retry: greenthread.sleep(random.randint(20, 200) / 100.0) finally: # NOTE(termie): this appears to be necessary to let the subprocess # call clean something up in between calls, without # it two execute calls in a row hangs the second one greenthread.sleep(0)
def test_with_cmd(self): cmd = 'telinit' err = exception.ProcessExecutionError(cmd=cmd) self.assertTrue(cmd in err.message)
def test_with_exit_code(self): exit_code = 0 err = exception.ProcessExecutionError(exit_code=exit_code) self.assertTrue(str(exit_code) in err.message)
def test_with_description(self): description = 'The Narwhal Bacons at Midnight' err = exception.ProcessExecutionError(description=description) self.assertTrue(description in err.message)
def test_defaults(self): err = exception.ProcessExecutionError() self.assertTrue('None\n' in err.message) self.assertTrue('code: -\n' in err.message)
def test_with_stderr(self): stderr = 'Cottonian library' err = exception.ProcessExecutionError(stderr=stderr) self.assertTrue(stderr in str(err.message))