common.sh revision 237344
1#!/bin/sh 2# 3# Common code used run regression tests for usr.bin/make. 4# 5# $FreeBSD: head/tools/regression/usr.bin/make/common.sh 237344 2012-06-20 21:38:16Z obrien $ 6 7# 8# Output a message and exit with an error. 9# 10fatal() 11{ 12 echo "fatal: $*" >/dev/stderr 13 exit 1 14} 15 16# 17# Check whether the working directory exists - it must. 18# 19ensure_workdir() 20{ 21 if [ ! -d ${WORK_DIR} ] ; then 22 fatal "working directory ${WORK_DIR} does not exist." 23 fi 24} 25 26# 27# Make sure all tests have been run 28# 29ensure_run() 30{ 31 if [ -z "${TEST_N}" ] ; then 32 TEST_N=1 33 fi 34 35 FAIL= 36 N=1 37 while [ ${N} -le ${TEST_N} ] ; do 38 if ! skip_test ${N} ; then 39 if [ ! -f ${OUTPUT_DIR}/status.${N} -o \ 40 ! -f ${OUTPUT_DIR}/stdout.${N} -o \ 41 ! -f ${OUTPUT_DIR}/stderr.${N} ] ; then 42 echo "Test ${SUBDIR}/${N} no yet run" 43 FAIL=yes 44 fi 45 fi 46 N=$((N + 1)) 47 done 48 49 if [ ! -z "${FAIL}" ] ; then 50 exit 1 51 fi 52} 53 54# 55# Output usage messsage. 56# 57print_usage() 58{ 59 echo "Usage: sh -v -m <path> -w <dir> $0 command(s)" 60 echo " setup - setup working directory" 61 echo " run - run the tests" 62 echo " show - show test results" 63 echo " compare - compare actual and expected results" 64 echo " diff - diff actual and expected results" 65 echo " reset - reset the test to its initial state" 66 echo " clean - delete working and output directory" 67 echo " test - setup + run + compare" 68 echo " prove - setup + run + compare + clean" 69 echo " desc - print short description" 70 echo " update - update the expected results with the current results" 71 echo " help - show this information" 72} 73 74# 75# Return 0 if we should skip the test. 1 otherwise 76# 77skip_test() 78{ 79 eval skip=\${TEST_${1}_SKIP} 80 if [ -z "${skip}" ] ; then 81 return 1 82 else 83 return 0 84 fi 85} 86 87# 88# Common function for setup and reset. 89# 90common_setup() 91{ 92 # 93 # If a Makefile exists in the source directory - copy it over 94 # 95 if [ -e Makefile -a ! -e ${WORK_DIR}/Makefile ] ; then 96 cp Makefile ${WORK_DIR}/Makefile 97 fi 98 99 # 100 # If the TEST_MAKE_DIRS variable is set, create those directories 101 # 102 set -- ${TEST_MAKE_DIRS} 103 while [ $# -ne 0 ] ; do 104 if [ ! -d ${WORK_DIR}/${1} ] ; then 105 mkdir -p -m ${2} ${WORK_DIR}/${1} 106 else 107 chmod ${2} ${WORK_DIR}/${1} 108 fi 109 shift ; shift 110 done 111 112 # 113 # If the TEST_COPY_FILES variable is set, copy those files over to 114 # the working directory. The value is assumed to be pairs of 115 # filenames and modes. 116 # 117 set -- ${TEST_COPY_FILES} 118 while [ $# -ne 0 ] ; do 119 if [ ! -e ${WORK_DIR}/${1} ] ; then 120 cp ${1} ${WORK_DIR}/${1} 121 fi 122 chmod ${2} ${WORK_DIR}/${1} 123 shift ; shift 124 done 125 126 # 127 # If the TEST_TOUCH variable is set, it is taken to be a list 128 # of pairs of filenames and arguments to touch(1). The arguments 129 # to touch must be surrounded by single quotes if there are more 130 # than one argument. 131 # 132 eval set -- ${TEST_TOUCH} 133 while [ $# -ne 0 ] ; do 134 eval touch ${2} ${WORK_DIR}/${1} 135 shift ; shift 136 done 137 138 # 139 # Now create links 140 # 141 eval set -- ${TEST_LINKS} 142 while [ $# -ne 0 ] ; do 143 eval ln ${WORK_DIR}/${1} ${WORK_DIR}/${2} 144 shift ; shift 145 done 146} 147 148# 149# Setup the test. This creates the working and output directories and 150# populates it with files. If there is a setup_test() function - call it. 151# 152eval_setup() 153{ 154 # 155 # Check whether the working directory exists. If it does exit 156 # fatally so that we don't clobber a test the user is working on. 157 # 158 if [ -d ${WORK_DIR} ] ; then 159 fatal "working directory ${WORK_DIR} already exists." 160 fi 161 162 # 163 # Now create it and the output directory 164 # 165 mkdir -p ${WORK_DIR} 166 rm -rf ${OUTPUT_DIR} 167 mkdir -p ${OUTPUT_DIR} 168 169 # 170 # Common stuff 171 # 172 common_setup 173 174 # 175 # Now after all execute the user's setup function if it exists. 176 # 177 setup_test 178} 179 180# 181# Default setup_test function does nothing. This may be overriden by 182# the test. 183# 184setup_test() 185{ 186} 187 188# 189# Reset the test. Here we need to rely on information from the test. 190# We executed the same steps as in the setup, by try not to clobber existing 191# files. 192# All files and directories that are listed on the TEST_CLEAN_FILES 193# variable are removed. Then the TEST_TOUCH list is executed and finally 194# the reset_test() function called if it exists. 195# 196eval_reset() 197{ 198 ensure_workdir 199 200 # 201 # Clean the output directory 202 # 203 rm -rf ${OUTPUT_DIR}/* 204 205 # 206 # Common stuff 207 # 208 common_setup 209 210 # 211 # Remove files. 212 # 213 for f in ${TEST_CLEAN_FILES} ; do 214 rm -rf ${WORK_DIR}/${f} 215 done 216 217 # 218 # Execute test's function 219 # 220 reset_test 221} 222 223# 224# Default reset_test function does nothing. This may be overriden by 225# the test. 226# 227reset_test() 228{ 229} 230 231# 232# Clean the test. This simply removes the working and output directories. 233# 234eval_clean() 235{ 236 # 237 # If you have special cleaning needs, provide a 'cleanup' shell script. 238 # 239 if [ -n "${TEST_CLEANUP}" ] ; then 240 . ${SRC_DIR}/cleanup 241 fi 242 if [ -z "${NO_TEST_CLEANUP}" ] ; then 243 rm -rf ${WORK_DIR} 244 rm -rf ${OUTPUT_DIR} 245 fi 246} 247 248# 249# Run the test. 250# 251eval_run() 252{ 253 ensure_workdir 254 255 if [ -z "${TEST_N}" ] ; then 256 TEST_N=1 257 fi 258 259 N=1 260 while [ ${N} -le ${TEST_N} ] ; do 261 if ! skip_test ${N} ; then 262 ( cd ${WORK_DIR} ; 263 exec 1>${OUTPUT_DIR}/stdout.${N} 2>${OUTPUT_DIR}/stderr.${N} 264 run_test ${N} 265 echo $? >${OUTPUT_DIR}/status.${N} 266 ) 267 fi 268 N=$((N + 1)) 269 done 270} 271 272# 273# Default run_test() function. It can be replaced by the 274# user specified regression test. The argument to this function is 275# the test number. 276# 277run_test() 278{ 279 eval args=\${TEST_${1}-test${1}} 280 ${MAKE_PROG} $args 281} 282 283# 284# Show test results. 285# 286eval_show() 287{ 288 ensure_workdir 289 290 if [ -z "${TEST_N}" ] ; then 291 TEST_N=1 292 fi 293 294 N=1 295 while [ ${N} -le ${TEST_N} ] ; do 296 if ! skip_test ${N} ; then 297 echo "=== Test ${N} Status ==================" 298 cat ${OUTPUT_DIR}/status.${N} 299 echo ".......... Stdout .................." 300 cat ${OUTPUT_DIR}/stdout.${N} 301 echo ".......... Stderr .................." 302 cat ${OUTPUT_DIR}/stderr.${N} 303 fi 304 N=$((N + 1)) 305 done 306} 307 308# 309# Compare results with expected results 310# 311eval_compare() 312{ 313 ensure_workdir 314 ensure_run 315 316 if [ -z "${TEST_N}" ] ; then 317 TEST_N=1 318 fi 319 320 echo "1..${TEST_N}" 321 N=1 322 while [ ${N} -le ${TEST_N} ] ; do 323 fail= 324 todo= 325 if ! skip_test ${N} ; then 326 do_compare stdout ${N} || fail="${fail}stdout " 327 do_compare stderr ${N} || fail="${fail}stderr " 328 do_compare status ${N} || fail="${fail}status " 329 eval todo=\${TEST_${N}_TODO} 330 fi 331 if [ ! -z "$fail" ]; then 332 echo -n "not " 333 fi 334 echo -n "ok ${N} ${SUBDIR}/${N}" 335 if [ ! -z "$fail" -o ! -z "$todo" ]; then 336 echo -n " # " 337 fi 338 if [ ! -z "$todo" ] ; then 339 echo -n "TODO $todo; " 340 fi 341 if [ ! -z "$fail" ] ; then 342 echo "reason: ${fail}" 343 fi 344 echo 345 N=$((N + 1)) 346 done 347} 348 349# 350# Check if the test result is the same as the expected result. 351# 352# $1 Input file 353# $2 Test number 354# 355do_compare() 356{ 357 local EXPECTED RESULT 358 EXPECTED="expected.$1.$2" 359 RESULT="${OUTPUT_DIR}/$1.$2" 360 361 if [ -f $EXPECTED ]; then 362 diff -q $EXPECTED $RESULT 1>/dev/null 2>/dev/null 363 return $? 364 else 365 return 1 # FAIL 366 fi 367} 368 369# 370# Diff current and expected results 371# 372eval_diff() 373{ 374 ensure_workdir 375 ensure_run 376 377 if [ -z "${TEST_N}" ] ; then 378 TEST_N=1 379 fi 380 381 N=1 382 while [ ${N} -le ${TEST_N} ] ; do 383 if ! skip_test ${N} ; then 384 FAIL= 385 do_diff stdout ${N} 386 do_diff stderr ${N} 387 do_diff status ${N} 388 fi 389 N=$((N + 1)) 390 done 391} 392 393# 394# Check if the test result is the same as the expected result. 395# 396# $1 Input file 397# $2 Test number 398# 399do_diff() 400{ 401 local EXPECTED RESULT 402 EXPECTED="expected.$1.$2" 403 RESULT="${OUTPUT_DIR}/$1.$2" 404 405 echo diff -u $EXPECTED $RESULT 406 if [ -f $EXPECTED ]; then 407 diff -u $EXPECTED $RESULT 408 else 409 echo "${EXPECTED} does not exist" 410 fi 411} 412 413# 414# Update expected results 415# 416eval_update() 417{ 418 ensure_workdir 419 ensure_run 420 421 if [ -z "${TEST_N}" ] ; then 422 TEST_N=1 423 fi 424 425 FAIL= 426 N=1 427 while [ ${N} -le ${TEST_N} ] ; do 428 if ! skip_test ${N} ; then 429 cp ${OUTPUT_DIR}/stdout.${N} expected.stdout.${N} 430 cp ${OUTPUT_DIR}/stderr.${N} expected.stderr.${N} 431 cp ${OUTPUT_DIR}/status.${N} expected.status.${N} 432 fi 433 N=$((N + 1)) 434 done 435} 436 437# 438# Print description 439# 440eval_desc() 441{ 442 echo "${SUBDIR}: ${DESC}" 443} 444 445# 446# Run the test 447# 448eval_test() 449{ 450 eval_setup 451 eval_run 452 eval_compare 453} 454 455# 456# Run the test for prove(1) 457# 458eval_prove() 459{ 460 eval_setup 461 eval_run 462 eval_compare 463 eval_clean 464} 465 466# 467# Main function. Execute the command(s) on the command line. 468# 469eval_cmd() 470{ 471 if [ $# -eq 0 ] ; then 472 # if no arguments given default to 'prove' 473 set -- prove 474 fi 475 476 for i 477 do 478 case $i in 479 480 setup | run | compare | diff | clean | reset | show | \ 481 test | prove | desc | update) 482 eval eval_$i 483 ;; 484 * | help) 485 print_usage 486 ;; 487 esac 488 done 489} 490 491############################################################################## 492# 493# Main code 494# 495 496# 497# Parse command line arguments. 498# 499args=`getopt m:w:v $*` 500if [ $? != 0 ]; then 501 echo 'Usage: ...' 502 exit 2 503fi 504set -- $args 505for i; do 506 case "$i" in 507 -m) 508 MAKE_PROG="$2" 509 shift 510 shift 511 ;; 512 -w) 513 WORK_BASE="$2" 514 shift 515 shift 516 ;; 517 -v) 518 VERBOSE=1 519 shift 520 ;; 521 --) 522 shift 523 break 524 ;; 525 esac 526done 527 528# 529# Determine our sub-directory. Argh. 530# 531SRC_DIR=`pwd` 532SRC_BASE=`while [ ! -f common.sh ] ; do cd .. ; done ; pwd` 533SUBDIR=`echo ${SRC_DIR} | sed "s@${SRC_BASE}/@@"` 534 535# 536# Construct working directory 537# 538WORK_BASE=${WORK_BASE:-"/tmp/$USER.make.test"} 539WORK_DIR=${WORK_BASE}/${SUBDIR} 540OUTPUT_DIR=${WORK_DIR}.OUTPUT 541 542# 543# Make to use 544# 545MAKE_PROG=${MAKE_PROG:-/usr/bin/make} 546