#!/bin/bash # Authors: Dalibor Pospíšil # Author: Dalibor Pospisil # # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # # 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 = ConditionalPhases # library-version = 2 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ __INTERNAL_ConditionalPhases_LIB_VERSION=2 __INTERNAL_ConditionalPhases_LIB_NAME='distribution/ConditionalPhases' : <<'=cut' =pod =head1 NAME BeakerLib library distribution/condpahses =head1 DESCRIPTION Implements conditional phases to eficiently select test phases to be execute using white and black lists. To use this functionality you need to import library distribution/ConditionalPhases and add following line to Makefile. @echo "RhtsRequires: library(distribution/ConditionalPhases)" >> $(METADATA) =head1 USAGE =head2 Conditional phases Each test phase can be conditionally skipped based on a bash regular expression given in CONDITIONAL_PHASES_BL and/or CONDITIONAL_PHASES_WL variables. =over =item CONDITIONAL_PHASES_BL It is a black list. If match phase name the respective phase should be skipped. =item CONDITIONAL_PHASES_WL It is a white list. If does B match phase name the respective phase should be skipped excluding phases contatning 'setup' or 'cleanup' in its name. Names 'setup' and 'cleanup' are matched case insenitively. =back Actual skipping has to be done in the test case itself by using return code of functions I, I, I, and I. Example: rlPhaseStartTest "phase name" && { ... rlPhaseEnd; } Evaluation of the phase relevancy works as follows: 1. If CONDITIONAL_PHASES_BL is non-empty and matches phase name => return 2. 2. If phase name contains word 'setup' or 'cleanup' or CONDITIONAL_PHASES_WL is empty => return 0. 3. If CONDITIONAL_PHASES_WL is non-empty and matches phase name => return 0 otherwise return 1. Normaly Setup and Cleanup phases are not skipped unless hey are B black-listed. To make the test work properly with conditional phases it is necessary to surround phase code with curly brackets and make it conditionally executed based on rlPhaseStart* function's exit code the same way as it is demostrated in the example above. To make the process easy you can use following command: sed 's/rlPhaseStart[^{]*$/& \&\& {/;s/rlPhaseEnd[^}]*$/&; }/' This code can be embedded in Makefile by modifying build target to following form: build: $(BUILT_FILES) grep -Eq 'rlPhase(Start[^{]*|End[^}]*)$' runtest.sh && sed -i 's/rlPhaseStart[^{]*$/& \&\& {/;s/rlPhaseEnd[^}]*$/&; }/' testrun.sh test -x runtest.sh || chmod a+x runtest.sh =cut #' echo -n "loading library $__INTERNAL_ConditionalPhases_LIB_NAME v$__INTERNAL_ConditionalPhases_LIB_VERSION... " # ConditionalPhasesLibraryLoaded ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{ ConditionalPhasesLibraryLoaded() { if [[ -n "$CONDITIONAL_PHASES_BL" || -n "$CONDITIONAL_PHASES_WL" ]]; then __INTERNAL_ConditionalPhases_eval() { # check phases black-list [[ -n "$CONDITIONAL_PHASES_BL" && "$1" =~ $CONDITIONAL_PHASES_BL ]] && { rlLogWarning "phase '$1' should be skipped as it is defined in \$CONDITIONAL_PHASES_BL='$CONDITIONAL_PHASES_BL'" return 2 } # always execute Setup, Cleanup and if no PHASES (white-list) specified [[ "$1" =~ $(echo "\<[Ss][Ee][Tt][Uu][Pp]\>") || "$1" =~ $(echo "\<[Cc][Ll][Ee][Aa][Nn][Uu][Pp]\>") ]] && { rlLogInfo "phase '$1' will be executed as 'setup' and 'cleanup' phases are allowed by default, these can be black-listed" return 0 } [[ -z "$CONDITIONAL_PHASES_WL" ]] && { rlLogInfo "phase '$1' will be executed as there is no rule for it" return 0 } [[ "$1" =~ $CONDITIONAL_PHASES_WL ]] && { rlLogInfo "phase '$1' will be executed as it is defined in \$CONDITIONAL_PHASES_WL='$CONDITIONAL_PHASES_WL'" return 0 } || { rlLogWarning "phase '$1' should be skipped as it is not defined in \$CONDITIONAL_PHASES_WL='$CONDITIONAL_PHASES_WL'" return 1 } } rlLogInfo "replacing rlPhaseStart by modified function with conditional phases implemented" :; rlPhaseStart() { if [ "x$1" = "xFAIL" -o "x$1" = "xWARN" ] ; then __INTERNAL_ConditionalPhases_eval "$2" && \ rljAddPhase "$1" "$2" return $? else rlLogError "rlPhaseStart: Unknown phase type: $1" return 1 fi } else rlLogInfo "Neither CONDITIONAL_PHASES_WL nor CONDITIONAL_PHASES_BL is defined, not applying modifications" fi }; # end of ConditionalPhasesLibraryLoaded }}} : <<'=cut' =pod =head1 AUTHORS =over =item * Dalibor Pospisil =back =cut echo 'done.'