diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am index 57ff0ac..6c8ce15 100644 --- a/src/tests/Makefile.am +++ b/src/tests/Makefile.am @@ -12,6 +12,7 @@ displaytests = \ emulation-80th-column.test \ emulation-back-tab.test \ emulation-multiline-scroll.test \ + window-resize.test \ unicode-combine-fallback-assert.test \ unicode-later-combining.test diff --git a/src/tests/README.md b/src/tests/README.md index 1ef4057..fc233c4 100644 --- a/src/tests/README.md +++ b/src/tests/README.md @@ -77,13 +77,19 @@ actions, which are expected to be different. `post` is a catchall script hook which allows custom verification acions to be coded. -### Client wrapper +### Client wrappers + +`tmux` injects a wrapper command into the test command before tmux. +If this is not run, a default command called `hold-stdin` is run +instead. These commands are expected to hold tmux's stdin open, +possibly injecting tmux commands, while the test runs. See +`window-resize.test` for an example of this that manipulates tmux +state. Alternately, this could use expect or something similar. `client` simply injects a wrapper command into the (long) test command between tmux and mosh. It's expected to interact with its wrapped command line as `expect` might do. This is not actually tested yet. - ## Logging and error reporting Each execution action is run, and recorded in diff --git a/src/tests/e2e-test b/src/tests/e2e-test index 038a12a..ecd4425 100755 --- a/src/tests/e2e-test +++ b/src/tests/e2e-test @@ -135,6 +135,8 @@ for i in $test_args; do server_tests="$server_tests $i";; verify|same|different) compare_tests="$compare_tests $i";; + tmux) + tmux=1;; client) client=1;; post) @@ -152,6 +154,11 @@ if [ -n "$client" ]; then client_wrapper="${test_script} client" 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" # XXX need to quote special chars in server pathname here somehow @@ -163,7 +170,7 @@ for run in $server_tests; do # 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 - if ! ${srcdir}/hold-stdin tmux -S "/tmp/.tmux-mosh-test-$$" -C new-session "${srcdir}/print-exitstatus ${client_wrapper} ${sut} \"${srcdir}/e2e-test-server\" \"${PWD}/${test_dir}/${run}\" \"${PWD}/${test_script} ${testarg}\"" > "${test_dir}/${run}.tmux.log"; then + if ! ${tmux_stdin} tmux -S "/tmp/.tmux-mosh-test-$$" -C new-session "${srcdir}/print-exitstatus ${client_wrapper} ${sut} \"${srcdir}/e2e-test-server\" \"${PWD}/${test_dir}/${run}\" \"${PWD}/${test_script} ${testarg}\"" > "${test_dir}/${run}.tmux.log"; then test_error "tmux failure on test %s\n" "$run" fi # Check for mosh failures diff --git a/src/tests/window-resize.test b/src/tests/window-resize.test new file mode 100755 index 0000000..7ce956e --- /dev/null +++ b/src/tests/window-resize.test @@ -0,0 +1,122 @@ +#!/bin/sh + +# +# This is a regression test for window resizing in Mosh. Making it +# happen is a little kludgy: we have to create other panes in tmux and +# resize them. But it works! +# + +fail() +{ + printf "$@" 2>&1 + exit 99 +} + + + +PATH=$PATH:.:$srcdir +# Top-level wrapper. +if [ $# -eq 0 ]; then + e2e-test $0 tmux baseline + exit +fi + +sleepf() +{ + (sleep .1 || sleep 1) > /dev/null 2>&1 +} + +seq() +{ + if [ $# -lt 1 -o $# -gt 3 ]; then + echo "bad args" >&2 + fi + first=$1 + incr=1 + last=0 + case $# in + 3) + incr=$2 + last=$3 + ;; + 2) + last=$2 + ;; + 1) + ;; + esac + while :; do + printf '%d\n' $first + first=$(expr $first + $incr) + if [ $first -gt $last ]; then + break + fi + done +} + +tmux_resize_commands() +{ + hv=$1 + shrink=$2 + grow=$3 + # Split the window into two panes. + printf "split-window -${hv}\n" + # Shrink the pane we created + for i in $(seq 1 10); do + sleepf + printf "resize-pane -${shrink}\n" + done + # And grow it + for i in $(seq 1 10); do + sleepf + printf "resize-pane -${grow}\n" + done + sleep 1 + # Remove the pane we created. + printf "kill-pane\n" +} + +tmux_commands() +{ + # An interactive shell is waiting for us in the mosh session. + # Start a full screen application that will redraw on window + # resize. + printf "send-keys 'less /etc/services' 0x0d\n" + sleep 1 + # we control the horizontal... + tmux_resize_commands v D U + sleep 1 + # and the vertical. + tmux_resize_commands h L R + sleep 1 + # Exit less. + printf "send-keys 'q'\n" + sleep 1 + # Exit mosh session shell. + printf "send-keys 'exit 0' 0x0d\n" + # need to sleep extra long here, to let child commands complete, + # and not have tmux exit prematurely + sleep 5 +} + +tmux_stdin() +{ + tmux_commands | "$@" + exit +} + +baseline() +{ + # Just start an interactive shell and wait. The tmux action drives. + sh +} + +case $1 in + tmux) + shift; + tmux_stdin "$@";; + baseline) + baseline;; + *) + fail "unknown test argument %s\n" $1;; +esac