ftracetest 11 KB

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