ftracetest 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  1. #!/bin/sh
  2. # SPDX-License-Identifier: GPL-2.0-only
  3. # ftracetest - Ftrace test shell scripts
  4. #
  5. # Copyright (C) Hitachi Ltd., 2014
  6. # Written by Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
  7. #
  8. usage() { # errno [message]
  9. [ ! -z "$2" ] && echo $2
  10. echo "Usage: ftracetest [options] [testcase(s)] [testcase-directory(s)]"
  11. echo " Options:"
  12. echo " -h|--help Show help message"
  13. echo " -k|--keep Keep passed test logs"
  14. echo " -K|--ktap Output in KTAP format"
  15. echo " -v|--verbose Increase verbosity of test messages"
  16. echo " -vv Alias of -v -v (Show all results in stdout)"
  17. echo " -vvv Alias of -v -v -v (Show all commands immediately)"
  18. echo " --fail-unsupported Treat UNSUPPORTED as a failure"
  19. echo " --fail-unresolved Treat UNRESOLVED as a failure"
  20. echo " -d|--debug Debug mode (trace all shell commands)"
  21. echo " -l|--logdir <dir> Save logs on the <dir>"
  22. echo " If <dir> is -, all logs output in console only"
  23. echo " --rv Run RV selftests instead of ftrace ones"
  24. exit $1
  25. }
  26. # default error
  27. err_ret=1
  28. # kselftest skip code is 4
  29. err_skip=4
  30. # umount required
  31. UMOUNT_DIR=""
  32. # cgroup RT scheduling prevents chrt commands from succeeding, which
  33. # induces failures in test wakeup tests. Disable for the duration of
  34. # the tests.
  35. readonly sched_rt_runtime=/proc/sys/kernel/sched_rt_runtime_us
  36. sched_rt_runtime_orig=$(cat $sched_rt_runtime)
  37. setup() {
  38. echo -1 > $sched_rt_runtime
  39. }
  40. cleanup() {
  41. echo $sched_rt_runtime_orig > $sched_rt_runtime
  42. if [ -n "${UMOUNT_DIR}" ]; then
  43. umount ${UMOUNT_DIR} ||:
  44. fi
  45. }
  46. errexit() { # message
  47. echo "Error: $1" 1>&2
  48. cleanup
  49. exit $err_ret
  50. }
  51. # Ensuring user privilege
  52. if [ `id -u` -ne 0 ]; then
  53. errexit "this must be run by root user"
  54. fi
  55. setup
  56. # Utilities
  57. absdir() { # file_path
  58. (cd `dirname $1`; pwd)
  59. }
  60. abspath() {
  61. echo `absdir $1`/`basename $1`
  62. }
  63. find_testcases() { #directory
  64. echo `find $1 -name \*.tc | sort`
  65. }
  66. parse_opts() { # opts
  67. local OPT_TEST_CASES=
  68. local OPT_TEST_DIR=
  69. while [ ! -z "$1" ]; do
  70. case "$1" in
  71. --help|-h)
  72. usage 0
  73. ;;
  74. --keep|-k)
  75. KEEP_LOG=1
  76. shift 1
  77. ;;
  78. --ktap|-K)
  79. KTAP=1
  80. shift 1
  81. ;;
  82. --verbose|-v|-vv|-vvv)
  83. if [ $VERBOSE -eq -1 ]; then
  84. usage "--console can not use with --verbose"
  85. fi
  86. VERBOSE=$((VERBOSE + 1))
  87. [ $1 = '-vv' ] && VERBOSE=$((VERBOSE + 1))
  88. [ $1 = '-vvv' ] && VERBOSE=$((VERBOSE + 2))
  89. shift 1
  90. ;;
  91. --console)
  92. if [ $VERBOSE -ne 0 ]; then
  93. usage "--console can not use with --verbose"
  94. fi
  95. VERBOSE=-1
  96. shift 1
  97. ;;
  98. --debug|-d)
  99. DEBUG=1
  100. shift 1
  101. ;;
  102. --stop-fail)
  103. STOP_FAILURE=1
  104. shift 1
  105. ;;
  106. --fail-unsupported)
  107. UNSUPPORTED_RESULT=1
  108. shift 1
  109. ;;
  110. --fail-unresolved)
  111. UNRESOLVED_RESULT=1
  112. shift 1
  113. ;;
  114. --logdir|-l)
  115. LOG_DIR=$2
  116. LINK_PTR=
  117. shift 2
  118. ;;
  119. --rv)
  120. RV_TEST=1
  121. shift 1
  122. ;;
  123. *.tc)
  124. if [ -f "$1" ]; then
  125. OPT_TEST_CASES="$OPT_TEST_CASES `abspath $1`"
  126. shift 1
  127. else
  128. usage 1 "$1 is not a testcase"
  129. fi
  130. ;;
  131. *)
  132. if [ -d "$1" ]; then
  133. OPT_TEST_DIR=`abspath $1`
  134. OPT_TEST_CASES="$OPT_TEST_CASES `find_testcases $OPT_TEST_DIR`"
  135. shift 1
  136. else
  137. usage 1 "Invalid option ($1)"
  138. fi
  139. ;;
  140. esac
  141. done
  142. if [ -n "$OPT_TEST_CASES" ]; then
  143. TEST_CASES=$OPT_TEST_CASES
  144. fi
  145. if [ -n "$OPT_TEST_DIR" -a -f "$OPT_TEST_DIR"/test.d/functions ]; then
  146. TOP_DIR=$OPT_TEST_DIR
  147. TEST_DIR=$TOP_DIR/test.d
  148. fi
  149. }
  150. # Parameters
  151. TRACING_DIR=`grep tracefs /proc/mounts | cut -f2 -d' ' | head -1`
  152. if [ -z "$TRACING_DIR" ]; then
  153. DEBUGFS_DIR=`grep debugfs /proc/mounts | cut -f2 -d' ' | head -1`
  154. if [ -z "$DEBUGFS_DIR" ]; then
  155. # If tracefs exists, then so does /sys/kernel/tracing
  156. if [ -d "/sys/kernel/tracing" ]; then
  157. mount -t tracefs nodev /sys/kernel/tracing ||
  158. errexit "Failed to mount /sys/kernel/tracing"
  159. TRACING_DIR="/sys/kernel/tracing"
  160. UMOUNT_DIR=${TRACING_DIR}
  161. # If debugfs exists, then so does /sys/kernel/debug
  162. elif [ -d "/sys/kernel/debug" ]; then
  163. mount -t debugfs nodev /sys/kernel/debug ||
  164. errexit "Failed to mount /sys/kernel/debug"
  165. TRACING_DIR="/sys/kernel/debug/tracing"
  166. UMOUNT_DIR=${TRACING_DIR}
  167. else
  168. err_ret=$err_skip
  169. errexit "debugfs and tracefs are not configured in this kernel"
  170. fi
  171. else
  172. TRACING_DIR="$DEBUGFS_DIR/tracing"
  173. fi
  174. fi
  175. if [ ! -d "$TRACING_DIR" ]; then
  176. err_ret=$err_skip
  177. errexit "ftrace is not configured in this kernel"
  178. fi
  179. TOP_DIR=`absdir $0`
  180. TEST_DIR=$TOP_DIR/test.d
  181. TEST_CASES=`find_testcases $TEST_DIR`
  182. KEEP_LOG=0
  183. KTAP=0
  184. DEBUG=0
  185. VERBOSE=0
  186. UNSUPPORTED_RESULT=0
  187. UNRESOLVED_RESULT=0
  188. STOP_FAILURE=0
  189. RV_TEST=0
  190. # Parse command-line options
  191. parse_opts $*
  192. LOG_TOP_DIR=$TOP_DIR/logs
  193. LOG_DATE=`date +%Y%m%d-%H%M%S`
  194. LOG_DIR=$LOG_TOP_DIR/$LOG_DATE/
  195. LINK_PTR=$LOG_TOP_DIR/latest
  196. [ $DEBUG -ne 0 ] && set -x
  197. if [ $RV_TEST -ne 0 ]; then
  198. TRACING_DIR=$TRACING_DIR/rv
  199. if [ ! -d "$TRACING_DIR" ]; then
  200. err_ret=$err_skip
  201. errexit "rv is not configured in this kernel"
  202. fi
  203. fi
  204. # Preparing logs
  205. if [ "x$LOG_DIR" = "x-" ]; then
  206. LOG_FILE=
  207. date
  208. else
  209. LOG_FILE=$LOG_DIR/ftracetest.log
  210. mkdir -p $LOG_DIR || errexit "Failed to make a log directory: $LOG_DIR"
  211. date > $LOG_FILE
  212. if [ "x-$LINK_PTR" != "x-" ]; then
  213. unlink $LINK_PTR
  214. ln -fs $LOG_DATE $LINK_PTR
  215. fi
  216. fi
  217. # Define text colors
  218. # Check available colors on the terminal, if any
  219. ncolors=`tput colors 2>/dev/null || echo 0`
  220. color_reset=
  221. color_red=
  222. color_green=
  223. color_blue=
  224. # If stdout exists and number of colors is eight or more, use them
  225. if [ -t 1 -a "$ncolors" -ge 8 ]; then
  226. color_reset="\033[0m"
  227. color_red="\033[31m"
  228. color_green="\033[32m"
  229. color_blue="\033[34m"
  230. fi
  231. strip_esc() {
  232. # busybox sed implementation doesn't accept "\x1B", so use [:cntrl:] instead.
  233. sed -E "s/[[:cntrl:]]\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g"
  234. }
  235. prlog() { # messages
  236. newline="\n"
  237. if [ "$1" = "-n" ] ; then
  238. newline=
  239. shift
  240. fi
  241. [ "$KTAP" != "1" ] && printf "$*$newline"
  242. [ "$LOG_FILE" ] && printf "$*$newline" | strip_esc >> $LOG_FILE
  243. }
  244. catlog() { #file
  245. if [ "${KTAP}" = "1" ]; then
  246. cat $1 | while read line ; do
  247. echo "# $line"
  248. done
  249. else
  250. cat $1
  251. fi
  252. [ "$LOG_FILE" ] && cat $1 | strip_esc >> $LOG_FILE
  253. }
  254. prlog "=== Ftrace unit tests ==="
  255. # Testcase management
  256. # Test result codes - Dejagnu extended code
  257. PASS=0 # The test succeeded.
  258. FAIL=1 # The test failed, but was expected to succeed.
  259. UNRESOLVED=2 # The test produced indeterminate results. (e.g. interrupted)
  260. UNTESTED=3 # The test was not run, currently just a placeholder.
  261. UNSUPPORTED=4 # The test failed because of lack of feature.
  262. XFAIL=5 # The test failed, and was expected to fail.
  263. # Accumulations
  264. PASSED_CASES=
  265. FAILED_CASES=
  266. UNRESOLVED_CASES=
  267. UNTESTED_CASES=
  268. UNSUPPORTED_CASES=
  269. XFAILED_CASES=
  270. UNDEFINED_CASES=
  271. TOTAL_RESULT=0
  272. INSTANCE=
  273. CASENO=0
  274. CASENAME=
  275. testcase() { # testfile
  276. CASENO=$((CASENO+1))
  277. CASENAME=`grep "^#[ \t]*description:" $1 | cut -f2- -d:`
  278. }
  279. checkreq() { # testfile
  280. requires=`grep "^#[ \t]*requires:" $1 | cut -f2- -d:`
  281. # Use eval to pass quoted-patterns correctly.
  282. eval check_requires "$requires"
  283. }
  284. test_on_instance() { # testfile
  285. grep -q "^#[ \t]*flags:.*instance" $1
  286. }
  287. ktaptest() { # result comment
  288. if [ "$KTAP" != "1" ]; then
  289. return
  290. fi
  291. local result=
  292. if [ "$1" = "1" ]; then
  293. result="ok"
  294. else
  295. result="not ok"
  296. fi
  297. shift
  298. local comment=$*
  299. if [ "$comment" != "" ]; then
  300. comment="# $comment"
  301. fi
  302. echo $result $CASENO $INSTANCE$CASENAME $comment
  303. }
  304. eval_result() { # sigval
  305. case $1 in
  306. $PASS)
  307. prlog " [${color_green}PASS${color_reset}]"
  308. ktaptest 1
  309. PASSED_CASES="$PASSED_CASES $CASENO"
  310. return 0
  311. ;;
  312. $FAIL)
  313. prlog " [${color_red}FAIL${color_reset}]"
  314. ktaptest 0
  315. FAILED_CASES="$FAILED_CASES $CASENO"
  316. return 1 # this is a bug.
  317. ;;
  318. $UNRESOLVED)
  319. prlog " [${color_blue}UNRESOLVED${color_reset}]"
  320. ktaptest 0 UNRESOLVED
  321. UNRESOLVED_CASES="$UNRESOLVED_CASES $CASENO"
  322. return $UNRESOLVED_RESULT # depends on use case
  323. ;;
  324. $UNTESTED)
  325. prlog " [${color_blue}UNTESTED${color_reset}]"
  326. ktaptest 1 SKIP
  327. UNTESTED_CASES="$UNTESTED_CASES $CASENO"
  328. return 0
  329. ;;
  330. $UNSUPPORTED)
  331. prlog " [${color_blue}UNSUPPORTED${color_reset}]"
  332. ktaptest 1 SKIP
  333. UNSUPPORTED_CASES="$UNSUPPORTED_CASES $CASENO"
  334. return $UNSUPPORTED_RESULT # depends on use case
  335. ;;
  336. $XFAIL)
  337. prlog " [${color_green}XFAIL${color_reset}]"
  338. ktaptest 1 XFAIL
  339. XFAILED_CASES="$XFAILED_CASES $CASENO"
  340. return 0
  341. ;;
  342. *)
  343. prlog " [${color_blue}UNDEFINED${color_reset}]"
  344. ktaptest 0 error
  345. UNDEFINED_CASES="$UNDEFINED_CASES $CASENO"
  346. return 1 # this must be a test bug
  347. ;;
  348. esac
  349. }
  350. # Signal handling for result codes
  351. SIG_RESULT=
  352. SIG_BASE=36 # Use realtime signals
  353. SIG_PID=$$
  354. exit_pass () {
  355. exit 0
  356. }
  357. SIG_FAIL=$((SIG_BASE + FAIL))
  358. exit_fail () {
  359. exit 1
  360. }
  361. trap 'SIG_RESULT=$FAIL' $SIG_FAIL
  362. SIG_UNRESOLVED=$((SIG_BASE + UNRESOLVED))
  363. exit_unresolved () {
  364. kill -s $SIG_UNRESOLVED $SIG_PID
  365. exit 0
  366. }
  367. trap 'SIG_RESULT=$UNRESOLVED' $SIG_UNRESOLVED
  368. SIG_UNTESTED=$((SIG_BASE + UNTESTED))
  369. exit_untested () {
  370. kill -s $SIG_UNTESTED $SIG_PID
  371. exit 0
  372. }
  373. trap 'SIG_RESULT=$UNTESTED' $SIG_UNTESTED
  374. SIG_UNSUPPORTED=$((SIG_BASE + UNSUPPORTED))
  375. exit_unsupported () {
  376. kill -s $SIG_UNSUPPORTED $SIG_PID
  377. exit 0
  378. }
  379. trap 'SIG_RESULT=$UNSUPPORTED' $SIG_UNSUPPORTED
  380. SIG_XFAIL=$((SIG_BASE + XFAIL))
  381. exit_xfail () {
  382. kill -s $SIG_XFAIL $SIG_PID
  383. exit 0
  384. }
  385. trap 'SIG_RESULT=$XFAIL' $SIG_XFAIL
  386. __run_test() { # testfile
  387. # setup PID and PPID, $$ is not updated.
  388. (cd $TRACING_DIR; read PID _ < /proc/self/stat; set -e; set -x;
  389. checkreq $1; initialize_system; . $1)
  390. [ $? -ne 0 ] && kill -s $SIG_FAIL $SIG_PID
  391. }
  392. # Run one test case
  393. run_test() { # testfile
  394. local testname=`basename $1`
  395. testcase $1
  396. prlog -n "[$CASENO]$INSTANCE$CASENAME"
  397. if [ ! -z "$LOG_FILE" ] ; then
  398. local testlog=`mktemp $LOG_DIR/${CASENO}-${testname}-log.XXXXXX`
  399. else
  400. local testlog=/proc/self/fd/1
  401. fi
  402. export TMPDIR=`mktemp -d /tmp/ftracetest-dir.XXXXXX`
  403. export FTRACETEST_ROOT=$TOP_DIR
  404. echo "execute$INSTANCE: "$1 > $testlog
  405. SIG_RESULT=0
  406. if [ $VERBOSE -eq -1 ]; then
  407. __run_test $1
  408. elif [ -z "$LOG_FILE" ]; then
  409. __run_test $1 2>&1
  410. elif [ $VERBOSE -ge 3 ]; then
  411. __run_test $1 | tee -a $testlog 2>&1
  412. elif [ $VERBOSE -eq 2 ]; then
  413. __run_test $1 2>> $testlog | tee -a $testlog
  414. else
  415. __run_test $1 >> $testlog 2>&1
  416. fi
  417. eval_result $SIG_RESULT
  418. if [ $? -eq 0 ]; then
  419. # Remove test log if the test was done as it was expected.
  420. [ $KEEP_LOG -eq 0 -a ! -z "$LOG_FILE" ] && rm $testlog
  421. else
  422. [ $VERBOSE -eq 1 -o $VERBOSE -eq 2 ] && catlog $testlog
  423. TOTAL_RESULT=1
  424. fi
  425. rm -rf $TMPDIR
  426. }
  427. # load in the helper functions
  428. . $TEST_DIR/functions
  429. if [ "$KTAP" = "1" ]; then
  430. echo "TAP version 13"
  431. casecount=`echo $TEST_CASES | wc -w`
  432. for t in $TEST_CASES; do
  433. test_on_instance $t || continue
  434. casecount=$((casecount+1))
  435. done
  436. echo "1..${casecount}"
  437. fi
  438. # Main loop
  439. for t in $TEST_CASES; do
  440. run_test $t
  441. if [ $STOP_FAILURE -ne 0 -a $TOTAL_RESULT -ne 0 ]; then
  442. echo "A failure detected. Stop test."
  443. exit 1
  444. fi
  445. done
  446. # Test on instance loop
  447. INSTANCE=" (instance) "
  448. for t in $TEST_CASES; do
  449. test_on_instance $t || continue
  450. SAVED_TRACING_DIR=$TRACING_DIR
  451. export TRACING_DIR=`mktemp -d $TRACING_DIR/instances/ftracetest.XXXXXX`
  452. run_test $t
  453. rmdir $TRACING_DIR
  454. TRACING_DIR=$SAVED_TRACING_DIR
  455. if [ $STOP_FAILURE -ne 0 -a $TOTAL_RESULT -ne 0 ]; then
  456. echo "A failure detected. Stop test."
  457. exit 1
  458. fi
  459. done
  460. (cd $TRACING_DIR; finish_system) # for cleanup
  461. prlog ""
  462. prlog "# of passed: " `echo $PASSED_CASES | wc -w`
  463. prlog "# of failed: " `echo $FAILED_CASES | wc -w`
  464. prlog "# of unresolved: " `echo $UNRESOLVED_CASES | wc -w`
  465. prlog "# of untested: " `echo $UNTESTED_CASES | wc -w`
  466. prlog "# of unsupported: " `echo $UNSUPPORTED_CASES | wc -w`
  467. prlog "# of xfailed: " `echo $XFAILED_CASES | wc -w`
  468. prlog "# of undefined(test bug): " `echo $UNDEFINED_CASES | wc -w`
  469. if [ "$KTAP" = "1" ]; then
  470. echo -n "# Totals:"
  471. echo -n " pass:"`echo $PASSED_CASES | wc -w`
  472. echo -n " fail:"`echo $FAILED_CASES | wc -w`
  473. echo -n " xfail:"`echo $XFAILED_CASES | wc -w`
  474. echo -n " xpass:0"
  475. echo -n " skip:"`echo $UNTESTED_CASES $UNSUPPORTED_CASES | wc -w`
  476. echo -n " error:"`echo $UNRESOLVED_CASES $UNDEFINED_CASES | wc -w`
  477. echo
  478. fi
  479. cleanup
  480. # if no error, return 0
  481. exit $TOTAL_RESULT