ant+jacoco+jenkins+HttpRunnerManager代碼覆蓋率統計平台搭建
實現思路通過jenkins構建,並使用HttpRunnerManager異步實現報告更新與展示。
現在整理一下我的實現流程:

一、創建jenkins節點並啟動此節點
創建jenkins節點,並使用docker容器啟動節點。
1、jenkins系統創建nodes節點
a、系統管理 - 管理節點 - 新建節點

b、創建成功后會出現如下界面
點擊agent.jar,下載agent.jar重命名為 slave.jar

2、生成鏡像,創建並運行節點容器
a、下載所需要的環境包
ant、maven、jacoco、jdk:從官網上下載
slave.jar:就是剛才下載的agent.jar。

b、編寫dockerfile文件
FROM python:3.6.6-stretch MAINTAINER test@123.com #環境變量 ENV MASTER_DOMAIN 'jenkins_Ip:8080' #第一步中的jenkins服務器的的IP及端口 ENV AGENT_NAME 'docker-slave-jacoco-medical' #jenkins的節點名稱 ENV SECRET '1222223333344444444445556666777777666' # 第一步中的jenkins節點的SECRET #創建目錄 RUN mkdir /var/tmp/jdk /var/tmp/maven /var/tmp/slave /var/tmp/ant /var/tmp/jacoco COPY jdk1.8.0_181.tar.gz /var/tmp/jdk/ COPY apache-maven-3.5.4-bin.tar.gz /var/tmp/maven/ COPY slave.jar /var/tmp/slave/ COPY apache-ant-1.10.5-bin.tar.gz /var/tmp/ant/ COPY jacoco-0.8.1.tar.gz /var/tmp/jacoco/ #解壓 RUN tar -xzvf /var/tmp/jdk/jdk1.8.0_181.tar.gz -C /var/tmp/jdk \ && cd /var/tmp/jdk && rm -rf *.tar.gz RUN tar -xzvf /var/tmp/maven/apache-maven-3.5.4-bin.tar.gz -C /var/tmp/maven \ && cd /var/tmp/maven && rm -rf *.tar.gz RUN tar -xzvf /var/tmp/ant/apache-ant-1.10.5-bin.tar.gz -C /var/tmp/ant \ && cd /var/tmp/ant && rm -rf *.tar.gz RUN tar -xzvf /var/tmp/jacoco/jacoco-0.8.1.tar.gz -C /var/tmp/jacoco \ && cd /var/tmp/jacoco && rm -rf *.tar.gz #EXPOSE 映射端口 EXPOSE 80 #環境變量 ENV ANT_HOME /var/tmp/ant/apache-ant-1.10.5 ENV JAVA_HOME /var/tmp/jdk/jdk1.8.0_181 ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ENV CATALINA_HOME /var/tmp/maven/apache-maven-3.5.4 ENV CATALINA_BASE /var/tmp/maven/apache-maven-3.5.4 ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin:$ANT_HOME/bin #環境變量生效 #RUN source /etc/profile #運行代碼 RUN cd /var/tmp/jdk/jdk1.8.0_181/bin && ln -s java java_1.8 CMD java_1.8 -jar /var/tmp/slave/slave.jar -jnlpUrl "http://${MASTER_DOMAIN}/computer/${AGENT_NAME}/slave-agent.jnlp" -secret "${SECRET}"
c、生成鏡像文件
在dockerfile所在的目錄下運行
docker build -t docker.io/slave_jacoco_medical:latest .
d、創建並運行容器
AGENT_NAME:jenkins節點名稱 SECRET:創建節點成功界面的secret值
-e:設置環境變量 --name:容器名稱
-v:掛載,需要把代碼所在的工作目錄、報告生成的目錄掛載到宿主機上
注意:此處容器的名字與jenkins節點遠程工作目錄名字一致,這樣會給后續異步生成報告帶來便捷,此處先不過多解釋。
(可以通過傳入的AGENT_NAME、SECRET變量,生成不同項目的容器)
docker run -d --restart always -p 9001:80 -e AGENT_NAME='docker-slave-jacoco-medical' \ -e SECRET='1222223333344444444445556666777777666' \ -v /var/jenkins_jacoco_jobs/jenkins_slave_medical_jobs:/jenkins_slave_jacoco_medical \ -v /jenkins_root/jenkins_medical_root:/root \ -v /var/ant_reports/medical_reports:/var/antreports \ --name jenkins_slave_jacoco_medical docker.io/slave_jacoco_medical:latest
二、jenkins創建job,使用jacoco運行程序
1、配置jdk和maven
jenkins使用maven生成jar包,需要先安裝jdk、maven
jenkins - 系統管理 - 全局工具配置


2、創建job
注意此處需要設置為剛才創建的節點名稱

源碼管理:

3、maven構建並使用ant+jacoco啟動腳本
通過 maven -f 路徑/pom.xml install 構建 或如圖設置

通過jacoco啟動程序:“構建 - Execute shell” 設置啟動腳本

啟動程序后,可通過 http://宿主機IP:9001/訪問接口(容器對外掛載的是9001端口)
# 如果程序已經啟動,殺掉進程 count=`ps -ef | grep jacocoagent | grep -v "grep" | wc -l` if [ $count -gt 0 ]; then ps aux|grep jacocoagent|grep -v grep|awk '{print $2}'|xargs kill -9 fi # 刪除merged.exec 確保構建后覆蓋率清為0 rm -rf /docker_slave_jacoco_medical/merged.exec \ #啟動程序 && java -javaagent:/var/tmp/jacoco/jacoco-0.8.1/lib/jacocoagent.jar=includes=*,output=tcpserver,port=8048,address=127.0.0.1 -jar /jenkins_slave_medical/workspace/jacoco_medical/target/mdc-service-0.0.1-SNAPSHOT.jar &
4、創建build.xml文件,生成報告
創建build.xml
<?xml version="1.0" ?> <project name="testExec" xmlns:jacoco="antlib:org.jacoco.ant" default="jacoco"> <property name="jacocoantPath" value="/var/tmp/jacoco/jacoco-0.8.1/lib/jacocoant.jar"/> <property name="jacocoexecPath" value="./merged.exec"/> <property name="workspacePath" value="."/> <property name="reportfolderPath" value="/var/antreports/reports"/> <property name="server_ip" value="127.0.0.1"/> <property name="server_port" value="8048"/> <!-- <property name="srcApiPath" value="/docker_slave_jacoco_medical/workspace/jacoco_medical/mdc-api/src/main/java"> <property name="classApiPPath" value="/docker_slave_jacoco_medical/workspace/jacoco_medical/mdc-api/target/classes"/> --> <property name="srcServicePath" value="/docker_slave_jacoco_medical/workspace/jacoco_medical/mdc-service/src/main/java"/> <property name="classServicePath" value="/docker_slave_jacoco_medical/workspace/jacoco_medical/mdc-service/target/classes/com"/> <taskdef uri="antlib:org.jacoco.ant" resource="org/jacoco/ant/antlib.xml"> <classpath path="${jacocoantPath}" /> </taskdef> <target name="merge"> <jacoco:merge destfile="merged.exec"> <fileset dir="${workspacePath}" includes="**/*.exec"/> </jacoco:merge> </target> <target name="dump"> <jacoco:dump address="${server_ip}" reset="false" destfile="${jacocoexecPath}" port="${server_port}" append="true"/> </target> <target name="jacoco"> <delete dir="${reportfolderPath}" /> <mkdir dir="${reportfolderPath}" /> <jacoco:report> <executiondata> <file file="${jacocoexecPath}" /> </executiondata> <structure name="JaCoCo Report"> <group name="order"> <classfiles> <fileset dir="${classServicePath}" /> </classfiles> <sourcefiles encoding="UTF-8"> <fileset dir="${srcServicePath}" /> </sourcefiles> </group> </structure> <html destdir="${reportfolderPath}" encoding="utf-8" /> </jacoco:report> </target> </project>
進入容器內部執行以下命令,即可生成報告
ant dump -buildfile 路徑/build.xml
ant jacoco -buildfile 路徑/build.xml
三、覆蓋率統計報告服務器
# 搜索並拉取鏡像 docker search tomcat docker pull tomcat # 創建並運行容器,把webapp目錄掛載出來 docker run -d --restart always -p 9090:8080 -v /var/ant_reports:/usr/local/tomcat/webapps --name tomcat_ant_reports docker.io/tomcat:latest
通過http://宿主機IP:9090/medical_reports/reports/ 即可查看代碼覆蓋率報告

四、httprunnermanager異步生成報告
1、在宿主機上添加異步任務代碼

celerycon.py :
from kombu import Exchange,Queue from celery import platforms import os BROKER_URL = 'amqp://user:password@rabbitmq的ip:port//'#與httprunnerManager使用同一個rabbitmq CELERY_RESULT_BACKEND = "db+mysql://root:123456@10.8.154.123:3309/test" #CELERY_RESULT_BACKEND ="amqp" CELERY_QUEUES = ( Queue("default",Exchange("default"),routing_key="default"), Queue("for_task_A",Exchange("for_task_A"),routing_key="for_task_A"), Queue("for_task_B",Exchange("for_task_B"),routing_key="for_task_B") ) CELERY_ROUTES = { 'ApiManager.tasks.taskA':{"queue":"for_task_A","routing_key":"for_task_A"}, 'tasks.taskB':{"queue":"for_task_B","routing_key":"for_task_B"} } CELERY_ACCEPT_CONTENT = ['pickle', 'json', 'msgpack', 'yaml'] platforms.C_FORCE_ROOT = True CELERYD_MAX_TASKS_PER_CHILD = 40
tasks.py :
import os from celery import Celery app = Celery() app.config_from_object("celerycon") #獲取配置文件 @app.task(bind=True) def taskA(self, tag, queue='for_task_A'): #在本機執行shell腳本,返回執行結果的狀態,成功返回0 #tag是傳入的參數(容器名稱) lac = os.system('bash -v /opt/jacoco_work/workSc/ApiManager/ant.sh' + tag) return "Success!" if lac == 0 else "Failure!" @app.task def taskB(self,x,y,z): return x + y + z
ant.sh :
#!bin/bash docker_name=$1 sudo docker exec $docker_name bin/bash -c "ant dump -buildfile /$docker_name/build.xml && ant jacoco -buildfile /$docker_name/build.xml"
#docker_name獲取的是執行代碼時傳入的第一個參數。 #build.xml直接放在jenkins節點(容器)的遠程工作目錄下,因之前遠程工作目錄與容器名字相同,此處可以把遠程工作目錄參數化。如此以來,以后不管任何項目都可以通過參數來生成相應
項目的報告。(這就是之前容器的名字與jenkins節點遠程工作目錄名字設置一致的原因)
2、宿主機上啟動任務
#進入workSc目錄下執行: # 啟動任務 celery multi start jacoco_work -A ApiManager.tasks -l info -n worker1.%h # 停止任務 celery multi stop jacoco_work -A ApiManager.tasks -l info -n worker1.%h
3、在httprunnerManager中添加任務代碼

views.py添加
from ApiManager.tasks import * def refresh1(request): # model:容器名稱(如:jenkins_slave_jacoco_medical) name = request.POST.get('model') taskA.delay(name) data = { 'msg': name + ' started', 'id': name } return render_to_response('refresh.html', data)
tasks.py添加
@shared_task def taskA(tag): # 以下代碼不會執行 lac = os.system('bash -v /opt/jacoco_work/workSc/ApiManager/ant.sh docker_slave_jacoco_medical') return lac
4、httprunnerManager添加訪問報告的鏈接
最后在httprunnerManager平台使用 iframe 展現 http://宿主機ip:9090/medical_reports/reports/ 頁面的報告
五、應用展示
注意:構建時是從gitlab直接拉取代碼,所以構建時注意看下開發配置的環境是否為測試環境。
1、在httprunnerManager平台,選擇jacoco搭建的環境,運行用例
2、接口測試完畢后,點擊”提交“實現異步生成報告

3、通過httprunnerManager平台查看報告:

如果大家有發現什么錯誤的地方或者好的建議,歡迎評論留言指出,謝謝。
