mirror of
https://github.com/pyenv/pyenv.git
synced 2026-10-03 07:51:06 +09:00
357 lines
10 KiB
Bash
Executable File
357 lines
10 KiB
Bash
Executable File
#!/usr/bin/env bats
|
|
|
|
load test_helper
|
|
|
|
@test "empty rehash" {
|
|
assert [ ! -d "${PYENV_ROOT}/shims" ]
|
|
run pyenv-rehash
|
|
assert_success ""
|
|
assert [ -d "${PYENV_ROOT}/shims" ]
|
|
rmdir "${PYENV_ROOT}/shims"
|
|
}
|
|
|
|
@test "non-writable shims directory" {
|
|
mkdir -p "${PYENV_ROOT}/shims"
|
|
chmod -w "${PYENV_ROOT}/shims"
|
|
skip_if_nonposix_security -w "${PYENV_ROOT}/shims"
|
|
|
|
run pyenv-rehash
|
|
assert_failure "pyenv: cannot rehash: ${PYENV_ROOT}/shims isn't writable"
|
|
}
|
|
|
|
@test "rehash in progress" {
|
|
export PYENV_REHASH_TIMEOUT=1
|
|
mkdir -p "${PYENV_ROOT}/shims"
|
|
touch "${PYENV_ROOT}/shims/.pyenv-shim"
|
|
#avoid failure due to a localized error message
|
|
LANG=C run pyenv-rehash
|
|
assert_failure
|
|
assert_output_glob <<!
|
|
pyenv: cannot rehash: couldn't acquire lock ${PYENV_ROOT}/shims/.pyenv-shim for 1 seconds. Last error message:
|
|
*/pyenv-rehash: line *: ${PYENV_ROOT}/shims/.pyenv-shim: cannot overwrite existing file
|
|
!
|
|
}
|
|
|
|
@test "wait until lock acquisition" {
|
|
export PYENV_REHASH_TIMEOUT=5
|
|
mkdir -p "${PYENV_ROOT}/shims"
|
|
touch "${PYENV_ROOT}/shims/.pyenv-shim"
|
|
bash -c "sleep 1 && rm -f ${PYENV_ROOT}/shims/.pyenv-shim" &
|
|
run pyenv-rehash
|
|
assert_success
|
|
}
|
|
|
|
@test "removes stale lockfile" {
|
|
mkdir -p "${PYENV_ROOT}/shims"
|
|
# A portable code to set mtime to "N minutes ago" is long and unwieldy,
|
|
# see https://unix.stackexchange.com/questions/806015/portably-set-a-files-time-to-n-minutes-ago
|
|
# Using a fixed timestamp far in the past is infinitely simpler and good enough for the test
|
|
touch -t 200001010000.00 "${PYENV_ROOT}/shims/.pyenv-shim"
|
|
run pyenv-rehash
|
|
assert_success ""
|
|
assert [ ! -e "${PYENV_ROOT}/shims/.pyenv-shim" ]
|
|
}
|
|
|
|
@test "creates shims" {
|
|
create_alt_executable_in_version "2.7" "python"
|
|
create_alt_executable_in_version "2.7" "fab"
|
|
create_alt_executable_in_version "3.4" "python"
|
|
create_alt_executable_in_version "3.4" "py.test"
|
|
|
|
assert [ ! -e "${PYENV_ROOT}/shims/fab" ]
|
|
assert [ ! -e "${PYENV_ROOT}/shims/python" ]
|
|
assert [ ! -e "${PYENV_ROOT}/shims/py.test" ]
|
|
|
|
run pyenv-rehash
|
|
assert_success ""
|
|
|
|
run ls "${PYENV_ROOT}/shims"
|
|
assert_success
|
|
assert_output <<OUT
|
|
fab
|
|
py.test
|
|
python
|
|
OUT
|
|
}
|
|
|
|
@test "removes stale shims" {
|
|
mkdir -p "${PYENV_ROOT}/shims"
|
|
touch "${PYENV_ROOT}/shims/oldshim1"
|
|
chmod +x "${PYENV_ROOT}/shims/oldshim1"
|
|
|
|
create_alt_executable_in_version "3.4" "fab"
|
|
create_alt_executable_in_version "3.4" "python"
|
|
|
|
run pyenv-rehash
|
|
assert_success ""
|
|
|
|
assert [ ! -e "${PYENV_ROOT}/shims/oldshim1" ]
|
|
}
|
|
|
|
@test "repairs an overwritten shim after the first shim" {
|
|
create_alt_executable_in_version "3.4" "aaa"
|
|
create_alt_executable_in_version "3.4" "python"
|
|
pyenv-rehash
|
|
printf '2\n' > "${PYENV_ROOT}/shims/python"
|
|
|
|
run pyenv-rehash
|
|
assert_success ""
|
|
assert cmp "${PYENV_ROOT}/shims/aaa" "${PYENV_ROOT}/shims/python"
|
|
|
|
PYENV_VERSION=3.4 run "${PYENV_ROOT}/shims/python"
|
|
assert_success
|
|
}
|
|
|
|
@test "repairs truncated shim contents and preserves trailing newlines" {
|
|
create_alt_executable_in_version "3.4" "aaa"
|
|
create_alt_executable_in_version "3.4" "python"
|
|
pyenv-rehash
|
|
|
|
for contents in empty newline nul; do
|
|
case "$contents" in
|
|
empty) : > "${PYENV_ROOT}/shims/python" ;;
|
|
newline) printf '\n' >> "${PYENV_ROOT}/shims/python" ;;
|
|
nul) printf '\0' >> "${PYENV_ROOT}/shims/python" ;;
|
|
esac
|
|
run pyenv-rehash
|
|
assert_success ""
|
|
assert cmp "${PYENV_ROOT}/shims/aaa" "${PYENV_ROOT}/shims/python"
|
|
done
|
|
}
|
|
|
|
@test "leaves valid shims unchanged when repairing another shim" {
|
|
create_alt_executable_in_version "3.4" "aaa"
|
|
create_alt_executable_in_version "3.4" "python"
|
|
pyenv-rehash
|
|
touch -t 200001010000.00 "${PYENV_ROOT}/shims/aaa"
|
|
touch -t 200101010000.00 "${PYENV_TEST_DIR}/newer"
|
|
printf '2\n' > "${PYENV_ROOT}/shims/python"
|
|
|
|
run pyenv-rehash
|
|
assert_success ""
|
|
assert [ "${PYENV_ROOT}/shims/aaa" -ot "${PYENV_TEST_DIR}/newer" ]
|
|
assert cmp "${PYENV_ROOT}/shims/aaa" "${PYENV_ROOT}/shims/python"
|
|
}
|
|
|
|
@test "repairs an unreadable shim without additional output" {
|
|
create_alt_executable_in_version "3.4" "aaa"
|
|
create_alt_executable_in_version "3.4" "python"
|
|
pyenv-rehash
|
|
chmod -r "${PYENV_ROOT}/shims/python"
|
|
skip_if_nonposix_security -r "${PYENV_ROOT}/shims/python"
|
|
|
|
run pyenv-rehash
|
|
assert_success ""
|
|
assert cmp "${PYENV_ROOT}/shims/aaa" "${PYENV_ROOT}/shims/python"
|
|
}
|
|
|
|
@test "does not read registered directories as shims" {
|
|
create_alt_executable_in_version "3.4" "aaa"
|
|
create_alt_executable_in_version "3.4" "python"
|
|
pyenv-rehash
|
|
rm "${PYENV_ROOT}/shims/python"
|
|
mkdir "${PYENV_ROOT}/shims/python"
|
|
|
|
run pyenv-rehash
|
|
assert_success ""
|
|
assert [ -d "${PYENV_ROOT}/shims/python" ]
|
|
}
|
|
|
|
@test "leaves valid shims unchanged with a multibyte root path" {
|
|
[[ $(LC_ALL=en_US.UTF-8 locale charmap 2>/dev/null) == UTF-8 ]] || skip "-- UTF-8 locale not installed"
|
|
export LC_ALL=en_US.UTF-8
|
|
export PYENV_ROOT="${PYENV_ROOT}/pyenv 路径"
|
|
create_alt_executable_in_version "3.4" "python"
|
|
pyenv-rehash
|
|
touch -t 200001010000.00 "${PYENV_ROOT}/shims/python"
|
|
touch -t 200101010000.00 "${PYENV_TEST_DIR}/newer"
|
|
|
|
run pyenv-rehash
|
|
assert_success ""
|
|
assert [ "${PYENV_ROOT}/shims/python" -ot "${PYENV_TEST_DIR}/newer" ]
|
|
}
|
|
|
|
@test "repairs explicitly registered hidden shims and preserves other dotfiles" {
|
|
create_hook rehash hidden.bash <<'SH'
|
|
register_shim .foo
|
|
register_shim python
|
|
SH
|
|
pyenv-rehash
|
|
printf 'keep\n' > "${PYENV_ROOT}/shims/.keep"
|
|
printf '2\n' > "${PYENV_ROOT}/shims/.foo"
|
|
|
|
run pyenv-rehash
|
|
assert_success ""
|
|
assert cmp "${PYENV_ROOT}/shims/python" "${PYENV_ROOT}/shims/.foo"
|
|
run cat "${PYENV_ROOT}/shims/.keep"
|
|
assert_success "keep"
|
|
assert [ ! -e "${PYENV_ROOT}/shims/.pyenv-shim" ]
|
|
}
|
|
|
|
@test "replaces a dangling registered symlink without writing through it" {
|
|
create_alt_executable_in_version "3.4" "aaa"
|
|
create_alt_executable_in_version "3.4" "python"
|
|
pyenv-rehash
|
|
rm "${PYENV_ROOT}/shims/python"
|
|
ln -s "${PYENV_TEST_DIR}/missing/python" "${PYENV_ROOT}/shims/python"
|
|
|
|
run pyenv-rehash
|
|
assert_success ""
|
|
assert [ ! -L "${PYENV_ROOT}/shims/python" ]
|
|
assert [ ! -e "${PYENV_TEST_DIR}/missing/python" ]
|
|
assert cmp "${PYENV_ROOT}/shims/aaa" "${PYENV_ROOT}/shims/python"
|
|
}
|
|
|
|
@test "preserves sourceable shims from the built-in rehash hook" {
|
|
export PYENV_HOOK_PATH="${_PYENV_INSTALL_PREFIX}/pyenv.d"
|
|
export PYENV_VERSION=3.4
|
|
create_alt_executable_in_version "3.4" "aaa"
|
|
create_alt_executable_in_version "3.4" "activate" <<'SH'
|
|
export PYENV_ACTIVATED=yes
|
|
SH
|
|
create_alt_executable_in_version "3.4" "activate.fish"
|
|
create_alt_executable_in_version "3.4" "gettext.sh"
|
|
|
|
pyenv-rehash
|
|
run pyenv-rehash
|
|
assert_success ""
|
|
assert cmp "${PYENV_ROOT}/shims/activate" "${PYENV_ROOT}/shims/activate.fish"
|
|
assert cmp "${PYENV_ROOT}/shims/activate" "${PYENV_ROOT}/shims/gettext.sh"
|
|
|
|
run bash -c '. "$PYENV_ROOT/shims/activate"; echo "$PYENV_ACTIVATED"'
|
|
assert_success "yes"
|
|
}
|
|
|
|
@test "does not overwrite hook customizations when a shim is registered again" {
|
|
create_alt_executable_in_version "3.4" "python"
|
|
create_hook rehash custom.bash <<'SH'
|
|
register_shim .foo
|
|
printf 'custom\n' > "$SHIM_PATH/.foo"
|
|
printf 'custom\n' > "$SHIM_PATH/python"
|
|
register_shim python
|
|
register_shim .foo
|
|
SH
|
|
|
|
run pyenv-rehash
|
|
assert_success ""
|
|
run cat "${PYENV_ROOT}/shims/python"
|
|
assert_success "custom"
|
|
run cat "${PYENV_ROOT}/shims/.foo"
|
|
assert_success "custom"
|
|
}
|
|
|
|
@test "repairs existing shims before rehash hooks invoke them" {
|
|
create_alt_executable_in_version "3.4" "python" "echo works"
|
|
pyenv-rehash
|
|
printf '2\n' > "${PYENV_ROOT}/shims/python"
|
|
create_hook rehash invoke.bash <<'SH'
|
|
PYENV_VERSION=3.4 "$SHIM_PATH/python"
|
|
SH
|
|
|
|
run pyenv-rehash
|
|
assert_success "works"
|
|
}
|
|
|
|
@test "binary install locations containing spaces" {
|
|
create_alt_executable_in_version "dirname1 p247" "python"
|
|
create_alt_executable_in_version "dirname2 preview1" "py.test"
|
|
|
|
assert [ ! -e "${PYENV_ROOT}/shims/python" ]
|
|
assert [ ! -e "${PYENV_ROOT}/shims/py.test" ]
|
|
|
|
run pyenv-rehash
|
|
assert_success ""
|
|
|
|
run ls "${PYENV_ROOT}/shims"
|
|
assert_success
|
|
assert_output <<OUT
|
|
py.test
|
|
python
|
|
OUT
|
|
}
|
|
|
|
@test "carries original IFS within hooks" {
|
|
create_hook rehash hello.bash <<SH
|
|
hellos=(\$(printf "hello\\tugly world\\nagain"))
|
|
echo HELLO="\$(printf ":%s" "\${hellos[@]}")"
|
|
exit
|
|
SH
|
|
|
|
IFS=$' \t\n' run pyenv-rehash
|
|
assert_success
|
|
assert_output "HELLO=:hello:ugly:world:again"
|
|
}
|
|
|
|
@test "sh-rehash in bash" {
|
|
create_alt_executable_in_version "3.4" "python"
|
|
PYENV_SHELL=bash run pyenv-sh-rehash
|
|
assert_success "command pyenv rehash
|
|
hash -r 2>/dev/null || true"
|
|
}
|
|
|
|
@test "sh-rehash in bash (integration)" {
|
|
create_alt_executable_in_version "3.4" "python"
|
|
PYENV_SHELL=bash run eval "$(pyenv-sh-rehash)"
|
|
assert_success
|
|
assert [ -x "${PYENV_ROOT}/shims/python" ]
|
|
}
|
|
|
|
@test "sh-rehash in fish" {
|
|
create_alt_executable_in_version "3.4" "python"
|
|
PYENV_SHELL=fish run pyenv-sh-rehash
|
|
assert_success "command pyenv rehash"
|
|
}
|
|
|
|
@test "sh-rehash in fish (integration)" {
|
|
command -v fish >/dev/null || skip "-- fish not installed"
|
|
create_alt_executable_in_version "3.4" "python"
|
|
PYENV_SHELL=fish fish -Nc "source (pyenv-sh-rehash | psub)"
|
|
assert_success
|
|
assert [ -x "${PYENV_ROOT}/shims/python" ]
|
|
}
|
|
|
|
@test "sh-rehash in pwsh" {
|
|
create_alt_executable_in_version "3.4" "python"
|
|
PYENV_SHELL=pwsh run pyenv-sh-rehash
|
|
assert_success "& (get-command pyenv -commandtype application) rehash"
|
|
}
|
|
|
|
@test "sh-rehash in pwsh (integration)" {
|
|
command -v pwsh >/dev/null || skip "-- pwsh not installed"
|
|
assert [ ! -x "${PYENV_ROOT}/shims/python" ]
|
|
create_alt_executable_in_version "3.4" "python"
|
|
run pwsh -nop -c -<<'!'
|
|
$ErrorActionPreference = "Stop"
|
|
$PSNativeCommandUseErrorActionPreference = $true
|
|
iex ((& pyenv init - pwsh) -join "`n")
|
|
& pyenv rehash
|
|
!
|
|
assert_success ""
|
|
assert [ -x "${PYENV_ROOT}/shims/python" ]
|
|
}
|
|
|
|
@test "shim sets _PYENV_SHIM_PATH when linked from elsewhere" {
|
|
export PYENV_VERSION="custom"
|
|
create_alt_executable python3
|
|
#must stub pyenv before rehash 'cuz the path is hardcoded into shims
|
|
create_stub pyenv <<!
|
|
[[ \$1 == 'exec' ]] && \
|
|
echo _PYENV_SHIM_PATH="\$_PYENV_SHIM_PATH"
|
|
!
|
|
pyenv-rehash
|
|
mkdir -p "${PYENV_TEST_DIR}/alt-shim"
|
|
ln -s "${PYENV_ROOT}/shims/python3" "${PYENV_TEST_DIR}/alt-shim/python3"
|
|
|
|
run "${PYENV_TEST_DIR}/alt-shim/python3"
|
|
assert_success
|
|
assert_output <<!
|
|
_PYENV_SHIM_PATH=${PYENV_TEST_DIR}/alt-shim
|
|
!
|
|
|
|
run python3
|
|
assert_success
|
|
assert_output <<!
|
|
_PYENV_SHIM_PATH=
|
|
!
|
|
}
|