diff options
Diffstat (limited to 'lldb/third_party/Python/module/pexpect-4.6/tests/test_which.py')
-rw-r--r-- | lldb/third_party/Python/module/pexpect-4.6/tests/test_which.py | 291 |
1 files changed, 291 insertions, 0 deletions
diff --git a/lldb/third_party/Python/module/pexpect-4.6/tests/test_which.py b/lldb/third_party/Python/module/pexpect-4.6/tests/test_which.py new file mode 100644 index 00000000000..15a8944153d --- /dev/null +++ b/lldb/third_party/Python/module/pexpect-4.6/tests/test_which.py @@ -0,0 +1,291 @@ +# -*- coding: utf-8 -*- +import subprocess +import tempfile +import shutil +import errno +import os + +import pexpect +from . import PexpectTestCase + +import pytest + + +class TestCaseWhich(PexpectTestCase.PexpectTestCase): + " Tests for pexpect.which(). " + + def test_which_finds_ls(self): + " which() can find ls(1). " + exercise = pexpect.which("ls") + assert exercise is not None + assert exercise.startswith('/') + + def test_path_from_env(self): + " executable found from optional env argument " + bin_name = 'pexpect-test-path-from-env' + tempdir = tempfile.mkdtemp() + try: + bin_path = os.path.join(tempdir, bin_name) + with open(bin_path, 'w') as f: + f.write('# test file not to be run') + try: + os.chmod(bin_path, 0o700) + found_path = pexpect.which(bin_name, env={'PATH': tempdir}) + finally: + os.remove(bin_path) + self.assertEqual(bin_path, found_path) + finally: + os.rmdir(tempdir) + + def test_os_defpath_which(self): + " which() finds an executable in $PATH and returns its abspath. " + + bin_dir = tempfile.mkdtemp() + temp_obj = tempfile.NamedTemporaryFile( + suffix=u'.sh', prefix=u'ǝpoɔıun-', + dir=bin_dir, delete=False) + bin_path = temp_obj.name + fname = os.path.basename(temp_obj.name) + save_path = os.environ['PATH'] + save_defpath = os.defpath + + try: + # setup + os.environ['PATH'] = '' + os.defpath = bin_dir + with open(bin_path, 'w') as fp: + pass + + # given non-executable, + os.chmod(bin_path, 0o400) + + # exercise absolute and relative, + assert pexpect.which(bin_path) is None + assert pexpect.which(fname) is None + + # given executable, + os.chmod(bin_path, 0o700) + + # exercise absolute and relative, + assert pexpect.which(bin_path) == bin_path + assert pexpect.which(fname) == bin_path + + finally: + # restore, + os.environ['PATH'] = save_path + os.defpath = save_defpath + + # destroy scratch files and folders, + if os.path.exists(bin_path): + os.unlink(bin_path) + if os.path.exists(bin_dir): + os.rmdir(bin_dir) + + def test_path_search_which(self): + " which() finds an executable in $PATH and returns its abspath. " + fname = 'gcc' + bin_dir = tempfile.mkdtemp() + bin_path = os.path.join(bin_dir, fname) + save_path = os.environ['PATH'] + try: + # setup + os.environ['PATH'] = bin_dir + with open(bin_path, 'w') as fp: + pass + + # given non-executable, + os.chmod(bin_path, 0o400) + + # exercise absolute and relative, + assert pexpect.which(bin_path) is None + assert pexpect.which(fname) is None + + # given executable, + os.chmod(bin_path, 0o700) + + # exercise absolute and relative, + assert pexpect.which(bin_path) == bin_path + assert pexpect.which(fname) == bin_path + + finally: + # restore, + os.environ['PATH'] = save_path + + # destroy scratch files and folders, + if os.path.exists(bin_path): + os.unlink(bin_path) + if os.path.exists(bin_dir): + os.rmdir(bin_dir) + + def test_which_follows_symlink(self): + " which() follows symlinks and returns its path. " + fname = 'original' + symname = 'extra-crispy' + bin_dir = tempfile.mkdtemp() + bin_path = os.path.join(bin_dir, fname) + sym_path = os.path.join(bin_dir, symname) + save_path = os.environ['PATH'] + try: + # setup + os.environ['PATH'] = bin_dir + with open(bin_path, 'w') as fp: + pass + os.chmod(bin_path, 0o400) + os.symlink(bin_path, sym_path) + + # should not be found because symlink points to non-executable + assert pexpect.which(symname) is None + + # but now it should -- because it is executable + os.chmod(bin_path, 0o700) + assert pexpect.which(symname) == sym_path + + finally: + # restore, + os.environ['PATH'] = save_path + + # destroy scratch files, symlinks, and folders, + if os.path.exists(sym_path): + os.unlink(sym_path) + if os.path.exists(bin_path): + os.unlink(bin_path) + if os.path.exists(bin_dir): + os.rmdir(bin_dir) + + def test_which_should_not_match_folders(self): + " Which does not match folders, even though they are executable. " + # make up a path and insert a folder that is 'executable', a naive + # implementation might match (previously pexpect versions 3.2 and + # sh versions 1.0.8, reported by @lcm337.) + fname = 'g++' + bin_dir = tempfile.mkdtemp() + bin_dir2 = os.path.join(bin_dir, fname) + save_path = os.environ['PATH'] + try: + os.environ['PATH'] = bin_dir + os.mkdir(bin_dir2, 0o755) + # should not be found because it is not executable *file*, + # but rather, has the executable bit set, as a good folder + # should -- it should not be returned because it fails isdir() + exercise = pexpect.which(fname) + assert exercise is None + + finally: + # restore, + os.environ['PATH'] = save_path + # destroy scratch folders, + for _dir in (bin_dir2, bin_dir,): + if os.path.exists(_dir): + os.rmdir(_dir) + + def test_which_should_match_other_group_user(self): + " which() returns executables by other, group, and user ownership. " + # create an executable and test that it is found using which() for + # each of the 'other', 'group', and 'user' permission bits. + fname = 'g77' + bin_dir = tempfile.mkdtemp() + bin_path = os.path.join(bin_dir, fname) + save_path = os.environ['PATH'] + try: + # setup + os.environ['PATH'] = bin_dir + + # an interpreted script requires the ability to read, + # whereas a binary program requires only to be executable. + # + # to gain access to a binary program, we make a copy of + # the existing system program echo(1). + bin_echo = None + for pth in ('/bin/echo', '/usr/bin/echo'): + if os.path.exists(pth): + bin_echo = pth + break + bin_which = None + for pth in ('/bin/which', '/usr/bin/which'): + if os.path.exists(pth): + bin_which = pth + break + if not bin_echo or not bin_which: + pytest.skip('needs `echo` and `which` binaries') + shutil.copy(bin_echo, bin_path) + isroot = os.getuid() == 0 + for should_match, mode in ( + # note that although the file may have matching 'group' or + # 'other' executable permissions, it is *not* executable + # because the current uid is the owner of the file -- which + # takes precedence + (False, 0o000), # ----------, no + (isroot, 0o001), # ---------x, no + (isroot, 0o010), # ------x---, no + (True, 0o100), # ---x------, yes + (False, 0o002), # --------w-, no + (False, 0o020), # -----w----, no + (False, 0o200), # --w-------, no + (isroot, 0o003), # --------wx, no + (isroot, 0o030), # -----wx---, no + (True, 0o300), # --wx------, yes + (False, 0o004), # -------r--, no + (False, 0o040), # ----r-----, no + (False, 0o400), # -r--------, no + (isroot, 0o005), # -------r-x, no + (isroot, 0o050), # ----r-x---, no + (True, 0o500), # -r-x------, yes + (False, 0o006), # -------rw-, no + (False, 0o060), # ----rw----, no + (False, 0o600), # -rw-------, no + (isroot, 0o007), # -------rwx, no + (isroot, 0o070), # ----rwx---, no + (True, 0o700), # -rwx------, yes + (isroot, 0o4001), # ---S-----x, no + (isroot, 0o4010), # ---S--x---, no + (True, 0o4100), # ---s------, yes + (isroot, 0o4003), # ---S----wx, no + (isroot, 0o4030), # ---S-wx---, no + (True, 0o4300), # --ws------, yes + (isroot, 0o2001), # ------S--x, no + (isroot, 0o2010), # ------s---, no + (True, 0o2100), # ---x--S---, yes + + ): + mode_str = '{0:0>4o}'.format(mode) + + # given file mode, + os.chmod(bin_path, mode) + + # exercise whether we may execute + can_execute = True + try: + subprocess.Popen(fname).wait() == 0 + except OSError as err: + if err.errno != errno.EACCES: + raise + # permission denied + can_execute = False + + assert should_match == can_execute, ( + should_match, can_execute, mode_str) + + # exercise whether which(1) would match + proc = subprocess.Popen((bin_which, fname), + env={'PATH': bin_dir}, + stdout=subprocess.PIPE) + bin_which_match = bool(not proc.wait()) + assert should_match == bin_which_match, ( + should_match, bin_which_match, mode_str) + + # finally, exercise pexpect's which(1) matches + # the same. + pexpect_match = bool(pexpect.which(fname)) + + assert should_match == pexpect_match == bin_which_match, ( + should_match, pexpect_match, bin_which_match, mode_str) + + finally: + # restore, + os.environ['PATH'] = save_path + + # destroy scratch files and folders, + if os.path.exists(bin_path): + os.unlink(bin_path) + if os.path.exists(bin_dir): + os.rmdir(bin_dir) |