unit_test.sh 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. #!/bin/bash
  2. declare -a dirs=(dao)
  3. declare -a packages
  4. declare -a projects
  5. declare mergeUser
  6. declare commitUser
  7. declare mergeID
  8. #init env
  9. function Init(){
  10. if [ ! -d "${CI_PROJECT_DIR}/../src" ];then
  11. mkdir ${CI_PROJECT_DIR}/../src
  12. fi
  13. ln -fs ${CI_PROJECT_DIR} ${CI_PROJECT_DIR}/../src
  14. export GOPATH=${CI_PROJECT_DIR}/..
  15. }
  16. function GetPackages(){
  17. reg="library/(.*)/(.*).go"
  18. for dir in ${dirs[@]}
  19. do
  20. reg+="|app/(service|interface|admin|job)/main/(.*)/${dir}/(.*).go"
  21. done
  22. files=`.rider/changefiles.sh ${suffix} | grep -E "${reg}"`
  23. if [[ "${files}" = "" ]]; then
  24. echo "shell.GetPackages: no change files"
  25. exit 0
  26. fi
  27. for file in ${files}
  28. do
  29. # if [[ "${file}" =~ "library"* || "${file}" =~ "/mock" ]]; then
  30. if [[ "${file}" =~ "/mock" ]]; then
  31. continue
  32. fi
  33. package="go-common/$(dirname ${file})"
  34. if [[ ${packages} =~ ${package} ]]; then
  35. continue
  36. fi
  37. packages+=${package}" "
  38. packageSplit=(${package//\// })
  39. project=$(printf "%s/" ${packageSplit[@]:0:6})
  40. if [[ ${projects} =~ ${project} || ${project} =~ "/library" ]]; then
  41. continue
  42. fi
  43. projects+=${project%*/}" "
  44. done
  45. if [[ ${packages} = "" || ${projects} = "" ]]; then
  46. echo "shell.GetPackages no change packages"
  47. exit 0
  48. fi
  49. }
  50. # GetUserInfo get userinfo by gitlab result.
  51. function GetUserInfo(){
  52. gitMergeRequestUrl="${CI_SERVER_URL}/api/v4/projects/${CI_PROJECT_ID}/repository/commits/${CI_COMMIT_SHA}/merge_requests?private_token=${CI_PRIVATE_TOKEN}"
  53. gitCommitUrl="${CI_SERVER_URL}/api/v4/projects/${CI_PROJECT_ID}/repository/commits/${CI_COMMIT_SHA}/statuses?private_token=${CI_PRIVATE_TOKEN}"
  54. mergeJson=$(curl -s ${gitMergeRequestUrl})
  55. commitJson=$(curl -s ${gitCommitUrl})
  56. if [[ "${mergeJson}" = "[]" ]] || [[ "${commitJson}" = "[]" ]]; then
  57. echo "Test not run, maybe you should try create a merge request first!"
  58. exit 0
  59. fi
  60. mergeID=$(echo ${mergeJson} | jq -r '.[0].iid')
  61. mergeUser=$(echo ${mergeJson} | jq -r '.[0].author.username')
  62. commitUser=$(echo ${commitJson} | jq -r '.[0].author.username')
  63. }
  64. # Magic ignore method Check()
  65. function Magic(){
  66. url="http://git.bilibili.co/api/v4/projects/${CI_PROJECT_ID}/merge_requests/${mergeID}/notes?private_token=${CI_PRIVATE_TOKEN}"
  67. json=$(curl -s ${url})
  68. admin="haoguanwei,chenjianrong,hedan,fengshanshan,zhaobingqing"
  69. len=$(echo ${json} | jq '.|length')
  70. for i in $(seq 0 $len)
  71. do
  72. comment=$(echo ${json} | jq -r ".[$i].body")
  73. user=$(echo ${json} | jq -r ".[$i].author.username")
  74. if [[ ${comment} = "+skiput" && ${admin} =~ ${user} ]]; then
  75. exit 0
  76. fi
  77. done
  78. }
  79. # Check determine whether the standard is up to standard
  80. #$1: commit_id
  81. function Check(){
  82. curl -s "${CI_UATSVEN_URL}/x/admin/apm/ut/git/report?project_id=${CI_PROJECT_ID}&merge_id=${mergeID}&commit_id=${CI_COMMIT_SHA}"
  83. checkURL="${CI_UATSVEN_URL}/x/admin/apm/ut/check?commit_id=${CI_COMMIT_SHA}"
  84. json=$(curl -s ${checkURL})
  85. code=$(echo ${json} | jq -r '.code')
  86. if [[ ${code} -ne 0 ]]; then
  87. echo -e "curl ${checkURL} response(${json})"
  88. exit 1
  89. fi
  90. package=$(echo ${json} | jq -r '.data.package')
  91. coverage=$(echo ${json} | jq -r '.data.coverage')
  92. passRate=$(echo ${json} | jq -r '.data.pass_rate')
  93. standard=$(echo ${json} | jq -r '.data.standard')
  94. increase=$(echo ${json} | jq -r '.data.increase')
  95. tyrant=$(echo ${json} | jq -r '.data.tyrant')
  96. lastCID=$(echo ${json} | jq -r '.data.last_cid')
  97. if ${tyrant}; then
  98. echo -e "\t续命失败!\n\t大佬,本次执行结果未达标哦(灬ꈍ ꈍ灬),请再次优化ut重新提交🆙"
  99. echo -e "\t---------------------------------------------------------------------"
  100. printf "\t%-14s %-14s %-14s %-14s\n" "本次覆盖率(%)" "本次通过率(%)" "本次增长量(%)" 执行pkg
  101. printf "\t%-13.2f %-13.2f %-13.2f %-12s\n" ${coverage} ${passRate} ${increase} ${package}
  102. echo -e "\t(达标标准:覆盖率>=${standard} && 通过率=100% && 同比当前package历史最高覆盖率的增长率>=0)"
  103. echo -e "\t---------------------------------------------------------------------"
  104. echo -e "本次执行详细结果查询地址请访问:http://sven.bilibili.co/#/ut?merge_id=${mergeID}&&pn=1&ps=20"
  105. exit 1
  106. else
  107. echo -e "\t恭喜你,续命成功,可以请求合并MR了!"
  108. fi
  109. }
  110. function ReadDir(){
  111. # get go-common/app all dir path
  112. gopath=${GOPATH%..}
  113. PathDirs=`find ${gopath}app -maxdepth 3 -type d`
  114. value=""
  115. for dir in ${PathDirs}
  116. do
  117. if [[ -d "$dir" ]];then
  118. for file in `find ${dir} -maxdepth 1 -type f |grep "OWNERS"`
  119. do
  120. owner=""
  121. substr=${dir#*"go-common"}
  122. while read line
  123. do
  124. if [[ "${line}" = "#"* ]] || [[ "${line}" = "" ]] || [[ "${line}" = "approvers:" ]];then
  125. continue
  126. elif [[ "${line}" = "labels:"* ]];then
  127. break
  128. else
  129. owner+="${line:1},"
  130. fi
  131. done < ${file}
  132. value+="{\"path\":\"go-common${substr}\",\"owner\":\"${owner%,}\"},"
  133. done
  134. fi
  135. done
  136. # delete "," at the end of value
  137. value=${value%,}
  138. echo "[${value}]" > path.out
  139. }
  140. # UTLint check the *_test.go files in the pkg
  141. # $1: pkg
  142. function UTLint()
  143. {
  144. cd $GOPATH
  145. declare -i numCase=0
  146. declare -i numAssertion=0
  147. files=$(ls $1 | grep -E "(.*)_test\.go")
  148. if [[ ${#files} -eq 0 ]];then
  149. echo "RunPKGUT.UTLint no *_test.go files in pkg($1)"
  150. exit 1
  151. fi
  152. for file in ${files}
  153. do
  154. numCase+=`grep -c -E "^func Test(.+)\(t \*testing\.T\) \{$" $1/${file}`
  155. numAssertion+=`grep -c -E "^(.*)So\((.+)\)$" $1/${file}`
  156. done
  157. if [[ ${numCase} -eq 0 || ${numAssertion} -eq 0 ]];then
  158. echo -e "RunPKGUT.UTLint no test case or assertion in pkg($1)"
  159. exit 1
  160. fi
  161. }
  162. # BazelTest execute bazel coverage and go tool
  163. # $1: pkg
  164. function BazelTest(){
  165. cd $GOPATH/go-common
  166. pkg=${1//go-common//}":go_default_test"
  167. path=${1//go-common\//}
  168. bazel coverage --config=ci --instrumentation_filter="//${path}[:],-//${path}/mock[/:]" --test_env=DEPLOY_ENV=uat --test_timeout=60 --test_env=APP_ID=bazel.test --test_output=all --cache_test_results=auto --test_arg=-convey-json ${pkg} > result.out
  169. if [[ ! -s result.out ]]; then
  170. echo "==================================WARNING!======================================"
  171. echo "No test case found,请完善如下路径测试用例: ${pkg} "
  172. exit 1
  173. else
  174. echo $?
  175. cp $GOPATH/go-common/bazel-out/k8-fastbuild/testlogs/${path}/go_default_test/coverage.dat ./
  176. go tool cover -html=coverage.dat -o cover.html
  177. fi
  178. }
  179. # BazelTest execute bazel coverage for All files
  180. # $1: pkg(go-common/app/admin/main/xxx/dao)
  181. function BazelTestAll(){
  182. cd $GOPATH/go-common
  183. pkg=${1//go-common//}"/..."
  184. path=${1//go-common\//}
  185. echo "RunProjUT.BazelTestAll(${1}) pkg(${pkg}) path(${path}) pwd($(pwd))"
  186. bazel coverage --config=ci --instrumentation_filter="//${path}[/:],-//${path}/mock[/:]" --test_env=DEPLOY_ENV=uat --test_timeout=60 --test_env=APP_ID=bazel.test --test_output=all --cache_test_results=auto --test_arg=-convey-json ${pkg} > result.out
  187. find bazel-out/k8-fastbuild/testlogs/${path} -name "coverage.dat" | xargs cat | sort -nr | rev | uniq -s 1 | rev > coverage.dat
  188. coverage=$(cat coverage.dat | awk '{sum += $2;covSum += $2 * $3;} END {print covSum/sum*100}')
  189. sed -if "s/coverage: .*%/coverage: ${coverage}%/g" result.out
  190. go tool cover -html=coverage.dat -o cover.html
  191. }
  192. # upload data to apm
  193. # $1: file result.out path
  194. function Upload () {
  195. if [[ ! -f "result.out" ]] || [[ ! -f "cover.html" ]] || [[ ! -f "coverage.dat" ]]; then
  196. echo "==================================WARNING!======================================"
  197. echo "No test found!~ 请完善如下路径测试用例: ${1} "
  198. exit 1
  199. fi
  200. url="${CI_UATSVEN_URL}/x/admin/apm/ut/upload?merge_id=${mergeID}&username=${mergeUser}&author=${commitUser}&commit_id=${CI_COMMIT_SHA}&pkg=${1}"
  201. json=$(curl -s ${url} -H "Content-type: multipart/form-data" -F "html_file=@cover.html" -F "report_file=@result.out" -F "data_file=@coverage.dat")
  202. if [[ "${json}" = "" ]]; then
  203. echo "RunPKGUT.Upload curl ${url} fail"
  204. exit 1
  205. fi
  206. msg=$(echo ${json} | jq -r '.message')
  207. data=$(echo ${json} | jq -r '.data')
  208. code=$(echo ${json} | jq -r '.code')
  209. if [[ ${code} -ne 0 ]]; then
  210. echo "=============================================================================="
  211. echo -e "RunPKGUT.Upload Response. message(${msg})"
  212. echo -e "RunPKGUT.Upload Response. data(${data})\n\n"
  213. echo -e "RunPKGUT.Upload Upload Fail! status(${code})"
  214. exit ${code}
  215. fi
  216. }
  217. function RunPKGUT(){
  218. for package in ${packages}
  219. do
  220. echo "RunPKGUT.UTLint Start. pkg(${package})"
  221. UTLint ${package}
  222. echo "RunPKGUT.BazelTest Start. pkg(${package})"
  223. BazelTest ${package}
  224. echo "RunPKGUT.Upload Start. pkg(${package})"
  225. Upload ${package}
  226. done
  227. return 0
  228. }
  229. function RunProjUT(){
  230. for project in ${projects}
  231. do
  232. echo "RunProjUT.BazelTestAll Start. project(${project})"
  233. BazelTestAll ${project}
  234. echo "RunProjUT.Upload BazelTest Start. project(${project})"
  235. Upload ${project%/*}
  236. done
  237. }
  238. function UploadApp(){
  239. ReadDir
  240. url="${CI_UATSVEN_URL}/x/admin/apm/ut/upload/app"
  241. curl -s ${url} -H "Content-type: multipart/form-data" -F "path_file=@path.out" > /dev/null
  242. echo "UploadApp() UpPath has finshed."
  243. }
  244. # run
  245. Init
  246. GetPackages
  247. GetUserInfo
  248. Magic
  249. RunPKGUT
  250. RunProjUT
  251. UploadApp
  252. Check