debug-test.sh 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. #!/bin/bash
  2. PROG=${0##*/}
  3. build_dir="build-ci-debug"
  4. # Print Color Commands
  5. red=$(tput setaf 1)
  6. green=$(tput setaf 2)
  7. yellow=$(tput setaf 3)
  8. blue=$(tput setaf 4)
  9. magenta=$(tput setaf 5)
  10. cyan=$(tput setaf 6)
  11. normal=$(tput sgr0)
  12. # Print Help Message
  13. ####################
  14. print_full_help() {
  15. cat << EOF
  16. Usage: $PROG [OPTION]... <test_regex> (test_number)
  17. Debug specific ctest program.
  18. Options:
  19. -h, --help display this help and exit
  20. -g run in gdb mode
  21. Arguments:
  22. <test_regex> (Mandatory) Supply one regex to the script to filter tests
  23. (test_number) (Optional) Test number to run a specific test
  24. Example:
  25. $PROG test-tokenizer
  26. $PROG test-tokenizer 3
  27. EOF
  28. }
  29. abort() {
  30. echo "Error: $1" >&2
  31. cat << EOF >&2
  32. Usage: $PROG [OPTION]... <test_regex> (test_number)
  33. Debug specific ctest program.
  34. Refer to --help for full instructions.
  35. EOF
  36. exit 1
  37. }
  38. # Dependency Sanity Check
  39. #########################
  40. check_dependency() {
  41. command -v "$1" >/dev/null 2>&1 || {
  42. abort "$1 is required but not found. Please install it and try again."
  43. }
  44. }
  45. check_dependency ctest
  46. check_dependency cmake
  47. # Step 0: Check the args
  48. ########################
  49. if [ x"$1" = x"-h" ] || [ x"$1" = x"--help" ]; then
  50. print_full_help >&2
  51. exit 0
  52. fi
  53. # Parse command-line options
  54. gdb_mode=false
  55. while getopts "g" opt; do
  56. case $opt in
  57. g)
  58. gdb_mode=true
  59. echo "gdb_mode Mode Enabled"
  60. ;;
  61. esac
  62. done
  63. # Shift the option parameters
  64. shift $((OPTIND - 1))
  65. # Positionial Argument Processing : <test_regex>
  66. if [ -z "${1}" ]; then
  67. abort "Test regex is required"
  68. else
  69. test_suite=${1:-}
  70. fi
  71. # Positionial Argument Processing : (test_number)
  72. test_number=${2:-}
  73. # Step 1: Reset and Setup folder context
  74. ########################################
  75. ## Sanity check that we are actually in a git repo
  76. repo_root=$(git rev-parse --show-toplevel)
  77. if [ ! -d "$repo_root" ]; then
  78. abort "Not in a Git repository."
  79. fi
  80. ## Reset folder to root context of git repo and Create and enter build directory
  81. pushd "$repo_root"
  82. rm -rf "$build_dir" && mkdir "$build_dir" || abort "Failed to make $build_dir"
  83. # Step 2: Setup Build Environment and Compile Test Binaries
  84. ###########################################################
  85. # Note: test-eval-callback requires -DLLAMA_CURL
  86. cmake -B "./$build_dir" -DCMAKE_BUILD_TYPE=Debug -DLLAMA_CUDA=1 -DLLAMA_CURL=1 || abort "Failed to build enviroment"
  87. pushd "$build_dir"
  88. make -j || abort "Failed to compile"
  89. popd > /dev/null || exit 1
  90. # Step 3: Find all tests available that matches REGEX
  91. ####################################################
  92. # Ctest Gather Tests
  93. # `-R test-tokenizer` : looks for all the test files named `test-tokenizer*` (R=Regex)
  94. # `-N` : "show-only" disables test execution & shows test commands that you can feed to GDB.
  95. # `-V` : Verbose Mode
  96. printf "\n\nGathering tests that fit REGEX: ${test_suite} ...\n"
  97. pushd "$build_dir"
  98. tests=($(ctest -R ${test_suite} -V -N | grep -E " +Test +#[0-9]+*" | cut -d':' -f2 | awk '{$1=$1};1'))
  99. if [ ${#tests[@]} -eq 0 ]; then
  100. abort "No tests avaliable... check your compliation process..."
  101. fi
  102. popd > /dev/null || exit 1
  103. # Step 4: Identify Test Command for Debugging
  104. #############################################
  105. # Select test number
  106. if [ -z $test_number ]; then
  107. # List out avaliable tests
  108. printf "Which test would you like to debug?\n"
  109. id=0
  110. for s in "${tests[@]}"
  111. do
  112. echo "Test# ${id}"
  113. echo " $s"
  114. ((id++))
  115. done
  116. # Prompt user which test they wanted to run
  117. printf "\nRun test#? "
  118. read test_number
  119. else
  120. printf "\nUser Already Requested #${test_number}\n"
  121. fi
  122. # Grab all tests commands
  123. pushd "$build_dir"
  124. sIFS=$IFS # Save Initial IFS (Internal Field Separator)
  125. IFS=$'\n' # Change IFS (Internal Field Separator) (So we split ctest output by newline rather than by spaces)
  126. test_args=($(ctest -R ${test_suite} -V -N | grep "Test command" | cut -d':' -f3 | awk '{$1=$1};1' )) # Get test args
  127. IFS=$sIFS # Reset IFS (Internal Field Separator)
  128. popd > /dev/null || exit 1
  129. # Grab specific test command
  130. single_test_name="${tests[test_number]}"
  131. single_test_command="${test_args[test_number]}"
  132. # Step 5: Execute or GDB Debug
  133. ##############################
  134. printf "${magenta}Running Test #${test_number}: ${single_test_name}${normal}\n"
  135. printf "${cyan}single_test_command: ${single_test_command}${normal}\n"
  136. if [ "$gdb_mode" = "true" ]; then
  137. # Execute debugger
  138. pushd "$repo_root" || exit 1
  139. eval "gdb --args ${single_test_command}"
  140. popd > /dev/null || exit 1
  141. else
  142. # Execute Test
  143. pushd "$repo_root" || exit 1
  144. eval "${single_test_command}"
  145. exit_code=$?
  146. popd > /dev/null || exit 1
  147. # Print Result
  148. printf "${blue}Ran Test #${test_number}: ${single_test_name}${normal}\n"
  149. printf "${yellow}Command: ${single_test_command}${normal}\n"
  150. if [ $exit_code -eq 0 ]; then
  151. printf "${green}TEST PASS${normal}\n"
  152. else
  153. printf "${red}TEST FAIL${normal}\n"
  154. fi
  155. fi
  156. # Return to the directory from which the user ran the command.
  157. popd > /dev/null || exit 1