fix indexerror on pushd(['.']) (hopefully last such); allow dirstack_unc tests to run if some temp drive letters already in use

This commit is contained in:
Bob Hyman 2016-09-05 22:04:55 -04:00
parent 0b261216bd
commit 4d735fde25
2 changed files with 36 additions and 26 deletions

View file

@ -23,13 +23,19 @@ from xonsh.dirstack import _unc_tempDrives
HERE = os.path.abspath(os.path.dirname(__file__))
PARENT = os.path.dirname(HERE)
def drive_in_use(letter):
return ON_WINDOWS and os.system('vol {}: 2>nul>nul'.format(letter)) == 0
pytestmark = pytest.mark.skipif(any(drive_in_use(l) for l in 'ywzx'),
reason='Drive letters used by tests are '
'are already used by Windows.')
MAX_TEMP_DRIVES = 4
TEMP_DRIVE = []
for d in 'zyxwvuts':
if not drive_in_use(d):
TEMP_DRIVE.append(d + ':')
pytestmark = pytest.mark.skipif(len(TEMP_DRIVE) < MAX_TEMP_DRIVES,
reason='Too many drive letters needed by tests '
'are already used by Windows.')
@pytest.yield_fixture(scope="module")
def shares_setup(tmpdir_factory):
@ -43,8 +49,8 @@ def shares_setup(tmpdir_factory):
if not ON_WINDOWS:
return []
shares = [[r'uncpushd_test_HERE', 'y:', HERE]
, [r'uncpushd_test_PARENT', 'w:', PARENT]]
shares = [[r'uncpushd_test_HERE', TEMP_DRIVE[1], HERE]
, [r'uncpushd_test_PARENT', TEMP_DRIVE[3], PARENT]]
for s, d, l in shares: # set up some shares on local machine. dirs already exist test case must invoke wd_setup.
subprocess.call(['NET', 'SHARE', s, '/delete'], universal_newlines=True) # clean up from previous run after good, long wait.
@ -96,7 +102,7 @@ def test_uncpushd_simple_push_pop(xonsh_builtins, shares_setup):
assert owd.casefold() == xonsh_builtins.__xonsh_env__['PWD'].casefold()
dirstack.pushd([r'\\localhost\uncpushd_test_HERE'])
wd = os.getcwd()
assert os.path.splitdrive(wd)[0].casefold() == 'z:'
assert os.path.splitdrive(wd)[0].casefold() == TEMP_DRIVE[0]
assert os.path.splitdrive(wd)[1].casefold() == '\\'
dirstack.popd([])
assert owd.casefold() == os.getcwd().casefold(), "popd returned cwd to expected dir"
@ -112,20 +118,20 @@ def test_uncpushd_push_to_same_share(xonsh_builtins):
assert owd.casefold() == xonsh_builtins.__xonsh_env__['PWD'].casefold()
dirstack.pushd([r'\\localhost\uncpushd_test_HERE'])
wd = os.getcwd()
assert os.path.splitdrive(wd)[0].casefold() == 'z:'
assert os.path.splitdrive(wd)[0].casefold() == TEMP_DRIVE[0]
assert os.path.splitdrive(wd)[1].casefold() == '\\'
assert len(_unc_tempDrives) == 1
assert len(DIRSTACK) == 1
dirstack.pushd([r'\\localhost\uncpushd_test_HERE'])
wd = os.getcwd()
assert os.path.splitdrive(wd)[0].casefold() == 'z:'
assert os.path.splitdrive(wd)[0].casefold() == TEMP_DRIVE[0]
assert os.path.splitdrive(wd)[1].casefold() == '\\'
assert len(_unc_tempDrives) == 1
assert len(DIRSTACK) == 2
dirstack.popd([])
assert os.path.isdir('z:\\'), "Temp drived not unmapped till last reference removed"
assert os.path.isdir(TEMP_DRIVE[0] + '\\'), "Temp drived not unmapped till last reference removed"
dirstack.popd([])
assert owd.casefold() == os.getcwd().casefold(), "popd returned cwd to expected dir"
assert len(_unc_tempDrives) == 0
@ -141,41 +147,41 @@ def test_uncpushd_push_other_push_same(xonsh_builtins):
owd = os.getcwd()
assert owd.casefold() == xonsh_builtins.__xonsh_env__['PWD'].casefold()
dirstack.pushd([r'\\localhost\uncpushd_test_HERE'])
assert os.getcwd().casefold() == 'z:\\'
assert os.getcwd().casefold() == TEMP_DRIVE[0] + '\\'
assert len(_unc_tempDrives) == 1
assert len(DIRSTACK) == 1
dirstack.pushd([r'\\localhost\uncpushd_test_PARENT'])
wd = os.getcwd()
assert os.getcwd().casefold() == 'x:\\'
assert os.getcwd().casefold() == TEMP_DRIVE[2] + '\\'
assert len(_unc_tempDrives) == 2
assert len(DIRSTACK) == 2
dirstack.pushd([r'\\localhost\uncpushd_test_HERE'])
assert os.getcwd().casefold() == 'z:\\'
assert os.getcwd().casefold() == TEMP_DRIVE[0] + '\\'
assert len(_unc_tempDrives) == 2
assert len(DIRSTACK) == 3
dirstack.popd([])
assert os.getcwd().casefold() == 'x:\\'
assert os.getcwd().casefold() == TEMP_DRIVE[2] + '\\'
assert len(_unc_tempDrives) == 2
assert len(DIRSTACK) == 2
assert os.path.isdir('x:\\')
assert os.path.isdir('z:\\')
assert os.path.isdir(TEMP_DRIVE[2] + '\\')
assert os.path.isdir(TEMP_DRIVE[0] + '\\')
dirstack.popd([])
assert os.getcwd().casefold() == 'z:\\'
assert os.getcwd().casefold() == TEMP_DRIVE[0] + '\\'
assert len(_unc_tempDrives) == 1
assert len(DIRSTACK) == 1
assert not os.path.isdir('x:\\')
assert os.path.isdir('z:\\')
assert not os.path.isdir(TEMP_DRIVE[2] + '\\')
assert os.path.isdir(TEMP_DRIVE[0] + '\\')
dirstack.popd([])
assert os.getcwd().casefold() == owd.casefold()
assert len(_unc_tempDrives) == 0
assert len(DIRSTACK) == 0
assert not os.path.isdir('x:\\')
assert not os.path.isdir('z:\\')
assert not os.path.isdir(TEMP_DRIVE[2] + '\\')
assert not os.path.isdir(TEMP_DRIVE[0] + '\\')
@pytest.mark.skipif( not ON_WINDOWS, reason="Windows-only UNC functionality")
@ -245,9 +251,9 @@ def test_uncpushd_cd_unc_auto_pushd(xonsh_builtins_cd, with_unc_check_enabled):
xonsh_builtins_cd.__xonsh_env__['AUTO_PUSHD'] = True
so, se, rc = dirstack.cd([r'\\localhost\uncpushd_test_PARENT'])
assert rc == 0
assert os.getcwd().casefold() == 'z:\\'
assert os.getcwd().casefold() == TEMP_DRIVE[0] + '\\'
assert len(DIRSTACK) == 1
assert os.path.isdir('z:\\')
assert os.path.isdir(TEMP_DRIVE[0] + '\\')
@pytest.mark.skipif(not ON_WINDOWS, reason="Windows-only UNC functionality")

View file

@ -51,6 +51,11 @@ def _unc_check_enabled()->bool:
return False if wval else True
def _is_unc_path( some_path)->bool:
"""True if path starts with 2 backward (or forward, due to python path hacking) slashes."""
return len(some_path) > 1 and some_path[0] == some_path[1] and some_path[0] in (os.sep, os.altsep)
def _unc_map_temp_drive(unc_path)->str:
"""Map a new temporary drive letter for each distinct share,
@ -209,15 +214,14 @@ def cd(args, stdin=None):
return '', 'cd: {0} is not a directory\n'.format(d), 1
if not os.access(d, os.X_OK):
return '', 'cd: permission denied: {0}\n'.format(d), 1
if ON_WINDOWS and len(d) > 1 and (d[0] == d[1]) and (d[0] in (os.sep, os.altsep)) \
and _unc_check_enabled() and (not env.get('AUTO_PUSHD')):
if ON_WINDOWS and _is_unc_path(d) and _unc_check_enabled() and (not env.get('AUTO_PUSHD')):
return '', "cd: can't cd to UNC path on Windows, unless $AUTO_PUSHD set or reg entry " \
+ r'HKCU\SOFTWARE\MICROSOFT\Command Processor\DisableUNCCheck:DWORD = 1' + '\n', 1
# now, push the directory onto the dirstack if AUTO_PUSHD is set
if cwd is not None and env.get('AUTO_PUSHD'):
pushd(['-n', '-q', cwd])
if ON_WINDOWS and len(d) > 1 and (d[0] == d[1]) and (d[0] in (os.sep, os.altsep)):
if ON_WINDOWS and _is_unc_path(d):
d = _unc_map_temp_drive(d)
_change_working_directory(d)
return None, None, 0
@ -304,7 +308,7 @@ def pushd(args, stdin=None):
e = 'Invalid argument to pushd: {0}\n'
return None, e.format(args.dir), 1
if new_pwd is not None:
if ON_WINDOWS and (new_pwd[0] == new_pwd[1]) and (new_pwd[0] in (os.sep, os.altsep)):
if ON_WINDOWS and _is_unc_path(new_pwd):
new_pwd = _unc_map_temp_drive(new_pwd)
if args.cd:
DIRSTACK.insert(0, os.path.expanduser(pwd))