(一)先看測試業務的情況:
有各種各樣的任務包括代碼構建、部署搭建、單元測試、功能自動化測試(包括許多模塊的功能自動化測試,有十幾個居多),性能測試、正確性驗證;復雜一點的是這些任務在不同的測試階段中都必須部署一套,一般測試至少都需要有三套環境:dailyrun環境、兩套test環境用來測試不同版本。日常每天有每日構建環境,正式版本發布有發布環境。要做到持續集成,則每天晚上都需要運行所有的構建、部署、ut、ft、性能、正確性,這些任務達到五十五個,彼此之間存在依賴關系,功能測試則由於資源有限不得不也做成前后依賴模式,占用資源比較多的分開運行。
問題有:
(1)原本使用jenkins默認的任務依賴模式,修改任務調度次序的時候就會很悲劇,每個回歸都需要從頭到尾的修改一次;
(2)當前一個任務由於各種原因超時或者是執行失敗的時候后面所有任務都等待,到了第二天要手工全部殺掉,否則無法運行;
(3)任務過多以后查找也很麻煩,難以找到對應任務的鏈接,每次翻都翻到手痛;遇到版本發布更痛苦,每個jenkins任務中git地址的版本都需要修改。
(4)測試結果用郵件發送的,沒有地方可以看到全部回歸的整體情況,比如某天掛了,並不能立即知道是build階段、deploy階段、ut階段或者是ft的具體某個階段的問題,還是要一層層去調查;
(二)我們的解決方案:
首先,這個系統要能夠替代jenkins的任務依賴關系,在修改任務依賴的時候可以通過全局配置,這樣解除掉問題1;
其次,每個任務設置超時時間去監控jenkins執行情況,當超時的時候殺死掉當前任務,同時不影響下面任務的執行,這就解決問題2;
第三,把jenkins信息和每個階段信息存放到mysql中,其中配置修改直接通過調用jenkins api,修改git地址,修改配置相關信息,這樣就解決問題3;
第四,當第一個任務做完以后,調度獨立以后,可以獲取到每個階段執行是否成功的情況,測試報告同時上傳到mysql數據庫中,前端再用個web系統展示。
jenkins 提供了一整套api體系,可以觸發任務,獲取任務狀態,可修改任務配置,將這些調用串起來。
為了能有效利用回歸機器資源,設置機器池子,運行jenkins任務的時候從池子中隨機獲取機器進行下發,這樣全部配置信息都來自於數據庫中,規避測試過程中各種配置不對的情況。
一個tip對於jenkins slave機器本身,使用ssh模式啟動,jenkins master會通過監控手段確保slave failover操作,當slave掛的時候master會啟動,不需要人工操作。
下面是任務依賴的配置
[ [{"jobname":"Cupid","slave":"TEST3-JK-10"}], [{"jobname":"Cupid-HiveTest","slave":"TEST3-JK-1"}], [{"jobname":"git-console","slave":"TEST3-JK-10.1"}], [{"jobname":"git-console-public","slave":"TEST3-2"}], [{"jobname":"OpenMrLocal","slave":"TEST3-JK-10"}], [{"jobname":"OpenMrOnLot","slave":"TEST3-JK-10"}], [{"jobname":"Graph","slave":"TEST3-JK-1222"}], [{"jobname":"MR","slave":"TEST3-JK-101"}], [{"jobname":"SqlTask-Finance","slave":"TEST3-JK-1180"}], [{"jobname":"SqlTask-Lot","slave":"TEST3-JK-1010"}], [{"jobname":"Moye","slave":"TEST3-JK-10"}], [{"jobname":"Security","slave":"TEST3-JK-1"}], [{"jobname":"SqlTask-Chinese","slave":"TEST3-JK-1"}], [{"jobname":"SqlTask-ServiceMode","slave":"TEST3-JK-1"}], [{"jobname":"SqlTask-Taobao","slave":"TEST3-JK-1"}], [{"jobname":"XLib","slave":"TEST3-JK-1"}], [{"jobname":"RESTFulAPI","slave":"TEST3-JK-1"},{"jobname":"RESTFulAPI-AdminTask","slave":"TEST3-JK-1"},{"jobname":"RESTFulAPI-Event","slave":"TEST3-JK-1"}], [{"jobname":"CopyTask","slave":"Test-1"}], [{"jobname":"ReplicationTask","slave":"Test-10"}], [{"jobname":"MetaTest-FromFinance","slave":"TEST3-JK-1"}], [{"jobname":"Console-UT","slave":"TEST3-JK-1693"}], [{"jobname":"SDK-UT","slave":"TEST3-JK-100"}], [{"jobname":"PL-492","slave":"1"}], [{"jobname":"FT-gcc492","slave":"Test-vm-13"}], [{"jobname":"RESTApi-FT","slave":"Test-vm-13"}], [{"jobname":"FT","slave":"Test-vm-10"}], [{"jobname":"Api-FT-gcc492","slave":"Test-vm-1"}], [{"jobname":"CppSdk-FT-gcc492","slave":"Test-vm-1"}], [{"jobname":"OldSdk-FT-gcc492","slave":"Test-vm-1"}], [{"jobname":"Lot","slave":"TEST3-JK-1"}] ]
該配置文件中用逗號分隔的表示任務是並行執行的關系,放在一個中括號里面用大括號分隔表示其前后存在依賴關系,執行完畢前面的才是后面的。下面是調用這個配置的主程序入口,這里的startbuilds會去讀取任務配置,API是對各種jenkins api的包裝
# -*- coding: utf-8 -*- import jenkins import sys reload(sys) sys.setdefaultencoding('utf-8') sys.path.append("./pkg") sys.path.append("./pkg/jenkinsapi") sys.path.append("./pkg/pytz") sys.path.append("./pkg/requests") sys.path.append("../watchmen/watchmen_upload/") import common ,cfg ,watchmen_upload from param import get_job_xml,get_job_slave,get_job_cfgparam,get_job_child,getAllJob,gendict,rerun,build_job_poll,build_job if __name__ == "__main__": print "start job dependencies" if len(sys.argv) < 2: print "please input the jobName" exit(1) args = sys.argv[1] print "jobName===>"+args api = jenkins.API() stime= common.getNow() api.startbuild(args)
下面的函數對jenkins里面的git配置進行修改
def modify_branch(jobname,new_branch): print(jobname) if jobname=="None" or jobname is None : return jkserver=jenkins.API().get_jenkins_instance() job=jkserver.get_job(jobname) try: branch=job.get_scm_branch() except Exception,e: print e return print(branch) job.modify_scm_branch(new_branch) branch=job.get_scm_branch() print(branch)
測試運行結果收集這塊,測試平台提供一個restful接口,每個模塊的報告最后調用一下這個接口,首先把自己的報告上傳到遠程的一個ftp上面,然后再把模塊名稱、環境名稱、成功失敗用例個數,這些信息上報上去,接口會存放這些信息到數據庫中,在前端webserver予以展示。