summaryrefslogtreecommitdiffstats
path: root/tests/include
diff options
context:
space:
mode:
Diffstat (limited to 'tests/include')
-rwxr-xr-xtests/include/ec.sh197
-rwxr-xr-xtests/include/include.sh124
-rw-r--r--tests/include/mpath.sh137
-rw-r--r--tests/include/scsi_debug.sh36
-rwxr-xr-xtests/include/tc.sh272
-rwxr-xr-xtests/include/utils.sh195
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
+}
+