日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

结合jenkins以及PTP平台的性能回归测试

發(fā)布時間:2025/7/14 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 结合jenkins以及PTP平台的性能回归测试 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

此文已由作者余笑天授權(quán)網(wǎng)易云社區(qū)發(fā)布。

歡迎訪問網(wǎng)易云社區(qū),了解更多網(wǎng)易技術(shù)產(chǎn)品運(yùn)營經(jīng)驗(yàn)。


1背景簡介

1.1 jenkins

Jenkins是一個用Java編寫的開源的持續(xù)集成工具。在與Oracle發(fā)生爭執(zhí)后,項(xiàng)目從Hudson項(xiàng)目復(fù)刻。Jenkins提供了軟件開發(fā)的持續(xù)集成服務(wù)。它運(yùn)行在Servlet容器中(例如Apache Tomcat)。它支持軟件配置管理(SCM)工具(包括AccuRev SCM、CVS、Subversion、Git、Perforce、Clearcase和RTC),可以執(zhí)行基于Apache Ant和Apache Maven的項(xiàng)目,以及任意的Shell腳本和Windows批處理命令。Jenkins的主要開發(fā)者是川口耕介。Jenkins是在MIT許可證下發(fā)布的自由軟件。可以通過各種手段觸發(fā)構(gòu)建。例如提交給版本控制系統(tǒng)時被觸發(fā),也可以通過類似Cron的機(jī)制調(diào)度,也可以在其他的構(gòu)建已經(jīng)完成時,還可以通過一個特定的URL進(jìn)行請求。

1.2 PTP平臺

?????? 性能測試一直是業(yè)界重點(diǎn)關(guān)注的部分,但是復(fù)雜的性能測試過程卻讓很多人望而生畏:管理測試用例、收集測試數(shù)據(jù)、進(jìn)行數(shù)據(jù)分析、編寫測試報告,每一項(xiàng)都需要耗費(fèi)很多心血。
于是,PTP平臺就這樣應(yīng)運(yùn)而生了,它是網(wǎng)易自主開發(fā)的自動化性能測試平臺,致力于將性能測試過程自動化、標(biāo)準(zhǔn)化、一體化,并且將性能測試過程持續(xù)起來,進(jìn)行更多數(shù)據(jù)分析。

?

2自動化流程

2.1創(chuàng)建任務(wù)

?????? QA管理員擁有新建節(jié)點(diǎn)權(quán)限,如需增加新節(jié)點(diǎn),請找各自的QA管理員。QA管理員在Jenkins上添加一個新節(jié)點(diǎn)步驟如下:

(1)點(diǎn)擊鏈接進(jìn)入

(2)輸入節(jié)點(diǎn)名稱,節(jié)點(diǎn)名稱通常以服務(wù)器hostname或者機(jī)器描述命名,比如qa10.server,ddb-23.photo,QA_AutoTest_1等。

(3)選擇Dumb Slave選項(xiàng),點(diǎn)擊OK按鈕

(4)輸入以下設(shè)置:

a.# of executors:輸入執(zhí)行器的個數(shù)(一個或者多個):這個值控制著Jenkins并發(fā)構(gòu)建的數(shù)量, 因此這個值會影響Jenkins系統(tǒng)的負(fù)載壓力。使用處理器個數(shù)作為其值會是比較好的選擇。

b.Remote FS root:輸入slave機(jī)器作為持續(xù)集成Home的路徑

c.Labels:用來對多節(jié)點(diǎn)分組,在目前杭研的應(yīng)用中,我們一般設(shè)置其跟節(jié)點(diǎn)名稱一樣

d.用法:一般選只運(yùn)行綁定到這臺機(jī)器的job

e.Launch Method選擇Launch slave agents via Java Web Start

(5)保存

Node Properties可設(shè)置環(huán)境變量,如果不設(shè)置就會使用jenkins主機(jī)上全局定義的環(huán)境變量,如下圖所示:

更詳細(xì)的創(chuàng)建教程可參見wiki:http://doc.hz.netease.com/pages/viewpage.action?pageId=36463105

2.2 自動化環(huán)境部署

?????? Jenkins上添加配置好的節(jié)點(diǎn),如下所示:

編寫自動化部署腳本:

import?requests import?time import?os import?sys#?web?is?deployed?on?two?servers,the?arguments?in?url:moduleId,envId,instanceId test_web_arg_1?=?('***','***','***') basi_url?=?'http://omad.hz.netease.com/api'productId?=?'***' envName='urs-regzj-perftest' branch='perftest_jenkins'def?get_token(appId,?appSecret):r?=?requests.get(basi_url?+?'/cli/login?appId=%s&appSecret=%s'?%?(appId,?appSecret)).jsonreturn?r['params']['token']def?deploy_web(appId,?appSecret,moduleId,envId):test_web_url?=?'/cli/deploy?token=%s&moduleId=%s&envId=%s'%(get_token(appId,?appSecret),moduleId,?envId)r?=?requests.get(basi_url?+?test_web_url).jsonprint?'Deploy?result:'def?get_status(appId,?appSecret,envId,instanceId):status_url?=?'/cli/istatus?token=%s&envId=%s&instanceId=%s'%(get_token(appId,?appSecret),?envId,?instanceId)r?=?requests.get(basi_url?+?status_url).jsonreturn?r['deployStatus'],r['status']def?check_deploy_result(appId,?appSecret,envId,instanceId):status?=?get_status(appId,?appSecret,envId,instanceId)print?'building?.......'times?=?0while?status[0]?==?'success':status?=?get_status(appId,?appSecret,envId,instanceId)times?+=?1

該過程主要是調(diào)用OMAD接口實(shí)現(xiàn)了自動化部署,分為以下幾個步驟:

(1)調(diào)用/api/cli/login接口獲取個人token信息;

(2)調(diào)用/api/cli/vcchange接口對指定產(chǎn)品的指定環(huán)境切換成指定分支;

(3)調(diào)用/api/cli/ls接口獲取當(dāng)前用戶有權(quán)限的所有產(chǎn)品的所有工程的信息;

(4)調(diào)用/api/cli/deploy接口對指定環(huán)境的指定分支進(jìn)行構(gòu)建部署。

執(zhí)行方式為python omad.py AccessKeyAccessSecret,其中$AccessKey和$AccessSecret為登錄OMAD后的個人認(rèn)證信息。

?

2.3 自動化腳本調(diào)試

????? 在腳本執(zhí)行前,我們需要腳本調(diào)試這個過程,該過程用來驗(yàn)證腳本是否能被正確執(zhí)行,若腳本本來就存在問題等到執(zhí)行時再去發(fā)現(xiàn)問題就可能浪費(fèi)大量執(zhí)行時間,因此在這個階段,我們需要執(zhí)行一次腳本,并驗(yàn)證腳本是否正確。

????? 首先我們需要將所有的腳本上傳到節(jié)點(diǎn)上,并保證該節(jié)點(diǎn)機(jī)安裝有一些壓測工具,這里以grinder為例,首先需要配置grinder.properties文件,以我的例子來說明:

script1?=?createUser script2?=?updateUinfo script3?=?updateToken script4?=?getUserInfo script5?=?setSpecialRelation script6?=?updateUserID script7?=?getToken script8?=?addFriend script9?=?getFriendRelation script10?=?updateRelationship script11?=?addGroup script12?=?queryTeam script13?=?queryTeamNoUser script14?=?joinTeams script15?=?sendTeamMsg script16?=?SendCustomMessage script17?=?sendGroupMessage script18?=?sendBatchAttachMsg script19?=?sendBatchMsg script20?=?kickgrinder.script?=?Serial.py grinder.processes?=?1 grinder.threads?=?1 grinder.runs?=?1

script.*代表是待調(diào)試腳本的名稱,Serial.py是主腳本名,grinder.processes ,grinder.threads,grinder.runs 分別是grinder的進(jìn)程,線程,以及運(yùn)行次數(shù),因?yàn)檫@部分主要是調(diào)試腳本,這里的參數(shù)全部設(shè)置為1。Serial.py實(shí)際是一個串行腳本,它負(fù)責(zé)順序執(zhí)行各腳本,代碼如下所示:

from?net.grinder.script.Grinder?import?grinder from?java.util?import?TreeMap #?TreeMap?is?the?simplest?way?to?sort?a?Java?map. scripts?=?TreeMap(grinder.properties.getPropertySubset("script")) #?Ensure?modules?are?initialised?in?the?process?thread. for?module?in?scripts.values():exec("import?%s"?%?module) def?create_test_runner(module):x=''exec("x?=?%s.TestRunner()"?%?module)return?x class?TestRunner:def?__init__(self):self.testRunners?=?[create_test_runner(m)?for?m?in?scripts.values()]#?This?method?is?called?for?every?run.def?__call__(self):#create_test_runner()for?testRunner?in?self.testRunners:?testRunner()

?????? 執(zhí)行完該腳本后需要驗(yàn)證該腳本的正確性,我的做法是驗(yàn)證classb-im14-0-data.log下的日志信息,讀取error列的值,具體代碼如下:

info?=?[] f?=?open('result.txt',?'w') path?=?os.getcwd() #print?path path+='/logs' os.chdir(path) path?=?os.getcwd() #print?path file=open('classb-im14-0-data.log','r') count=len(file.readlines()) while(count!=interfaceNum):count=len(file.readlines()) file=open('classb-im14-0-data.log','r') for?line?in?file:info.append(line.strip())if?line.find("Thread")>=0:continueelse:vec=line.split(',')if?vec[5].strip()!='0':#print?vec[5]str=testIdToScene(vec[2].strip())if?str==None:f.write('testId?does?not?exit')excuteflag=Falsebreakelse:str+=('?Error\n')f.write(str)flag=False if?flag==True?and?excuteflag==True:f.write('All?interfaces?have?been?successfully?executed') f.close() file.close()

?????? 以上腳本實(shí)現(xiàn)了讀取error值的功能,但是在jenkins上即使執(zhí)行過程中產(chǎn)生錯誤,只要構(gòu)建過程中每個程序的退出狀態(tài)是正常的,仍然會顯示構(gòu)建成功,為此需要編寫以下腳本,使腳本執(zhí)行失敗時保證該構(gòu)建過程同時失敗:

#!/bin/bash if?grep?"All?interfaces?have?been?successfully?executed"?result.txt thenecho?"result?is?right"exit?0 elseecho?"result?is?wrong"exit?1 fi

?????? 該腳本在有腳本執(zhí)行失敗的情況下會強(qiáng)制退出狀態(tài)為1,從而使得構(gòu)建失敗。

?

2.4 自動化腳本執(zhí)行以及結(jié)果收集

?????? 腳本執(zhí)行需要借助ptp平臺的插件,具體如圖所示:

?????? 執(zhí)行完成后,需要獲取PTP平臺的執(zhí)行結(jié)果,判斷執(zhí)行過程中是否有錯誤產(chǎn)生,具體腳本如下所示:

import?os flagSucess=True path?=?os.getcwd() path_pertest=path path+='/projects' path_curr=path f=open("/home/qatest/monitorTools/conf/topnFilesRes.txt") file?=?open('result.txt',?'w') info=[] for?line?in?f:tmp=line.strip()path+="/"+tmpinfo.append(path)path=path_curr for?i?in?info:i+="/logs"os.chdir(i)fileSize?=?os.path.getsize("error_grinder.log")if?fileSize!=0:flagSucess=Falseos.chdir(path_pertest)i?+=?"?make?an?error"file.write(i) if?flagSucess: file.write("All?rounds?have?been?successfully?executed")

完成該部分后需要將測試結(jié)果持久化到數(shù)據(jù)庫,這部分的思路是調(diào)用平臺的/api/v1.0/round/${roundId}/summary接口,解析json數(shù)據(jù),然后插入到數(shù)據(jù)庫,具體代碼如下。

首先需要利用httpclient獲取該接口的結(jié)果然后進(jìn)行解析:

public?class?GetRoundsAndJasonParse {@SuppressWarnings("finally")public??String??getJasonRes(String?roundID)?throws?HttpException{String?res=null;String?prefix="http://perf.hz.netease.com/api/v1.0/round/";prefix+=roundID;?prefix+="/summary";HttpClient?client?=?new?HttpClient();GetMethod?getMethod?=?new?GetMethod(prefix);try{??client.executeMethod(getMethod);//res?=?new?String(getMethod.getResponseBodyAsString());BufferedReader?reader?=?new?BufferedReader(new?InputStreamReader(getMethod.getResponseBodyAsStream()));StringBuffer?stringBuffer?=?new?StringBuffer();?String?str?=?"";?while((str?=?reader.readLine())!=null){?stringBuffer.append(str);?}?res?=?stringBuffer.toString();?}?catch?(HttpException?e){e.printStackTrace();}finally{getMethod.releaseConnection();return?res;}}public?ArrayList<Perf>?getValue(JsonObject?json,String[]?key){FormattingPerf?fp?=?new?FormattingPerf();ArrayList<Perf>?res=new?ArrayList<Perf>();ArrayList<String>?values=new?ArrayList<String>();??????String?machine_name=null;String?test_id=null;String?tmp=null;try{//if(json.containsKey(key))String?resStr?=?json.get("success").getAsString();if(resStr.equals("false"))System.out.println("Check?your?roundID");else{JsonArray?array=json.get("data").getAsJsonArray();??for(int?i=0;i<array.size();i++){JsonObject?subObject=array.get(i).getAsJsonObject();machine_name=subObject.get("machine_name").getAsString();test_id=subObject.get("test_id").getAsString();if(machine_name.equals("all")&&!test_id.equals("0")){for(int?j=0;j<key.length;j++){tmp=subObject.get(key[j]).getAsString();values.add(tmp);}Perf?perf=new?Perf(values);fp.formatPerf(perf);res.add(perf);values.clear();}}??}}catch?(Exception?e){e.printStackTrace();}??return?res;}@SuppressWarnings("finally")public??ArrayList<Perf>?parseJason(String?jasonbody)?throws?JsonIOException,?JsonSyntaxException{//ArrayList<String>?res=new?ArrayList<String>();ArrayList<Perf>?res=new?ArrayList<Perf>();JsonParser?parse?=new?JsonParser();try{JsonObject?json=(JsonObject)?parse.parse(jasonbody);String[]?key={"test_id","perf_round_id","tps","response_ave","response90","err_rate","mean_response_length"};res=getValue(json,key);}?catch?(JsonIOException?e){e.printStackTrace();}catch?(JsonSyntaxException?e){e.printStackTrace();}finally{return?res;}}

然后需要進(jìn)行進(jìn)行數(shù)據(jù)持久化的操作,這部分的代碼實(shí)現(xiàn)的方式有多重,就不在此贅述,至此完成了自動化回歸的部分過程,后續(xù)的結(jié)合哨兵監(jiān)控以及對資源、性能數(shù)據(jù)進(jìn)行進(jìn)一步分析可以做更多的工作,歡迎有興趣的同學(xué)一起來討論。



免費(fèi)體驗(yàn)云安全(易盾)內(nèi)容安全、驗(yàn)證碼等服務(wù)

更多網(wǎng)易技術(shù)、產(chǎn)品、運(yùn)營經(jīng)驗(yàn)分享請點(diǎn)擊。




相關(guān)文章:
【推薦】?MySQL InnoDB 索引原理
【推薦】?如何用GO實(shí)現(xiàn)一個tail -f功能以及相應(yīng)的思維發(fā)散

轉(zhuǎn)載于:https://www.cnblogs.com/zyfd/p/9887562.html

總結(jié)

以上是生活随笔為你收集整理的结合jenkins以及PTP平台的性能回归测试的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。