云原生災(zāi)備產(chǎn)品HyperBDR自動化測試實踐
HyperBDR是一款基于云原生理念的遷移和容災(zāi)產(chǎn)品,核心的業(yè)務(wù)場景是將源端以塊級別差量方式同步至云原生存儲中,目前已經(jīng)實現(xiàn)對塊存儲和對象存儲支持,最后再利用Boot-in-Cloud專利技術(shù)將業(yè)務(wù)系統(tǒng)一鍵式恢復(fù)至可用狀態(tài),真正做到了對云原生編排能力的充分利用,滿足遷移和災(zāi)備等業(yè)務(wù)場景的不同需求。
HyperBDR目前已經(jīng)支持的源端操作系統(tǒng)大版本就將近10個(
Windows/CentOS/Redhat/Ubuntu/SUSE/國產(chǎn)化操作系統(tǒng)),小版本更是超過幾百個,而在目標(biāo)目標(biāo)云平臺也陸續(xù)支持了將近40個(公有云、專有云、私有云、超融合、虛擬化等),并且數(shù)量還在增加。假設(shè)我們將源端的操作系統(tǒng)到全部云平臺進(jìn)行一次覆蓋性測試,組合的測試用例可能超過10000個。
這么大規(guī)模的情況下想做到測試覆蓋,單純依靠人力顯然不現(xiàn)實,必須引入自動化測試手段對核心業(yè)務(wù)場景進(jìn)行測試,這樣不僅可以滿足自動化測試的需要,也可以在日常開發(fā)過程中及時讓開發(fā)人員在新開發(fā)功能中對核心流程的影響,進(jìn)一步提升產(chǎn)品的穩(wěn)定性和可靠性。
痛點分析
我們先來看一下手工測試情況下,HyperBDR產(chǎn)品測試的幾個痛點:
痛點一、測試用例多,人力資源不足
在上述源端和目標(biāo)端的規(guī)模情況下,即使做一些基本冒煙,一次完整的測試的場景用例也依然有一百多種。例如:
- ? 源端(19種):CentOS(6/7/8)、Redhat(6/7/8)、SUSE(11/12)、Ubuntu(14.04/16.04/18.04/20.04)、Windows(2003/2008/2012/2016/2019)、Oracle Linux、國產(chǎn)化操作系統(tǒng)
- ? 目標(biāo)端(9種):OpenStack、AWS、阿里云、騰訊云、華為云、移動云、ZStack、超融合產(chǎn)品、超融合產(chǎn)品
如此計算下來,一次測試的場景是171種。可能有的同學(xué)會說,這些用例也不是很多呀,跑一次也用不了多久,所以接下來讓我們看一下HyperBDR在測試過程中第二個痛點:測試周期問題。
痛點二、測試周期長
不同于業(yè)務(wù)測試,HyperBDR單一場景的測試是非常耗時的,我們先忽略前期資源準(zhǔn)備時間和各種配置時間,單純就數(shù)據(jù)同步和啟動過程進(jìn)行一下分析:
- ? 數(shù)據(jù)同步:簡單來說數(shù)據(jù)同步的過程就是將源端操作系統(tǒng)內(nèi)的有效數(shù)據(jù)(不是分配容量),以塊級別方式讀出,寫入到目標(biāo)的云原生存儲中。其中,第一次為全量,后續(xù)為永久增量。以Windows為例,假設(shè)有效數(shù)據(jù)為500G,如果按照千兆局域網(wǎng)帶寬80%利用率計算,傳輸速度大概在800 Mbps,大約為80 MB/s,耗時約為1小時8分鐘。
- ? 主機(jī)啟動:根據(jù)不同的云原生存儲類型,啟動時間有很大的差異性,例如華為云的塊存儲,由于快照機(jī)制以及可以支持交換系統(tǒng)盤,所以啟動時間與容量基本沒有關(guān)系,基本可以控制在5分鐘之內(nèi)。但是對于國內(nèi)的大多數(shù)云平臺來說,并沒有這樣的能力,像阿里云在有快照生成卷時,底層限速為40 MB/s,這樣一下子就拉長了恢復(fù)實踐。我們以對象存儲為例,假設(shè)我們從內(nèi)網(wǎng)(Internal網(wǎng)絡(luò))將對象存儲數(shù)據(jù)恢復(fù)至塊存儲,一個500G有效數(shù)據(jù)磁盤的恢復(fù)時間大約在40分鐘左右。
所以我們在處理單一主機(jī)的一次測試,耗時至少在2個小時之內(nèi)。按照上面假設(shè)的場景,一天測試下來,可能連一朵云的完整測試都無法完成??赡苓@里又有同學(xué)說了,你為什么不并發(fā)呀?這又引出了我們第三個痛點問題:成本。
痛點三、測試成本
之所以無法完全采用并發(fā)的原因,是受限于網(wǎng)絡(luò)帶寬因素。在內(nèi)部研發(fā)環(huán)境中,我們的外網(wǎng)帶寬只有40Mbps,在上述測試場景中,500G的數(shù)據(jù)在帶寬充分利用的前提下,全量數(shù)據(jù)傳輸?shù)臅r間在35小時左右。這無疑進(jìn)一步擴(kuò)大了一次測試的周期。
另外一點,源端這么多環(huán)境,如果再加上不同場景,需要占用的源端的計算和存儲資源是海量的。隨著產(chǎn)品不停地迭代,資源占用會越來越多。所以為了解決這一問題,我們決定采用部分公有云環(huán)境,來解決本地資源不足的問題。根據(jù)資源使用的特點,主要采用按量計費方式,實現(xiàn)成本最優(yōu)。在實際測試過程中,主要產(chǎn)生的云資源包括:計算、塊存儲、對象存儲、網(wǎng)絡(luò)等。在自動化測試中,盡可能縮短資源周期,避免浪費,及時清理資源。另外,還需要對資源賬單情況進(jìn)行監(jiān)控,避免資源殘留。
需求分析
基本原則:不要重復(fù)制造輪子
進(jìn)行自動化測試開發(fā)工作,并沒有增加新的開發(fā)人員。開發(fā)工作主要由研發(fā)團(tuán)隊負(fù)責(zé),測試團(tuán)隊作為使用方。但是由于開發(fā)團(tuán)隊有自身產(chǎn)品研發(fā)任務(wù),所以為了避免對產(chǎn)品研發(fā)造成影響,制定的第一個原則就是不要重復(fù)制造輪子,盡可能復(fù)用現(xiàn)有技術(shù)積累和第三方組件,靈活的實現(xiàn)自動化測試的目標(biāo)。
需求一、源端自動化創(chuàng)建與銷毀
首先要解決的就是源端資源的靈活創(chuàng)建,而這方面最簡單的就是利用Terraform,結(jié)合不同的模板實現(xiàn)源端資源創(chuàng)建和銷毀能力。這樣,我們至少擁有了阿里云、華為云、AWS、OpenStack、VMware五大云作為源端的能力。
第二個要解決的是代理方式自動化注冊問題。源端主機(jī)需要進(jìn)行Agent安裝和注冊后,才能被HyperBDR識別進(jìn)行后續(xù)流程。根據(jù)操作系統(tǒng)不同,又分為Linux和Windows系統(tǒng)。Linux系統(tǒng)中,可以使用SSH登錄系統(tǒng)后執(zhí)行安裝,而Windows則是利用WinRM方式進(jìn)行Agent安裝。
第三,可擴(kuò)展性滿足更多場景化需求。雖然Terraform本身提供了remote執(zhí)行方式,但是為了后續(xù)的可擴(kuò)展性,可以結(jié)合Ansible實現(xiàn)相關(guān)功能。未來的測試場景可能還包含對源端各種應(yīng)用數(shù)據(jù)完整性的測試,此時在準(zhǔn)備源端時還需要額外的準(zhǔn)備應(yīng)用和數(shù)據(jù),使用Terraform結(jié)合Ansible,可以實現(xiàn)最大的靈活性。
需求二、測試場景與測試工具解耦,滿足擴(kuò)展性需求
簡單來說,自動化測試程度越高,開發(fā)成本越高,后期維護(hù)的成本會更高。因此在規(guī)劃自動化測試時,要降低測試場景和測試工具之間的耦合性。這樣才能最大程度滿足測試場景的可擴(kuò)展性。換言之,測試場景是由測試工具進(jìn)行靈活組合實現(xiàn)的,而二者之間的差距是通過各種配置文件進(jìn)行融會貫通。
具體到HyperBDR的自動化測試規(guī)劃中,我們將場景定義為:
- ? 為了驗證主線流程的穩(wěn)定性,我們設(shè)計了這樣的場景:阿里云的一臺CentOS 7操作系統(tǒng)主機(jī),容災(zāi)到阿里云對象存儲中,利用該數(shù)據(jù),主機(jī)可以正常啟動,系統(tǒng)啟動后,可以正常ping通IP地址,可以正常SSH到系統(tǒng)內(nèi)部,寫入一個文件
- ? 為了驗證華為云驅(qū)動的穩(wěn)定性,我們設(shè)計的場景如下:將阿里云的N臺主機(jī)(包含各個版本的操作系統(tǒng)),容災(zāi)到華為云的對象存儲或塊存儲中,再將主機(jī)在華為云進(jìn)行啟動,啟動后,利用ping通IP地址,可以正常登錄系統(tǒng),寫入一個文件
- ? 為了驗證增量數(shù)據(jù),我們設(shè)計的場景如下:將阿里云的N臺主機(jī)安裝數(shù)據(jù)庫,并且構(gòu)建一定量數(shù)據(jù)進(jìn)行記錄,容災(zāi)到華為云對象存儲中,再將主機(jī)在華為云進(jìn)行啟動,啟動后,除了常規(guī)驗證外,還要對數(shù)據(jù)庫是否可以訪問以及數(shù)據(jù)記錄條數(shù)進(jìn)行比對
而測試工具提供的能力上,我們進(jìn)行了這樣的定義:
- ? 源端創(chuàng)建/刪除資源:完全由Terraform實現(xiàn),但是為了后續(xù)程序更好的銜接,在產(chǎn)生主機(jī)后,自動產(chǎn)生一個conf文件,作為后續(xù)命令的輸入,而主機(jī)內(nèi)不同的應(yīng)用則通過編寫Ansible模板實現(xiàn)
- ? 目標(biāo)平臺配置/數(shù)據(jù)同步/啟動主機(jī)/清理資源:這幾部分主要通過調(diào)用HyperBDR SDK實現(xiàn),而具體的配置則在配置文件中進(jìn)行修改,如果是不同場景時,只需要不同的配置文件即可實現(xiàn)
以上全部的步驟,均是可以單獨執(zhí)行的,而每一步完成后,寫入統(tǒng)一的CSV文件,這樣步驟在連接時可以通過該文件形成統(tǒng)一性。后續(xù)可以將該CSV文件直接推送到數(shù)據(jù)可視化工具中,形成趨勢展現(xiàn)的效果。
需求三、實現(xiàn)場景自動化,測試失敗及時通知
在實際應(yīng)用中,幾乎從研發(fā)到交付的整個過程中都需要使用該工具。比如研發(fā)同學(xué)在提交代碼前,至少需要對基本流程進(jìn)行一次測試;交付同事在搭建一些演示環(huán)境時,也可以利用該腳本提高效率;而測試同事更是對這個工具有強(qiáng)烈的需求。
那么真正的不同場景自動化工作,則是由Jenkins任務(wù)完成串聯(lián),并且在測試失敗后,可以及時通知大家,盡快進(jìn)行修改。例如:每個小時,做一次小的冒煙測試,確保主線流程是否穩(wěn)定;每天凌晨,做一次基本冒煙,確保已經(jīng)支持云平臺的穩(wěn)定性;每周做一次大冒煙,確保主要的操作系統(tǒng)版本的穩(wěn)定性。這樣不僅節(jié)約了人力資源,也能第一時間發(fā)現(xiàn)版本中的不穩(wěn)定因素。
實現(xiàn)方式
整體架構(gòu)
根據(jù)上面的需求,完整的工具包含兩部分:
- Terraform:主要包含了源端創(chuàng)建使用的模板以及ansible playbooks,Terraform在每次執(zhí)行后,會自動產(chǎn)生源端主機(jī)列表,用于AutoTest工具的命令行輸入?yún)?shù)
- AutoTest工具:使用Python語言開發(fā),主要通過對HyperBDR SDK調(diào)用控制HyperBDR實現(xiàn)自動化流程調(diào)度,各個階段都是通過獨立命令行進(jìn)行控制,所有的可變部分在配置文件進(jìn)行修改
- AutoTest配置文件包含以下三部分配置:
- 基本配置:HyperBDR SDK鑒權(quán)信息,以及平臺整體配置
- 目標(biāo)云平臺配置:目標(biāo)云平臺鑒權(quán)信息,配置參數(shù)等,根據(jù)不同的存儲類型分為塊存儲和對象存儲
- 容災(zāi)/遷移配置:用于定義主機(jī)在目標(biāo)端的啟動參數(shù)
Terraform創(chuàng)建資源并遠(yuǎn)程執(zhí)行指令
Terraform的使用方面,有很多教程,這里不再贅述。這里主要說明一些Terraform使用的一些細(xì)節(jié)功能,滿足Terraform于AutoTest之間的腳本串聯(lián)。
內(nèi)置方法remote-exec
Terraform創(chuàng)建資源后,會自動安裝Agent注冊到HyperBDR中,為了減少遠(yuǎn)程主機(jī)操作復(fù)雜度,這里將Agent上傳至新創(chuàng)建的主機(jī),再進(jìn)行安裝實現(xiàn)自動注冊。
Terraform本身通過provisioner提供遠(yuǎn)程連接、上傳并執(zhí)行的方式,基本結(jié)構(gòu)如下:
如果是Windows,則連接方式為winrm方式,這里要注意的一點是,啟動的資源必須已經(jīng)開啟了WinRM,否則無法使用該方式進(jìn)行連接。一種開啟WinRM方式是利用user-data方式。這里看一下具體的示例
與Ansible結(jié)合
直接利用Terraform的遠(yuǎn)程執(zhí)行方式很簡便,但是對于更多的復(fù)雜場景在支持上,并不夠靈活,所以我們引入Ansible來加強(qiáng)我們對資源的控制。與remote-exec相對應(yīng)的指令是local-exec,即通過執(zhí)行本地的Ansible指令實現(xiàn)對遠(yuǎn)程資源的控制。目錄結(jié)構(gòu)如下:
我們將Ansible Playbooks存放在單獨的目錄中,Terraform中實現(xiàn)方式如下:
輸出
為了串接Terraform和AutoTest,我們需要Terraform每次執(zhí)行后,輸出一個主機(jī)列表,包含了一些基本信息,當(dāng)然這也可以作為Ansible Inventory文件使用。利用local_file resource,直接將我們想要寫入的內(nèi)容定向輸出到文件中。具體實現(xiàn)如下:
Terraform本地緩存
由于眾所周知的原因,Terraform在執(zhí)行init命令的時候,會訪問github,這就造成安裝過程中有一定的失敗概率,為了減少失敗的風(fēng)險,需要采用本地緩存的方式,避免訪問網(wǎng)絡(luò)造成的風(fēng)險。先來看一下目錄結(jié)構(gòu):
install.sh用于將下載好的terraform二進(jìn)制包進(jìn)行解壓縮安裝,同時會將plugins-cache拷貝至$HOME/.terraform.d目錄,最后生成.terraformrc文件。
在實際執(zhí)行時,通過指定參數(shù)實現(xiàn)從本地執(zhí)行安裝,這種方式網(wǎng)上大部分文檔都沒有提及到:
在構(gòu)建plugins-cache時,我們主要使用terraform providers mirror命令,例如:
為此我們在項目中增加了一個腳本,來自動化更新我們的緩存:
Taskflow串聯(lián)執(zhí)行流程,實現(xiàn)擴(kuò)展性
在AutoTest工具開發(fā)過程中,我們主要復(fù)用了OpenStack部分Python模塊簡化開發(fā),主要使用的模塊為stevedore和taskflow,另外為了簡化CSV文件操作,使用了pandas庫來進(jìn)行操作。
利用驅(qū)動方式擴(kuò)展命令行
在setup.cfg中,我們定義了下面的驅(qū)動,每一個指令對應(yīng)一個Taskflow的執(zhí)行流程。
在代碼加載時,通過輸入而不同參數(shù),動態(tài)加載相應(yīng)的流水線:
利用Taskflow串接流程
Taskflow是OpenStack中非常優(yōu)秀的庫,對Task執(zhí)行過程進(jìn)行了抽象后,方便上層上時序業(yè)務(wù)場景使用。所以在應(yīng)用中為了簡化開發(fā)過程,在Taskflow之上做了適當(dāng)?shù)某橄?,將?zhí)行過程和執(zhí)行內(nèi)容進(jìn)行分離,即基類中進(jìn)行執(zhí)行,而子類中只需要定義相關(guān)具體的任務(wù)即可。
基類代碼示例如下:
一個具體的子類實現(xiàn)如下:
通過上述抽象,可以很快速的利用HyperBDR SDK實現(xiàn)各種應(yīng)用場景,最大程度滿足后續(xù)可擴(kuò)展性的需求。
Jenkins串聯(lián)自動化測試流程
工具實現(xiàn)后,不僅可以滿足手工分步執(zhí)行的需要,也可以利用Jenkins串接流程,滿足場景自動化測試的需求。
場景自動化
我們在git中新建一個項目,名稱為autotest-cases,用于自動化場景測試。示例結(jié)構(gòu)如下:
我們以場景名稱命名目錄,每一個目錄下均有單獨一套的terraform模板和hyperbdr配置文件。這樣定義Jenkins任務(wù)時,就可以把測試場景作為一個目錄,靈活的進(jìn)行加載。
其中Jenkinsifle的基本結(jié)構(gòu)為:
通過對每一階段的定義,能夠清晰的了解每一階段執(zhí)行的結(jié)果以及失敗的原因,最終將結(jié)果發(fā)送至釘釘中,及時了解當(dāng)前代碼的穩(wěn)定性。
異常處理
在整個自動化測試流程中,如果在中間任何一個步驟失敗,都需要對資源進(jìn)行及時清理,避免對下一次測試的影響。所以定義一個全局的失敗,進(jìn)行強(qiáng)制資源清理。
總結(jié)
目前,在HyperBDR的日常開發(fā)中,我們還在不斷完善自動化測試的場景,但是經(jīng)過這一輪的實現(xiàn),讓我對自動化測試有了全新的認(rèn)知。
自動化測試能否實現(xiàn)全面覆蓋呢?至少在HyperBDR中不行,因為HyperBDR的源端和目標(biāo)端造成了測試場景的不可預(yù)期性,很難完全通過自動化腳本來模擬出復(fù)雜場景,特別是異常場景。例如:對源端主機(jī)內(nèi)部的破壞性測試,對數(shù)據(jù)傳輸鏈路的一些攻擊場景,需要配合監(jiān)控才能發(fā)現(xiàn)是否滿足預(yù)期。這些場景,利用自動化測試模擬開發(fā)代價太大,而且可能發(fā)生的場景還在不斷變化,根本無法滿足版本快速迭代的需求。當(dāng)然你如果有一個幾百人的研發(fā)團(tuán)隊,專門做這件事情,那另當(dāng)別論,不過這樣的投入產(chǎn)出比是否合理,值得探討。
自動化測試中,哪些該”自動“,哪些該”手動“?在實現(xiàn)自動化測試過程中,不要盲目的追求”自動“。自動程度越高,開發(fā)成本越高,靈活性大打折扣,導(dǎo)致可利用的場景較少,這反而與預(yù)期相違背。以HyperBDR場景為例,倒不如將每個流程進(jìn)行切分,實現(xiàn)局部自動化,實現(xiàn)多個工具形成工具集,再用流程串聯(lián)方式構(gòu)建場景化。
后續(xù)的計劃有哪些?隨著產(chǎn)品不停的迭代,自動化測試還將不斷的擴(kuò)展,除了支持代理方式,還會增加對無代理方式、塊存儲方式自動化的支持,但是這些的開發(fā)模式全部以上述框架為前提。上述測試主要還是針對接口的測試,對于前端的測試還將引入Selenium實現(xiàn),實現(xiàn)的范圍仍然以主線流程為主。最后,逐步豐富數(shù)據(jù)測試場景,增加對數(shù)據(jù)完整性的測試。
隨著DevOps理念逐步改變傳統(tǒng)研發(fā)流程,自動化測試作為其中的一環(huán)也是必不可少的,也是未來開發(fā)人員必備的技能之一。但是自動化測試不同于產(chǎn)品研發(fā),要學(xué)會”斷“的思想,理解測試的需求和場景,才能做出適配性最好的自動化測試工具。