powerline/tests/test_shells/test.sh

548 lines
16 KiB
Bash
Executable File
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/sh
. tests/bot-ci/scripts/common/main.sh
set +x
: ${PYTHON:=python}
FAIL_SUMMARY=""
FAILED=0
if test "x$1" = "x--fast" ; then
FAST=1
shift
fi
ONLY_SHELL="$1"
ONLY_TEST_TYPE="$2"
ONLY_TEST_CLIENT="$3"
if ! test -z "$ONLY_SHELL$ONLY_TEST_TYPE$ONLY_TEST_CLIENT" ; then
FAST=
fi
export PYTHON
if test "x$ONLY_SHELL" = "x--help" ; then
cat << EOF
Usage:
$0 [[[ONLY_SHELL | ""] (ONLY_TEST_TYPE | "")] (ONLY_TEST_CLIENT | "")]
ONLY_SHELL: execute only tests for given shell
ONLY_TEST_TYPE: execute only "daemon" or "nodaemon" tests
ONLY_TEST_CLIENT: use only given test client (one of C, python, render, shell)
EOF
exit 0
fi
check_screen_log() {
TEST_TYPE="$1"
TEST_CLIENT="$2"
SH="$3"
if test -e tests/test_shells/${SH}.${TEST_TYPE}.ok ; then
diff -a -u tests/test_shells/${SH}.${TEST_TYPE}.ok tests/shell/${SH}.${TEST_TYPE}.${TEST_CLIENT}.log
return $?
elif test -e tests/test_shells/${SH}.ok ; then
diff -a -u tests/test_shells/${SH}.ok tests/shell/${SH}.${TEST_TYPE}.${TEST_CLIENT}.log
return $?
else
cat tests/shell/${SH}.${TEST_TYPE}.${TEST_CLIENT}.log
return 1
fi
}
run() {
TEST_TYPE="$1"
shift
TEST_CLIENT="$1"
shift
SH="$1"
shift
local local_path="$PWD/tests/shell/path:$PWD/scripts"
if test "x$SH" = "xfish" ; then
local_path="${local_path}:/usr/bin:/bin"
fi
if test $TEST_TYPE = daemon ; then
local additional_prompts=1
else
local additional_prompts=
fi
env -i \
LANG=en_US.UTF-8 \
PATH="$local_path" \
TERM="screen-256color" \
COLUMNS="${COLUMNS}" \
LINES="${LINES}" \
TEST_TYPE="${TEST_TYPE}" \
TEST_CLIENT="${TEST_CLIENT}" \
SH="${SH}" \
DIR1="${DIR1}" \
POWERLINE_NO_ZSH_ZPYTHON="$(test $TEST_TYPE = zpython || echo 1)" \
DIR2="${DIR2}" \
XDG_CONFIG_HOME="$PWD/tests/shell/fish_home" \
IPYTHONDIR="$PWD/tests/shell/ipython_home" \
PYTHONPATH="${PWD}${PYTHONPATH:+:}$PYTHONPATH" \
POWERLINE_CONFIG_OVERRIDES="${POWERLINE_CONFIG_OVERRIDES}" \
POWERLINE_THEME_OVERRIDES="${POWERLINE_THEME_OVERRIDES}" \
POWERLINE_SHELL_CONTINUATION=$additional_prompts \
POWERLINE_SHELL_SELECT=$additional_prompts \
POWERLINE_CONFIG_PATHS="$PWD/powerline/config_files" \
POWERLINE_COMMAND_ARGS="${POWERLINE_COMMAND_ARGS}" \
POWERLINE_COMMAND="${POWERLINE_COMMAND}" \
"$@"
}
# HACK: get newline for use in strings given that "\n" and $'' do not work.
NL="$(printf '\nE')"
NL="${NL%E}"
do_run_test() {
TEST_TYPE="$1"
shift
TEST_CLIENT="$1"
shift
SH="$1"
SESNAME="powerline-shell-test-${SH}-$$"
# Note: when running screen with setuid libc unsets LD_LIBRARY_PATH, so it
# cannot be added to the `env -i` call above.
run "${TEST_TYPE}" "${TEST_CLIENT}" "${SH}" \
screen -L -c tests/test_shells/screenrc -d -m -S "$SESNAME" \
env LD_LIBRARY_PATH="${LD_LIBRARY_PATH}" \
"$@"
while ! screen -S "$SESNAME" -X readreg a tests/test_shells/input.$SH ; do
sleep 0.1s
done
# Wait for screen to initialize
sleep 1
local attempts=100
while ! screen -S "$SESNAME" -p 0 -X width 300 1 >/dev/null ; do
sleep 0.1s
attempts=$(( attempts - 1 ))
if test $attempts -eq 0 ; then
echo "Waiting for too long: assuming test failed"
echo "Failed ${SH}. Full output:"
echo '============================================================'
cat tests/shell/${SH}.${TEST_TYPE}.${TEST_CLIENT}.full.log
echo '____________________________________________________________'
if test "x$POWERLINE_TEST_NO_CAT_V" != "x1" ; then
echo "Full output (cat -v):"
echo '============================================================'
cat -v tests/shell/${SH}.${TEST_TYPE}.${TEST_CLIENT}.full.log
echo '____________________________________________________________'
fi
return 1
fi
done
if ( \
test "x${SH}" = "xdash" \
|| ( \
test "x${SH}" = "xipython" \
&& test "$PYTHON_IMPLEMENTATION" = "PyPy" \
) \
|| ( \
test "x${SH}" = "xpdb" \
&& ( \
( \
test "$PYTHON_VERSION_MAJOR" -eq 3 \
&& test "$PYTHON_VERSION_MINOR" -eq 2 \
&& test "$PYTHON_IMPLEMENTATION" = "CPython" \
) \
|| test "$PYTHON_IMPLEMENTATION" = "PyPy" \
) \
) \
) ; then
# If I do not use this hack for dash then output will look like
#
# command1
# command2
# …
# prompt1> prompt2> …
while read -r line ; do
if test "$(screen -S "$SESNAME" -p 0 -X stuff "$line$NL")" = "No screen session found." ; then
break
fi
sleep 1
done < tests/test_shells/input.$SH
else
screen -S "$SESNAME" -p 0 -X paste a
fi
# Wait for screen to exit (sending command to non-existing screen session
# fails; when launched instance exits corresponding session is deleted)
while screen -S "$SESNAME" -X blankerprg "" > /dev/null ; do
sleep 0.1s
done
${PYTHON} ./tests/test_shells/postproc.py ${TEST_TYPE} ${TEST_CLIENT} ${SH}
rm -f tests/shell/3rd/pid
if ! check_screen_log ${TEST_TYPE} ${TEST_CLIENT} ${SH} ; then
echo '____________________________________________________________'
if test "x$POWERLINE_TEST_NO_CAT_V" != "x1" ; then
# Repeat the diff to make it better viewable in travis output
echo "Diff (cat -v):"
echo '============================================================'
check_screen_log ${TEST_TYPE} ${TEST_CLIENT} ${SH} | cat -v
echo '____________________________________________________________'
fi
echo "Failed ${SH}. Full output:"
echo '============================================================'
cat tests/shell/${SH}.${TEST_TYPE}.${TEST_CLIENT}.full.log
echo '____________________________________________________________'
if test "x$POWERLINE_TEST_NO_CAT_V" != "x1" ; then
echo "Full output (cat -v):"
echo '============================================================'
cat -v tests/shell/${SH}.${TEST_TYPE}.${TEST_CLIENT}.full.log
echo '____________________________________________________________'
fi
case ${SH} in
*ksh)
${SH} -c 'echo ${KSH_VERSION}'
;;
dash)
# ?
;;
busybox)
busybox --help
;;
*)
${SH} --version
;;
esac
if which dpkg >/dev/null ; then
dpkg -s ${SH}
fi
return 1
fi
return 0
}
run_test() {
TEST_TYPE="$1"
TEST_CLIENT="$2"
SH="$3"
local attempts=3
if test -n "$ONLY_SHELL$ONLY_TEST_TYPE$ONLY_TEST_CLIENT" ; then
attempts=1
fi
while test $attempts -gt 0 ; do
rm -f tests/shell/${SH}.${TEST_TYPE}.${TEST_CLIENT}.log
rm -f tests/shell/${SH}.${TEST_TYPE}.${TEST_CLIENT}.full.log
do_run_test "$@" && return 0
attempts=$(( attempts - 1 ))
done
return 1
}
test -d tests/shell && rm -r tests/shell
mkdir tests/shell
git init tests/shell/3rd
git --git-dir=tests/shell/3rd/.git checkout -b BRANCH
export DIR1=""
export DIR2=""
mkdir tests/shell/3rd/"$DIR1"
mkdir tests/shell/3rd/"$DIR2"
mkdir tests/shell/3rd/'\[\]'
mkdir tests/shell/3rd/'%%'
mkdir tests/shell/3rd/'#[bold]'
mkdir tests/shell/3rd/'(echo)'
mkdir tests/shell/3rd/'$(echo)'
mkdir tests/shell/3rd/'`echo`'
mkdir tests/shell/3rd/'«Unicode!»'
mkdir tests/shell/fish_home
mkdir tests/shell/fish_home/fish
mkdir tests/shell/fish_home/fish/generated_completions
cp -r tests/test_shells/ipython_home tests/shell
mkdir tests/shell/path
ln -s "$(which "${PYTHON}")" tests/shell/path/python
ln -s "$(which screen)" tests/shell/path
ln -s "$(which env)" tests/shell/path
ln -s "$(which git)" tests/shell/path
ln -s "$(which sleep)" tests/shell/path
ln -s "$(which cat)" tests/shell/path
ln -s "$(which false)" tests/shell/path
ln -s "$(which true)" tests/shell/path
ln -s "$(which kill)" tests/shell/path
ln -s "$(which echo)" tests/shell/path
ln -s "$(which which)" tests/shell/path
ln -s "$(which dirname)" tests/shell/path
ln -s "$(which wc)" tests/shell/path
ln -s "$(which stty)" tests/shell/path
ln -s "$(which cut)" tests/shell/path
ln -s "$(which bc)" tests/shell/path
ln -s "$(which expr)" tests/shell/path
ln -s "$(which mktemp)" tests/shell/path
ln -s "$(which grep)" tests/shell/path
ln -s "$(which sed)" tests/shell/path
ln -s "$(which rm)" tests/shell/path
ln -s "$(which uname)" tests/shell/path
ln -s "$(which test)" tests/shell/path
ln -s "$(which pwd)" tests/shell/path
ln -s ../../test_shells/bgscript.sh tests/shell/path
ln -s ../../test_shells/waitpid.sh tests/shell/path
if which socat ; then
ln -s "$(which socat)" tests/shell/path
fi
for pexe in powerline powerline-config powerline-render powerline.sh powerline.py ; do
if test -e scripts/$pexe ; then
ln -s "$PWD/scripts/$pexe" tests/shell/path
elif test -e client/$pexe ; then
ln -s "$PWD/client/$pexe" tests/shell/path
elif which $pexe ; then
ln -s "$(which $pexe)" tests/shell/path
else
echo "Executable $pexe was not found"
exit 1
fi
done
ln -s python tests/shell/path/pdb
PDB_PYTHON=pdb
if test -z "$POWERLINE_RC_EXE" ; then
if which rc-status >/dev/null ; then
# On Gentoo `rc` executable is from OpenRC. Thus app-shells/rc instals
# `rcsh` executable.
POWERLINE_RC_EXE=rcsh
else
POWERLINE_RC_EXE=rc
fi
fi
if which "$POWERLINE_RC_EXE" >/dev/null ; then
ln -s "$(which $POWERLINE_RC_EXE)" tests/shell/path/rc
fi
for exe in bash zsh busybox fish tcsh mksh dash ipython ; do
if which $exe >/dev/null ; then
if test "$exe" = "fish" ; then
fish_version="$(fish --version 2>&1)"
fish_version="${fish_version##* }"
fish_version_major="${fish_version%%.*}"
fish_version_minor="${fish_version#*.}"
fish_version_patch="${fish_version_minor#*.}"
fish_version_dev="${fish_version_patch#*-}"
if test "$fish_version_dev" = "$fish_version_patch" ; then
fish_version_dev=""
fi
fish_version_minor="${fish_version_minor%%.*}"
fish_version_patch="${fish_version_patch%%-*}"
if test $fish_version_major -lt 2 || ( \
test $fish_version_major -eq 2 && (\
test $fish_version_minor -lt 1 || (\
test $fish_version_minor -eq 1 &&
test $fish_version_patch -lt 2 && \
test -z "$fish_version_dev"
) \
) \
) ; then
continue
fi
fi
ln -s "$(which $exe)" tests/shell/path
fi
done
unset ENV
export ADDRESS="powerline-ipc-test-$$"
export PYTHON
echo "Powerline address: $ADDRESS"
check_test_client() {
local executable="$1"
local client_type="$2"
local actual_mime_type="$(file --mime-type --brief --dereference "tests/shell/path/$executable" | cut -d/ -f1)"
local expected_mime_type
case "$client_type" in
C) expected_mime_type="application/x-executable" ;;
python) expected_mime_type="text/x-python" ;;
render) expected_mime_type="text/x-python" ;;
shell) expected_mime_type="text/x-shellscript" ;;
esac
expected_mime_type="${expected_mime_type%/*}"
if test "$expected_mime_type" != "$actual_mime_type" ; then
echo "Expected $executable to have MIME type $expected_mime_type, but got $actual_mime_type"
FAILED=1
FAIL_SUMMARY="${FAIL_SUMMARY}${NL}M ${executable}"
fi
}
if test -z "${ONLY_SHELL}" || test "x${ONLY_SHELL%sh}" != "x${ONLY_SHELL}" || test "x${ONLY_SHELL}" = xbusybox || test "x${ONLY_SHELL}" = xrc ; then
scripts/powerline-config shell command
for TEST_TYPE in "daemon" "nodaemon" ; do
if test "x$ONLY_TEST_TYPE" != "x" && test "x$ONLY_TEST_TYPE" != "x$TEST_TYPE" ; then
continue
fi
if test x$FAST = x1 ; then
if test $TEST_TYPE = daemon ; then
VARIANTS=3
else
VARIANTS=4
fi
EXETEST="$(( ${RANDOM:-`date +%N | sed s/^0*//`} % $VARIANTS ))"
echo "Execute tests: $EXETEST"
fi
if test $TEST_TYPE = daemon ; then
sh -c '
echo $$ > tests/shell/daemon_pid
$PYTHON ./scripts/powerline-daemon -s$ADDRESS -f >tests/shell/daemon_log 2>&1
' &
fi
echo "> Testing $TEST_TYPE"
I=-1
for POWERLINE_COMMAND in \
powerline \
powerline-render \
powerline.py \
powerline.sh
do
case "$POWERLINE_COMMAND" in
powerline) TEST_CLIENT=C ;;
powerline-render) TEST_CLIENT=render ;;
powerline.py) TEST_CLIENT=python ;;
powerline.sh) TEST_CLIENT=shell ;;
esac
check_test_client "$POWERLINE_COMMAND" $TEST_CLIENT
if test "$TEST_CLIENT" = render && test "$TEST_TYPE" = daemon ; then
continue
fi
I="$(( I + 1 ))"
if test "$TEST_CLIENT" = "C" && ! test -x scripts/powerline ; then
if which powerline >/dev/null ; then
POWERLINE_COMMAND=powerline
else
continue
fi
fi
if test "$TEST_CLIENT" = "shell" && ! test -x tests/shell/path/socat ; then
continue
fi
if test "x$ONLY_TEST_CLIENT" != "x" && test "x$TEST_CLIENT" != "x$ONLY_TEST_CLIENT" ; then
continue
fi
POWERLINE_COMMAND_ARGS="--socket $ADDRESS"
POWERLINE_COMMAND="$POWERLINE_COMMAND"
export POWERLINE_COMMAND
echo ">> powerline command is ${POWERLINE_COMMAND:-empty}"
J=-1
for TEST_COMMAND in \
"bash --norc --noprofile -i" \
"zsh -f -i" \
"fish -i" \
"tcsh -f -i" \
"busybox ash -i" \
"mksh -i" \
"dash -i" \
"rc -i -p"
do
J="$(( J + 1 ))"
if test x$FAST = x1 ; then
if test $(( (I + J) % $VARIANTS )) -ne $EXETEST ; then
continue
fi
fi
SH="${TEST_COMMAND%% *}"
# dash tests are not stable, see #931
if test x$FAST$SH = x1dash ; then
continue
fi
if test "x$ONLY_SHELL" != "x" && test "x$ONLY_SHELL" != "x$SH" ; then
continue
fi
if ! test -x tests/shell/path/$SH ; then
continue
fi
echo ">>> $(readlink "tests/shell/path/$SH")"
if ! run_test $TEST_TYPE $TEST_CLIENT $TEST_COMMAND ; then
FAILED=1
FAIL_SUMMARY="${FAIL_SUMMARY}${NL}T ${TEST_TYPE} ${TEST_CLIENT} ${TEST_COMMAND}"
fi
done
done
if test $TEST_TYPE = daemon ; then
$PYTHON ./scripts/powerline-daemon -s$ADDRESS -k
wait $(cat tests/shell/daemon_pid)
if ! test -z "$(cat tests/shell/daemon_log)" ; then
echo '____________________________________________________________'
echo "Daemon log:"
echo '============================================================'
cat tests/shell/daemon_log
FAILED=1
FAIL_SUMMARY="${FAIL_SUMMARY}${NL}L ${TEST_TYPE} ${TEST_CLIENT} ${TEST_COMMAND}"
fi
fi
done
fi
if $PYTHON scripts/powerline-daemon -s$ADDRESS > tests/shell/daemon_log_2 2>&1 ; then
sleep 1
$PYTHON scripts/powerline-daemon -s$ADDRESS -k
else
echo "Daemon exited with status $?"
FAILED=1
FAIL_SUMMARY="${FAIL_SUMMARY}${NL}D"
fi
if ! test -z "$(cat tests/shell/daemon_log_2)" ; then
echo '____________________________________________________________'
echo "Daemon log (2nd):"
echo '============================================================'
cat tests/shell/daemon_log_2
FAILED=1
FAIL_SUMMARY="${FAIL_SUMMARY}${NL}L"
fi
if ( test "x${ONLY_SHELL}" = "x" || test "x${ONLY_SHELL}" = "xzsh" ) \
&& ( test "x${ONLY_TEST_TYPE}" = "x" || test "x${ONLY_TEST_TYPE}" = "xzpython" ) \
&& zsh -f -c 'zmodload libzpython' 2>/dev/null; then
echo "> zpython"
if ! run_test zpython zpython zsh -f -i ; then
FAILED=1
FAIL_SUMMARY="${FAIL_SUMMARY}${NL}T zpython zsh -f -i"
fi
fi
if test "x${ONLY_SHELL}" = "x" || test "x${ONLY_SHELL}" = "xpdb" ; then
if ! ( test "$PYTHON_IMPLEMENTATION" = "PyPy" && test "$PYTHON_VERSION_MAJOR" = 2 ) ; then
if test "x${ONLY_TEST_TYPE}" = "x" || test "x${ONLY_TEST_TYPE}" = "xsubclass" ; then
echo "> pdb subclass"
if ! run_test subclass python $PDB_PYTHON "$PWD/tests/test_shells/pdb-main.py" ; then
FAILED=1
FAIL_SUMMARY="${FAIL_SUMMARY}${NL}T pdb $PDB_PYTHON $PWD/tests/test_shells/pdb-main.py"
fi
fi
if test "x${ONLY_TEST_TYPE}" = "x" || test "x${ONLY_TEST_TYPE}" = "xmodule" ; then
echo "> pdb module"
MODULE="powerline.bindings.pdb"
if test "$PYTHON_MM" = "2.6" ; then
MODULE="powerline.bindings.pdb.__main__"
fi
if ! run_test module python $PDB_PYTHON -m$MODULE "$PWD/tests/test_shells/pdb-script.py" ; then
FAILED=1
FAIL_SUMMARY="${FAIL_SUMMARY}${NL}T pdb $PDB_PYTHON -m$MODULE $PWD/tests/test_shells/pdb-script"
fi
fi
fi
fi
if test "x${ONLY_SHELL}" = "x" || test "x${ONLY_SHELL}" = "xipython" ; then
if which ipython >/dev/null ; then
# Define some overrides which should be ignored by IPython.
POWERLINE_CONFIG_OVERRIDES='common.term_escape_style=fbterm'
POWERLINE_THEME_OVERRIDES='in.segments.left=[]'
echo "> $(which ipython)"
if ! run_test ipython ipython ipython ; then
FAILED=1
FAIL_SUMMARY="${FAIL_SUMMARY}${NL}T ipython"
fi
unset POWERLINE_THEME_OVERRIDES
unset POWERLINE_CONFIG_OVERRIDES
fi
fi
if test $FAILED -eq 0 ; then
rm -r tests/shell
else
echo "${FAIL_SUMMARY}"
fi
exit $FAILED