suite.sh 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. # HACK: get newline for use in strings given that "\n" and $'' do not work.
  2. NL="$(printf '\nE')"
  3. NL="${NL%E}"
  4. FAIL_SUMMARY=""
  5. # Test success marker. If END_MARKER file exists, we know that all tests
  6. # finished. If FAIL_SUMMARY_FILE exists we know that some tests failed, this
  7. # file will contain information about failed tests. Build is considered
  8. # successful if tests ended without any of them failing.
  9. END_MARKER="$BUILD_DIR/.tests_finished"
  10. FAIL_SUMMARY_FILE="$BUILD_DIR/.test_errors"
  11. ANSI_CLEAR="\033[0K"
  12. if test "$TRAVIS" = "true"; then
  13. ci_fold() {
  14. local action="$1"
  15. local name="$2"
  16. name="$(echo -n "$name" | tr '\n\0' '--' | sed 's/[^A-Za-z0-9]\{1,\}/-/g')"
  17. name="$(echo -n "$name" | sed 's/-$//')"
  18. echo -en "travis_fold:${action}:${name}\r${ANSI_CLEAR}"
  19. }
  20. elif test "$GITHUB_ACTIONS" = "true"; then
  21. ci_fold() {
  22. local action="$1"
  23. local name="$2"
  24. name="$(echo -n "$name" | tr '\n\0' '--' | sed 's/[^A-Za-z0-9]\{1,\}/-/g')"
  25. name="$(echo -n "$name" | sed 's/-$//')"
  26. case "$action" in
  27. start)
  28. echo "::group::${name}"
  29. ;;
  30. end)
  31. echo "::endgroup::"
  32. ;;
  33. *)
  34. :;;
  35. esac
  36. }
  37. else
  38. ci_fold() {
  39. return 0
  40. }
  41. fi
  42. enter_suite() {
  43. set +x
  44. FAILED=0
  45. rm -f "${END_MARKER}"
  46. local suite_name="$1"
  47. export NVIM_TEST_CURRENT_SUITE="${NVIM_TEST_CURRENT_SUITE}/$suite_name"
  48. ci_fold start "${NVIM_TEST_CURRENT_SUITE}"
  49. set -x
  50. }
  51. exit_suite() {
  52. set +x
  53. if test $FAILED -ne 0 ; then
  54. echo "Suite ${NVIM_TEST_CURRENT_SUITE} failed, summary:"
  55. echo "${FAIL_SUMMARY}"
  56. else
  57. ci_fold end "${NVIM_TEST_CURRENT_SUITE}"
  58. fi
  59. export NVIM_TEST_CURRENT_SUITE="${NVIM_TEST_CURRENT_SUITE%/*}"
  60. if test "$1" != "--continue" ; then
  61. exit $FAILED
  62. else
  63. local saved_failed=$FAILED
  64. FAILED=0
  65. return $saved_failed
  66. fi
  67. }
  68. fail() {
  69. local test_name="$1"
  70. local fail_char="$2"
  71. local message="$3"
  72. : ${fail_char:=F}
  73. : ${message:=Test $test_name failed}
  74. local full_msg="$fail_char $NVIM_TEST_CURRENT_SUITE|$test_name :: $message"
  75. FAIL_SUMMARY="${FAIL_SUMMARY}${NL}${full_msg}"
  76. echo "${full_msg}" >> "${FAIL_SUMMARY_FILE}"
  77. echo "Failed: $full_msg"
  78. FAILED=1
  79. }
  80. run_test() {
  81. local cmd="$1"
  82. test $# -gt 0 && shift
  83. local test_name="$1"
  84. : ${test_name:=$cmd}
  85. test $# -gt 0 && shift
  86. if ! eval "$cmd" ; then
  87. fail "${test_name}" "$@"
  88. fi
  89. }
  90. run_test_wd() {
  91. local hang_ok=
  92. if test "$1" = "--allow-hang" ; then
  93. hang_ok=1
  94. shift
  95. fi
  96. local timeout="$1"
  97. test $# -gt 0 && shift
  98. local cmd="$1"
  99. test $# -gt 0 && shift
  100. local restart_cmd="$1"
  101. : ${restart_cmd:=true}
  102. test $# -gt 0 && shift
  103. local test_name="$1"
  104. : ${test_name:=$cmd}
  105. test $# -gt 0 && shift
  106. local output_file="$(mktemp)"
  107. local status_file="$(mktemp)"
  108. local sid_file="$(mktemp)"
  109. local restarts=5
  110. local prev_tmpsize=-1
  111. while test $restarts -gt 0 ; do
  112. : > "$status_file"
  113. : > "$sid_file"
  114. setsid \
  115. env \
  116. output_file="$output_file" \
  117. status_file="$status_file" \
  118. sid_file="$sid_file" \
  119. cmd="$cmd" \
  120. CI_DIR="$CI_DIR" \
  121. sh -c '
  122. . "${CI_DIR}/common/test.sh"
  123. ps -o sid= > "$sid_file"
  124. (
  125. ret=0
  126. if ! eval "$cmd" 2>&1 ; then
  127. ret=1
  128. fi
  129. echo "$ret" > "$status_file"
  130. ) | tee -a "$output_file"
  131. '
  132. while test "$(stat -c "%s" "$status_file")" -eq 0 ; do
  133. prev_tmpsize=$tmpsize
  134. sleep $timeout
  135. tmpsize="$(stat -c "%s" "$output_file")"
  136. if test $tempsize -eq $prev_temsize ; then
  137. # no output, assuming either hang or exit
  138. break
  139. fi
  140. done
  141. restarts=$(( restarts - 1 ))
  142. if test "$(stat -c "%s" "$status_file")" -eq 0 ; then
  143. # Status file not updated, assuming hang
  144. # SID not known, this should not ever happen
  145. if test "$(stat -c "%s" "$sid_file")" -eq 0 ; then
  146. fail "$test_name" E "Shell did not run"
  147. break
  148. fi
  149. # Kill all processes which belong to one session: should get rid of test
  150. # processes as well as sh itself.
  151. pkill -KILL -s$(cat "$sid_file")
  152. if test $restarts -eq 0 ; then
  153. if test -z "$hang_ok" ; then
  154. fail "$test_name" E "Test hang up"
  155. fi
  156. else
  157. echo "Test ${test_name} hang up, restarting"
  158. eval "$restart_cmd"
  159. fi
  160. else
  161. local new_failed="$(cat "$status_file")"
  162. if test "$new_failed" != "0" ; then
  163. fail "$test_name" F "Test failed in run_test_wd"
  164. fi
  165. break
  166. fi
  167. done
  168. rm -f "$output_file"
  169. rm -f "$status_file"
  170. rm -f "$sid_file"
  171. }
  172. ended_successfully() {
  173. if test -f "${FAIL_SUMMARY_FILE}" ; then
  174. echo 'Test failed, complete summary:'
  175. cat "${FAIL_SUMMARY_FILE}"
  176. return 1
  177. fi
  178. if ! test -f "${END_MARKER}" ; then
  179. echo 'ended_successfully called before end marker was touched'
  180. return 1
  181. fi
  182. return 0
  183. }
  184. end_tests() {
  185. touch "${END_MARKER}"
  186. ended_successfully
  187. }