def test_exitcode_nonzero(self): cmd = ['false'] with pytest.raises(subprocess.CalledProcessError) as excinfo: popen_rt(cmd) err = excinfo.value assert err.returncode > 0 assert err.cmd == cmd assert not err.output
def test_stdin(self, tmpdir): text = 'foo\nbar' infile = tmpdir.join('stdin') infile.write(text) out, err = popen_rt(['cat'], stdin=infile.open()) assert out == text assert not err
def test_stderr(self): text = 'Lorem ipsum' out, err = popen_rt('echo -n %s >&2' % text, shell=True, stderr=subprocess.PIPE) assert not out assert err == text
def test_stream_merge(self): text_out = 'this is stdout' text_err = 'this is stderr' out, err = popen_rt('echo -n %s; echo -n %s >&2' % (text_out, text_err), shell=True) assert out == text_out + text_err assert not err
def test_stream_separate(self): text_out = 'this is stdout' text_err = 'this is stderr' out, err = popen_rt('echo -n %s; echo -n %s >&2' % (text_out, text_err), shell=True, stderr=subprocess.PIPE) assert out == text_out assert err == text_err
def test_raise_stdout(self): with pytest.raises(exc.CheckbValueError): popen_rt(['false'], stdout=None)
def test_shell(self): popen_rt('true && true', shell=True)
def test_stdout(self): text = 'Lorem ipsum' out, err = popen_rt(['echo', '-n', text]) assert out == text assert not err
def test_exitcode_zero(self): out, err = popen_rt(['true']) assert not out assert not err
def _run_playbook(self, test_playbook, ipaddr, playbook_vars): '''Run the ansible-playbook command to execute given playbook containing the task. :param str test_playbook: name of the playbook, relative to the task directory :param str ipaddr: IP address of the machine the task will be run on :param dict playbook_vars: vars dict created by :meth:`_create_playbook_vars` :return: stream output of the ansible-playbook command (stdout and stderr merged together) :rtype: str :raise CheckbPlaybookError: when the playbook is not syntactically correct ''' ansible_dir = os.path.join(config.get_config()._data_dir, 'ansible') # dump variables for future use varsfile, allvarsfile = self._dump_playbook_vars(playbook_vars) # figure out the ansible-playbook command cmd = [ 'ansible-playbook', 'runner.yml', '--inventory=%s,' % ipaddr, # the ending comma is important '--extra-vars=@%s' % allvarsfile, ] # for local execution, run as root unless instructed otherwise if not self.run_remotely and playbook_vars['become_root']: cmd.append('--become') if self.run_remotely: if self.arg_data['ssh_privkey']: cmd.append('--private-key=%s' % self.arg_data['ssh_privkey']) else: cmd.append('--connection=local') if self.arg_data['debug']: cmd.append('-vv') log.debug('Running ansible playbook %s', ' '.join(cmd)) try: # during playbook execution, handle system signals asking us to # quit signal.signal(signal.SIGINT, self._interrupt_handler) signal.signal(signal.SIGTERM, self._interrupt_handler) output, _ = os_utils.popen_rt(cmd, cwd=ansible_dir) return output except subprocess.CalledProcessError as e: log.error('ansible-playbook ended with %d return code', e.returncode) log.debug(e.output) raise exc.CheckbError(e) except exc.CheckbInterruptError as e: log.error( 'System interrupt %s detected. Pulling logs and ' 'stopping execution.', e) cmd_failsafe = cmd + ['--tags', 'failsafe'] try: os_utils.popen_rt(cmd_failsafe, cwd=ansible_dir) except (subprocess.CalledProcessError, exc.CheckbInterruptError) as e2: log.error( 'Error during failsafe pulling logs, ignoring and ' 'raising the original error. The current error is: %s:%s', e2.__class__.__name__, e2) raise e finally: # reset signal handling to default behavior signal.signal(signal.SIGINT, signal.SIG_DFL) signal.signal(signal.SIGTERM, signal.SIG_DFL)