def test_code_out_err(self): subproc = os.path.join(this_base, 'subproc.py') returncode, out, err = k3proc.command('python', subproc, '222') self.assertEqual(222, returncode) self.assertEqual('out-1\nout-2\n', out) self.assertEqual('err-1\nerr-2\n', err) try: returncode, out, err = k3proc.command_ex('python', subproc, '222') except k3proc.CalledProcessError as e: self.assertEqual(222, e.returncode) self.assertEqual('out-1\nout-2\n', e.stdout) self.assertEqual('out-1\nout-2\n'.splitlines(), e.out) self.assertEqual('err-1\nerr-2\n', e.stderr) self.assertEqual('err-1\nerr-2\n'.splitlines(), e.err) self.assertEqual('python', e.cmd[0]) self.assertTrue(e.cmd[1].endswith('subproc.py')) self.assertEqual('222', e.cmd[2]) self.assertEqual({}, e.options) else: self.fail('expect k3proc.CalledProcessError to be raised') returncode, out, err = k3proc.command_ex('python', subproc, '0') self.assertEqual(0, returncode) self.assertEqual('out-1\nout-2\n', out) self.assertEqual('err-1\nerr-2\n', err) returncode, out, err = k3proc.command('python', subproc, '0') self.assertEqual(0, returncode) self.assertEqual('out-1\nout-2\n', out) self.assertEqual('err-1\nerr-2\n', err)
def test_tty(self): returncode, out, err = k3proc.command( 'python', '-c', 'import sys; print(sys.stdout.isatty())', tty=True, ) dd('returncode:', returncode) dd('out:', out) dd('err:', err) self.assertEqual(0, returncode) self.assertEqual('True\n', out) self.assertEqual("", err) # without pseudo tty, no color outupt: _, out, _ = k3proc.command( 'python', '-c', 'import sys; print(sys.stdout.isatty())', tty=False, ) self.assertEqual('False\n', out) # by default no tty: _, out, _ = k3proc.command( 'python', '-c', 'import sys; print(sys.stdout.isatty())', ) self.assertEqual('False\n', out)
def test_lazyload(self): code, out, err = k3proc.command( 'python', '-c', 'import k3confloader as cl; print(1)', check=True, cwd=os.path.join(this_base, 'lazyload'), ) dd("code:", code) dd("out:", out) dd("err:", err) self.assertEqual('1', out.strip()) # When reading attributes, there should be an error try: k3proc.command( 'python', '-c', 'import k3confloader as cl; print(cl.conf.uid)', check=False, cwd=os.path.join(this_base, 'lazyload'), ) except k3proc.CalledProcessError as e: self.assertEqual('should not be here', e.stderr.strip()) self.assertEqual(1, e.returncode)
def test_capture(self): # no capture read_stdin_in_subproc = ''' import k3proc; k3proc.command( 'python', '-c', 'import sys; print(sys.stdin.read())', capture={} ) ''' returncode, out, err = k3proc.command( 'python', '-c', read_stdin_in_subproc.format('False'), input="123", ) dd('returncode:', returncode) dd('out:', out) dd('err:', err) self.assertEqual(0, returncode) self.assertEqual("123\n", out) # capture returncode, out, err = k3proc.command( 'python', '-c', read_stdin_in_subproc.format('True'), input="123", ) dd('returncode:', returncode) dd('out:', out) dd('err:', err) self.assertEqual(0, returncode) self.assertEqual("", out) # default capture returncode, out, err = k3proc.command( 'python', '-c', read_stdin_in_subproc.format('None'), input="123", ) dd('returncode:', returncode) dd('out:', out) dd('err:', err) self.assertEqual(0, returncode) self.assertEqual("", out)
def test_error_str_with_capture_false(self): try: k3proc.command( 'python', '-c', 'import sys; sys.exit(1)', capture=False, check=True, ) except k3proc.CalledProcessError as e: self.assertEqual('', e.stdout) self.assertEqual([], e.out) self.assertEqual('', e.stderr) self.assertEqual([], e.err)
def test_cwd(self): returncode, out, err = k3proc.command( 'python', 'subproc.py', '111', cwd=this_base) self.assertEqual(111, returncode) returncode, out, err = k3proc.command('python', 'subproc.py', '111') if 'PyPy' in sys.version: # PyPy does not return code correctly. it is 1 self.assertNotEqual(0, returncode) else: # 2 for can not find subproc.py self.assertEqual(2, returncode)
def test_error_str(self): try: k3proc.command( 'python', '-c', 'import sys, os; os.write(1, b"foo"); os.write(2, b"bar"); sys.exit(1)', check=True, env={"foo": "bar"}, cwd="/tmp", input="123") except k3proc.CalledProcessError as e: s = '\n'.join([ "CalledProcessError", 'python -c import sys, os; os.write(1, b"foo"); os.write(2, b"bar"); sys.exit(1)', "options: {'cwd': '/tmp', 'env': {'foo': 'bar'}, 'input': '123'}", "exit code: 1", "foo", "bar", ]) self.assertEqual(s, str(e)) self.assertEqual(s, repr(e)) # text=False try: k3proc.command( 'python', '-c', 'import sys, os; os.write(1, b"\x01"); os.write(2, b"\x02"); sys.exit(1)', check=True, env={"foo": "bar"}, cwd="/tmp", text=False, input=b"123") except k3proc.CalledProcessError as e: s = '\n'.join([ "CalledProcessError", 'python -c import sys, os; os.write(1, b"\x01"); os.write(2, b"\x02"); sys.exit(1)', "options: {'cwd': '/tmp', 'env': {'foo': 'bar'}, 'input': b'123'}", "exit code: 1", "b'\\x01'", "b'\\x02'", ]) self.assertEqual(s, str(e)) self.assertEqual(s, repr(e))
def test_env(self): returncode, out, err = k3proc.command('python', 'print_env.py', 'abc', env={"abc": "xyz"}, cwd=this_base) dd('returncode:', returncode) dd('out:', out) dd('err:', err) self.assertEqual(0, returncode) self.assertEqual('xyz\n', out)
def test_input(self): returncode, out, err = k3proc.command('python', 'read_fd.py', '0', input='abc', cwd=this_base) dd('returncode:', returncode) dd('out:', out) dd('err:', err) self.assertEqual(0, returncode) self.assertEqual('abc\n', out)
def test_inherit_env(self): returncode, out, err = k3proc.command( 'python', '-c', 'import os; print(os.environ.get("PATH"))', env={"abc": "xyz"}, inherit_env=False, ) dd('returncode:', returncode) dd('out:', out) dd('err:', err) self.assertEqual(0, returncode) self.assertEqual('None\n', out, "no PATH inherited")
def test_close_fds(self): read_fd = os.path.join(this_base, 'read_fd.py') with open(read_fd) as f: fd = f.fileno() os.set_inheritable(fd, True) returncode, out, err = k3proc.command( 'python', read_fd, str(fd), close_fds=False) dd(returncode, out, err) self.assertEqual(0, returncode) self.assertEqual('###\n', out) self.assertEqual('', err) returncode, out, err = k3proc.command( 'python', read_fd, str(fd), close_fds=True) self.assertEqual(1, returncode) self.assertEqual('errno=9\n', out) self.assertEqual('', err)
def cmdx(cmd, *arguments, **options): """ Alias to k3proc.command() with ``check=True``. Returns: (int, list, list): exit code, stdout and stderr in lines of str. """ dd("cmdx:", cmd, arguments, options) ddstack() options['check'] = True code, out, err = command(cmd, *arguments, **options) out = out.splitlines() err = err.splitlines() return code, out, err
def _test_get_conf(self, k, v, cwd=None): code, out, err = k3proc.command( 'python', '-c', 'import k3confloader as cl; print(cl.conf.' + k + ')', check=True, cwd=cwd, ) dd("k, v:", k, v) dd("code:", code) dd("out:", out) dd("err:", err) self.assertEqual(v, out.strip())
def test_text_true(self): cmd = ['python', '-c', 'import os; os.write(1, b"\\x89")', ] self.assertRaises( UnicodeDecodeError, k3proc.command, *cmd ) returncode, out, err = k3proc.command(*cmd, text=False) dd('returncode:', returncode) dd('out:', out) dd('err:', err) self.assertEqual(0, returncode) self.assertEqual(b'\x89', out)
def cmdf(cmd, *arguments, flag='', **options): """ Alias to k3proc.command(). Behaviors is specified with ``flag`` Args: cmd(str): the path to executable. arguments: arguments flag(str or list or tuple): str flags. - 'x' or ('raise', ): raise CalledProcessError if return code is not 0 - 't' or ('tty', ): start sub process in a tty. - 'n' or ('none', ): if return code is not 0, return None. - 'p' or ('pass', ): do not capture stdin, stdout and stderr. - 'o' or ('stdout', ): only return stdout in list of str. - '0' or ('oneline', ): only return the first line of stdout. options: other options pass to k3proc.command(). Returns: str: first line of stdout. """ dd("cmdf:", cmd, arguments, options) dd("flag:", flag) mp = { 'x': 'raise', 't': 'tty', 'n': 'none', 'p': 'pass', 'o': 'stdout', '0': 'oneline', } if isinstance(flag, str): flag = [mp[x] for x in flag] if 'raise' in flag: options['check'] = True if 'tty' in flag: options['tty'] = True if 'pass' in flag: options['capture'] = False code, out, err = command(cmd, *arguments, **options) # reaching here means there is no check of exception if code != 0 and 'none' in flag: return None out = out.splitlines() err = err.splitlines() if 'stdout' in flag: dd("cmdf: out:", out) return out if 'oneline' in flag: dd("cmdf: out:", out) if len(out) > 0: return out[0] return '' return code, out, err