1#!/bin/sh 2# 3# Copyright (c) Linux Test Project, 2014-2017 4# 5# This program is free software; you can redistribute it and/or modify 6# it under the terms of the GNU General Public License as published by 7# the Free Software Foundation; either version 2 of the License, or 8# (at your option) any later version. 9# 10# This program is distributed in the hope that it will be useful, 11# but WITHOUT ANY WARRANTY; without even the implied warranty of 12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13# GNU General Public License for more details. 14# 15# You should have received a copy of the GNU General Public License along 16# with this program; if not, write to the Free Software Foundation, Inc., 17# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18# 19# Written by Cyril Hrubis <chrubis@suse.cz> 20# 21# This is a LTP test library for shell. 22# 23 24export LTP_RET_VAL=0 25export TST_COUNT=1 26export TST_LIB_LOADED=1 27export TST_TMPDIR_RHOST=0 28 29. tst_ansi_color.sh 30 31# Exit values map 32tst_flag2mask() 33{ 34 case "$1" in 35 TPASS) return 0;; 36 TFAIL) return 1;; 37 TBROK) return 2;; 38 TWARN) return 4;; 39 TINFO) return 16;; 40 TCONF) return 32;; 41 *) tst_brkm TBROK "Invalid resm type '$1'";; 42 esac 43} 44 45tst_resm() 46{ 47 local ttype="$1" 48 49 tst_flag2mask "$ttype" 50 local mask=$? 51 LTP_RET_VAL=$((LTP_RET_VAL|mask)) 52 53 local ret=$1 54 shift 55 56 printf "$TCID $TST_COUNT " 57 tst_print_colored $ret "$ret:" 58 echo " $@" 59 60 case "$ret" in 61 TPASS|TFAIL) 62 TST_COUNT=$((TST_COUNT+1));; 63 esac 64} 65 66tst_brkm() 67{ 68 case "$1" in 69 TFAIL) ;; 70 TBROK) ;; 71 TCONF) ;; 72 *) tst_brkm TBROK "Invalid tst_brkm type '$1'";; 73 esac 74 75 local ret=$1 76 shift 77 tst_resm "$ret" "$@" 78 tst_exit 79} 80 81tst_record_childstatus() 82{ 83 if [ $# -ne 1 ]; then 84 tst_brkm TBROK "Requires child pid as parameter" 85 fi 86 87 local child_pid=$1 88 local ret=0 89 90 wait $child_pid 91 ret=$? 92 if [ $ret -eq 127 ]; then 93 tst_brkm TBROK "Child process pid='$child_pid' does not exist" 94 fi 95 LTP_RET_VAL=$((LTP_RET_VAL|ret)) 96} 97 98tst_require_root() 99{ 100 if [ "$(id -ru)" != 0 ]; then 101 tst_brkm TCONF "Must be super/root for this test!" 102 fi 103} 104 105tst_exit() 106{ 107 if [ -n "${TST_CLEANUP:-}" -a -z "${TST_NO_CLEANUP:-}" ]; then 108 $TST_CLEANUP 109 fi 110 111 if [ -n "${LTP_IPC_PATH:-}" -a -f "${LTP_IPC_PATH:-}" ]; then 112 rm -f "$LTP_IPC_PATH" 113 fi 114 115 # Mask out TINFO 116 exit $((LTP_RET_VAL & ~16)) 117} 118 119tst_tmpdir() 120{ 121 if [ -z "$TMPDIR" ]; then 122 export TMPDIR="/tmp" 123 fi 124 125 TST_TMPDIR=$(mktemp -d "$TMPDIR/$TCID.XXXXXXXXXX") 126 127 chmod 777 "$TST_TMPDIR" 128 129 TST_STARTWD=$(pwd) 130 131 cd "$TST_TMPDIR" 132} 133 134tst_rmdir() 135{ 136 if [ -n "$TST_TMPDIR" ]; then 137 cd "$LTPROOT" 138 rm -r "$TST_TMPDIR" 139 [ "$TST_TMPDIR_RHOST" = 1 ] && tst_cleanup_rhost 140 fi 141} 142 143# 144# Checks if commands passed as arguments exists 145# 146tst_check_cmds() 147{ 148 local cmd 149 for cmd in $*; do 150 if ! command -v $cmd > /dev/null 2>&1; then 151 tst_brkm TCONF "'$cmd' not found" 152 fi 153 done 154} 155 156# tst_retry "command" [times] 157# try run command for specified times, default is 3. 158# Function returns 0 if succeed in RETRIES times or the last retcode the cmd 159# returned 160tst_retry() 161{ 162 local cmd="$1" 163 local RETRIES=${2:-"3"} 164 local i=$RETRIES 165 166 while [ $i -gt 0 ]; do 167 eval "$cmd" 168 ret=$? 169 if [ $ret -eq 0 ]; then 170 break 171 fi 172 i=$((i-1)) 173 sleep 1 174 done 175 176 if [ $ret -ne 0 ]; then 177 tst_resm TINFO "Failed to execute '$cmd' after $RETRIES retries" 178 fi 179 180 return $ret 181} 182 183# tst_timeout "command arg1 arg2 ..." timeout 184# Runs command for specified timeout (in seconds). 185# Function returns retcode of command or 1 if arguments are invalid. 186tst_timeout() 187{ 188 local command=$1 189 local timeout=$(echo $2 | grep -o "^[0-9]\+$") 190 191 # command must be non-empty string with command to run 192 if [ -z "$command" ]; then 193 echo "first argument must be non-empty string" 194 return 1 195 fi 196 197 # accept only numbers as timeout 198 if [ -z "$timeout" ]; then 199 echo "only numbers as second argument" 200 return 1 201 fi 202 203 setsid sh -c "eval $command" 2>&1 & 204 local pid=$! 205 while [ $timeout -gt 0 ]; do 206 kill -s 0 $pid 2>/dev/null 207 if [ $? -ne 0 ]; then 208 break 209 fi 210 timeout=$((timeout - 1)) 211 sleep 1 212 done 213 214 local ret=0 215 if [ $timeout -le 0 ]; then 216 ret=128 217 kill -TERM -- -$pid 218 fi 219 220 wait $pid 221 ret=$((ret | $?)) 222 223 return $ret 224} 225 226ROD_SILENT() 227{ 228 $@ > /dev/null 2>&1 229 if [ $? -ne 0 ]; then 230 tst_brkm TBROK "$@ failed" 231 fi 232} 233 234ROD_BASE() 235{ 236 local cmd 237 local arg 238 local file 239 local flag 240 241 for arg; do 242 file="${arg#\>}" 243 if [ "$file" != "$arg" ]; then 244 flag=1 245 if [ -n "$file" ]; then 246 break 247 fi 248 continue 249 fi 250 251 if [ -n "$flag" ]; then 252 file="$arg" 253 break 254 fi 255 256 cmd="$cmd $arg" 257 done 258 259 if [ -n "$flag" ]; then 260 $cmd > $file 261 else 262 $@ 263 fi 264} 265 266ROD() 267{ 268 ROD_BASE "$@" 269 if [ $? -ne 0 ]; then 270 tst_brkm TBROK "$@ failed" 271 fi 272} 273 274EXPECT_PASS() 275{ 276 ROD_BASE "$@" 277 if [ $? -eq 0 ]; then 278 tst_resm TPASS "$@ passed as expected" 279 else 280 tst_resm TFAIL "$@ failed unexpectedly" 281 fi 282} 283 284EXPECT_FAIL() 285{ 286 # redirect stderr since we expect the command to fail 287 ROD_BASE "$@" 2> /dev/null 288 if [ $? -ne 0 ]; then 289 tst_resm TPASS "$@ failed as expected" 290 else 291 tst_resm TFAIL "$@ passed unexpectedly" 292 fi 293} 294 295tst_mkfs() 296{ 297 local fs_type=$1 298 local device=$2 299 shift 2 300 local fs_opts="$@" 301 302 if [ -z "$fs_type" ]; then 303 tst_brkm TBROK "No fs_type specified" 304 fi 305 306 if [ -z "$device" ]; then 307 tst_brkm TBROK "No device specified" 308 fi 309 310 tst_resm TINFO "Formatting $device with $fs_type extra opts='$fs_opts'" 311 312 ROD_SILENT mkfs.$fs_type $fs_opts $device 313} 314 315tst_umount() 316{ 317 local device="$1" 318 local i=0 319 320 if ! grep -q "$device" /proc/mounts; then 321 tst_resm TINFO "The $device is not mounted, skipping umount" 322 return 323 fi 324 325 while [ "$i" -lt 50 ]; do 326 if umount "$device" > /dev/null; then 327 return 328 fi 329 330 i=$((i+1)) 331 332 tst_resm TINFO "umount($device) failed, try $i ..." 333 tst_resm TINFO "Likely gvfsd-trash is probing newly mounted "\ 334 "fs, kill it to speed up tests." 335 336 tst_sleep 100ms 337 done 338 339 tst_resm TWARN "Failed to umount($device) after 50 retries" 340} 341 342# Check a module file existence 343# Should be called after tst_tmpdir() 344tst_module_exists() 345{ 346 local mod_name="$1" 347 348 if [ -f "$mod_name" ]; then 349 TST_MODPATH="$mod_name" 350 return 351 fi 352 353 local mod_path="$LTPROOT/testcases/bin/$mod_name" 354 if [ -f "$mod_path" ]; then 355 TST_MODPATH="$mod_path" 356 return 357 fi 358 359 if [ -n "$TST_TMPDIR" ]; then 360 mod_path="$TST_STARTWD/$mod_name" 361 if [ -f "$mod_path" ]; then 362 TST_MODPATH="$mod_path" 363 return 364 fi 365 fi 366 367 tst_brkm TCONF "Failed to find module '$mod_name'" 368} 369 370# Appends LTP path when doing su 371tst_su() 372{ 373 local usr="$1" 374 shift 375 376 su "$usr" -c "PATH=\$PATH:$LTPROOT/testcases/bin/ $@" 377} 378 379TST_CHECKPOINT_WAIT() 380{ 381 ROD tst_checkpoint wait 10000 "$1" 382} 383 384TST_CHECKPOINT_WAKE() 385{ 386 ROD tst_checkpoint wake 10000 "$1" 1 387} 388 389TST_CHECKPOINT_WAKE2() 390{ 391 ROD tst_checkpoint wake 10000 "$1" "$2" 392} 393 394TST_CHECKPOINT_WAKE_AND_WAIT() 395{ 396 TST_CHECKPOINT_WAKE "$1" 397 TST_CHECKPOINT_WAIT "$1" 398} 399 400# Check that test name is set 401if [ -z "$TCID" ]; then 402 tst_brkm TBROK "TCID is not defined" 403fi 404 405if [ -z "$TST_TOTAL" ]; then 406 tst_brkm TBROK "TST_TOTAL is not defined" 407fi 408 409export TCID="$TCID" 410export TST_TOTAL="$TST_TOTAL" 411 412# Setup LTPROOT, default to current directory if not set 413if [ -z "$LTPROOT" ]; then 414 export LTPROOT="$PWD" 415 export LTP_DATAROOT="$LTPROOT/datafiles" 416else 417 export LTP_DATAROOT="$LTPROOT/testcases/data/$TCID" 418fi 419 420if [ "$TST_NEEDS_CHECKPOINTS" = "1" ]; then 421 LTP_IPC_PATH="/dev/shm/ltp_${TCID}_$$" 422 423 LTP_IPC_SIZE=$(getconf PAGESIZE) 424 if [ $? -ne 0 ]; then 425 tst_brkm TBROK "getconf PAGESIZE failed" 426 fi 427 428 ROD_SILENT dd if=/dev/zero of="$LTP_IPC_PATH" bs="$LTP_IPC_SIZE" count=1 429 ROD_SILENT chmod 600 "$LTP_IPC_PATH" 430 export LTP_IPC_PATH 431fi 432