diff options
Diffstat (limited to 'tests/include')
-rwxr-xr-x | tests/include/ec.sh | 197 | ||||
-rwxr-xr-x | tests/include/include.sh | 124 | ||||
-rw-r--r-- | tests/include/mpath.sh | 137 | ||||
-rw-r--r-- | tests/include/scsi_debug.sh | 36 | ||||
-rwxr-xr-x | tests/include/tc.sh | 272 | ||||
-rwxr-xr-x | tests/include/utils.sh | 195 |
6 files changed, 961 insertions, 0 deletions
diff --git a/tests/include/ec.sh b/tests/include/ec.sh new file mode 100755 index 0000000..12f7fe2 --- /dev/null +++ b/tests/include/ec.sh @@ -0,0 +1,197 @@ +#!/bin/bash + +# Copyright (c) 2016 Red Hat, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# 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, see <http://www.gnu.org/licenses/>. + +# Author: Lin Li <lilin@redhat.com> + +path=$(pwd) +source ../include/utils.sh || exit 1 +source ../include/include.sh || exit 1 +source ../include/tc.sh || exit 1 +source ../include/mpath.sh || exit 1 +source ../include/scsi_debug.sh || exit 1 + +#this script usually is only used by current case +#private global variables, lower case and no under line is okay +mpath= + +function _isconfig (){ + [ -z $mpath ] && return 2 + Cmd "multipath -ll $mpath" +} + +function _init (){ +#will improve this function +#should return the multipathed disk created by scsi_debug, don't consider the other mutipathed disks +#olnly append the black list exception to /etc/multipath.conf not override + Setup_Multipath || Fail "failed to create multipathed device via scsi_debug" + mpath=$RETURN_STR + + _isconfig +} + +function _destroy (){ + sleep 10 + Cmd "multipath -F" + sleep 5 + Cmd "modprobe -r scsi_debug" +} + +# ---------------------------------------------------------# +# Print_kernel_info() +# Usage: +# print the detail running kernel information. +# Parameter: # NULL +# Returns: +# Return code: +# 0 on success +# 1 if something went wrong. +# ---------------------------------------------------------# +function Print_kernel_info (){ + Cmd "lsb_release -a" + Cmd "uname -a" +} + + + +# ---------------------------------------------------------# +# Setup_Multipath () +# Usage: +# return mpath_name if we have multipath devices, if not, +# we use scsi_debug to create a multipath device. +# Parameter: +# NULL +# Returns: +# Return code: +# 0 on success +# 1 if something went wrong. +# Return string: +# RETURN_STR # $mpath_name_list, like "mpath0 mpath1" +# ---------------------------------------------------------# + +function Setup_Multipath (){ + RETURN_STR='' + local mpath_name_list=$(dmsetup table \ + | perl -ne 'print "$1 " if /(mpath[a-z0-9]+):[0-9 ]+multipath.*/') + if [ "CHK${mpath_name_list}" != "CHK" ];then + mpath_name_list="$(echo ${mpath_name_list} | sed -e 's/ $//')" + echo "INFO: Found multipath devices: ${mpath_name_list}" +#RHEL 5 will disable some wwn mpath if we install OS with ondisk=mapper/mpath0 +# option, so we need to enable them all + if [ "CHK$(uname -r | egrep "2\.6\.18.*el5")" != "CHK" ];then + cat << AA > /etc/multipath.conf +defaults { + user_friendly_names yes +} +blacklist { + device { + vendor .* + product .* + } +} +blacklist_exceptions { + device { + vendor Linux + product scsi_debug + } + device { + vendor IQSTOR + product .* + } + device { + vendor NETAPP + product .* + } + device { + vendor HITACHI + product .* + } +} +AA + service multipathd start + sleep 5s #multipathd return premature + multipath -r + multipathd -k'reconfigure' + mpath_name_list=$(dmsetup table \ + | perl -ne 'print "$1 " if /(mpath[a-z0-9]+):[0-9 ]+multipath.*/') + fi + if [ "CHK${mpath_name_list}" == "CHK" ];then + echo -n "FATAL: still no mulipath devices setup," + echo " check code in Setup_Multipath()" + RETURN_STR='' + return 1 + fi + RETURN_STR="${mpath_name_list}" + return 0 + fi +#setup scsi_debug + echo "INFO: Loading scsi_debug module for simulation of mpath" + local dev_size=100 + if [ "CHK$(uname -m)" == "CHKi386" ] \ + || [ "CHK$(uname -m)" == "CHKi686" ]; then +#i386 platform cannot allocate 100 MiB in kernel space + dev_size=10 + fi + modprobe scsi_debug dev_size_mb=${dev_size} \ + num_tgts=1 vpd_use_hostno=0 \ + add_host=4 delay=20 \ + max_luns=2 no_lun_0=1 2>&1 1>/dev/null + + echo "INFO: Waiting for udev to create /dev/sdX" + sleep 15s #wait for udev to create /dev/sdX + rpm -q device-mapper-multipath 2>/dev/null 1>/dev/null + if [ $? -ne 0 ];then + echo "INFO: Installing device-mapper-multipath via yum" + yum -y install device-mapper-multipath + fi +#enable multipath for scsi_debug. + cat << AA > /etc/multipath.conf +defaults { +#Enable multibus is for mutlbus testing + path_grouping_policy multibus + user_friendly_names yes +} +blacklist { + device { + vendor .* + product .* + } +} +blacklist_exceptions { + device { + vendor Linux + product scsi_debug + } +} +AA + echo "INFO: /etc/multipath.conf updated" + cat /etc/multipath.conf + echo "INFO: Restarting multiapth and reload configuration" + service multipathd restart + sleep 5s #multipathd return premature + multipathd -k'reconfig' + + mpath_name_list=$(dmsetup table | perl -ne 'print "$1 " if /(mpath[a-z0-9]+):[0-9 ]+multipath.*/') + if [ "CHK${mpath_name_list}" != "CHK" ];then + mpath_name_list="$(echo ${mpath_name_list} | sed -e 's/ $//')" + echo "INFO: found mpath: ${mpath_name_list}" + RETURN_STR="${mpath_name_list}" + return 0 + fi + return 1 +} #end of functoin Setup_Multipath + + diff --git a/tests/include/include.sh b/tests/include/include.sh new file mode 100755 index 0000000..5144b39 --- /dev/null +++ b/tests/include/include.sh @@ -0,0 +1,124 @@ +#!/bin/bash + +# Copyright (c) 2016 Red Hat, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# 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, see <http://www.gnu.org/licenses/>. + +# Author: Lin Li <lilin@redhat.com> + + + +#----------------------------------------------------------------------------# +# Mp_Conf_Up_Def () +# Usage: +# Update default section of /etc/multipath.conf, will also reload conf. +# Parameter: +# $config_change #config string want to change, like 'polling_interval 5' +# Returns: +# Return code: +# 0 on success +# 1 if something went wrong. +# Return string: +# NULL +#----------------------------------------------------------------------------# + +function Mp_Conf_Up_Def (){ + EX_USAGE=64 # Bad arg format + if [ $# -lt 1 ]; then + echo 'Usage: Mp_Conf_Up_Def $config_change' + exit "${EX_USAGE}" + fi + RETURN_STR='' + local multipath_conf_filename="/etc/multipath.conf" + local config_change="$1" + echo ${config_change} + if [ "CHK${config_change}" == "CHK" ];then + echo 'Usage: Mp_Conf_Up_Def $config_change' + exit "${EX_USAGE}" + fi + python2 -c " +import sys +sys.path.append('"${MP_INCLUDE_PATH}"') +from mpconf import * +update_df_section('""${config_change}""') +" +#TODO: we need to check configuration before we return 0 + RETURN_STR="" + return 0 +} #end of functoin Mp_Conf_Up_Def + + +# ---------------------------------------------------------# +# Print_multipath_pkginfo()() +# Usage: +# print the multipath pacakge information +# Parameter: +# NULL +# Returns: +# Return code: +# 0 on success +# 1 if something went wrong. +# ---------------------------------------------------------# +function Print_multipath_pkginfo (){ + Cmd "rpm -qi device-mapper-multipath" + Cmd "rpm -qi kpartx" +} + +# ---------------------------------------------------------# +# Mutipathd_stop() +# Usage: +# check if multipathd stops, if not stop it +# Parameter: +# NULL +# Returns: +# Return code: +# 0 on success +# 1 if something went wrong. +# ---------------------------------------------------------# +function Multipathd_stop (){ +# { ! Cmd pidof multipathd ; } || Cmd "service multipathd stop" + { ! Cmd pidof multipathd ; } || Cmd "kill -9 `pidof multipathd`" +} + +# ---------------------------------------------------------# +# Mutipathd_start() +# Usage: +# check if multipathd is installed, if not start it +# Parameter: +# NULL +# Returns: +# Return code: +# 0 on success +# 1 if something went wrong. +# ---------------------------------------------------------# +function Multipathd_start (){ +# { Cmd pidof multipathd ; } || Cmd "service multipathd start" + { Cmd pidof multipathd ; } || Cmd "multipathd" +} + +# ---------------------------------------------------------# +# Mutipath_installation() +# Usage: +# check if multipath starts, if not install it with yum +# Parameter: +# NULL +# Returns: +# Return code: +# 0 on success +# 1 if something went wrong. +# ---------------------------------------------------------# +function Multipath_installation (){ + Cmd "rpm -qi device-mapper-multipath" && return 0 + Cmd "yum install -y device-mapper-multipath" +} diff --git a/tests/include/mpath.sh b/tests/include/mpath.sh new file mode 100644 index 0000000..22a68f9 --- /dev/null +++ b/tests/include/mpath.sh @@ -0,0 +1,137 @@ +#!/bin/bash + +# Copyright (c) 2016 Red Hat, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# 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, see <http://www.gnu.org/licenses/>. + +# Author: Lin Li <lilin@redhat.com> + + +# filename: loop.sh + +# USAGE + +test x$LXT_MPATH = x || return +LXT_MPATH=1 + +#source /mnt/tests/kernel/storage/include/bash_modules/lxt/tc.sh + +# make sure multipathd is running +get_mpath_disks() +{ + multipathd_running || texit "multipathd is not running" + multipathd -k'show maps' 2>/dev/null | grep '^mpath' | awk '{print +"/dev/mapper/" $1}' + return 0 +} + +# make sure multipathd is running +get_wwid_of_disk() +{ +# we should not use scsi_id or /dev/disk/by-id to get the wwid +# since multipath could replace the white spaces of wwid if +# having white spaces. we should use +# multipathd show paths format %w %d +# to get the wwid + + for dev in `ls /dev/disk/by-id/*` + do + if readlink $dev | grep -qw "$disk$" + then + wwid=$(basename $dev | sed 's/^[^-]*-//g') + break + fi + done + if test X$wwid = X + then + wwid=$(/lib/udev/scsi_id --page=0x83 --whitelisted --device=/dev/$disk) + fi + echo $wwid + +# multipathd_running || texit "multipathd is not running" +# local disk=$1 +# local wwid=$(multipathd show paths format %d,%w | grep "^$disk\s*," | \ +# awk -F, '{ print $2 }' | sed 's/\s//g') +# echo $wwid +} + + +# make sure multipathd is running +get_mpath_disk_by_scsi_device() +{ +# multipathd_running || texit "multipathd is not running" + local disk=$1 + wwid=$(get_wwid_of_disk $disk) + local mpath=$(multipathd show maps format %w,%n | grep "^$wwid\s*," \ + | awk -F, '{ print $2 }' | sed 's/\s//g') + echo $mpath +} + +# make sure multipathd is running +get_major_minor_by_scsi_device() +{ + multipathd_running || texit "multipathd is not running" + local disk=$1 + local mm=$(multipathd show paths format %d,%D | grep "^$disk\s*," | \ + awk -F, '{ print $2 }' | sed 's/\s//g') + echo $mm +} + +# make sure multipathd is running +get_hcil_by_scsi_device() +{ + multipathd_running || texit "multipathd is not running" + local disk=$1 + local hcil=$(multipathd show paths format %d,%i | grep "^$disk\s*," | \ + awk -F, '{ print $2 }' | sed 's/\s//g') + echo $hcil +} + +# make sure multipathd is running +is_mpath() +{ + multipathd_running || texit "multipathd is not running" + local mpath=$1 + multipathd show maps format %n | grep -w "^$mpath" &> /dev/null +} + +multipathd_running() +{ + pidof multipathd &> /dev/null && return 0 + return 1 +} + +# will set find_multipaths no and start multipathd +setup_multipath() +{ + trun "rpm -q device-mapper-multipath || yum install -y device-mapper-multipath" || texit "fail to install multipath" + test -f /etc/multipath.conf && cp /etc/multipath.conf /etc/multipath.conf.storage_qe + trun "mpathconf --enable --find_multipaths n --with_multipathd y" + trun "multipath -r" +} + +get_unused_mpath() +{ + multipathd_running &>/dev/null || texit "multipathd is not running" + rootdisk=$(get_root_disk) + rootmpath=$(get_mpath_disk_by_scsi_device $rootdisk) + if is_null $rootmpath; then + $maps=$(multipathd show maps format "%n" | grep -v name) + else + $maps=$(multipathd show maps format "%n" | grep -v name | grep -v $rootmpath) + fi + + echo $maps +} + diff --git a/tests/include/scsi_debug.sh b/tests/include/scsi_debug.sh new file mode 100644 index 0000000..8ec184f --- /dev/null +++ b/tests/include/scsi_debug.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +# Copyright (c) 2016 Red Hat, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# 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, see <http://www.gnu.org/licenses/>. + +# Author: Lin Li <lilin@redhat.com> + +# filename: function + +# USAGE + +test x$LXT_SCSI_DEBUG = x || return +LXT_SCSI_DEBUG=1 + + +get_scsi_debug_devices () +{ + ls /sys/block/sd* -d 2>/dev/null | while read dev; do + dev=$(basename $dev); + grep -qw scsi_debug /sys/block/$dev/device/model && echo "/dev/$dev" && break; + done + + return 0 +} diff --git a/tests/include/tc.sh b/tests/include/tc.sh new file mode 100755 index 0000000..9ad385d --- /dev/null +++ b/tests/include/tc.sh @@ -0,0 +1,272 @@ +#!/bin/bash + +# Copyright (c) 2016 Red Hat, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# 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, see <http://www.gnu.org/licenses/>. + +# Author: Lin Li <lilin@redhat.com> + +# filename: function + +# USAGE + +test x$LXT_TC = x || return +LXT_TC=1 + +# +# print the current date +# usage: d=$(tdate) +# +tdate () +{ + date '+%T' 2>/dev/null +} + +# +# print the log information +# usage: tlog "hello world" "WARNING" +# +tlog () +{ + local msg=$1 + local log_level=${2:-INFO} + local cur_date=$(tdate) + + echo "[$log_level][$cur_date]$msg" + + return 0 +} + +# +# run the cmd and format the log. return the exitint status of cmd +# use the global variables: tSTDOUT and tSTDERR to return the stdout and stderr +# usage: trun "ls" +# trun "ls"; echo $? +# stdout=$tSTDOUT +# stderr=$tSTDERR +# +trun () +{ + local cmd="$*" + + _trun_ "$cmd" +} + +# +# verify the execution of command +# if the cmd return 0, mark this checkpoint failed and return 1 +# if not, mark it passed and return 0 +# usage: tnot "ls /not_existing" +# +tnot () { + local cmd="$*" + _trun_ "$cmd" 1 + if test $? -eq 0; then + tfail_ "$cmd" ; + else + tpass_ "$cmd" ; + fi +} + +# +# verify the execution of command +# if the cmd return 0, mark this checkpoint passed and return 0 +# if not, mark it failed and return 1 +# usage: tok "ls /" +# +tok () +{ + local cmd="$*" + _trun_ "$cmd" 0 + if test $? -eq 0; then + tpass_ "$cmd" ; + else + tfail_ "$cmd" ; + fi +} + +# +# verify the execution of command +# if the cmd return 0, mark this checkpoint passed and return 0 +# if not, mark it failes and exit +# usage: terr "ls" +# +#terr () +#{ +# tok "$*" || tend +#} + +# +# verify the execution of command +# if the cmd return 0, will continue to run the script +# if not, mark it failes and exit +# usage: terr "ls" +# +terr () +{ + local cmd="$*" + _trun_ "$cmd" 0 + if test $? -ne 0; then + tfail_ "$cmd" ; + tend ; + fi +} + +# +# exit the program and print the log message +# usage: texit "error message" 100 +# similar to the exception +# +texit () +{ + msg=$1 + err=$2 + is_null $err && err=1 + test $err -lt 1 || err=1 + + tlog "$msg" "ERROR" + exit $2 +} + +# +# print the test report, cleanup the testing bed and close the testing. +# usage: tend +# +tend () +{ + local pcount=$(wc -l $tPASS_FILE | awk '{print $1}') + local fcount=$(wc -l $tFAIL_FILE | awk '{print $1}') + local total=$(( $pcount + $fcount )) + + echo "#################################Test Report###############################" + echo "TOTAL : $total" + echo "PASSED : $pcount" + echo "FAILED : $fcount" + cat $tPASS_FILE $tFAIL_FILE + echo "###########################End of running $0########################" + +#cleanup + rm -f $tPASS_FILE $tFAIL_FILE $tRETURN_FILE $tSTDERR_FILE +# rm -rf $LXT_TMP_DIR + if [[ $pcount -eq 0 ]] && [[ $total -eq 0 ]];then + exit 0 + fi + test $pcount -eq 0 && exit 1 + test $pcount -eq $total && exit 0 + exit 1 +} + +# +# private function +# + +# +# print the error message and call stack. return 1 +# +tfail_ () +{ + local msg=$* + tlog "$msg" "ERROR" >>$tFAIL_FILE + + return 1 +} + +# +# print the sucessful message. return 0 +# +tpass_ () +{ + local msg=$* + tlog "$msg" "PASS" >> $tPASS_FILE + + return 0 +} + +_trun_ () +{ + local cmd="$1" + local chk="$2" + local cur_date=$(tdate) + + local stdout=$(eval "$cmd" 2>$tSTDERR_FILE; echo $? >$tRETURN_FILE 2>/dev/null) +#timeout -- how to set timeout? + local exit_status=$(< $tRETURN_FILE) + local stderr=$(< $tSTDERR_FILE) + local msg=CMD +#tnot + if test x$chk = x1; then + test $exit_status -eq 0 || msg=PASS + test $exit_status -eq 0 && msg=FAIL +#should let the tester know this is the negative testing +#if cmd return 0 we will return 1 and vice versa + cmd="[NOT] $cmd" + fi +#tok + if test x$chk = x0; then + test $exit_status -eq 0 && msg=PASS + test $exit_status -eq 0 || msg=FAIL + fi + + tSTDOUT=$stdout + tSTDERR=$stderr + + test $tIGNORE_STDOUT -eq 1 && stdout='redirect the stdout to /dev/null' + test $tIGNORE_STDERR -eq 1 && stderr='redirect the stderr to /dev/null' + + echo "[$msg][$cur_date][$HOSTNAME]$cmd" + echo "STDOUT:" + test "x$stdout" = x || echo "$stdout" + echo "STDERR:$stderr" + echo "RETURN:$exit_status" + echo + + return $exit_status +} + +# +# setup the testing environment +# +_tsetup_ () +{ + + LXT_TMP_DIR="/mnt/testarea/lxt"; + + test -z "$HOSTNAME" && HOSTNAME=$(hostname) + test -d "$LXT_TMP_DIR" || mkdir -p "$LXT_TMP_DIR" >& /dev/null || exit 1 + + tSTDERR_FILE="$LXT_TMP_DIR/stderr.$$" + test -e "$tSTDERR_FILE" || > "$tSTDERR_FILE" || exit 1 + tRETURN_FILE="$LXT_TMP_DIR/return.$$" + test -e "$tRETURN_FILE" || > "$tRETURN_FILE" || exit 1 + tPASS_FILE="$LXT_TMP_DIR/tc.pass.$$" + test -e "$tPASS_FILE" || > "$tPASS_FILE" || exit 1 + tFAIL_FILE="$LXT_TMP_DIR/tc.fail.$$" + test -e "$tFAIL_FILE" || > "$tFAIL_FILE" || exit 1 +} + +# +# main +# + +# global variables +tIGNORE_STDOUT=0 +tIGNORE_STDERR=0 +tSTDOUT= +tSTDERR= +#LXT_TMP_DIR +# only used in this file +tPASS_FILE= +tFAIL_FILE= + +_tsetup_ diff --git a/tests/include/utils.sh b/tests/include/utils.sh new file mode 100755 index 0000000..404c3e8 --- /dev/null +++ b/tests/include/utils.sh @@ -0,0 +1,195 @@ +#!/bin/bash + +# Copyright (c) 2016 Red Hat, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# 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, see <http://www.gnu.org/licenses/>. + +# Author: Lin Li <lilin@redhat.com> + + +#summary of this script: +# this script is used to provide the generai utils for the automation script based on shell +# all the global variables should be upper case and began with under line since this script will be used by many scripts +# and we don't want the their value is be override by mistake + + +###############################global variables###################################### + +#the global variables should begin with under line plus some special keyword?? +#global variables, can be used by other scripts +#the stdout and stderr of the cmd execution in Cmd function +#can get the exit status of the Cmd function by $? +_STDOUT= +_STDERR= +#if set to 1 will not print the stdout and stderr in the function Cmd +#should set them to 0 after using it +_IGNORE_STDOUT=0 +_IGNORE_STDERR=0 + +#current hostname, same as the global variable HOSTNAME +#don't use readonly since we maybe source this file many times in the same shell environment +[ -z "$HOSTNAME" ] && HOSTNAME=$(hostname) + +#private global variables, only used in current script +#temp dir and files used by Cmd to capture the stderr and exit status of cmd execution +_TEMP_DIR="/tmp/lstf" +[ -d $_TEMP_DIR ] || mkdir -p $_TEMP_DIR >& /dev/null || Fail "failed to mkdir $_TEMP_DIR" + +_TEMP_STDERR_FILE="$_TEMP_DIR/stderr.$$" +[ -e $_TEMP_STDERR_FILE ] || touch $_TEMP_STDERR_FILE || Fail "failed to create $_TEMP_STDERR_FILE" +_TEMP_RETURN_FILE="$_TEMP_DIR/return.$$" +[ -e $_TEMP_RETURN_FILE ] || touch $_TEMP_RETURN_FILE || Fail "failed to create $_TEMP_RETURN_FILE" + +############################################################################################### + +#private function +#print the formated date string + +function _date_str (){ + date 2>/dev/null +} + +############################################################################################### +#summary: +# eval the paramters and format the output +# don't support stderr redirection in the passed command +#usage: +# Cmd ls -a +# if you don't want to print the stdout or stderr you can set the global variables _IGNORE_STDOUT and _IGNORE_STDERR, for example +# _IGNORE_STDOUT=1 +# Cmd ls -a +# _IGNORE_STDOUT=0 +#return: +# return the exit status of paramter value execution +# store the stdout and stderr to the global variables _STDOUT and _STDERR +############################################################################################### + +function Cmd (){ +#use the double qutoa to store all the arguments as a single string + local cmd="$*" + local date_str=$(_date_str) + local stdout=$(eval $cmd 2>$_TEMP_STDERR_FILE; echo $? >$_TEMP_RETURN_FILE 2>/dev/null) + +#why cannot get the exit status of the value of eval by this ? +# local exit_status=$? +#remove the \n hence don't use this method +# local exit_status=$(cat $_TEMP_RETURN_FILE) + + local exit_status=$(< $_TEMP_RETURN_FILE) + local stderr=$(< $_TEMP_STDERR_FILE) + + _STDOUT=$stdout + _STDERR=$stderr + +#will not print the stdout and stderr if the 2 global variables set to 1 + [ $_IGNORE_STDOUT -eq 1 ] && stdout='redirect the stdout to /dev/null' + [ $_IGNORE_STDERR -eq 1 ] && stderr='redirect the stderr to /dev/null' + + echo "[CMD][$date_str][$HOSTNAME]#$cmd" + echo "STDOUT:$stdout" + echo "STDERR:$stderr" + echo "RETURN:$exit_status" + echo + + return $exit_status +} + +############################################################################################### +#summary: +# print the formated log +# consider filter the output through the level +# level should be INFO, ERROR, WARNING, PASSED +#usage: +# Log "msg" "level" +# Log "msg" +# don't use it like this : Log msg level +#return: +# 0 +############################################################################################### + +#should redirect io to stderr if log_level is error? + +function Log (){ + local msg=$1 + local log_level=${2:-INFO} + local date_str=$(_date_str) + + echo "[$log_level][$date_str]:$msg" + echo + + return 0 +} + +############################################################################################### +#summary: +# print the formated error message, call stack information and exit the program with 1 +#usage: +# Fail error_msg +#exit: +# 1 +############################################################################################### + +function Fail (){ + local msg=$* + local stack=`caller 0` + + Log "$stack" + Log "$msg" "ERROR" + + exit 1 +} + +############################################################################################### +#summary: +# print the formated passed message and exit the program with 0 +#usage: +# Pass +#exit: +# 0 +############################################################################################### + +function Pass (){ + Log "Test case passed" "PASSED" + + exit 0 +} + +############################################################################################### +#summary: +# assert the expression, +# if the exiting status of the expression is not 0 fail the case and print the failed message +# if 0 do nothing just return 0 +#usage: +# Assert "$exit_status -eq 0" "failed string" +# Assert "ls /dev/sdb" "failed string" +#return/exit: +# the exiting value of expression +############################################################################################### + +function Assert (){ +#should consider the expr is integra or expression, script? + local expr=$1 + local failed_msg=$2 + [ $expr ] || Fail "$failed_msg" + + return 0 +} + +is_null() +{ + local string=$1 + string=$(echo $string | sed 's/\s//g') + test -z $string +} + |