7c68667bc0
Recent versions of tmux master gave us an 80x23 window. tmux has been fixed to default to 80x24, and also to allow setting window sizes in control mode. These flags fortunately do not conflict with older versions tmux. So we use them to avoid problems going forward.
327 lines
7.8 KiB
Bash
Executable File
327 lines
7.8 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
. "$(dirname "$0")/e2e-test-subrs"
|
|
|
|
#
|
|
# Validate that mosh produces expected output, using screen captures
|
|
# in tmux.
|
|
#
|
|
|
|
log()
|
|
{
|
|
printf "$@"
|
|
}
|
|
|
|
error()
|
|
{
|
|
printf "$@" >&2
|
|
}
|
|
|
|
dump_logs()
|
|
{
|
|
dir=$1
|
|
shift
|
|
testname=$(basename "$dir" .d)
|
|
for logfile in $dir/*.tmux.log; do
|
|
printf "travis_fold:start:%s-%s\n" "$testname" "$(basename "$logfile")"
|
|
cat "$logfile"
|
|
printf "travis_fold:end:%s-%s\n" "$testname" "$(basename "$logfile")"
|
|
done
|
|
}
|
|
|
|
test_success()
|
|
{
|
|
exit 0
|
|
}
|
|
test_failure()
|
|
{
|
|
error "$@"
|
|
exit 1
|
|
}
|
|
test_skipped()
|
|
{
|
|
error "$@"
|
|
exit 77
|
|
}
|
|
test_error()
|
|
{
|
|
error "$@"
|
|
exit 99
|
|
}
|
|
test_exitstatus()
|
|
{
|
|
status=$1
|
|
shift
|
|
error "$@"
|
|
exit "$status"
|
|
}
|
|
|
|
|
|
# Tmux check.
|
|
tmux_check()
|
|
{
|
|
# OpenBSD tmux does not have '-V'.
|
|
if [ "$(uname -s)" = "OpenBSD" ]; then
|
|
openbsd_major="$(uname -r)"
|
|
openbsd_major="${openbsd_major%%.*}"
|
|
if [ "${openbsd_major}" -ge 6 ]; then
|
|
return 0
|
|
fi
|
|
fi
|
|
version=$(tmux -V)
|
|
if [ $? != 0 ]; then
|
|
error "tmux unavailable\n"
|
|
return 1
|
|
fi
|
|
if [ "$version" = "tmux master" ]; then
|
|
return 0
|
|
fi
|
|
version=${version##tmux }
|
|
version_major=${version%%.*}
|
|
version_minor=${version##*.}
|
|
# need version 1.8 for capture-pane
|
|
if [ "$version_major" -lt 1 ] ||
|
|
{ [ "$version_major" -eq 1 ] && [ "$version_minor" -lt 8 ]; }; then
|
|
error "tmux version %s too old\n" "$version"
|
|
return 1
|
|
fi
|
|
# Finally, check that tmux actually works to some degree.
|
|
tmux -C new-session true
|
|
}
|
|
|
|
ssh_localhost_check()
|
|
{
|
|
ssh localhost :
|
|
if [ $? -ne 0 ]; then
|
|
error "ssh to localhost failed\n"
|
|
return 1
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
# These two functions are wrappers for mosh-client/mosh-server to turn
|
|
# on verbosity and log stderr.
|
|
mosh_client()
|
|
{
|
|
if [ -z "$MOSH_CLIENT" ] || [ -z "$MOSH_E2E_TEST" ]; then
|
|
test_error "mosh_client: variables missing\n"
|
|
fi
|
|
exec 2> "${MOSH_E2E_TEST}.client.stderr"
|
|
exec "$MOSH_CLIENT" $MOSH_CLIENT_ARGS "$@"
|
|
}
|
|
|
|
mosh_server()
|
|
{
|
|
if [ -z "$MOSH_SERVER" ] || [ -z "$MOSH_E2E_TEST" ]; then
|
|
test_error "mosh_server: variables missing\n"
|
|
fi
|
|
exec 2> "${MOSH_E2E_TEST}.server.stderr"
|
|
exec "$MOSH_SERVER" new -vv $MOSH_SERVER_ARGS -@ "$@"
|
|
}
|
|
|
|
# main
|
|
# Set up environment
|
|
if [ -z "$srcdir" ]; then
|
|
export srcdir=$PWD
|
|
else
|
|
srcdir="$(cd "$srcdir" && pwd)"
|
|
if [ $? -ne 0 ]; then
|
|
error "can't cd to srcdir: %s\n" "$srcdir"
|
|
exit 99
|
|
fi
|
|
fi
|
|
|
|
# Wrappers.
|
|
case "$(basename "$0")" in
|
|
mosh-client)
|
|
mosh_client "$@"
|
|
exit
|
|
;;
|
|
mosh-server)
|
|
mosh_server "$@"
|
|
exit
|
|
;;
|
|
*)
|
|
;;
|
|
esac
|
|
|
|
if [ $# -lt 2 ]; then
|
|
test_error "not enough args\n"
|
|
fi
|
|
|
|
# Get arguments (only one so far)
|
|
test_name=$1
|
|
shift
|
|
test_args=$@
|
|
# XXX could use AM testsubdir macro instead
|
|
test_dir=$(basename "${test_name}").d
|
|
test_script="${test_name}"
|
|
|
|
tests_dir=$(dirname "${test_name}")
|
|
if ! set_locale "${tests_dir}"; then
|
|
test_error "e2e-test: no usable locale\n"
|
|
fi
|
|
|
|
if ! tmux_check; then
|
|
test_skipped "tmux unavailable\n"
|
|
fi
|
|
|
|
rm -rf "${test_dir}"
|
|
mkdir "${test_dir}"
|
|
|
|
|
|
on_exit() {
|
|
rv=$?
|
|
if test $rv -ne 0; then
|
|
dump_logs "$test_dir" $test_args
|
|
fi
|
|
exit $rv
|
|
}
|
|
trap on_exit EXIT
|
|
|
|
# Set up tests to run.
|
|
server_tests=
|
|
compare_tests=
|
|
for i in $test_args; do
|
|
case $i in
|
|
baseline|direct|variant)
|
|
server_tests="$server_tests $i";;
|
|
verify|same|different)
|
|
compare_tests="$compare_tests $i";;
|
|
tmux)
|
|
tmux=1;;
|
|
client)
|
|
client=1;;
|
|
server)
|
|
server=1;;
|
|
post)
|
|
post=1;;
|
|
mosh-args)
|
|
mosh_args=$("${test_script}" mosh-args);;
|
|
client-args)
|
|
MOSH_CLIENT_ARGS=$("${test_script}" client-args)
|
|
export MOSH_CLIENT_ARGS;;
|
|
server-args)
|
|
MOSH_SERVER_ARGS=$("${test_script}" server-args)
|
|
export MOSH_SERVER_ARGS;;
|
|
*)
|
|
error 'unknown test type argument %s\n' "$i"
|
|
exit 99
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# Run test(s).
|
|
client_wrapper=
|
|
if [ -n "$client" ]; then
|
|
client_wrapper="${test_script} client"
|
|
fi
|
|
|
|
server_wrapper="\"${srcdir}/e2e-test-server\""
|
|
if [ -n "$server" ]; then
|
|
server_wrapper="\"${srcdir}/${test_script}\" server"
|
|
fi
|
|
tmux_stdin="${srcdir}/hold-stdin"
|
|
if [ -n "$tmux" ]; then
|
|
tmux_stdin="${test_script} tmux"
|
|
fi
|
|
|
|
|
|
|
|
for run in $server_tests; do
|
|
log "Running server test %s.\n" "$run"
|
|
# These three variables are for the benefit of the mosh-client and mosh-server wrappers.
|
|
export MOSH_CLIENT="$PWD/../frontend/mosh-client"
|
|
export MOSH_SERVER="$PWD/../frontend/mosh-server"
|
|
export MOSH_E2E_TEST="$PWD/${test_dir}/${run}"
|
|
# XXX need to quote special chars in server pathname here somehow
|
|
sut="../../scripts/mosh --client=${srcdir}/mosh-client --server=${srcdir}/mosh-server --local --bind-server=127.0.0.1 ${mosh_args} 127.0.0.1"
|
|
if [ "$run" = "direct" ]; then
|
|
sut=""
|
|
fi
|
|
# Actually execute code under test
|
|
# XXX tmux 1.8 requires shell command as a single arg; once we move to 2.0, undo these quotes
|
|
# XXX this ignores $TMPDIR, because it results in an overlong pathname on OS X
|
|
tmux_socket="/tmp/.tmux-mosh-test-$$"
|
|
ln -fs "${tmux_socket}" "${test_dir}/tmux-socket"
|
|
# tmux <= 2.5 ignore -x/-y, but the client sets the session to 80x24.
|
|
# tmux from 2017-05-27 and later should default to an 80x24 session,
|
|
# but do use -x/-y on control-master clients.
|
|
${tmux_stdin} tmux -f /dev/null -S "${tmux_socket}" -C new-session -x 80 -y 24 "${srcdir}/print-exitstatus ${client_wrapper} ${sut} ${server_wrapper} \"${PWD}/${test_dir}/${run}\" \"${PWD}/${test_script} ${run}\"" > "${test_dir}/${run}.tmux.log"
|
|
rv=$?
|
|
rm -f "${tmux_socket}" "${test_dir}/tmux-socket"
|
|
if [ $rv -ne 0 ]; then
|
|
test_error "tmux failure on test %s\n" "$run"
|
|
fi
|
|
# Check for mosh failures
|
|
if ! grep -q "@@@ exitstatus: 0 @@@" "${test_dir}/${run}.tmux.log"; then
|
|
test_error "mosh-client had non-zero exitstatus\n"
|
|
fi
|
|
|
|
# Check for server harness failures
|
|
if [ -z "$server" ]; then
|
|
if [ ! -s "${test_dir}/${run}.capture" ] \
|
|
|| [ ! -s "${test_dir}/${run}.exitstatus" ]; then
|
|
test_error "server harness failure on test %s\n" "$run"
|
|
fi
|
|
read -r server_rv < "${test_dir}/${run}.exitstatus"
|
|
if [ "$server_rv" -ne 0 ]; then
|
|
test_error "server harness exited with status %s\n" "$server_rv"
|
|
fi
|
|
fi
|
|
if [ "${run}" != "direct" ]; then
|
|
# Check for "round-trip" failures
|
|
if grep -q "round-trip Instruction verification failed" "${test_dir}/${run}.server.stderr"; then
|
|
test_error "Round-trip Instruction verification failed on server during %s\n" "$run"
|
|
fi
|
|
# Check for 0-timeout select() issue
|
|
if egrep -q "(polls, rate limiting|consecutive polls)" "${test_dir}/${run}.server.stderr"; then
|
|
test_error "select() with zero timeout called too often on server during %s\n" "$run"
|
|
fi
|
|
# Check for assert()
|
|
if egrep -q "assertion.*failed" "${test_dir}/${run}.server.stderr"; then
|
|
test_error "assertion during %s\n" "$run"
|
|
fi
|
|
fi
|
|
# XXX We'd also like to check for "target state Instruction
|
|
# verification failed", a new check, but tmux's lack of BCE
|
|
# support forces mosh to clear lines with spaces and change a
|
|
# framebuffer in a way that causes this to fire spuriously.
|
|
done
|
|
|
|
for compare in $compare_tests; do
|
|
log "Running server comparison %s.\n" "$compare"
|
|
# Compare captures
|
|
if [ "$compare" = verify ]; then
|
|
test1="direct"
|
|
test2="baseline"
|
|
else
|
|
test1="baseline"
|
|
test2="variant"
|
|
fi
|
|
if diff -q "${test_dir}/${test1}.capture" "${test_dir}/${test2}.capture"; then
|
|
differ=n
|
|
else
|
|
differ=y
|
|
fi
|
|
if [ "$compare" = different ]; then
|
|
desired=y
|
|
badresult=same
|
|
else
|
|
desired=n
|
|
badresult=different
|
|
fi
|
|
if [ $differ != $desired ]; then
|
|
test_failure "Output is %s between tests %s and %s\n" "$badresult" "$test1" "$test2"
|
|
fi
|
|
done
|
|
|
|
# Run a post script (usually a custom validation of results)
|
|
if [ -n "$post" ]; then
|
|
"${test_script}" post
|
|
status=$?
|
|
if [ $status -ne 0 ]; then
|
|
test_exitstatus $status "Post test failed with exitstatus %d\n" $status
|
|
fi
|
|
fi
|