1#!/bin/sh 2# SPDX-License-Identifier: GPL-2.0-or-later 3# Copyright (c) Linux Test Project, 2014-2021 4# Author: Cyril Hrubis <chrubis@suse.cz> 5# 6# LTP test library for shell. 7 8[ -n "$TST_LIB_LOADED" ] && return 0 9 10export TST_PASS=0 11export TST_FAIL=0 12export TST_BROK=0 13export TST_WARN=0 14export TST_CONF=0 15export TST_COUNT=1 16export TST_ITERATIONS=1 17export TST_TMPDIR_RHOST=0 18export TST_LIB_LOADED=1 19 20. tst_ansi_color.sh 21. tst_security.sh 22 23# default trap function 24trap "tst_brk TBROK 'test interrupted'" INT 25trap "unset _tst_setup_timer_pid; tst_brk TBROK 'test terminated'" TERM 26 27_tst_do_exit() 28{ 29 local ret=0 30 TST_DO_EXIT=1 31 32 if [ -n "$TST_DO_CLEANUP" -a -n "$TST_CLEANUP" -a -z "$TST_NO_CLEANUP" ]; then 33 if command -v $TST_CLEANUP >/dev/null 2>/dev/null; then 34 $TST_CLEANUP 35 else 36 tst_res TWARN "TST_CLEANUP=$TST_CLEANUP declared, but function not defined (or cmd not found)" 37 fi 38 fi 39 40 if [ "$TST_NEEDS_DEVICE" = 1 -a "$TST_DEVICE_FLAG" = 1 ]; then 41 if ! tst_device release "$TST_DEVICE"; then 42 tst_res TWARN "Failed to release device '$TST_DEVICE'" 43 fi 44 fi 45 46 if [ "$TST_NEEDS_TMPDIR" = 1 -a -n "$TST_TMPDIR" ]; then 47 cd "$LTPROOT" 48 rm -r "$TST_TMPDIR" 49 [ "$TST_TMPDIR_RHOST" = 1 ] && tst_cleanup_rhost 50 fi 51 52 if [ -n "$TST_NEEDS_CHECKPOINTS" -a -f "$LTP_IPC_PATH" ]; then 53 rm $LTP_IPC_PATH 54 fi 55 56 _tst_cleanup_timer 57 58 if [ $TST_FAIL -gt 0 ]; then 59 ret=$((ret|1)) 60 fi 61 62 if [ $TST_BROK -gt 0 ]; then 63 ret=$((ret|2)) 64 fi 65 66 if [ $TST_WARN -gt 0 ]; then 67 ret=$((ret|4)) 68 fi 69 70 if [ $TST_CONF -gt 0 -a $TST_PASS -eq 0 ]; then 71 ret=$((ret|32)) 72 fi 73 74 if [ $TST_BROK -gt 0 -o $TST_FAIL -gt 0 -o $TST_WARN -gt 0 ]; then 75 _tst_check_security_modules 76 fi 77 78 echo 79 echo "Summary:" 80 echo "passed $TST_PASS" 81 echo "failed $TST_FAIL" 82 echo "broken $TST_BROK" 83 echo "skipped $TST_CONF" 84 echo "warnings $TST_WARN" 85 86 exit $ret 87} 88 89_tst_inc_res() 90{ 91 case "$1" in 92 TPASS) TST_PASS=$((TST_PASS+1));; 93 TFAIL) TST_FAIL=$((TST_FAIL+1));; 94 TBROK) TST_BROK=$((TST_BROK+1));; 95 TWARN) TST_WARN=$((TST_WARN+1));; 96 TCONF) TST_CONF=$((TST_CONF+1));; 97 TINFO) ;; 98 *) tst_brk TBROK "Invalid res type '$1'";; 99 esac 100} 101 102tst_res() 103{ 104 local res=$1 105 shift 106 107 tst_color_enabled 108 local color=$? 109 110 _tst_inc_res "$res" 111 112 printf "$TST_ID $TST_COUNT " >&2 113 tst_print_colored $res "$res: " >&2 114 echo "$@" >&2 115} 116 117tst_brk() 118{ 119 local res=$1 120 shift 121 122 if [ "$TST_DO_EXIT" = 1 ]; then 123 tst_res TWARN "$@" 124 return 125 fi 126 127 tst_res "$res" "$@" 128 _tst_do_exit 129} 130 131ROD_SILENT() 132{ 133 local tst_out 134 135 tst_out="$(tst_rod $@ 2>&1)" 136 if [ $? -ne 0 ]; then 137 echo "$tst_out" 138 tst_brk TBROK "$@ failed" 139 fi 140} 141 142ROD() 143{ 144 tst_rod "$@" 145 if [ $? -ne 0 ]; then 146 tst_brk TBROK "$@ failed" 147 fi 148} 149 150_tst_expect_pass() 151{ 152 local fnc="$1" 153 shift 154 155 tst_rod "$@" 156 if [ $? -eq 0 ]; then 157 tst_res TPASS "$@ passed as expected" 158 return 0 159 else 160 $fnc TFAIL "$@ failed unexpectedly" 161 return 1 162 fi 163} 164 165_tst_expect_fail() 166{ 167 local fnc="$1" 168 shift 169 170 # redirect stderr since we expect the command to fail 171 tst_rod "$@" 2> /dev/null 172 if [ $? -ne 0 ]; then 173 tst_res TPASS "$@ failed as expected" 174 return 0 175 else 176 $fnc TFAIL "$@ passed unexpectedly" 177 return 1 178 fi 179} 180 181EXPECT_PASS() 182{ 183 _tst_expect_pass tst_res "$@" 184} 185 186EXPECT_PASS_BRK() 187{ 188 _tst_expect_pass tst_brk "$@" 189} 190 191EXPECT_FAIL() 192{ 193 _tst_expect_fail tst_res "$@" 194} 195 196EXPECT_FAIL_BRK() 197{ 198 _tst_expect_fail tst_brk "$@" 199} 200 201TST_RETRY_FN_EXP_BACKOFF() 202{ 203 local tst_fun="$1" 204 local tst_exp=$2 205 local tst_sec=$(($3 * 1000000)) 206 local tst_delay=1 207 208 _tst_multiply_timeout tst_sec 209 210 if [ $# -ne 3 ]; then 211 tst_brk TBROK "TST_RETRY_FN_EXP_BACKOFF expects 3 parameters" 212 fi 213 214 if ! tst_is_int "$tst_sec"; then 215 tst_brk TBROK "TST_RETRY_FN_EXP_BACKOFF: tst_sec must be integer ('$tst_sec')" 216 fi 217 218 while true; do 219 eval "$tst_fun" 220 if [ "$?" = "$tst_exp" ]; then 221 break 222 fi 223 224 if [ $tst_delay -lt $tst_sec ]; then 225 tst_sleep ${tst_delay}us 226 tst_delay=$((tst_delay*2)) 227 else 228 tst_brk TBROK "\"$tst_fun\" timed out" 229 fi 230 done 231 232 return $tst_exp 233} 234 235TST_RETRY_FUNC() 236{ 237 if [ $# -ne 2 ]; then 238 tst_brk TBROK "TST_RETRY_FUNC expects 2 parameters" 239 fi 240 241 TST_RETRY_FN_EXP_BACKOFF "$1" "$2" 1 242 return $2 243} 244 245TST_RTNL_CHK() 246{ 247 local msg1="RTNETLINK answers: Function not implemented" 248 local msg2="RTNETLINK answers: Operation not supported" 249 local msg3="RTNETLINK answers: Protocol not supported" 250 local output="$($@ 2>&1 || echo 'LTP_ERR')" 251 local msg 252 253 echo "$output" | grep -q "LTP_ERR" || return 0 254 255 for msg in "$msg1" "$msg2" "$msg3"; do 256 echo "$output" | grep -q "$msg" && tst_brk TCONF "'$@': $msg" 257 done 258 259 tst_brk TBROK "$@ failed: $output" 260} 261 262TST_CHECKPOINT_WAIT() 263{ 264 ROD tst_checkpoint wait 10000 "$1" 265} 266 267TST_CHECKPOINT_WAKE() 268{ 269 ROD tst_checkpoint wake 10000 "$1" 1 270} 271 272TST_CHECKPOINT_WAKE2() 273{ 274 ROD tst_checkpoint wake 10000 "$1" "$2" 275} 276 277TST_CHECKPOINT_WAKE_AND_WAIT() 278{ 279 TST_CHECKPOINT_WAKE "$1" 280 TST_CHECKPOINT_WAIT "$1" 281} 282 283tst_mount() 284{ 285 local mnt_opt mnt_err 286 287 if [ -n "$TST_FS_TYPE" ]; then 288 mnt_opt="-t $TST_FS_TYPE" 289 mnt_err=" $TST_FS_TYPE type" 290 fi 291 292 ROD_SILENT mkdir -p $TST_MNTPOINT 293 mount $mnt_opt $TST_DEVICE $TST_MNTPOINT $TST_MNT_PARAMS 294 local ret=$? 295 296 if [ $ret -eq 32 ]; then 297 tst_brk TCONF "Cannot mount${mnt_err}, missing driver?" 298 fi 299 300 if [ $ret -ne 0 ]; then 301 tst_brk TBROK "Failed to mount device${mnt_err}: mount exit = $ret" 302 fi 303} 304 305tst_umount() 306{ 307 local mntpoint="${1:-$TST_MNTPOINT}" 308 local i=0 309 310 [ -z "$mntpoint" ] && return 311 312 if ! echo "$mntpoint" | grep -q ^/; then 313 tst_brk TCONF "The '$mntpoint' is not an absolute path" 314 fi 315 316 if ! grep -q "${mntpoint%/}" /proc/mounts; then 317 tst_res TINFO "The '$mntpoint' is not mounted, skipping umount" 318 return 319 fi 320 321 while [ "$i" -lt 50 ]; do 322 if umount "$mntpoint" > /dev/null; then 323 return 324 fi 325 326 i=$((i+1)) 327 328 tst_res TINFO "umount($mntpoint) failed, try $i ..." 329 tst_res 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_res TWARN "Failed to umount($mntpoint) after 50 retries" 336} 337 338tst_mkfs() 339{ 340 local fs_type=${1:-$TST_FS_TYPE} 341 local device=${2:-$TST_DEVICE} 342 [ $# -ge 1 ] && shift 343 [ $# -ge 1 ] && shift 344 local fs_opts="$@" 345 346 if [ -z "$fs_type" ]; then 347 tst_brk TBROK "No fs_type specified" 348 fi 349 350 if [ -z "$device" ]; then 351 tst_brk TBROK "No device specified" 352 fi 353 354 tst_require_cmds mkfs.$fs_type 355 356 tst_res TINFO "Formatting $device with $fs_type extra opts='$fs_opts'" 357 ROD_SILENT mkfs.$fs_type $fs_opts $device 358} 359 360# Detect whether running under hypervisor: Microsoft Hyper-V 361# Return 0: running under Hyper-V 362# Return 1: not running under Hyper-V (bare metal, other hypervisor or 363# failure of detection) 364tst_virt_hyperv() 365{ 366 local v 367 368 tst_cmd_available systemd-detect-virt || return 1 369 370 v="$(systemd-detect-virt)" 371 372 [ $? -eq 0 ] || return 1 373 [ "$v" = "microsoft" ] || return 1 374 375 return 0 376} 377 378tst_cmd_available() 379{ 380 command -v $1 >/dev/null 2>&1 381} 382 383tst_require_cmds() 384{ 385 local cmd 386 for cmd in $*; do 387 tst_cmd_available $cmd || tst_brk TCONF "'$cmd' not found" 388 done 389} 390 391tst_check_cmds() 392{ 393 local cmd 394 for cmd in $*; do 395 if ! tst_cmd_available $cmd; then 396 tst_res TCONF "'$cmd' not found" 397 return 1 398 fi 399 done 400 return 0 401} 402 403tst_require_drivers() 404{ 405 [ $# -eq 0 ] && return 0 406 407 local drv 408 409 drv="$(tst_check_drivers $@ 2>&1)" 410 411 [ $? -ne 0 ] && tst_brk TCONF "$drv driver not available" 412 return 0 413} 414 415tst_require_kconfigs() 416{ 417 local delim 418 419 if [ $# -gt 2 ]; then 420 return 0 421 elif [ $# -eq 1 ]; then 422 delim="$TST_NEEDS_KCONFIGS_IFS" 423 else 424 delim="$2" 425 fi 426 427 [ -z "$1" ] && return 0 428 429 tst_check_kconfigs "$1" "$delim" > /dev/null 430 431 [ $? -ne 0 ] && tst_brk TCONF "Aborting due to unsuitable kernel config, see above!" 432 return 0 433} 434 435tst_is_int() 436{ 437 [ "$1" -eq "$1" ] 2>/dev/null 438 return $? 439} 440 441tst_is_num() 442{ 443 echo "$1" | grep -Eq '^[-+]?[0-9]+\.?[0-9]*$' 444} 445 446tst_usage() 447{ 448 if [ -n "$TST_USAGE" ]; then 449 $TST_USAGE 450 else 451 echo "usage: $0" 452 echo "OPTIONS" 453 fi 454 455 echo "-h Prints this help" 456 echo "-i n Execute test n times" 457} 458 459_tst_resstr() 460{ 461 echo "$TST_PASS$TST_FAIL$TST_CONF" 462} 463 464_tst_rescmp() 465{ 466 local res=$(_tst_resstr) 467 468 if [ "$1" = "$res" ]; then 469 tst_brk TBROK "Test didn't report any results" 470 fi 471} 472 473_tst_multiply_timeout() 474{ 475 [ $# -ne 1 ] && tst_brk TBROK "_tst_multiply_timeout expect 1 parameter" 476 eval "local timeout=\$$1" 477 478 LTP_TIMEOUT_MUL=${LTP_TIMEOUT_MUL:-1} 479 480 local err="LTP_TIMEOUT_MUL must be number >= 1!" 481 482 tst_is_num "$LTP_TIMEOUT_MUL" || tst_brk TBROK "$err ($LTP_TIMEOUT_MUL)" 483 484 if ! tst_is_int "$LTP_TIMEOUT_MUL"; then 485 LTP_TIMEOUT_MUL=$(echo "$LTP_TIMEOUT_MUL" | cut -d. -f1) 486 LTP_TIMEOUT_MUL=$((LTP_TIMEOUT_MUL+1)) 487 tst_res TINFO "ceiling LTP_TIMEOUT_MUL to $LTP_TIMEOUT_MUL" 488 fi 489 490 [ "$LTP_TIMEOUT_MUL" -ge 1 ] || tst_brk TBROK "$err ($LTP_TIMEOUT_MUL)" 491 [ "$timeout" -ge 1 ] || tst_brk TBROK "timeout need to be >= 1 ($timeout)" 492 493 eval "$1='$((timeout * LTP_TIMEOUT_MUL))'" 494 return 0 495} 496 497_tst_cleanup_timer() 498{ 499 if [ -n "$_tst_setup_timer_pid" ]; then 500 kill -TERM $_tst_setup_timer_pid 2>/dev/null 501 wait $_tst_setup_timer_pid 2>/dev/null 502 fi 503} 504 505_tst_setup_timer() 506{ 507 TST_TIMEOUT=${TST_TIMEOUT:-300} 508 509 if [ "$TST_TIMEOUT" = -1 ]; then 510 tst_res TINFO "Timeout per run is disabled" 511 return 512 fi 513 514 if ! tst_is_int "$TST_TIMEOUT" || [ "$TST_TIMEOUT" -lt 1 ]; then 515 tst_brk TBROK "TST_TIMEOUT must be int >= 1! ($TST_TIMEOUT)" 516 fi 517 518 local sec=$TST_TIMEOUT 519 _tst_multiply_timeout sec 520 local h=$((sec / 3600)) 521 local m=$((sec / 60 % 60)) 522 local s=$((sec % 60)) 523 local pid=$$ 524 525 tst_res TINFO "timeout per run is ${h}h ${m}m ${s}s" 526 527 _tst_cleanup_timer 528 529 tst_timeout_kill $sec $pid & 530 531 _tst_setup_timer_pid=$! 532 533 while true; do 534 local state 535 536 state=$(cut -d' ' -f3 "/proc/$_tst_setup_timer_pid/stat") 537 538 if [ "$state" = "S" ]; then 539 break; 540 fi 541 542 tst_sleep 1ms 543 done 544} 545 546tst_require_root() 547{ 548 if [ "$(id -ru)" != 0 ]; then 549 tst_brk TCONF "Must be super/root for this test!" 550 fi 551} 552 553tst_require_module() 554{ 555 local _tst_module=$1 556 557 for tst_module in "$_tst_module" \ 558 "$LTPROOT/testcases/bin/$_tst_module" \ 559 "$TST_STARTWD/$_tst_module"; do 560 561 if [ -f "$tst_module" ]; then 562 TST_MODPATH="$tst_module" 563 break 564 fi 565 done 566 567 if [ -z "$TST_MODPATH" ]; then 568 tst_brk TCONF "Failed to find module '$_tst_module'" 569 fi 570 571 tst_res TINFO "Found module at '$TST_MODPATH'" 572} 573 574tst_set_timeout() 575{ 576 TST_TIMEOUT="$1" 577 _tst_setup_timer 578} 579 580_tst_init_checkpoints() 581{ 582 local pagesize 583 584 LTP_IPC_PATH="/dev/shm/ltp_${TST_ID}_$$" 585 pagesize=$(tst_getconf PAGESIZE) 586 if [ $? -ne 0 ]; then 587 tst_brk TBROK "tst_getconf PAGESIZE failed" 588 fi 589 ROD_SILENT dd if=/dev/zero of="$LTP_IPC_PATH" bs="$pagesize" count=1 590 ROD_SILENT chmod 600 "$LTP_IPC_PATH" 591 export LTP_IPC_PATH 592} 593 594tst_run() 595{ 596 local _tst_i 597 local _tst_data 598 local _tst_max 599 local _tst_name 600 601 if [ -n "$TST_TEST_PATH" ]; then 602 for _tst_i in $(grep '^[^#]*\bTST_' "$TST_TEST_PATH" | sed 's/.*TST_//; s/[="} \t\/:`].*//'); do 603 case "$_tst_i" in 604 DISABLE_APPARMOR|DISABLE_SELINUX);; 605 SETUP|CLEANUP|TESTFUNC|ID|CNT|MIN_KVER);; 606 OPTS|USAGE|PARSE_ARGS|POS_ARGS);; 607 NEEDS_ROOT|NEEDS_TMPDIR|TMPDIR|NEEDS_DEVICE|DEVICE);; 608 NEEDS_CMDS|NEEDS_MODULE|MODPATH|DATAROOT);; 609 NEEDS_DRIVERS|FS_TYPE|MNTPOINT|MNT_PARAMS);; 610 NEEDS_KCONFIGS|NEEDS_KCONFIGS_IFS);; 611 IPV6|IPV6_FLAG|IPVER|TEST_DATA|TEST_DATA_IFS);; 612 RETRY_FUNC|RETRY_FN_EXP_BACKOFF|TIMEOUT);; 613 NET_DATAROOT|NET_MAX_PKT|NET_RHOST_RUN_DEBUG|NETLOAD_CLN_NUMBER);; 614 NET_SKIP_VARIABLE_INIT|NEEDS_CHECKPOINTS);; 615 CHECKPOINT_WAIT|CHECKPOINT_WAKE);; 616 CHECKPOINT_WAKE2|CHECKPOINT_WAKE_AND_WAIT);; 617 *) tst_res TWARN "Reserved variable TST_$_tst_i used!";; 618 esac 619 done 620 621 for _tst_i in $(grep '^[^#]*\b_tst_' "$TST_TEST_PATH" | sed 's/.*_tst_//; s/[="} \t\/:`].*//'); do 622 tst_res TWARN "Private variable or function _tst_$_tst_i used!" 623 done 624 fi 625 626 OPTIND=1 627 628 while getopts ":hi:$TST_OPTS" _tst_name $TST_ARGS; do 629 case $_tst_name in 630 'h') tst_usage; exit 0;; 631 'i') TST_ITERATIONS=$OPTARG;; 632 '?') tst_usage; exit 2;; 633 *) $TST_PARSE_ARGS "$_tst_name" "$OPTARG";; 634 esac 635 done 636 637 if ! tst_is_int "$TST_ITERATIONS"; then 638 tst_brk TBROK "Expected number (-i) not '$TST_ITERATIONS'" 639 fi 640 641 if [ "$TST_ITERATIONS" -le 0 ]; then 642 tst_brk TBROK "Number of iterations (-i) must be > 0" 643 fi 644 645 [ "$TST_NEEDS_ROOT" = 1 ] && tst_require_root 646 647 [ "$TST_DISABLE_APPARMOR" = 1 ] && tst_disable_apparmor 648 [ "$TST_DISABLE_SELINUX" = 1 ] && tst_disable_selinux 649 650 tst_require_cmds $TST_NEEDS_CMDS 651 tst_require_kconfigs "$TST_NEEDS_KCONFIGS" 652 tst_require_drivers $TST_NEEDS_DRIVERS 653 654 if [ -n "$TST_MIN_KVER" ]; then 655 tst_kvcmp -lt "$TST_MIN_KVER" && \ 656 tst_brk TCONF "test requires kernel $TST_MIN_KVER+" 657 fi 658 659 _tst_setup_timer 660 661 [ "$TST_NEEDS_DEVICE" = 1 ] && TST_NEEDS_TMPDIR=1 662 663 if [ "$TST_NEEDS_TMPDIR" = 1 ]; then 664 if [ -z "$TMPDIR" ]; then 665 export TMPDIR="/tmp" 666 fi 667 668 TST_TMPDIR=$(mktemp -d "$TMPDIR/LTP_$TST_ID.XXXXXXXXXX") 669 670 chmod 777 "$TST_TMPDIR" 671 672 TST_STARTWD=$(pwd) 673 674 cd "$TST_TMPDIR" 675 fi 676 677 TST_MNTPOINT="${TST_MNTPOINT:-$PWD/mntpoint}" 678 if [ "$TST_NEEDS_DEVICE" = 1 ]; then 679 680 TST_DEVICE=$(tst_device acquire) 681 682 if [ ! -b "$TST_DEVICE" -o $? -ne 0 ]; then 683 unset TST_DEVICE 684 tst_brk TBROK "Failed to acquire device" 685 fi 686 687 TST_DEVICE_FLAG=1 688 fi 689 690 [ -n "$TST_NEEDS_MODULE" ] && tst_require_module "$TST_NEEDS_MODULE" 691 692 [ -n "$TST_NEEDS_CHECKPOINTS" ] && _tst_init_checkpoints 693 694 if [ -n "$TST_SETUP" ]; then 695 if command -v $TST_SETUP >/dev/null 2>/dev/null; then 696 TST_DO_CLEANUP=1 697 $TST_SETUP 698 else 699 tst_brk TBROK "TST_SETUP=$TST_SETUP declared, but function not defined (or cmd not found)" 700 fi 701 fi 702 703 #TODO check that test reports some results for each test function call 704 while [ $TST_ITERATIONS -gt 0 ]; do 705 if [ -n "$TST_TEST_DATA" ]; then 706 tst_require_cmds cut tr wc 707 _tst_max=$(( $(echo $TST_TEST_DATA | tr -cd "$TST_TEST_DATA_IFS" | wc -c) +1)) 708 for _tst_i in $(seq $_tst_max); do 709 _tst_data="$(echo "$TST_TEST_DATA" | cut -d"$TST_TEST_DATA_IFS" -f$_tst_i)" 710 _tst_run_tests "$_tst_data" 711 done 712 else 713 _tst_run_tests 714 fi 715 TST_ITERATIONS=$((TST_ITERATIONS-1)) 716 done 717 _tst_do_exit 718} 719 720_tst_run_tests() 721{ 722 local _tst_data="$1" 723 local _tst_i 724 725 TST_DO_CLEANUP=1 726 for _tst_i in $(seq ${TST_CNT:-1}); do 727 if command -v ${TST_TESTFUNC}1 > /dev/null 2>&1; then 728 _tst_run_test "$TST_TESTFUNC$_tst_i" $_tst_i "$_tst_data" 729 else 730 _tst_run_test "$TST_TESTFUNC" $_tst_i "$_tst_data" 731 fi 732 done 733} 734 735_tst_run_test() 736{ 737 local _tst_res=$(_tst_resstr) 738 local _tst_fnc="$1" 739 shift 740 741 $_tst_fnc "$@" 742 _tst_rescmp "$_tst_res" 743 TST_COUNT=$((TST_COUNT+1)) 744} 745 746if [ -z "$TST_ID" ]; then 747 _tst_filename=$(basename $0) || \ 748 tst_brk TCONF "Failed to set TST_ID from \$0 ('$0'), fix it with setting TST_ID before sourcing tst_test.sh" 749 TST_ID=${_tst_filename%%.*} 750fi 751export TST_ID="$TST_ID" 752 753if [ -z "$LTPROOT" ]; then 754 export LTPROOT="$PWD" 755 export TST_DATAROOT="$LTPROOT/datafiles" 756else 757 export TST_DATAROOT="$LTPROOT/testcases/data/$TST_ID" 758fi 759 760if [ -z "$TST_NO_DEFAULT_RUN" ]; then 761 if TST_TEST_PATH=$(command -v $0) 2>/dev/null; then 762 if ! grep -q tst_run "$TST_TEST_PATH"; then 763 tst_brk TBROK "Test $0 must call tst_run!" 764 fi 765 fi 766 767 if [ -z "$TST_TESTFUNC" ]; then 768 tst_brk TBROK "TST_TESTFUNC is not defined" 769 fi 770 771 TST_TEST_DATA_IFS="${TST_TEST_DATA_IFS:- }" 772 773 TST_NEEDS_KCONFIGS_IFS="${TST_NEEDS_KCONFIGS_IFS:-,}" 774 775 if [ -n "$TST_CNT" ]; then 776 if ! tst_is_int "$TST_CNT"; then 777 tst_brk TBROK "TST_CNT must be integer" 778 fi 779 780 if [ "$TST_CNT" -le 0 ]; then 781 tst_brk TBROK "TST_CNT must be > 0" 782 fi 783 fi 784 785 if [ -n "$TST_POS_ARGS" ]; then 786 if ! tst_is_int "$TST_POS_ARGS"; then 787 tst_brk TBROK "TST_POS_ARGS must be integer" 788 fi 789 790 if [ "$TST_POS_ARGS" -le 0 ]; then 791 tst_brk TBROK "TST_POS_ARGS must be > 0" 792 fi 793 fi 794 795 TST_ARGS="$@" 796 797 while getopts ":hi:$TST_OPTS" tst_name; do 798 case $tst_name in 799 'h') TST_PRINT_HELP=1;; 800 *);; 801 esac 802 done 803 804 shift $((OPTIND - 1)) 805 806 if [ -n "$TST_POS_ARGS" ]; then 807 if [ -z "$TST_PRINT_HELP" -a $# -ne "$TST_POS_ARGS" ]; then 808 tst_brk TBROK "Invalid number of positional parameters:"\ 809 "have ($@) $#, expected ${TST_POS_ARGS}" 810 fi 811 else 812 if [ -z "$TST_PRINT_HELP" -a $# -ne 0 ]; then 813 tst_brk TBROK "Unexpected positional arguments '$@'" 814 fi 815 fi 816fi 817