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