unit_test.sh 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. #!/bin/bash
  2. CI_SERVER_URL="http://git.bilibili.co"
  3. CI_UATSVEN_URL="http://uat-sven.bilibili.co"
  4. CI_PRIVATE_TOKEN="WVYk-ezyXKq-C82v-1Bi"
  5. CI_PROJECT_ID="682"
  6. CI_COMMIT_SHA=${PULL_PULL_SHA}
  7. exitCode=0
  8. # get packages
  9. dirs=(dao)
  10. declare packages
  11. function GetPackages(){
  12. reg="library"
  13. length=${#dirs[@]}
  14. for((i=0;i<length;i++))
  15. do
  16. reg+="|$1/"${dirs[i]}"(/.*)*"
  17. done
  18. for value in `find $1 -type d |grep -E ${reg}`
  19. do
  20. len=`ls ${value}| grep .go | wc -l`
  21. if [[ ${len} -gt 0 ]];then
  22. packages+="go-common/"${value}" "
  23. fi
  24. done
  25. }
  26. # upload data to apm
  27. # $1: SvenURL
  28. # $2: file result.out path
  29. function Upload () {
  30. if [[ ! -f "$2/result.out" ]] || [[ ! -f "$2/cover.html" ]] || [[ ! -f "$2/coverage.dat" ]]; then
  31. echo "==================================WARNING!======================================"
  32. echo "No test found!~ 请完善如下路径测试用例: ${pkg} "
  33. exit 1
  34. fi
  35. json=$(curl $1 -H "Content-type: multipart/form-data" -F "html_file=@$2/cover.html" -F "report_file=@$2/result.out" -F "data_file=@$2/coverage.dat")
  36. if [[ "${json}" = "" ]]; then
  37. echo "shell.Upload curl $1 fail"
  38. exit 1
  39. fi
  40. msg=$(echo ${json} | jq -r '.message')
  41. data=$(echo ${json} | jq -r '.data')
  42. code=$(echo ${json} | jq -r '.code')
  43. if [[ "${data}" = "" ]]; then
  44. echo "shell.Upload curl $1 fail,data return null"
  45. exit 1
  46. fi
  47. echo "=============================================================================="
  48. if [[ ${code} -ne 0 ]]; then
  49. echo -e "返回 message(${msg})"
  50. echo -e "返回 data(${data})\n\n"
  51. fi
  52. return ${code}
  53. }
  54. # GoTest execute go test and go tool
  55. # $1: pkg
  56. function GoTest(){
  57. go test -v $1 -coverprofile=cover.out -covermode=set -convey-json -timeout=60s > result.out
  58. go tool cover -html=cover.out -o cover.html
  59. }
  60. # BazelTest execute bazel coverage and go tool
  61. # $1: pkg
  62. function BazelTest(){
  63. pkg=${1//go-common//}":go_default_test"
  64. path=${1//go-common\//}
  65. bazel coverage --instrumentation_filter="//${path}[:]" --test_env=DEPLOY_ENV=uat --test_timeout=60 --test_env=APP_ID=bazel.test --test_output=all --cache_test_results=no --test_arg=-convey-json ${pkg} > result.out
  66. if [[ ! -s result.out ]]; then
  67. echo "==================================WARNING!======================================"
  68. echo "No test case found,请完善如下路径测试用例: ${pkg} "
  69. exit 1
  70. else
  71. echo $?
  72. cat bazel-out/k8-fastbuild/testlogs/${path}/go_default_test/coverage.dat | grep -v "/monkey.go" > coverage.dat
  73. go tool cover -html=coverage.dat -o cover.html
  74. fi
  75. }
  76. # UTLint check the *_test.go files in the pkg
  77. # $1: pkg
  78. function UTLint()
  79. {
  80. path=${1//go-common\//}
  81. declare -i numCase=0
  82. declare -i numAssertion=0
  83. files=$(ls ${path} | grep -E "(.*)_test\.go")
  84. if [[ ${#files} -eq 0 ]];then
  85. echo "shell.UTLint no *_test.go files in pkg:$1"
  86. exit 1
  87. fi
  88. for file in ${files}
  89. do
  90. numCase+=`grep -c -E "^func Test(.+)\(t \*testing\.T\) \{$" ${path}/${file}`
  91. numAssertion+=`grep -c -E "^(.*)So\((.+)\)$" ${path}/${file}`
  92. done
  93. if [[ ${numCase} -eq 0 || ${numAssertion} -eq 0 ]];then
  94. echo -e "shell.UTLint no test case or assertion in pkg:$1"
  95. exit 1
  96. fi
  97. echo "shell.UTLint pkg:$1 succeeded"
  98. }
  99. # upload path to apm
  100. # $1: SvenURL
  101. # $2: file result.out path
  102. function UpPath() {
  103. curl $1 -H "Content-type: multipart/form-data" -F "path_file=@$2/path.out"
  104. }
  105. function ReadDir(){
  106. # get go-common/app all dir path
  107. PathDirs=`find app -maxdepth 3 -type d`
  108. value=""
  109. for dir in ${PathDirs}
  110. do
  111. if [[ -d "$dir" ]];then
  112. for file in `find ${dir} -maxdepth 1 -type f |grep "CONTRIBUTORS.md"`
  113. do
  114. owner=""
  115. substr=${dir#*"go-common"}
  116. while read line
  117. do
  118. if [[ "${line}" = "# Owner" ]];then
  119. continue
  120. elif [[ "${line}" = "" ]]|| [[ "${line}" = "#"* ]];then
  121. break
  122. else
  123. owner+="${line},"
  124. fi
  125. done < ${file}
  126. value+="{\"path\":\"go-common${substr}\",\"owner\":\"${owner%,}\"},"
  127. done
  128. fi
  129. done
  130. # delete "," at the end of value
  131. value=${value%,}
  132. echo "[${value}]" > path.out
  133. }
  134. # start work
  135. function Start(){
  136. GetPackages $1
  137. if [[ ${packages} = "" ]]; then
  138. echo "shell.Start no change packages"
  139. exit 0
  140. fi
  141. #Get gitlab result
  142. gitMergeRequestUrl="${CI_SERVER_URL}/api/v4/projects/${CI_PROJECT_ID}/repository/commits/${CI_COMMIT_SHA}/merge_requests?private_token=${CI_PRIVATE_TOKEN}"
  143. gitCommitUrl="${CI_SERVER_URL}/api/v4/projects/${CI_PROJECT_ID}/repository/commits/${CI_COMMIT_SHA}/statuses?private_token=${CI_PRIVATE_TOKEN}"
  144. mergeJson=$(curl -s ${gitMergeRequestUrl})
  145. commitJson=$(curl -s ${gitCommitUrl})
  146. if [[ "${mergeJson}" != "[]" ]] && [[ "${commitJson}" != "[]" ]]; then
  147. merge_id=$(echo ${mergeJson} | jq -r '.[0].iid')
  148. exitCode=$?
  149. if [[ ${exitCode} -ne 0 ]]; then
  150. echo "shell.Start curl ${gitMergeRequestUrl%=*}=*** error .return(${mergeJson})"
  151. exit 1
  152. fi
  153. username=$(echo ${mergeJson} | jq -r '.[0].author.username')
  154. authorname=$(echo ${commitJson} | jq -r '.[0].author.username')
  155. else
  156. echo "Test not run, maybe you should try create a merge request first!"
  157. exit 0
  158. fi
  159. #Magic time
  160. Magic
  161. #Normal process
  162. for pkg in ${packages}
  163. do
  164. svenUrl="${CI_UATSVEN_URL}/x/admin/apm/ut/upload?merge_id=${merge_id}&username=${username}&author=${authorname}&commit_id=${CI_COMMIT_SHA}&pkg=${pkg}"
  165. echo "shell.Start ut lint pkg:${pkg}"
  166. UTLint "${pkg}"
  167. echo "shell.Start Go bazel test pkg:${pkg}"
  168. BazelTest "${pkg}"
  169. Upload ${svenUrl} $(pwd)
  170. exitCode=$?
  171. if [[ ${exitCode} -ne 0 ]]; then
  172. echo "shell.Start upload fail, status(${exitCode})"
  173. exit 1
  174. fi
  175. done
  176. # upload all dirs
  177. ReadDir
  178. pathUrl="${CI_UATSVEN_URL}/x/admin/apm/ut/upload/app"
  179. UpPath ${pathUrl} $(pwd)
  180. echo "UpPath has finshed...... $(pwd)"
  181. return 0
  182. }
  183. # Check determine whether the standard is up to standard
  184. #$1: commit_id
  185. function Check(){
  186. curl "${CI_UATSVEN_URL}/x/admin/apm/ut/git/report?project_id=${CI_PROJECT_ID}&merge_id=${merge_id}&commit_id=$1"
  187. checkURL="${CI_UATSVEN_URL}/x/admin/apm/ut/check?commit_id=$1"
  188. json=$(curl -s ${checkURL})
  189. code=$(echo ${json} | jq -r '.code')
  190. if [[ ${code} -ne 0 ]]; then
  191. echo -e "curl ${checkURL} response(${json})"
  192. exit 1
  193. fi
  194. package=$(echo ${json} | jq -r '.data.package')
  195. coverage=$(echo ${json} | jq -r '.data.coverage')
  196. passRate=$(echo ${json} | jq -r '.data.pass_rate')
  197. standard=$(echo ${json} | jq -r '.data.standard')
  198. increase=$(echo ${json} | jq -r '.data.increase')
  199. tyrant=$(echo ${json} | jq -r '.data.tyrant')
  200. lastCID=$(echo ${json} | jq -r '.data.last_cid')
  201. if ${tyrant}; then
  202. echo -e "\t续命失败!\n\t大佬,本次执行结果未达标哦(灬ꈍ ꈍ灬),请再次优化ut重新提交🆙"
  203. echo -e "\t---------------------------------------------------------------------"
  204. printf "\t%-14s %-14s %-14s %-14s\n" "本次覆盖率(%)" "本次通过率(%)" "本次增长量(%)" 执行pkg
  205. printf "\t%-13.2f %-13.2f %-13.2f %-12s\n" ${coverage} ${passRate} ${increase} ${package}
  206. echo -e "\t(达标标准:覆盖率>=${standard} && 通过率=100% && 同比当前package历史最高覆盖率的增长率>=0)"
  207. echo -e "\t---------------------------------------------------------------------"
  208. exitCode=1
  209. else
  210. echo -e "\t恭喜你,续命成功,可以请求MR了"
  211. fi
  212. }
  213. # Magic ignore method Check()
  214. function Magic(){
  215. url="http://git.bilibili.co/api/v4/projects/${CI_PROJECT_ID}/merge_requests/${merge_id}/notes?private_token=${CI_PRIVATE_TOKEN}"
  216. json=$(curl -s ${url})
  217. for comment in $(echo ${json} | jq -r '.[].body')
  218. do
  219. if [[ ${comment} == "+skiput" ]]; then
  220. exit 0
  221. fi
  222. done
  223. }
  224. # run
  225. Start $1
  226. echo -e "【我们万众一心】:"
  227. Check ${CI_COMMIT_SHA}
  228. echo -e "本次执行详细结果查询地址请访问:http://sven.bilibili.co/#/ut?merge_id=${merge_id}&&pn=1&ps=20"
  229. if [[ ${exitCode} -ne 0 ]]; then
  230. echo -e "执行失败!!!请解决问题后再次提交。具体请参考:http://info.bilibili.co/pages/viewpage.action?pageId=9841745"
  231. exit 1
  232. else
  233. echo -e "执行成功."
  234. exit 0
  235. fi