2021-09-27 13:10:35 +00:00
|
|
|
#!/bin/sh
|
|
|
|
#
|
passt: Relicense to GPL 2.0, or any later version
In practical terms, passt doesn't benefit from the additional
protection offered by the AGPL over the GPL, because it's not
suitable to be executed over a computer network.
Further, restricting the distribution under the version 3 of the GPL
wouldn't provide any practical advantage either, as long as the passt
codebase is concerned, and might cause unnecessary compatibility
dilemmas.
Change licensing terms to the GNU General Public License Version 2,
or any later version, with written permission from all current and
past contributors, namely: myself, David Gibson, Laine Stump, Andrea
Bolognani, Paul Holzinger, Richard W.M. Jones, Chris Kuhn, Florian
Weimer, Giuseppe Scrivano, Stefan Hajnoczi, and Vasiliy Ulyanov.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2023-04-05 18:11:44 +00:00
|
|
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
2021-09-27 13:10:35 +00:00
|
|
|
#
|
|
|
|
# PASST - Plug A Simple Socket Transport
|
|
|
|
# for qemu/UNIX domain socket mode
|
|
|
|
#
|
|
|
|
# PASTA - Pack A Subtle Tap Abstraction
|
|
|
|
# for network namespace/tap device mode
|
|
|
|
#
|
|
|
|
# test/lib/term - Set up tmux sessions and panes, handle terminals and logs
|
|
|
|
#
|
|
|
|
# Copyright (c) 2021 Red Hat GmbH
|
|
|
|
# Author: Stefano Brivio <sbrivio@redhat.com>
|
|
|
|
|
|
|
|
STATUS_FILE=
|
|
|
|
STATUS_FILE_NTESTS=
|
|
|
|
STATUS_FILE_INDEX=0
|
|
|
|
STATUS_COLS=
|
|
|
|
STATUS_PASS=0
|
|
|
|
STATUS_FAIL=0
|
|
|
|
|
|
|
|
PR_RED='\033[1;31m'
|
|
|
|
PR_GREEN='\033[1;32m'
|
|
|
|
PR_YELLOW='\033[1;33m'
|
|
|
|
PR_BLUE='\033[1;34m'
|
|
|
|
PR_NC='\033[0m'
|
|
|
|
PR_DELAY_INIT=100 # ms
|
|
|
|
|
|
|
|
# info() - Highlight test log pane, print message to it and to log file
|
|
|
|
# $@: Message to print
|
|
|
|
info() {
|
|
|
|
tmux select-pane -t ${PANE_INFO}
|
2022-09-13 04:35:20 +00:00
|
|
|
echo "${@}" >> $STATEBASE/log_pipe
|
2021-09-27 13:10:35 +00:00
|
|
|
echo "${@}" >> "${LOGFILE}"
|
|
|
|
}
|
|
|
|
|
|
|
|
# info_n() - Highlight, print message to pane and to log file without newline
|
|
|
|
# $@: Message to print
|
|
|
|
info_n() {
|
|
|
|
tmux select-pane -t ${PANE_INFO}
|
2022-09-13 04:35:20 +00:00
|
|
|
printf "${@}" >> $STATEBASE/log_pipe
|
2021-09-27 13:10:35 +00:00
|
|
|
printf "${@}" >> "${LOGFILE}"
|
|
|
|
}
|
|
|
|
|
|
|
|
# info_nolog() - Highlight test log pane, print message to it
|
|
|
|
# $@: Message to print
|
|
|
|
info_nolog() {
|
|
|
|
tmux select-pane -t ${PANE_INFO}
|
2022-09-13 04:35:20 +00:00
|
|
|
echo "${@}" >> $STATEBASE/log_pipe
|
2021-09-27 13:10:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
# info_nolog() - Print message to log file
|
|
|
|
# $@: Message to print
|
|
|
|
log() {
|
|
|
|
echo "${@}" >> "${LOGFILE}"
|
|
|
|
}
|
|
|
|
|
|
|
|
# info_nolog_n() - Send message to pane without highlighting it, without newline
|
|
|
|
# $@: Message to print
|
|
|
|
info_nolog_n() {
|
|
|
|
tmux send-keys -l -t ${PANE_INFO} "${@}"
|
|
|
|
}
|
|
|
|
|
|
|
|
# info_sep() - Print given separator, horizontally filling test log pane
|
|
|
|
# $1: Separator character
|
|
|
|
info_sep() {
|
|
|
|
tmux send-keys -l -N ${STATUS_COLS} -t ${PANE_INFO} "${1}"
|
|
|
|
tmux send-keys -t ${PANE_INFO} C-m
|
|
|
|
}
|
|
|
|
|
|
|
|
# sleep_char() - Sleep for typed characted resembling interactive input
|
|
|
|
# $1: Character typed to pane
|
|
|
|
sleep_char() {
|
|
|
|
[ ${FAST} -eq 1 ] && return
|
|
|
|
|
|
|
|
if [ "${1}" = " " ]; then
|
|
|
|
PR_DELAY=$((PR_DELAY + 40))
|
|
|
|
elif [ -n "$(printf '%s' "${1}" | tr -d [:alnum:])" ]; then
|
|
|
|
PR_DELAY=$((PR_DELAY + 30))
|
|
|
|
elif [ ${PR_DELAY} -ge 30 ]; then
|
|
|
|
PR_DELAY=$((PR_DELAY / 3 * 2))
|
|
|
|
fi
|
|
|
|
|
|
|
|
sleep "$(printf 0.%03i ${PR_DELAY})" || sleep 1
|
|
|
|
}
|
|
|
|
|
|
|
|
# display_delay() - Simple delay, omitted if $FAST is set
|
|
|
|
display_delay() {
|
|
|
|
[ ${FAST} -eq 1 ] && return
|
|
|
|
|
|
|
|
sleep "${1}" || sleep 1
|
|
|
|
}
|
|
|
|
|
|
|
|
# switch_pane() - Highlight given pane and reset character delay
|
|
|
|
# $1: Pane number
|
|
|
|
switch_pane() {
|
|
|
|
tmux select-pane -t ${1}
|
|
|
|
PR_DELAY=${PR_DELAY_INIT}
|
|
|
|
display_delay "0.2"
|
|
|
|
}
|
|
|
|
|
|
|
|
# cmd_write() - Write a command to a pane, letter by letter, and execute it
|
|
|
|
# $1: Pane number
|
|
|
|
# $@: Command to issue
|
|
|
|
cmd_write() {
|
|
|
|
__pane_no=${1}
|
|
|
|
shift
|
|
|
|
|
|
|
|
switch_pane ${__pane_no}
|
|
|
|
|
|
|
|
__str="${@}"
|
|
|
|
while [ -n "${__str}" ]; do
|
|
|
|
__rem="${__str#?}"
|
|
|
|
__first="${__str%"$__rem"}"
|
|
|
|
if [ "${__first}" = ";" ]; then
|
|
|
|
tmux send-keys -t ${__pane_no} -l '\;'
|
|
|
|
else
|
|
|
|
tmux send-keys -t ${__pane_no} -l "${__first}"
|
|
|
|
fi
|
|
|
|
sleep_char "${__first}"
|
|
|
|
__str="${__rem}"
|
|
|
|
done
|
|
|
|
tmux send-keys -t ${__pane_no} "C-m"
|
|
|
|
}
|
|
|
|
|
|
|
|
# text_write() - Write text to info pane, letter by letter
|
|
|
|
# $1: Pane number
|
|
|
|
# $@: Command to issue
|
|
|
|
text_write() {
|
|
|
|
__str="${@}"
|
|
|
|
while [ -n "${__str}" ]; do
|
|
|
|
__rem="${__str#?}"
|
|
|
|
__first="${__str%"$__rem"}"
|
|
|
|
if [ "${__first}" = ";" ]; then
|
|
|
|
tmux send-keys -t ${PANE_INFO} -l '\;'
|
|
|
|
else
|
|
|
|
tmux send-keys -t ${PANE_INFO} -l "${__first}"
|
|
|
|
fi
|
|
|
|
sleep_char "${__first}"
|
|
|
|
__str="${__rem}"
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
|
|
|
# text_backspace() - Slow backspace motion for demo
|
|
|
|
# $1: Number of backspace characters
|
|
|
|
text_backspace() {
|
|
|
|
for __count in $(seq 0 ${1}); do
|
|
|
|
tmux send-keys -t ${PANE_INFO} Bspace
|
|
|
|
sleep 0.1
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
|
|
|
# em_write() - Write to log pane in red, for demo
|
|
|
|
# $@: Text
|
|
|
|
em_write() {
|
|
|
|
info_n "${PR_RED}${@}${PR_NC}"
|
|
|
|
}
|
|
|
|
|
|
|
|
# pane_kill() - Kill a single pane given its name
|
|
|
|
# $1: Pane name
|
|
|
|
pane_kill() {
|
|
|
|
__pane_number=$(eval echo \$PANE_${1})
|
|
|
|
tmux kill-pane -t ${__pane_number}
|
|
|
|
}
|
|
|
|
|
|
|
|
# pane_highlight() - Highlight a single pane given its name
|
|
|
|
# $1: Pane name
|
|
|
|
pane_highlight() {
|
|
|
|
__pane_number=$(eval echo \$PANE_${1})
|
|
|
|
switch_pane ${__pane_number}
|
|
|
|
sleep 3
|
|
|
|
}
|
|
|
|
|
2022-02-21 12:35:45 +00:00
|
|
|
# pane_resize() - Resize a pane given its name
|
|
|
|
# $1: Pane name
|
|
|
|
# $2: Direction: U, D, L, or R
|
|
|
|
# $3: Adjustment in lines or columns
|
|
|
|
pane_resize() {
|
|
|
|
__pane_number=$(eval echo \$PANE_${1})
|
|
|
|
tmux resize-pane -${2} -t ${__pane_number} ${3}
|
|
|
|
}
|
|
|
|
|
2021-09-27 13:10:35 +00:00
|
|
|
# pane_run() - Issue a command in given pane name
|
|
|
|
# $1: Pane name
|
|
|
|
# $@: Command to issue
|
|
|
|
pane_run() {
|
|
|
|
__pane_name="${1}"
|
|
|
|
shift
|
|
|
|
|
|
|
|
__pane_number=$(eval echo \$PANE_${__pane_name})
|
|
|
|
|
|
|
|
eval ${__pane_name}_LAST_CMD=\"\${@}\"
|
|
|
|
|
|
|
|
cmd_write ${__pane_number} "${@}"
|
|
|
|
}
|
|
|
|
|
|
|
|
# pane_wait() - Wait for command to be done in given pane name
|
|
|
|
# $1: Pane name
|
|
|
|
pane_wait() {
|
2022-01-26 06:40:35 +00:00
|
|
|
__lc="$(echo "${1}" | tr [A-Z] [a-z])"
|
2022-04-06 07:54:32 +00:00
|
|
|
sleep 0.1 || sleep 1
|
2022-01-26 06:40:35 +00:00
|
|
|
|
|
|
|
__done=0
|
|
|
|
while
|
|
|
|
__l="$(tail -1 ${LOGDIR}/pane_${__lc}.log | tr -d [:cntrl:])"
|
|
|
|
case ${__l} in
|
|
|
|
'$ ' | '# ' | '# # ' | *"$ " | *"# ") return ;;
|
|
|
|
*" #[m " | *" #[m [K" | *"]# ["*) return ;;
|
2022-02-21 12:35:45 +00:00
|
|
|
*' $ [6n' | *' # [6n' ) return ;;
|
2022-01-26 06:40:35 +00:00
|
|
|
esac
|
|
|
|
do sleep 0.1 || sleep 1; done
|
2021-09-27 13:10:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
# pane_parse() - Print last line, @EMPTY@ if command had no output
|
|
|
|
# $1: Pane name
|
|
|
|
pane_parse() {
|
|
|
|
__pane_lc="$(echo "${1}" | tr [A-Z] [a-z])"
|
|
|
|
|
2022-05-12 05:12:05 +00:00
|
|
|
__buf="$(tail -n2 ${LOGDIR}/pane_${__pane_lc}.log | head -n1 | sed 's/^[^\r]*\r\([^\r]\)/\1/' | tr -d '\r\n')"
|
2021-09-27 13:10:35 +00:00
|
|
|
|
|
|
|
[ "# $(eval printf '%s' \"\$${1}_LAST_CMD\")" != "${__buf}" ] && \
|
|
|
|
[ "$ $(eval printf '%s' \"\$${1}_LAST_CMD\")" != "${__buf}" ] &&
|
|
|
|
printf '%s' "${__buf}" || printf '@EMPTY@'
|
|
|
|
}
|
|
|
|
|
2022-05-12 03:36:21 +00:00
|
|
|
# pane_status() - Wait for command to complete and return its exit status
|
|
|
|
# $1: Pane name
|
|
|
|
pane_status() {
|
|
|
|
pane_wait "${1}"
|
2022-05-18 23:24:47 +00:00
|
|
|
|
|
|
|
[ ${DEMO} -eq 1 ] && return 0
|
|
|
|
|
2022-05-12 03:36:21 +00:00
|
|
|
__status="$(pane_parse "${1}")"
|
2022-09-14 09:52:14 +00:00
|
|
|
while ! [ "${__status}" -eq "${__status}" ] 2>/dev/null; do
|
2022-05-12 03:36:21 +00:00
|
|
|
sleep 1
|
|
|
|
pane_run "${1}" 'echo $?'
|
|
|
|
pane_wait "${1}"
|
|
|
|
__status="$(pane_parse "${1}")"
|
|
|
|
done
|
|
|
|
return ${__status}
|
|
|
|
}
|
|
|
|
|
2022-09-12 10:56:16 +00:00
|
|
|
# pane_watch_context() - Set up pane to watch commands executing in context(s)
|
|
|
|
# $1: Pane number
|
|
|
|
# $2: Description (for pane label)
|
|
|
|
# $@: Context name or names
|
|
|
|
pane_watch_contexts() {
|
|
|
|
__pane_number="${1}"
|
|
|
|
__desc="${2}"
|
|
|
|
shift 2
|
|
|
|
__name="${2}"
|
|
|
|
|
|
|
|
tmux select-pane -t ${__pane_number} -T "${__desc}"
|
|
|
|
__cmd="tail -f --retry"
|
|
|
|
for c; do
|
|
|
|
__cmd="${__cmd} ${LOGDIR}/context_${c}.log"
|
|
|
|
done
|
|
|
|
cmd_write ${__pane_number} "${__cmd}"
|
|
|
|
}
|
|
|
|
|
2022-09-12 10:56:17 +00:00
|
|
|
# pane_or_context_run() - Issue a command in given context or pane
|
|
|
|
# $1: Context or lower-case pane name
|
|
|
|
# $@: Command to issue
|
|
|
|
pane_or_context_run() {
|
|
|
|
__name="${1}"
|
|
|
|
shift
|
|
|
|
if context_exists "${__name}"; then
|
2022-09-12 10:56:22 +00:00
|
|
|
# Redirect stdin to stop ssh from eating the test instructions file we have on stdin
|
|
|
|
context_run "${__name}" "$@" >/dev/null 2>&1 < /dev/null
|
2022-09-12 10:56:17 +00:00
|
|
|
else
|
|
|
|
__uc="$(echo "${__name}" | tr [a-z] [A-Z])"
|
|
|
|
pane_run "${__uc}" "$@"
|
|
|
|
pane_status "${__uc}"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
# pane_or_context_run_bg() - Issue a background command in given context or pane
|
|
|
|
# $1: Context or lower-case pane name
|
|
|
|
# $@: Command to issue
|
|
|
|
pane_or_context_run_bg() {
|
|
|
|
__name="${1}"
|
|
|
|
shift
|
|
|
|
if context_exists "${__name}"; then
|
2022-09-12 10:56:22 +00:00
|
|
|
# Redirect stdin to stop ssh from eating the test instructions file we have on stdin
|
|
|
|
context_run_bg "${__name}" "$@" >/dev/null 2>&1 < /dev/null
|
2022-09-12 10:56:17 +00:00
|
|
|
else
|
|
|
|
__uc="$(echo "${__name}" | tr [a-z] [A-Z])"
|
|
|
|
pane_run "${__uc}" "$@"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
# pane_or_context_output() - Get output from a command in a context or pane
|
|
|
|
# $1: Context or lower-case pane name
|
|
|
|
# $@: Command to issue
|
|
|
|
pane_or_context_output() {
|
|
|
|
__name="${1}"
|
|
|
|
shift
|
|
|
|
if context_exists "${__name}"; then
|
2022-09-12 10:56:22 +00:00
|
|
|
# Redirect stdin to stop ssh from eating the test instructions file we have on stdin
|
|
|
|
__output=$(context_run "${__name}" "$@" 2>/dev/null </dev/null)
|
2022-09-12 10:56:17 +00:00
|
|
|
if [ -z "${__output}" ]; then
|
|
|
|
echo "@EMPTY@"
|
|
|
|
else
|
|
|
|
echo "${__output}"
|
|
|
|
fi
|
|
|
|
else
|
|
|
|
__uc="$(echo "${__name}" | tr [a-z] [A-Z])"
|
|
|
|
pane_run "${__uc}" "$@"
|
|
|
|
pane_wait "${__uc}"
|
|
|
|
pane_parse "${__uc}"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
# pane_or_context_wait() - Wait for a command to be done in a context or pane
|
|
|
|
# $1: Context or lower-case pane name
|
|
|
|
pane_or_context_wait() {
|
|
|
|
__name="${1}"
|
|
|
|
shift
|
|
|
|
if context_exists "${__name}"; then
|
|
|
|
context_wait "${__name}"
|
|
|
|
else
|
|
|
|
__uc="$(echo "${__name}" | tr [a-z] [A-Z])"
|
|
|
|
pane_wait "${__uc}"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2021-09-27 13:10:35 +00:00
|
|
|
# status_file_end() - Display and log messages when tests from one file are done
|
|
|
|
status_file_end() {
|
|
|
|
[ -z "${STATUS_FILE}" ] && return
|
|
|
|
|
|
|
|
info_sep "="
|
|
|
|
log
|
|
|
|
tmux select-pane -t ${PANE_INFO} -T ""
|
|
|
|
STATUS_FILE=
|
|
|
|
}
|
|
|
|
|
|
|
|
# status_file_start() - Display and log messages when tests from one file start
|
|
|
|
status_file_start() {
|
|
|
|
switch_pane ${PANE_INFO}
|
|
|
|
|
|
|
|
status_file_end
|
|
|
|
|
|
|
|
info_nolog "Starting tests in file: ${1}\n"
|
|
|
|
log "=== ${1}"
|
|
|
|
tmux select-pane -t ${PANE_INFO} -T "${1}"
|
|
|
|
|
|
|
|
STATUS_FILE="${1}"
|
|
|
|
STATUS_FILE_NTESTS="${2}"
|
|
|
|
STATUS_FILE_INDEX=0
|
|
|
|
}
|
|
|
|
|
|
|
|
# status_file_start() - Display and log messages when a single test starts
|
|
|
|
status_test_start() {
|
|
|
|
switch_pane ${PANE_INFO}
|
|
|
|
|
|
|
|
info_nolog "Starting test: ${1}"
|
|
|
|
log "> ${1}"
|
|
|
|
|
|
|
|
STATUS_FILE_INDEX=$((STATUS_FILE_INDEX + 1))
|
|
|
|
tmux select-pane -t ${PANE_INFO} -T "${STATUS_FILE} [${STATUS_FILE_INDEX}/${STATUS_FILE_NTESTS}] - ${1}"
|
|
|
|
}
|
|
|
|
|
|
|
|
# info_check() - Display and log messages for a single test condition check
|
|
|
|
info_check() {
|
|
|
|
switch_pane ${PANE_INFO}
|
|
|
|
|
2022-09-13 04:35:20 +00:00
|
|
|
printf "${PR_YELLOW}?${PR_NC} ${@}" >> $STATEBASE/log_pipe
|
2021-09-27 13:10:35 +00:00
|
|
|
printf "? ${@}" >> "${LOGFILE}"
|
|
|
|
}
|
|
|
|
|
|
|
|
# info_check_passed() - Display and log a new line when a check passes
|
|
|
|
info_check_passed() {
|
|
|
|
switch_pane ${PANE_INFO}
|
|
|
|
|
2022-09-13 04:35:20 +00:00
|
|
|
printf "\n" >> $STATEBASE/log_pipe
|
2021-09-27 13:10:35 +00:00
|
|
|
printf "\n" >> ${LOGFILE}
|
|
|
|
}
|
|
|
|
|
|
|
|
# info_check_failed() - Display and log messages when a check fails
|
|
|
|
info_check_failed() {
|
|
|
|
switch_pane ${PANE_INFO}
|
|
|
|
|
2022-09-13 04:35:20 +00:00
|
|
|
printf " ${PR_RED}!${PR_NC}\n" >> $STATEBASE/log_pipe
|
2021-09-27 13:10:35 +00:00
|
|
|
printf " < failed.\n" >> "${LOGFILE}"
|
|
|
|
}
|
|
|
|
|
|
|
|
# info_passed() - Display, log, and make status bar blink when a test passes
|
|
|
|
info_passed() {
|
|
|
|
switch_pane ${PANE_INFO}
|
|
|
|
|
|
|
|
info_nolog "...${PR_GREEN}passed${PR_NC}.\n"
|
|
|
|
log "...passed."
|
|
|
|
log
|
|
|
|
|
|
|
|
for i in `seq 1 3`; do
|
|
|
|
tmux set status-right-style 'bg=colour1 fg=colour2 bold'
|
|
|
|
sleep "0.1"
|
|
|
|
tmux set status-right-style 'bg=colour1 fg=colour233 bold'
|
|
|
|
sleep "0.1"
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
|
|
|
# info_failed() - Display, log, and make status bar blink when a test passes
|
|
|
|
info_failed() {
|
|
|
|
switch_pane ${PANE_INFO}
|
|
|
|
|
|
|
|
info_nolog "...${PR_RED}failed${PR_NC}.\n"
|
|
|
|
log "...failed."
|
|
|
|
log
|
|
|
|
|
|
|
|
for i in `seq 1 3`; do
|
|
|
|
tmux set status-right-style 'bg=colour1 fg=colour196 bold'
|
|
|
|
sleep "0.1"
|
|
|
|
tmux set status-right-style 'bg=colour1 fg=colour233 bold'
|
|
|
|
sleep "0.1"
|
|
|
|
done
|
|
|
|
|
|
|
|
pause_continue \
|
|
|
|
"Press any key to pause test session" \
|
|
|
|
"Resuming in " \
|
|
|
|
"Paused, press any key to continue" \
|
|
|
|
5
|
|
|
|
}
|
|
|
|
|
|
|
|
# info_skipped() - Display and log skipped test
|
|
|
|
info_skipped() {
|
|
|
|
switch_pane ${PANE_INFO}
|
|
|
|
|
|
|
|
info_nolog "...${PR_YELLOW}skipped${PR_NC}.\n"
|
|
|
|
log "...skipped."
|
|
|
|
log
|
|
|
|
}
|
|
|
|
|
|
|
|
# info_layout() - Display string for new test layout
|
|
|
|
info_layout() {
|
|
|
|
switch_pane ${PANE_INFO}
|
|
|
|
|
|
|
|
info_nolog "Test layout: ${PR_BLUE}${@}${PR_NC}.\n"
|
|
|
|
}
|
|
|
|
|
|
|
|
# status_test_ok() - Update counter of passed tests, log and display message
|
|
|
|
status_test_ok() {
|
|
|
|
STATUS_PASS=$((STATUS_PASS + 1))
|
|
|
|
tmux set status-right "PASS: ${STATUS_PASS} | FAIL: ${STATUS_FAIL} | #(TZ="UTC" date -Iseconds)"
|
|
|
|
info_passed
|
|
|
|
}
|
|
|
|
|
|
|
|
# status_test_fail() - Update counter of failed tests, log and display message
|
|
|
|
status_test_fail() {
|
|
|
|
STATUS_FAIL=$((STATUS_FAIL + 1))
|
|
|
|
tmux set status-right "PASS: ${STATUS_PASS} | FAIL: ${STATUS_FAIL} | #(TZ="UTC" date -Iseconds)"
|
|
|
|
info_failed
|
|
|
|
}
|
|
|
|
|
|
|
|
# status_test_fail() - Update counter of failed tests, log and display message
|
|
|
|
status_test_skip() {
|
|
|
|
info_skipped
|
|
|
|
}
|
|
|
|
|
|
|
|
# table_header() - Print table header to log pane
|
|
|
|
# $1: Header description
|
|
|
|
# $@: Column headers
|
|
|
|
table_header() {
|
|
|
|
perf_th ${@}
|
|
|
|
|
|
|
|
__ifs="${IFS}"
|
|
|
|
IFS=" "
|
|
|
|
|
|
|
|
__desc="${1}"
|
|
|
|
shift
|
|
|
|
|
|
|
|
__max_len=4
|
|
|
|
__count=0
|
|
|
|
for __h in ${@}; do
|
|
|
|
[ ${#__h} -gt ${__max_len} ] && __max_len=${#__h}
|
|
|
|
__count=$((__count + 1))
|
|
|
|
done
|
|
|
|
|
|
|
|
# > xxxx |<
|
|
|
|
__outer_len=$((__max_len + 3))
|
|
|
|
__width_fields=$((__outer_len * __count + 1))
|
|
|
|
|
|
|
|
TABLE_HEADER_LEFT=$((STATUS_COLS - __width_fields))
|
|
|
|
TABLE_CELL_SIZE=$((__max_len + 2))
|
|
|
|
TABLE_COLS=${__count}
|
|
|
|
|
|
|
|
__pad_left=$((TABLE_HEADER_LEFT - ${#__desc} - 2))
|
|
|
|
__buf="$(printf %-${__pad_left}s%s "" "${__desc}: ")"
|
|
|
|
for __h in ${@}; do
|
|
|
|
__pad_left=$(( (TABLE_CELL_SIZE - ${#__h} + 1) / 2))
|
|
|
|
__pad_right=$(( (TABLE_CELL_SIZE - ${#__h}) / 2))
|
|
|
|
__buf="${__buf}$(printf "|%-${__pad_left}s%s%-${__pad_right}s" "" ${__h} "")"
|
|
|
|
done
|
|
|
|
|
|
|
|
info_n "${__buf}|"
|
|
|
|
|
|
|
|
IFS="${__ifs}"
|
|
|
|
}
|
|
|
|
|
|
|
|
# table_row() - Print main table row to log pane
|
|
|
|
# $@: Column headers
|
|
|
|
table_row() {
|
|
|
|
perf_tr ${@}
|
|
|
|
|
|
|
|
__line="${@}"
|
|
|
|
__buf="$(printf %-${TABLE_HEADER_LEFT}s "")"
|
|
|
|
for __i in $(seq 1 ${TABLE_COLS}); do
|
|
|
|
__buf="${__buf}|"
|
|
|
|
for __j in $(seq 1 ${TABLE_CELL_SIZE}); do
|
|
|
|
__buf="${__buf}-"
|
|
|
|
done
|
|
|
|
done
|
|
|
|
info_n "\n${__buf}|\n"
|
|
|
|
|
|
|
|
__pad_left=$(( (TABLE_HEADER_LEFT - ${#__line} + 1) / 2))
|
|
|
|
__pad_right=$(( (TABLE_HEADER_LEFT - ${#__line}) / 2))
|
|
|
|
info_n "$(printf "%-${__pad_left}s%s%-${__pad_right}s|" "" "${__line}" "")"
|
|
|
|
}
|
|
|
|
|
|
|
|
# table_line() - Print simple line to log pane
|
|
|
|
# $@: Column headers
|
|
|
|
table_line() {
|
|
|
|
perf_tr ${@}
|
|
|
|
|
|
|
|
__line="${@}"
|
|
|
|
info_n "\n"
|
|
|
|
|
|
|
|
__pad_left=$(( (TABLE_HEADER_LEFT - ${#__line} + 1) / 2))
|
|
|
|
__pad_right=$(( (TABLE_HEADER_LEFT - ${#__line}) / 2))
|
|
|
|
info_n "$(printf "%-${__pad_left}s%s%-${__pad_right}s|" "" "${__line}" "")"
|
|
|
|
}
|
|
|
|
|
|
|
|
table_cell() {
|
|
|
|
__len="${1}"
|
|
|
|
shift
|
|
|
|
|
|
|
|
__content="${@}"
|
|
|
|
|
|
|
|
__pad_left=$((TABLE_CELL_SIZE - __len - 1))
|
|
|
|
info_n "$(printf "%-${__pad_left}s%s |" "" "${__content}")"
|
|
|
|
}
|
|
|
|
|
|
|
|
table_end() {
|
|
|
|
__buf="$(printf %-${TABLE_HEADER_LEFT}s "")"
|
|
|
|
for __i in $(seq 1 ${TABLE_COLS}); do
|
|
|
|
__buf="${__buf}'"
|
|
|
|
for __j in $(seq 1 ${TABLE_CELL_SIZE}); do
|
|
|
|
__buf="${__buf}-"
|
|
|
|
done
|
|
|
|
done
|
|
|
|
info_n "\n${__buf}'\n"
|
|
|
|
}
|
|
|
|
|
2022-10-31 09:41:40 +00:00
|
|
|
# table_value() - Print generic table value in its own cell
|
|
|
|
# $1: Value, can be '-' to indicate a filler
|
|
|
|
# $2: Scale, exponent of 10
|
|
|
|
# $3: Error value, scaled: if value is less than this, print in red
|
|
|
|
# $4: Warning value, scaled: if value is less than this, print in yellow
|
|
|
|
table_value() {
|
|
|
|
[ "${1}" = "-" ] && table_cell 1 "-" && perf_td 0 "" && return 0
|
|
|
|
if [ "${2}" != "0" ]; then
|
|
|
|
__v="$(echo "scale=1; x=( ${1} + 10^$((${2} - 1)) / 2 ) / 10^${2}; if ( x < 1 && x > 0 ) print 0; x" | bc -l)"
|
|
|
|
else
|
|
|
|
__v="${1}"
|
|
|
|
fi
|
|
|
|
perf_td 0 "${__v}"
|
|
|
|
|
|
|
|
__red="${3}"
|
|
|
|
__yellow="${4}"
|
|
|
|
if [ "$(echo "${__v} < ${__red}" | bc -l)" = "1" ]; then
|
|
|
|
table_cell ${#__v} "${PR_RED}${__v}${PR_NC}"
|
|
|
|
return 1
|
|
|
|
elif [ "$(echo "${__v} < ${__yellow}" | bc -l)" = "1" ]; then
|
|
|
|
table_cell ${#__v} "${PR_YELLOW}${__v}${PR_NC}"
|
|
|
|
return 1
|
|
|
|
else
|
|
|
|
table_cell ${#__v} "${PR_GREEN}${__v}${PR_NC}"
|
|
|
|
return 0
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2021-09-27 13:10:35 +00:00
|
|
|
table_value_throughput() {
|
|
|
|
[ "${1}" = "-" ] && table_cell 1 "-" && perf_td 0 "" && return 0
|
|
|
|
__v="$(echo "scale=1; x=( ${1} + 10^8 / 2 ) / 10^9; if ( x < 1 && x > 0 ) print 0; x" | bc -l)"
|
|
|
|
perf_td 31 "${__v}"
|
|
|
|
|
|
|
|
__red="${2}"
|
|
|
|
__yellow="${3}"
|
|
|
|
if [ "$(echo "${__v} < ${__red}" | bc -l)" = "1" ]; then
|
|
|
|
table_cell ${#__v} "${PR_RED}${__v}${PR_NC}"
|
|
|
|
return 1
|
|
|
|
elif [ "$(echo "${__v} < ${__yellow}" | bc -l)" = "1" ]; then
|
|
|
|
table_cell ${#__v} "${PR_YELLOW}${__v}${PR_NC}"
|
|
|
|
return 1
|
|
|
|
else
|
|
|
|
table_cell ${#__v} "${PR_GREEN}${__v}${PR_NC}"
|
|
|
|
return 0
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
table_value_latency() {
|
|
|
|
[ "${1}" = "-" ] && table_cell 1 "-" && perf_td 0 "" && return 0
|
|
|
|
|
|
|
|
__v="$(echo "scale=6; 1 / ${1} * 10^6" | bc -l)"
|
|
|
|
__v="${__v%.*}"
|
|
|
|
|
|
|
|
perf_td 11 "${__v}"
|
|
|
|
|
|
|
|
__red="${2}"
|
|
|
|
__yellow="${3}"
|
|
|
|
if [ "$(echo "${__v} > ${__red}" | bc -l)" = "1" ]; then
|
|
|
|
table_cell ${#__v} "${PR_RED}${__v}${PR_NC}"
|
|
|
|
return 1
|
|
|
|
elif [ "$(echo "${__v} > ${__yellow}" | bc -l)" = "1" ]; then
|
|
|
|
table_cell ${#__v} "${PR_YELLOW}${__v}${PR_NC}"
|
|
|
|
return 1
|
|
|
|
else
|
|
|
|
table_cell ${#__v} "${PR_GREEN}${__v}${PR_NC}"
|
|
|
|
return 0
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
# pause_continue() - Pause for a while, wait for keystroke, resume on second one
|
|
|
|
pause_continue() {
|
|
|
|
tmux select-pane -t ${PANE_INFO}
|
|
|
|
info_nolog "${1}"
|
|
|
|
info_nolog_n "${2}"
|
|
|
|
|
2022-09-13 04:35:24 +00:00
|
|
|
__pause_tmp="${STATEBASE}/pause.tmp"
|
|
|
|
echo > "${__pause_tmp}"
|
2021-09-27 13:10:35 +00:00
|
|
|
tmux pipe-pane -O -t ${PANE_INFO} "cat >> ${__pause_tmp}"
|
|
|
|
__pane_buf=
|
|
|
|
__wait=0
|
|
|
|
sleep 1
|
|
|
|
for __i in $(seq ${4} -1 0); do
|
|
|
|
if [ "$(tail -n1 ${__pause_tmp} | tr -d -c [:print:])" != "${__pane_buf}" ]; then
|
|
|
|
__wait=1
|
|
|
|
break
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ ${__i} -ne ${4} ]; then
|
|
|
|
tmux send-keys -t ${PANE_INFO} Bspace
|
|
|
|
tmux send-keys -t ${PANE_INFO} Bspace
|
|
|
|
__pane_buf="${__pane_buf} "
|
|
|
|
fi
|
|
|
|
info_nolog_n "${__i} "
|
|
|
|
__pane_buf="${__pane_buf}${__i} "
|
|
|
|
sleep 1
|
|
|
|
done
|
|
|
|
|
|
|
|
if [ ${__wait} -eq 1 ]; then
|
|
|
|
tmux send-keys -t ${PANE_INFO} Bspace
|
|
|
|
tmux send-keys -t ${PANE_INFO} Bspace
|
|
|
|
info_nolog ""
|
|
|
|
info_nolog "${3}"
|
|
|
|
__pane_buf="$(tail -n1 ${__pause_tmp})"
|
|
|
|
while true; do
|
|
|
|
[ "$(tail -n1 ${__pause_tmp})" != "${__pane_buf}" ] && break
|
|
|
|
sleep 1
|
|
|
|
done
|
|
|
|
fi
|
|
|
|
tmux pipe-pane -O -t ${PANE_INFO} ""
|
|
|
|
rm "${__pause_tmp}"
|
|
|
|
info_nolog ""
|
|
|
|
}
|
|
|
|
|
2022-02-22 17:29:45 +00:00
|
|
|
# run_term() - Start tmux session, running entry point, with recording if needed
|
2021-09-27 13:10:35 +00:00
|
|
|
run_term() {
|
2022-09-13 04:35:19 +00:00
|
|
|
TMUX="tmux new-session -s passt_test -eSTATEBASE=$STATEBASE -ePCAP=$PCAP -eDEBUG=$DEBUG"
|
2021-09-27 13:10:35 +00:00
|
|
|
|
|
|
|
if [ ${CI} -eq 1 ]; then
|
2022-02-22 17:29:45 +00:00
|
|
|
printf '\e[8;50;240t'
|
2022-09-13 04:35:28 +00:00
|
|
|
asciinema rec --overwrite "${STATEBASE}/ci.uncut" -c "$TMUX /bin/sh -c './ci from_term'"
|
|
|
|
video_postprocess "${STATEBASE}/ci.uncut"
|
2021-09-27 13:10:35 +00:00
|
|
|
elif [ ${DEMO} -eq 1 ]; then
|
2022-02-22 17:29:45 +00:00
|
|
|
printf '\e[8;40;130t'
|
2022-09-13 04:35:28 +00:00
|
|
|
asciinema rec --overwrite "${STATEBASE}/demo.uncut" -c "$TMUX /bin/sh -c './run_demo from_term'"
|
|
|
|
video_postprocess "${STATEBASE}/demo.uncut"
|
2021-09-27 13:10:35 +00:00
|
|
|
else
|
2022-10-06 15:19:12 +00:00
|
|
|
$TMUX /bin/sh -c "./run from_term ${*}"
|
2021-09-27 13:10:35 +00:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
# term() - Set up terminal window and panes for regular tests or CI
|
|
|
|
term() {
|
2022-05-12 03:27:21 +00:00
|
|
|
tmux set-option default-shell "/bin/sh"
|
|
|
|
|
2021-09-27 13:10:35 +00:00
|
|
|
tmux set status-interval 1
|
|
|
|
tmux rename-window ''
|
|
|
|
|
|
|
|
tmux set window-status-format '#W'
|
|
|
|
tmux set window-status-current-format '#W'
|
|
|
|
tmux set status-left ''
|
|
|
|
tmux set window-status-separator ''
|
|
|
|
|
|
|
|
tmux set window-status-style 'bg=colour1 fg=colour233 bold'
|
|
|
|
tmux set status-style 'bg=colour1 fg=colour233 bold'
|
|
|
|
tmux set status-right-style 'bg=colour1 fg=colour233 bold'
|
|
|
|
|
|
|
|
tmux new-window -n "Testing commit: ${COMMIT}"
|
|
|
|
|
|
|
|
tmux set window-status-format '#W'
|
|
|
|
tmux set window-status-current-format '#W'
|
|
|
|
tmux set status-left ''
|
|
|
|
tmux set window-status-separator ''
|
|
|
|
|
|
|
|
tmux set window-status-current-style 'bg=colour1 fg=colour233 bold'
|
|
|
|
tmux set status-right '#(TZ="UTC" date -Iseconds)'
|
|
|
|
tmux set status-right-length 50
|
|
|
|
tmux set status-right-style 'bg=colour1 fg=colour233 bold'
|
|
|
|
|
|
|
|
tmux set history-limit 500000
|
|
|
|
tmux select-pane -t 0 -T ''
|
|
|
|
tmux set pane-border-format '#T'
|
|
|
|
tmux set pane-border-style 'fg=colour2 bg=colour233'
|
|
|
|
tmux set pane-active-border-style 'fg=colour233 bg=colour4 bold'
|
|
|
|
tmux set pane-border-status bottom
|
|
|
|
}
|
|
|
|
|
|
|
|
# term_demo() - Set up terminal window and panes for demo
|
|
|
|
term_demo() {
|
2022-05-12 03:27:21 +00:00
|
|
|
tmux set-option default-shell "/bin/sh"
|
|
|
|
|
2021-09-27 13:10:35 +00:00
|
|
|
tmux set status-interval 1
|
|
|
|
tmux rename-window ''
|
|
|
|
|
|
|
|
tmux set window-status-format '#W'
|
|
|
|
tmux set window-status-current-format '#W'
|
|
|
|
tmux set status-left ''
|
|
|
|
tmux set window-status-separator ''
|
|
|
|
|
|
|
|
tmux set window-status-style 'bg=colour1 fg=colour15 bold'
|
|
|
|
tmux set status-right ''
|
|
|
|
tmux set status-style 'bg=colour1 fg=colour15 bold'
|
|
|
|
tmux set status-right-style 'bg=colour1 fg=colour15 bold'
|
|
|
|
|
|
|
|
tmux new-window -n "Demo at commit: ${COMMIT}"
|
|
|
|
|
|
|
|
tmux set window-status-format '#W'
|
|
|
|
tmux set window-status-current-format '#W'
|
|
|
|
tmux set status-left ''
|
|
|
|
tmux set window-status-separator ''
|
|
|
|
|
|
|
|
tmux select-pane -t 0 -T ''
|
|
|
|
tmux set pane-border-format '#T'
|
|
|
|
tmux set pane-border-style 'fg=colour2 bg=colour233'
|
|
|
|
tmux set pane-active-border-style 'fg=colour15 bg=colour4 bold'
|
|
|
|
tmux set pane-border-status bottom
|
|
|
|
}
|