mirror of
https://github.com/tmux/tmux.git
synced 2026-07-09 10:59:30 +00:00
Add alerts test.
This commit is contained in:
291
regress/alerts.sh
Normal file
291
regress/alerts.sh
Normal file
@@ -0,0 +1,291 @@
|
||||
#!/bin/sh
|
||||
|
||||
# monitor-activity, monitor-bell and monitor-silence: both the
|
||||
# alert-activity, alert-bell and alert-silence hooks and the winlink alert
|
||||
# flags (window_activity_flag, window_bell_flag, window_silence_flag and
|
||||
# the #, !, ~ characters in window_flags). The sessions are detached so
|
||||
# alert flags are set even on the current window; the *-action options
|
||||
# still decide whether the hooks fire. Panes run cat: activity is
|
||||
# generated by the tty echo of send-keys and a bell by sending a BEL and
|
||||
# newline for cat to write back.
|
||||
|
||||
PATH=/bin:/usr/bin
|
||||
TERM=screen
|
||||
LC_ALL=C.UTF-8
|
||||
LANG=C.UTF-8
|
||||
export TERM LC_ALL LANG
|
||||
|
||||
[ -z "$TEST_TMUX" ] && TEST_TMUX=$(readlink -f ../tmux)
|
||||
OUT=$(mktemp -d)
|
||||
TMUX_TMPDIR="$OUT"
|
||||
export TMUX_TMPDIR
|
||||
TMUX="$TEST_TMUX -Ltest-alerts-$$ -f/dev/null"
|
||||
|
||||
fail()
|
||||
{
|
||||
echo "$*" >&2
|
||||
$TMUX kill-server 2>/dev/null || true
|
||||
rm -rf "$OUT"
|
||||
exit 1
|
||||
}
|
||||
|
||||
cleanup()
|
||||
{
|
||||
$TMUX kill-server 2>/dev/null || true
|
||||
rm -rf "$OUT"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
wait_for()
|
||||
{
|
||||
option=$1
|
||||
expected=$2
|
||||
i=0
|
||||
|
||||
while [ $i -lt 30 ]; do
|
||||
value=$($TMUX show -gqv "$option" 2>/dev/null || true)
|
||||
[ "$value" = "$expected" ] && return 0
|
||||
i=$((i + 1))
|
||||
sleep 0.2
|
||||
done
|
||||
fail "expected $option to be '$expected' but got '$value'"
|
||||
}
|
||||
|
||||
assert_unchanged()
|
||||
{
|
||||
option=$1
|
||||
expected=$2
|
||||
i=0
|
||||
|
||||
while [ $i -lt 10 ]; do
|
||||
value=$($TMUX show -gqv "$option" 2>/dev/null || true)
|
||||
[ "$value" = "$expected" ] || \
|
||||
fail "expected $option to remain '$expected' but got '$value'"
|
||||
i=$((i + 1))
|
||||
sleep 0.2
|
||||
done
|
||||
}
|
||||
|
||||
wait_for_fmt()
|
||||
{
|
||||
target=$1
|
||||
fmt=$2
|
||||
expected=$3
|
||||
i=0
|
||||
|
||||
while [ $i -lt 30 ]; do
|
||||
value=$($TMUX display -pt "$target" "$fmt" 2>/dev/null || true)
|
||||
[ "$value" = "$expected" ] && return 0
|
||||
i=$((i + 1))
|
||||
sleep 0.2
|
||||
done
|
||||
fail "expected $fmt for $target to be '$expected' but got '$value'"
|
||||
}
|
||||
|
||||
assert_fmt_unchanged()
|
||||
{
|
||||
target=$1
|
||||
fmt=$2
|
||||
expected=$3
|
||||
i=0
|
||||
|
||||
while [ $i -lt 10 ]; do
|
||||
value=$($TMUX display -pt "$target" "$fmt" 2>/dev/null || true)
|
||||
[ "$value" = "$expected" ] || \
|
||||
fail "expected $fmt for $target to remain '$expected' but got '$value'"
|
||||
i=$((i + 1))
|
||||
sleep 0.2
|
||||
done
|
||||
}
|
||||
|
||||
flags_have()
|
||||
{
|
||||
target=$1
|
||||
char=$2
|
||||
|
||||
flags=$($TMUX display -pt "$target" '#{window_flags}') ||
|
||||
fail "display window_flags failed"
|
||||
case "$flags" in
|
||||
*"$char"*) ;;
|
||||
*) fail "expected '$char' in window_flags for $target: '$flags'" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
flags_lack()
|
||||
{
|
||||
target=$1
|
||||
char=$2
|
||||
|
||||
flags=$($TMUX display -pt "$target" '#{window_flags}') ||
|
||||
fail "display window_flags failed"
|
||||
case "$flags" in
|
||||
*"$char"*) fail "unexpected '$char' in window_flags for $target: '$flags'" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
bell()
|
||||
{
|
||||
$TMUX send-keys -t "$1" -H 07 0a || fail "send-keys bell failed"
|
||||
}
|
||||
|
||||
activity()
|
||||
{
|
||||
$TMUX send-keys -t "$1" -l x || fail "send-keys activity failed"
|
||||
}
|
||||
|
||||
$TMUX new -d -s mon -n w0 cat || fail "new-session mon failed"
|
||||
|
||||
$TMUX set -g @log '' || fail "set @log failed"
|
||||
$TMUX set-hook -g alert-bell \
|
||||
'set -gF @log "#{@log}|alert-bell:#{hook_session_name}:#{hook_window_name}"' ||
|
||||
fail "set-hook alert-bell failed"
|
||||
$TMUX set-hook -g alert-activity \
|
||||
'set -gF @log "#{@log}|alert-activity:#{hook_session_name}:#{hook_window_name}"' ||
|
||||
fail "set-hook alert-activity failed"
|
||||
$TMUX set-hook -g alert-silence \
|
||||
'set -gF @log "#{@log}|alert-silence:#{hook_session_name}:#{hook_window_name}"' ||
|
||||
fail "set-hook alert-silence failed"
|
||||
|
||||
# A bell in a non-current window (monitor-bell defaults to on) fires
|
||||
# alert-bell and sets the bell flag, shown as ! in window_flags.
|
||||
$TMUX neww -d -t mon: -n bellw cat || fail "new-window bellw failed"
|
||||
assert_fmt_unchanged mon:bellw '#{window_bell_flag}' 0
|
||||
flags_lack mon:bellw '!'
|
||||
bell mon:bellw
|
||||
wait_for @log '|alert-bell:mon:bellw'
|
||||
wait_for_fmt mon:bellw '#{window_bell_flag}' 1
|
||||
flags_have mon:bellw '!'
|
||||
|
||||
# Bells are not deduplicated: a second bell fires the hook again even
|
||||
# though the flag is still set.
|
||||
bell mon:bellw
|
||||
wait_for @log '|alert-bell:mon:bellw|alert-bell:mon:bellw'
|
||||
|
||||
# Selecting the window clears the alert flags.
|
||||
$TMUX selectw -t mon:bellw || fail "select-window bellw failed"
|
||||
wait_for_fmt mon:bellw '#{window_bell_flag}' 0
|
||||
flags_lack mon:bellw '!'
|
||||
$TMUX selectw -t mon:w0 || fail "select-window w0 failed"
|
||||
|
||||
# A bell in the current window of a detached session still sets the flag
|
||||
# and bell-action any (the default) fires the hook for the current window.
|
||||
$TMUX set -g @log '' || fail "reset @log failed"
|
||||
bell mon:w0
|
||||
wait_for @log '|alert-bell:mon:w0'
|
||||
wait_for_fmt mon:w0 '#{window_bell_flag}' 1
|
||||
$TMUX selectw -t mon:bellw || fail "select-window bellw failed"
|
||||
$TMUX selectw -t mon:w0 || fail "select-window w0 failed"
|
||||
wait_for_fmt mon:w0 '#{window_bell_flag}' 0
|
||||
|
||||
# bell-action none: the flag is still set but the hook does not fire.
|
||||
$TMUX set -t mon bell-action none || fail "set bell-action none failed"
|
||||
$TMUX set -g @log '' || fail "reset @log failed"
|
||||
bell mon:bellw
|
||||
wait_for_fmt mon:bellw '#{window_bell_flag}' 1
|
||||
assert_unchanged @log ''
|
||||
$TMUX set -ut mon bell-action || fail "unset bell-action failed"
|
||||
$TMUX selectw -t mon:bellw || fail "select-window bellw failed"
|
||||
$TMUX selectw -t mon:w0 || fail "select-window w0 failed"
|
||||
|
||||
# monitor-bell off: neither the flag nor the hook.
|
||||
$TMUX set -wt mon:bellw monitor-bell off || fail "set monitor-bell failed"
|
||||
$TMUX set -g @log '' || fail "reset @log failed"
|
||||
bell mon:bellw
|
||||
assert_fmt_unchanged mon:bellw '#{window_bell_flag}' 0
|
||||
assert_unchanged @log ''
|
||||
|
||||
# monitor-activity defaults to off: output sets neither flag nor hook.
|
||||
$TMUX neww -d -t mon: -n actw cat || fail "new-window actw failed"
|
||||
$TMUX set -g @log '' || fail "reset @log failed"
|
||||
activity mon:actw
|
||||
assert_fmt_unchanged mon:actw '#{window_activity_flag}' 0
|
||||
assert_unchanged @log ''
|
||||
|
||||
# With monitor-activity on, output fires alert-activity and sets the
|
||||
# activity flag, shown as # in window_flags.
|
||||
$TMUX set -wt mon:actw monitor-activity on ||
|
||||
fail "set monitor-activity failed"
|
||||
activity mon:actw
|
||||
wait_for @log '|alert-activity:mon:actw'
|
||||
wait_for_fmt mon:actw '#{window_activity_flag}' 1
|
||||
flags_have mon:actw '#'
|
||||
|
||||
# While the flag is set further activity does not fire the hook again.
|
||||
$TMUX set -g @log '' || fail "reset @log failed"
|
||||
activity mon:actw
|
||||
assert_unchanged @log ''
|
||||
|
||||
# On a detached session selecting the window does not clear the activity
|
||||
# flag: session_set_current treats the selection itself as activity and
|
||||
# the flag is raised again at once because the session is not attached.
|
||||
# No hook fires as activity-action other does not apply to the current
|
||||
# window.
|
||||
$TMUX selectw -t mon:actw || fail "select-window actw failed"
|
||||
assert_fmt_unchanged mon:actw '#{window_activity_flag}' 1
|
||||
$TMUX selectw -t mon:w0 || fail "select-window w0 failed"
|
||||
assert_fmt_unchanged mon:actw '#{window_activity_flag}' 1
|
||||
assert_unchanged @log ''
|
||||
|
||||
# With a client attached, selecting the window does clear the activity
|
||||
# flag and it stays clear for the current window.
|
||||
mkfifo "$OUT/fifo" || fail "mkfifo failed"
|
||||
$TMUX -C attach -t mon <"$OUT/fifo" >"$OUT/control.out" 2>&1 &
|
||||
exec 3>"$OUT/fifo"
|
||||
wait_for_fmt mon: '#{session_attached}' 1
|
||||
$TMUX selectw -t mon:actw || fail "select-window actw failed"
|
||||
wait_for_fmt mon:actw '#{window_activity_flag}' 0
|
||||
flags_lack mon:actw '#'
|
||||
$TMUX selectw -t mon:w0 || fail "select-window w0 failed"
|
||||
exec 3>&-
|
||||
wait_for_fmt mon: '#{session_attached}' 0
|
||||
|
||||
# Once the flag is clear the alert is re-armed.
|
||||
activity mon:actw
|
||||
wait_for @log '|alert-activity:mon:actw'
|
||||
|
||||
# Activity in the current window of a detached session sets the flag but
|
||||
# activity-action other (the default) does not fire the hook.
|
||||
$TMUX set -wt mon:w0 monitor-activity on ||
|
||||
fail "set monitor-activity w0 failed"
|
||||
$TMUX set -g @log '' || fail "reset @log failed"
|
||||
activity mon:w0
|
||||
wait_for_fmt mon:w0 '#{window_activity_flag}' 1
|
||||
assert_unchanged @log ''
|
||||
$TMUX set -wut mon:w0 monitor-activity ||
|
||||
fail "unset monitor-activity w0 failed"
|
||||
|
||||
# monitor-silence: a quiet window fires alert-silence after the interval
|
||||
# and sets the silence flag, shown as ~ in window_flags. The hook fires
|
||||
# only once while the flag remains set even though the timer keeps
|
||||
# running.
|
||||
$TMUX neww -d -t mon: -n silw cat || fail "new-window silw failed"
|
||||
assert_fmt_unchanged mon:silw '#{window_silence_flag}' 0
|
||||
$TMUX set -g @log '' || fail "reset @log failed"
|
||||
$TMUX set -wt mon:silw monitor-silence 1 || fail "set monitor-silence failed"
|
||||
wait_for @log '|alert-silence:mon:silw'
|
||||
wait_for_fmt mon:silw '#{window_silence_flag}' 1
|
||||
flags_have mon:silw '~'
|
||||
assert_unchanged @log '|alert-silence:mon:silw'
|
||||
$TMUX set -wt mon:silw monitor-silence 0 ||
|
||||
fail "reset monitor-silence failed"
|
||||
$TMUX selectw -t mon:silw || fail "select-window silw failed"
|
||||
wait_for_fmt mon:silw '#{window_silence_flag}' 0
|
||||
flags_lack mon:silw '~'
|
||||
$TMUX selectw -t mon:w0 || fail "select-window w0 failed"
|
||||
|
||||
# A window linked into two sessions: the hook fires once per winlink and
|
||||
# the flag is set in both sessions. Selecting the window in one session
|
||||
# clears the flags on every winlink.
|
||||
$TMUX new -d -s mon2 || fail "new-session mon2 failed"
|
||||
$TMUX neww -d -t mon: -n shw cat || fail "new-window shw failed"
|
||||
$TMUX link-window -d -s mon:shw -t mon2:5 || fail "link-window failed"
|
||||
$TMUX set -g @log '' || fail "reset @log failed"
|
||||
bell mon:shw
|
||||
wait_for @log '|alert-bell:mon:shw|alert-bell:mon2:shw'
|
||||
wait_for_fmt mon:shw '#{window_bell_flag}' 1
|
||||
wait_for_fmt mon2:5 '#{window_bell_flag}' 1
|
||||
$TMUX selectw -t mon2:5 || fail "select-window mon2:5 failed"
|
||||
wait_for_fmt mon2:5 '#{window_bell_flag}' 0
|
||||
wait_for_fmt mon:shw '#{window_bell_flag}' 0
|
||||
|
||||
exit 0
|
||||
Reference in New Issue
Block a user