sudo/tests/sudoers-options-sanity-test/distribution/Library/tcf/lib.sh

904 lines
22 KiB
Bash

#!/bin/bash
# try-check-final.sh
# Authors: Dalibor Pospíšil <dapospis@redhat.com>
# Author: Dalibor Pospisil <dapospis@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2012 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# library-prefix = tcf
# library-version = 14
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
__INTERNAL_tcf_LIB_VERSION=14
: <<'=cut'
=pod
=head1 NAME
BeakerLib library Try-Check-Final
=head1 DESCRIPTION
This file contains functions which gives user the ability to define blocks of
code where some of the blocks can be automatically skipped if some of preceeding
blocks failed.
ATTENTION
This plugin modifies some beakerlib functions! If you suspect that it breakes
some functionality set the environment variable TCF_NOHACK to nonempty value.
=head1 USAGE
To use this functionality you need to import library distribution/tcf and add
following line to Makefile.
@echo "RhtsRequires: library(distribution/tcf)" >> $(METADATA)
=head1 FUNCTIONS
=cut
echo -n "loading library try-check-final v$__INTERNAL_tcf_LIB_VERSION... "
let __INTERNAL_tcf_DEBUG_LEVEL_LOW=3
let __INTERNAL_tcf_DEBUG_LEVEL_MED=$__INTERNAL_tcf_DEBUG_LEVEL_LOW+1
let __INTERNAL_tcf_DEBUG_LEVEL_HIGH=$__INTERNAL_tcf_DEBUG_LEVEL_LOW+2
# global variables {{{
__INTERNAL_tcf_result=0
__INTERNAL_tcf_result_file="${BEAKERLIB_DIR:-"/var/tmp"}/tcf.result"
echo -n "$__INTERNAL_tcf_result" > "$__INTERNAL_tcf_result_file"
__INTERNAL_tcf_current_level_data=()
__INTERNAL_tcf_current_level_val=0
__INTERNAL_tcf_journal=()
#}}}
# __INTERNAL_tcf_colorize ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_tcf_colorize() {
local a
case $1 in
PASS)
a="${__INTERNAL_tcf_color_green}${1}${__INTERNAL_tcf_color_reset}"
;;
FAIL)
a="${__INTERNAL_tcf_color_red}${1}${__INTERNAL_tcf_color_reset}"
;;
SKIPPING|WARNING)
a="${__INTERNAL_tcf_color_yellow}${1}${__INTERNAL_tcf_color_reset}"
;;
BEGIN|INFO)
a="${__INTERNAL_tcf_color_blue}${1}${__INTERNAL_tcf_color_reset}"
;;
*)
a=$1
esac
echo -n "$a"
}; # end of __INTERNAL_tcf_colorize }}}
# __INTERNAL_tcf_colors_setup ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_tcf_colors_setup(){
T="$TERM"
[[ -t 1 ]] || T=""
[[ -t 2 ]] || T=""
[[ "$1" == "--force" ]] && T="xterm"
case $T in
xterm|screen)
__INTERNAL_tcf_color_black="\e[0;30m"
__INTERNAL_tcf_color_dark_gray="\e[1;30m"
__INTERNAL_tcf_color_blue="\e[0;34m"
__INTERNAL_tcf_color_light_blue="\e[1;34m"
__INTERNAL_tcf_color_green="\e[0;32m"
__INTERNAL_tcf_color_light_green="\e[1;32m"
__INTERNAL_tcf_color_cyan="\e[0;36m"
__INTERNAL_tcf_color_light_cyan="\e[1;36m"
__INTERNAL_tcf_color_red="\e[0;31m"
__INTERNAL_tcf_color_light_red="\e[1;31m"
__INTERNAL_tcf_color_purple="\e[0;35m"
__INTERNAL_tcf_color_light_purple="\e[1;35m"
__INTERNAL_tcf_color_brown="\e[0;33m"
__INTERNAL_tcf_color_yellow="\e[1;33m"
__INTERNAL_tcf_color_light_gray="\e[0;37m"
__INTERNAL_tcf_color_white="\e[1;37m"
__INTERNAL_tcf_color_reset="\e[00m"
;;
* )
__INTERNAL_tcf_color_black=""
__INTERNAL_tcf_color_dark_gray=""
__INTERNAL_tcf_color_blue=""
__INTERNAL_tcf_color_light_blue=""
__INTERNAL_tcf_color_green=""
__INTERNAL_tcf_color_light_green=""
__INTERNAL_tcf_color_cyan=""
__INTERNAL_tcf_color_light_cyan=""
__INTERNAL_tcf_color_red=""
__INTERNAL_tcf_color_light_red=""
__INTERNAL_tcf_color_purple=""
__INTERNAL_tcf_color_light_purple=""
__INTERNAL_tcf_color_brown=""
__INTERNAL_tcf_color_yellow=""
__INTERNAL_tcf_color_light_gray=""
__INTERNAL_tcf_color_white=""
__INTERNAL_tcf_color_reset=""
;;
esac
}; # end of __INTERNAL_tcf_colors_setup
__INTERNAL_tcf_colors_setup; # }}}
# __INTERNAL_tcf_copy_function ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_tcf_copy_function() {
declare -F $1 > /dev/null || return 1
eval "$(echo -n "${2}() "; declare -f ${1} | tail -n +2)"
}; # end of __INTERNAL_tcf_copy_function }}}
# __INTERNAL_tcf_addE2R ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_tcf_addE2R() {
__INTERNAL_tcf_copy_function $1 TCF_orig_$1
eval "${1}() { TCF_orig_${1} \"\$@\"; tcfE2R; }"
}; # end of __INTERNAL_tcf_addE2R }}}
# __INTERNAL_tcf_insertE2R ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_tcf_insertE2R() {
__INTERNAL_tcf_copy_function $1 TCF_orig_$1
eval "$(echo -n "${1}() "; declare -f ${1} | tail -n +2 | sed -e 's/\(.*__INTERNAL_ConditionalAssert.*\)/\1\ntcfE2R;/')"
}; # end of __INTERNAL_tcf_insertE2R }}}
# __INTERNAL_tcf_get_current_level ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_tcf_get_current_level() {
local l=$__INTERNAL_tcf_current_level_val
if [[ $1 ]]; then
l=$(($l+$1))
fi
local i
for i in $(seq 1 $(($l*2)) ); do echo -n " "; done
return $l
}; # end of __INTERNAL_tcf_get_current_level }}}
# __INTERNAL_tcf_incr_current_level ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_tcf_incr_current_level() {
let __INTERNAL_tcf_current_level_val++
__INTERNAL_Log_prefix=$(__INTERNAL_tcf_get_current_level)
}; # end of __INTERNAL_tcf_incr_current_level }}}
# __INTERNAL_tcf_decr_current_level ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_tcf_decr_current_level() {
let __INTERNAL_tcf_current_level_val--
__INTERNAL_Log_prefix=$(__INTERNAL_tcf_get_current_level)
}; # end of __INTERNAL_tcf_decr_current_level }}}
# __INTERNAL_tcf_do_hack ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_tcf_do_hack() {
LogDebug "TCF_NOHACK='$TCF_NOHACK'"
if [[ -z "$TCF_NOHACK" ]]; then
tcfChk "Apply TCF beakerlib hacks" && {
rlLog " injecting tcf hacks into the beakerlib functions"
echo -n "patching rlLog"
local rlL=$(declare -f rlLog | sed -e 's|\] ::|\0${__INTERNAL_Log_prefix}|;s|$3 $1"|${3:+"$3 "}$1"|')
eval "$rlL"
echo -n ", rljAddTest"
__INTERNAL_tcf_copy_function rljAddTest __INTERNAL_tcf_orig_rljAddTest
true; rljAddTest() {
local a="${__INTERNAL_Log_prefix}$1"; shift
[[ "$1" != "FAIL" ]]; tcfE2R
__INTERNAL_tcf_journal=("${__INTERNAL_tcf_journal[@]}" "$1" "$a")
__INTERNAL_tcf_orig_rljAddTest "$a" "$@"
}
echo -n ", rljAddMessage"
__INTERNAL_tcf_copy_function rljAddMessage __INTERNAL_tcf_orig_rljAddMessage
true; rljAddMessage() {
local a="${__INTERNAL_Log_prefix}$1"; shift
__INTERNAL_tcf_journal=("${__INTERNAL_tcf_journal[@]}" "$1" "$a")
__INTERNAL_tcf_orig_rljAddMessage "$a" "$@"
}
echo -n ", __INTERNAL_LogAndJournalFail"
__INTERNAL_tcf_copy_function __INTERNAL_LogAndJournalFail __INTERNAL_tcf_orig___INTERNAL_LogAndJournalFail
true; __INTERNAL_LogAndJournalFail() {
tcfNOK
__INTERNAL_tcf_orig___INTERNAL_LogAndJournalFail "$@"
}
echo "."
tcfFin --no-assert --ignore; }
else
Log "skip hacking beakerlib functions"
fi
}; # end of __INTERNAL_tcf_do_hack }}}
# __INTERNAL_tcf_kill_old_plugin ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_tcf_kill_old_plugin() {
tcfChk "Get rid of the old TCF implementation. removing" && {
local comma='' i
for i in Try Chk Fin E2R RES OK NOK NEG TCFcheckFinal TCFreport; do
echo -n "${comma}rl$i"
unset -f rl$i
comma=', '
done
echo '.'
tcfFin --no-assert; }
}; # end of __INTERNAL_tcf_kill_old_plugin }}}
: <<'=cut'
=pod
=head2 Block functions
=cut
# __INTERNAL_tcf_parse_params ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_tcf_parse_params() {
local GETOPT=$(getopt -q -o if: -l ignore,no-assert,fail-tag: -- "$@")
eval set -- "$GETOPT"
echo "local ignore noass title fail_tag"
echo "[ -z \"\$ignore\" ] && ignore=0"
echo "[ -z \"\$noass\" ] && noass=0"
echo "[ -z \"\$fail_tag\" ] && fail_tag='FAIL'"
while [[ -n "$@" ]]; do
case $1 in
--)
shift; break
;;
--ignore|-i)
echo "ignore=1"
echo "noass=1"
;;
--no-assert|-n)
echo "noass=1"
;;
--fail-tag|-f)
shift
echo "fail_tag='$1'"
;;
*)
echo "unknown option $1"
return 1
;;
esac
shift;
done
[[ -n "$1" ]] && echo "title=\"${1}\""
echo "eval set -- \"$(echo "$GETOPT" | sed -e 's/.*-- //')\""
}; # end of __INTERNAL_tcf_parse_params }}}
# tcfTry ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
: <<'=cut'
=pod
=head3 tcfTry
Starting function of block which will be skipped if an error has been detected
by tcfFin function occurent before.
tcfTry ["title"] [-i|--ignore] [--no-assert] [--fail-tag TAG] && {
<some code>
tcfFin; }
If title is omitted than noting is printed out so no error will be reported (no
Assert is executed) thus at least the very top level tcfTry should have title.
tcfTry and tcfChk blocks are stackable so you can organize them into a hierarchy
structure.
Note that tcfFin has to be used otherwise the overall result will not be
accurate.
=over
=item title
Text which will be displayed and logged at the beginning and the end (in tcfFin
function) of the block.
=item -i, --ignore
Do not propagate the actual result to the higher level result.
=item -n, --no-assert
Do not log error into the journal.
=item -f, --fail-tag TAG
If the result of the block is FAIL, use TAG instead ie. INFO or WARNING.
=back
Returns 1 if and error occured before, otherwise returns 0.
=cut
tcfTry() {
LogMoreLow -f "begin '$*'"
local vars=$(__INTERNAL_tcf_parse_params "$@") || { Log "$vars" FAIL; return 1; }
LogMoreMed -f "vars:\n$vars"
LogMoreLow -f "evaluating options start"
eval "$vars"
LogMoreLow -f "evaluating options end"
local incr=
local pp="SKIPPING"
tcfRES; # to set __INTERNAL_tcf_result
LogMoreLow -f "result was $__INTERNAL_tcf_result"
if [[ $__INTERNAL_tcf_result -eq 0 ]]; then
__INTERNAL_tcf_current_level_data=("$__INTERNAL_tcf_result" "$vars" "${__INTERNAL_tcf_current_level_data[@]}")
pp="BEGIN"
incr=1
fi
if [[ -n "$title" ]]; then
Log "$title" "$pp"
[[ -n "$incr" ]] && {
LogMoreLow -f "increment indentation level"
__INTERNAL_tcf_incr_current_level
}
fi
LogMoreLow -f "end"
return $__INTERNAL_tcf_result
}; # end of tcfTry }}}
# tcfChk ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
: <<'=cut'
=pod
=head3 tcfChk
Starting function of block which will be always executed.
tcfChk ["title"] [-i|--ignore] [--no-assert] [--fail-tag TAG] && {
<some code>
tcfFin; }
If title is omitted than noting is printed out so no error will be reported (no
Assert is executed) thus at least the very top level tcfChk should have title.
tcfTry and tcfChk blocks are stackable so you can organize them into a hierarchy
structure.
Note that tcfFin has to be used otherwise the overall result will not be
accurate.
For details about arguments see tcfTry.
Returns 0.
=cut
tcfChk() {
LogMoreLow -f "begin '$*'"
tcfRES; # to set __INTERNAL_tcf_result
local res=$__INTERNAL_tcf_result
tcfRES 0
tcfTry "$@"
__INTERNAL_tcf_current_level_data[0]=$res
LogMoreLow -f "end"
return $__INTERNAL_tcf_result
}; # end of tcfChk }}}
# tcfFin ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
: <<'=cut'
=pod
=head3 tcfFin
Ending function of block. It does some evaluation of previous local and global
results and puts it into the global result.
tcfTry ["title"] && {
<some code>
tcfFin [-i|--ignore] [--no-assert] [--fail-tag TAG]; }
Local result is actualy exit code of the last command int the body.
Global result is an internal varibale hodning previous local results.
Respectively last error or 0.
For details about arguments see tcfTry.
Returns local result of the preceeding block.
=cut
tcfFin() {
local RES=$?
LogMoreLow -f "begin '$*'"
LogMoreMed -f "previous exit code was '$RES'"
local vars=$(__INTERNAL_tcf_parse_params "$@") || { Log "$vars" FAIL; return 1; }
LogMoreMed -f "vars:\n$vars"
LogMoreLow -f "evaluating options start"
eval "$vars"
LogMoreLow -f "evaluating options end"
tcfRES; # to set __INTERNAL_tcf_result
[[ $RES -ne 0 ]] && tcfRES $RES
RES=$__INTERNAL_tcf_result
LogMoreMed -f "overall result is '$RES'"
LogMoreMed -f "data:\n${__INTERNAL_tcf_current_level_data[1]}"
LogMoreLow -f "evaluating data start"
eval "${__INTERNAL_tcf_current_level_data[1]}"
LogMoreLow -f "evaluating data end"
if [[ -n "$title" ]]; then
__INTERNAL_tcf_decr_current_level
if [[ $ignore -eq 1 ]]; then
RES=0
[[ $__INTERNAL_tcf_result -ne 0 ]] && title="$title - ignored"
fi
if [[ $noass -eq 0 ]]; then
tcfAssert0 "$title" $__INTERNAL_tcf_result "$fail_tag"
else
if [[ $__INTERNAL_tcf_result -eq 0 ]]; then
local pp="PASS"
LogInfo "$title - $pp"
else
local pp="${fail_tag:-FAIL}"
LogWarn "$title - $pp"
fi
fi
fi
if [[ $__INTERNAL_tcf_result -eq 0 || $ignore -eq 1 ]]; then
tcfRES ${__INTERNAL_tcf_current_level_data[0]}
fi
local i
for i in 0 1; do unset __INTERNAL_tcf_current_level_data[$i]; done
__INTERNAL_tcf_current_level_data=("${__INTERNAL_tcf_current_level_data[@]}")
LogMoreLow -f "end"
return $RES
}; # end of tcfFin }}}
: <<'=cut'
=pod
=head2 Functions for manipulation with the results
=cut
# tcfRES ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
: <<'=cut'
=pod
=head3 tcfRES
Sets and return the global result.
tcfRES [-p|--print] [number]
=over
=item -p --print
Also print the result value.
=item number
If present the global result is set to this value.
=back
Returns global result.
=cut
tcfRES() {
local p=0
while [[ -n "$1" ]]; do
case $1 in
--print|-p)
p=1
;;
*)
break
;;
esac
shift
done
if [[ -n "$1" ]]; then
__INTERNAL_tcf_result=$1
echo -n "$__INTERNAL_tcf_result" > "$__INTERNAL_tcf_result_file"
else
__INTERNAL_tcf_result="$(cat "$__INTERNAL_tcf_result_file")"
fi
[[ $p -eq 1 ]] && echo $__INTERNAL_tcf_result
return $__INTERNAL_tcf_result
}; # end of tcfRES }}}
# tcfOK ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
: <<'=cut'
=pod
=head3 tcfOK
Sets the global result to 0.
tcfOK
Returns global result.
=cut
tcfOK() {
tcfRES 0
}; # end of tcfOK }}}
# tcfNOK ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
: <<'=cut'
=pod
=head3 tcfNOK
Sets the global result to 1 or given number.
tcfNOK [number]
=over
=item number
If present the global result is set to this value.
=back
Returns global result.
=cut
tcfNOK() {
if [[ -n "$1" ]]; then
[[ $1 -eq 0 ]] && echo "You have requested result '0'. You should use tcfOK instead."
tcfRES $1
else
tcfRES 1
fi
}; # end of tcfNOK }}}
# tcfE2R ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
: <<'=cut'
=pod
=head3 tcfE2R
Converts exit code of previous command to local result if the exit code is not 0
(zero).
<some command>
tcfE2R [number]
=over
=item number
If present use it instead of exit code.
=back
Returns original exit code or given number.
=cut
tcfE2R() {
local res=$?
[[ -n "$1" ]] && res=$1
[[ $res -ne 0 ]] && tcfRES $res
return $res
}; # end of tcfE2R }}}
: <<'=cut'
=pod
=head2 Functions for manipulation with the exit codes
=cut
# tcfNEG ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
: <<'=cut'
=pod
=head3 tcfNEG
Negates exit code of previous command.
<some command>
tcfNEG
Returns 1 if original exit code was 0, otherwise returns 0.
=cut
tcfNEG() {
[[ $? -eq 0 ]] && return 1 || return 0
}; # end of tcfNEG }}}
# tcfRun ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
: <<'=cut'
=pod
=head3 tcfRun
Simmilar to rlRun but it also annouces the beginnign of the command.
tcfRun [--fail-tag|-f TAG] command [exp_result [title]]
Moreover if 'command not found' appears on STDERR it should produce WARNING.
=over
=item command
Command to execute.
=item exp_result
Specification of expect resutl.
It can be a list of values or intervals or * for any result. Also negation (!) can be used.
Example:
<=2,7,10-12,>252,!254 means following values 0,1,2,7,10,11,12,253,255
=item title
Text which will be displayed and logged at the beginning and the end of command execution.
=item --fail-tag | -f
If the command fails use TAG instead of FAIL.
=back
Returns exit code of the executed command.
=cut
tcfRun() {
LogMore_ -f "begin $*"
optsBegin
optsAdd 'fail-tag|f' --mandatory
optsAdd 'timeout' --optional 'timeout="${1:-10}"'
optsAdd 'kill-timeout|kt' --mandatory --default 5
optsAdd 'signal' --mandatory --default TERM
optsAdd 'check-code' --mandatory --default 'kill -0 $cmdpid >&/dev/null'
optsAdd 'kill-code' --mandatory --default '/bin/kill -$signal -- $cmdpid'
optsAdd 'allow-skip|as' --flag
optsAdd 'no-assert|n' --flag
optsDone; eval "${optsCode}"
LogMore_ -f "after opts $*"
[[ -z "$allowskip" ]] && tcfChk
local orig_expecode="${2:-0}"
local expecode="$orig_expecode"
[[ "$expecode" == "*" ]] && expecode="0-255"
local command="$1"
local comment="Running command '$command'"
[[ -n "$3" ]] && comment="$3"
[[ -n "$expecode" ]] && {
expecode=$(echo "$expecode" | tr ',-' '\n ' | sed -e 's/^!=/!/;s/^=//;s/^<=\(.\+\)$/0 \1/;s/^>=\(.\+\)$/\1 255/;s/^<\(.\+\)$/0 \$(( \1 - 1 ))/;s/^>\(.\+\)$/\$(( \1 + 1 )) 255/' | while read line; do [[ "$line" =~ ^[^\ ]+$ ]] && echo "$line" || eval seq $line; done; )
tcfE2R
LogMoreLow -f "orig_expecode='$orig_expecode'"
LogMoreLow -f "expecode='$expecode'"
}
tcfTry ${noassert:+--no-assert} "$comment" && {
local errout=$(mktemp)
LogMoreLow -f "executing '$command'"
if [[ "$optsPresent" =~ $(echo "\<timeout\>") ]]; then
LogDebug -f "using watchdog feature"
local ec="$(mktemp)"
eval "$command; echo $? > $ec 2> >(tee $errout)" &
local cmdpid=$!
local time_start=$(date +%s)
local timeout_t=$(( $time_start + $timeout ))
while true; do
if ! eval "$checkcode"; then
Log "command finished in $(($(date +%s) - $time_start )) seconds"
local res="$(cat $ec)"
break
elif [[ $(date +%s) -ge $timeout_t ]]; then
echo
Log "command is still running, sending $signal signal"
eval "$killcode"
tcfNOK 255
echo 255 > $ec
let timeout_t+=killtimeout
signal=KILL
fi
sleep 0.1
done
rm -f $ec
else
eval "$command" 2> >(tee $errout)
local res=$?
fi
LogMoreLow -f "got '$res'"
local resmatch=$(echo "$expecode" | grep "^\!\?${res}$")
LogMoreLow -f "resmatch='$resmatch'"
[[ -n "$resmatch" && ! "$resmatch" =~ '!' ]]
if tcfE2R; then
! grep -iq "command not found" $errout || { failtag='WARNING'; tcfNOK; }
else
Log "Expected result was '$orig_expecode', got '$res'!"
fi
tcfFin ${failtag:+--fail-tag "$failtag"}; }
rm -f $errout
[[ -z "$allowskip" ]] && tcfFin
LogMore_ -f "end $*"
return $res
}; # end of tcfRun }}}
: <<'=cut'
=pod
=head2 Functions for logging
=cut
# tcfAssert0 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
tcfAssert0() {
LogMoreLow -f "begin '$*'"
local RES="${3:-FAIL}"
[[ $2 -eq 0 ]] && RES='PASS'
Log "$1" $RES
LogMoreLow -f "end"
}; # end of tcfAssert0 }}}
# tcfCheckFinal ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
: <<'=cut'
=pod
=head3 tcfCheckFinal
Check that all tcfTry / tcfChk functions have been close by tcfFin.
tcfCheckFinal
=cut
tcfCheckFinal() {
tcfAssert0 "Check that TCF block cache is empty" ${#__INTERNAL_tcf_current_level_data[@]}
tcfAssert0 "Check that TCF current level is 0" $__INTERNAL_tcf_current_level_val
}; # end of tcfCheckFinal }}}
echo "done."
: <<'=cut'
=pod
=head2 Self check functions
=cut
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# tcfSelfCheck {{{
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
: <<'=cut'
=pod
=head3 tcfSelfCheck
Does some basic functionality tests.
tcfSelfCheck
The function is called also by the following command:
./lib.sh selfcheck
=cut
tcfSelfCheck() {
tcfChk "check 1" &&{
tcfTry "try 1.1 - true" &&{
true
tcfFin;}
tcfTry "try 1.2 - false" &&{
false
tcfFin;}
tcfTry "try 1.3 - true" &&{
true
tcfFin;}
tcfFin;}
tcfChk "check 2" &&{
tcfTry "try 2.1 - true" &&{
true
tcfFin;}
tcfTry "try 2.2 - true - ignore" &&{
true
tcfFin -i;}
tcfTry "try 2.3 - true" &&{
true
tcfFin;}
tcfFin;}
tcfChk "check 3" &&{
tcfTry "try 3.1 - true" &&{
true
tcfFin;}
tcfTry "try 3.2 - false - ignore" &&{
false
tcfFin -i;}
tcfTry "try 3.3 - true" &&{
true
tcfFin;}
tcfFin;}
tcfCheckFinal
tcfAssert0 "Overall result" $(tcfRES -p)
LogReport
}
if [[ "$1" == "selfcheck" ]]; then
tcfSelfCheck
fi; # end of tcfSelfCheck }}}
# tcfLibraryLoaded ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
tcfLibraryLoaded() {
rlImport distribution/Log
declare -F rlDie > /dev/null && {
#rlJournalStart
#rlPhaseStartSetup "TCF"
echo -e "\nrunning inside the beakerlib - using rlAssert0"
true; tcfAssert0() {
local text="$1"
[[ "$3" != "FAIL" && "$3" != "PASS" ]] && text="$text - $3"
__INTERNAL_ConditionalAssert "$text" "$2"
}
__INTERNAL_tcf_do_hack
#rlPhaseEnd
#rlJournalEnd
};
if declare -F rlE2R >& /dev/null; then
__INTERNAL_tcf_kill_old_plugin
fi
true
}; # end of tcfLibraryLoaded }}}
: <<'=cut'
=pod
=head1 AUTHORS
=over
=item *
Dalibor Pospisil <dapospis@redhat.com>
=back
=cut