mirror of
https://github.com/tmux/tmux.git
synced 2026-10-13 06:04:34 +00:00
Tests for 5661 etc, from Alexandre Fiori.
This commit is contained in:
51
regress/cfg-client-free.sh
Normal file
51
regress/cfg-client-free.sh
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# a client lost while the configuration is loading is freed
|
||||||
|
|
||||||
|
PATH=/bin:/usr/bin
|
||||||
|
TERM=screen
|
||||||
|
|
||||||
|
[ -z "$TEST_TMUX" ] && TEST_TMUX=$(readlink -f ../tmux)
|
||||||
|
|
||||||
|
TMPDIR=$(mktemp -d) || exit 1
|
||||||
|
TMUX="$TEST_TMUX -S$TMPDIR/tmux.sock"
|
||||||
|
|
||||||
|
cleanup()
|
||||||
|
{
|
||||||
|
touch $TMPDIR/go
|
||||||
|
$TMUX kill-server 2>/dev/null
|
||||||
|
rm -rf "$TMPDIR"
|
||||||
|
}
|
||||||
|
trap cleanup 0 1 15
|
||||||
|
|
||||||
|
# Poll until a command succeeds.
|
||||||
|
wait_for()
|
||||||
|
{
|
||||||
|
i=0
|
||||||
|
while ! "$@"; do
|
||||||
|
[ $i -eq 100 ] && exit 1
|
||||||
|
i=$((i + 1))
|
||||||
|
sleep 0.1
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# The run-shell holds the configuration until the go file exists.
|
||||||
|
cat <<EOF >$TMPDIR/conf
|
||||||
|
new-session -d -s keep
|
||||||
|
run-shell 'touch $TMPDIR/started; i=0; while [ ! -f $TMPDIR/go ] && [ \$i -lt 100 ]; do sleep 0.1; i=\$((i + 1)); done'
|
||||||
|
EOF
|
||||||
|
|
||||||
|
cd $TMPDIR || exit 1
|
||||||
|
$TMUX -v -f$TMPDIR/conf new-session -d -s first </dev/null &
|
||||||
|
pid=$!
|
||||||
|
wait_for test -f $TMPDIR/started
|
||||||
|
kill $pid
|
||||||
|
wait $pid
|
||||||
|
log=$(echo $TMPDIR/tmux-server-*.log)
|
||||||
|
wait_for grep -q 'lost client' $log
|
||||||
|
c=$(sed -n 's/.* lost client //p' $log)
|
||||||
|
|
||||||
|
# The client is freed straight away, well before the configuration ends.
|
||||||
|
wait_for grep -q "free client $c " $log
|
||||||
|
|
||||||
|
exit 0
|
||||||
90
regress/cfg-client-lost-before-wait.sh
Normal file
90
regress/cfg-client-lost-before-wait.sh
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# A client lost before its configuration callback fires must not start waiting.
|
||||||
|
|
||||||
|
PATH=/bin:/usr/bin
|
||||||
|
TERM=screen
|
||||||
|
|
||||||
|
[ -z "$TEST_TMUX" ] && TEST_TMUX=$(readlink -f ../tmux)
|
||||||
|
|
||||||
|
python3 - "$TEST_TMUX" "$(dirname "$0")/../tmux-protocol.h" <<'PY'
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
import re
|
||||||
|
import socket
|
||||||
|
import struct
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import tempfile
|
||||||
|
import time
|
||||||
|
|
||||||
|
tmux = sys.argv[1]
|
||||||
|
header = Path(sys.argv[2]).read_text()
|
||||||
|
version = int(re.search(r"#define PROTOCOL_VERSION\s+(\d+)", header)[1])
|
||||||
|
enum = re.search(r"enum msgtype\s*\{(.*?)\};", header, re.S)[1]
|
||||||
|
enum = re.sub(r"/\*.*?\*/", "", enum, flags=re.S)
|
||||||
|
types = {}
|
||||||
|
value = 0
|
||||||
|
for entry in enum.split(","):
|
||||||
|
entry = entry.strip()
|
||||||
|
if not entry:
|
||||||
|
continue
|
||||||
|
if "=" in entry:
|
||||||
|
entry, number = entry.split("=")
|
||||||
|
value = int(number.strip())
|
||||||
|
types[entry.strip()] = value
|
||||||
|
value += 1
|
||||||
|
|
||||||
|
def message(name, body=b""):
|
||||||
|
return struct.pack("=IIII", types[name], 16 + len(body), version,
|
||||||
|
os.getpid()) + body
|
||||||
|
|
||||||
|
def wait_for(predicate):
|
||||||
|
end = time.monotonic() + 5
|
||||||
|
while time.monotonic() < end:
|
||||||
|
result = predicate()
|
||||||
|
if result:
|
||||||
|
return result
|
||||||
|
time.sleep(0.05)
|
||||||
|
raise AssertionError("timed out waiting for client cleanup")
|
||||||
|
|
||||||
|
with tempfile.TemporaryDirectory(prefix="tmux-cfg-early-") as tmp:
|
||||||
|
root = Path(tmp)
|
||||||
|
sockpath = root / "socket"
|
||||||
|
go = root / "go"
|
||||||
|
conf = root / "conf"
|
||||||
|
conf.write_text("run-shell 'i=0; while [ ! -f %s ] && [ $i -lt 100 ]; "
|
||||||
|
"do sleep 0.1; i=$((i + 1)); done'\n" % go)
|
||||||
|
server = subprocess.Popen([tmux, "-D", "-v", "-S", str(sockpath),
|
||||||
|
"-f", str(conf)], cwd=tmp, stdout=subprocess.DEVNULL)
|
||||||
|
logpath = root / ("tmux-server-%d.log" % server.pid)
|
||||||
|
|
||||||
|
def log():
|
||||||
|
return logpath.read_text() if logpath.exists() else ""
|
||||||
|
|
||||||
|
try:
|
||||||
|
wait_for(sockpath.exists)
|
||||||
|
with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as client:
|
||||||
|
client.connect(str(sockpath))
|
||||||
|
# Both messages are read together. The short MSG_COMMAND makes
|
||||||
|
# proc_event_cb lose the client before server_loop runs its queue.
|
||||||
|
client.sendall(message("MSG_IDENTIFY_CWD", tmp.encode() + b"\0") +
|
||||||
|
message("MSG_IDENTIFY_CLIENTPID", struct.pack("=i", os.getpid())) +
|
||||||
|
message("MSG_IDENTIFY_DONE") + message("MSG_COMMAND"))
|
||||||
|
lost = wait_for(lambda: re.search(r"lost client (\S+)", log()))[1]
|
||||||
|
wait_for(lambda: "free client %s (0 references)" % lost in log())
|
||||||
|
contents = log()
|
||||||
|
callback = "cmdq_next <client-%d>: [cfg_client_done/" % os.getpid()
|
||||||
|
assert contents.index("lost client " + lost) < \
|
||||||
|
contents.index(callback), contents
|
||||||
|
# Cleanup must happen while configuration is still blocked.
|
||||||
|
assert "cmdq_next <global>: [cfg_done/" not in contents, contents
|
||||||
|
finally:
|
||||||
|
go.touch()
|
||||||
|
server.terminate()
|
||||||
|
try:
|
||||||
|
server.wait(timeout=3)
|
||||||
|
except subprocess.TimeoutExpired:
|
||||||
|
server.kill()
|
||||||
|
server.wait()
|
||||||
|
PY
|
||||||
60
regress/cfg-load-once.sh
Normal file
60
regress/cfg-load-once.sh
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# the configuration is loaded once if the client that started it is lost, and
|
||||||
|
# the next client still waits for it to finish
|
||||||
|
|
||||||
|
PATH=/bin:/usr/bin
|
||||||
|
TERM=screen
|
||||||
|
|
||||||
|
[ -z "$TEST_TMUX" ] && TEST_TMUX=$(readlink -f ../tmux)
|
||||||
|
|
||||||
|
TMPDIR=$(mktemp -d) || exit 1
|
||||||
|
TMUX="$TEST_TMUX -S$TMPDIR/tmux.sock"
|
||||||
|
|
||||||
|
cleanup()
|
||||||
|
{
|
||||||
|
touch $TMPDIR/go
|
||||||
|
$TMUX kill-server 2>/dev/null
|
||||||
|
rm -rf "$TMPDIR"
|
||||||
|
}
|
||||||
|
trap cleanup 0 1 15
|
||||||
|
|
||||||
|
# Poll until a command succeeds.
|
||||||
|
wait_for()
|
||||||
|
{
|
||||||
|
i=0
|
||||||
|
while ! "$@"; do
|
||||||
|
[ $i -eq 100 ] && exit 1
|
||||||
|
i=$((i + 1))
|
||||||
|
sleep 0.1
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# The run-shell holds the configuration until the go file exists.
|
||||||
|
cat <<EOF >$TMPDIR/conf
|
||||||
|
set -ga @runs x
|
||||||
|
new-session -d -s keep
|
||||||
|
run-shell 'touch $TMPDIR/started; i=0; while [ ! -f $TMPDIR/go ] && [ \$i -lt 100 ]; do sleep 0.1; i=\$((i + 1)); done'
|
||||||
|
set -g @late 1
|
||||||
|
EOF
|
||||||
|
|
||||||
|
cd $TMPDIR || exit 1
|
||||||
|
$TMUX -v -f$TMPDIR/conf new-session -d -s first </dev/null &
|
||||||
|
pid=$!
|
||||||
|
wait_for test -f $TMPDIR/started
|
||||||
|
kill $pid
|
||||||
|
wait $pid
|
||||||
|
log=$(echo $TMPDIR/tmux-server-*.log)
|
||||||
|
wait_for grep -q 'lost client' $log
|
||||||
|
|
||||||
|
# The second client must identify before the configuration is released.
|
||||||
|
$TMUX new-session -d -s second \; display -p '#{@runs} #{@late}' \
|
||||||
|
</dev/null >$TMPDIR/out &
|
||||||
|
pid=$!
|
||||||
|
wait_for grep -q "name is client-$pid\$" $log
|
||||||
|
touch $TMPDIR/go
|
||||||
|
wait $pid || exit 1
|
||||||
|
|
||||||
|
[ "$(cat $TMPDIR/out)" = "x 1" ] || exit 1
|
||||||
|
|
||||||
|
exit 0
|
||||||
40
regress/swap-pane-zoom-error.sh
Normal file
40
regress/swap-pane-zoom-error.sh
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# swap-pane refusing a floating pane must leave the zoom alone
|
||||||
|
|
||||||
|
PATH=/bin:/usr/bin
|
||||||
|
TERM=screen
|
||||||
|
|
||||||
|
[ -z "$TEST_TMUX" ] && TEST_TMUX=$(readlink -f ../tmux)
|
||||||
|
TMUX="$TEST_TMUX -LtestA$$ -f/dev/null"
|
||||||
|
$TMUX kill-server 2>/dev/null
|
||||||
|
|
||||||
|
TMP=$(mktemp)
|
||||||
|
trap "rm -f $TMP; $TMUX kill-server 2>/dev/null" 0 1 15
|
||||||
|
|
||||||
|
$TMUX new -d
|
||||||
|
$TMUX splitw -d
|
||||||
|
$TMUX new-pane -d
|
||||||
|
|
||||||
|
echo $($TMUX lsp -F'#{pane_id}:#{pane_floating_flag}') >$TMP
|
||||||
|
(echo "%0:0 %1:0 %2:1"|cmp -s - $TMP) || exit 1
|
||||||
|
|
||||||
|
$TMUX resize-pane -Z -t %0
|
||||||
|
[ "$($TMUX display -p '#{window_zoomed_flag}')" = 1 ] || exit 1
|
||||||
|
|
||||||
|
$TMUX swap-pane -Z -D -t %2
|
||||||
|
[ "$?" = 0 ] && exit 1
|
||||||
|
[ "$($TMUX display -p '#{window_zoomed_flag}')" = 1 ] || exit 1
|
||||||
|
|
||||||
|
$TMUX swap-pane -Z -U -t %2
|
||||||
|
[ "$?" = 0 ] && exit 1
|
||||||
|
[ "$($TMUX display -p '#{window_zoomed_flag}')" = 1 ] || exit 1
|
||||||
|
|
||||||
|
# A swap that is allowed still happens.
|
||||||
|
$TMUX swap-pane -D -t %0 || exit 1
|
||||||
|
echo $($TMUX lsp -F'#{pane_id}') >$TMP
|
||||||
|
(echo "%1 %0 %2"|cmp -s - $TMP) || exit 1
|
||||||
|
|
||||||
|
$TMUX kill-server 2>/dev/null
|
||||||
|
|
||||||
|
exit 0
|
||||||
Reference in New Issue
Block a user