標籤:

【技術乾貨】Rally源碼解讀系列之概覽

OpenStack經歷了與CloudStack、Eucalyptus、OpenNebula等開源IaaS平台的競爭後,現如今的OpenStack可謂是前景一片光明,尤其是在開源IaaS的層面,幾乎已經成為業界的標準。一大批致力於OpenStack商業化的公司也在蓬勃發展,而作為商業化道路的最重要節點,測試,也必不可少成為行業的一大熱點,這從OpenStack測試項目Rally的蓬勃發展中就可見一斑。

Rally

談到Rally,他和通常意義上的自動化測試工具,如:loadrunner、jmeter、qtp等相比,其優缺點都非常明顯。

傳統自動化測試軟體在針對openstack測試時其優缺點如下:

優點

  1. 節省人力:通過程序模擬大量並發操作,節省了測試人力。

  2. 完善的報表:傳統自動化測試軟體,由於在測試領域耕耘多年,積累了完善的報表輸出功能。

  3. 發壓方式:在發壓方式上,有全面的實現,除了可以按照時間,設置並發外,還可以設置階梯發壓,或者定製完全模擬線上環境的非線性發壓,在壓力產生上,可以做到多樣、準確。

  4. 時間計算:此類軟體對相應時間的計算非常精確,不僅僅會計算一個事務的相應時間,同時也會計算在腳本中,由於腳本本身(如:字元串處理,返回值驗證等)造成的時間浪費情況,進而得到更精確的事務相應時間。

  5. 支持分散式發壓,可以勝任大壓力場景。

  6. 學習成本:傳統意義上的自動化測試工具,大多在測試行業耕耘多年,積累了大量的學習資料及對工具熟悉了解的測試工程師,這樣學習成本低,人員招募也更容易。

缺點

  1. 實現複雜:由於傳統發壓軟體是已協議支持各種不同被測軟體的測試場景實現的,而針對OpenStack,一般選擇http協議,這樣實現比較複雜,需要按照介面編寫大量的實現腳本,實現效率低。

  2. 開發語言限制:python作為OpenStack的開發語言,在OpenStack公司得到廣泛的使用,但現在還沒有比較成熟的基於pathon的傳統型性能測試功能,這為軟體在公司內的推廣帶來了成本(開發人員希望通過發壓軟體實現特殊場景,但不得不去學習java或者c)。

  3. 商業成本:很多傳統自動化測試軟體都為商業軟體,其lisence價格昂貴,使用成本高。

  4. 可擴展性:由於這些自動化工具大多不是開源項目,所以限制了其軟體的擴張性。

Rally作為OpenStack社區原生的測試工具,其優缺點如下:

優點

  1. 節省人力:通過程序模擬大量並發操作,節省了測試人力。

  2. 原生性:Rally誕生於OpenStack社區,註定了其對OpenStack操作具有更好的支持,從底層使用的基礎工具包,到上層實現、業務調用模式等,無不體現著rally在openstack測試中的優越性。

  3. 共享:Rally是一個開放性軟體,其源代碼的公開,可以保證其測試結果的真實、透明。

  4. 擴展性:同時,其公開代碼,利用社區共享發展的模式,也為其功能的定製化打下基礎,其擁有更好的擴張性和適應性,在功能上也帶來了無限可能。

  5. Rally中已經預設了大量的OpenStack經典測試場景(用例)的實現,甚至大部分時候,測試人員不需要自己編寫代碼,可以直接進行測試。而在定製場景的時候,由於rally的everything is plugin(一切皆是插架)特性,決定了其一方面從代碼結構來說,具有非常便捷和自由的擴展性;另一方面,其已有的海量basis active(基礎功能模塊,如:創建虛擬機),又為實現新場景提供了良好的代碼支持。所以在效率上rally在openstack測試方面,表現優秀。

缺點

  1. 報表簡單,缺乏log等信息記錄,造成問題定位困難;

  2. 開源項目,且誕生時間比較短,其穩定性上有所欠缺,項目中還隱藏著很多bug;

  3. 發壓方式比較單一,目前僅有serial、rps、constant和constantfor duration這4中方式;

  4. 不支持分散式發壓;

  5. 學習資料比較少,學習成本高。

實際應用

通過對比以上優劣勢不難發現,Rally在OpenStack測試領域有著明顯的優勢,但是面對上面提到的劣勢,也對我們測試人員提出了更高的要求。

首先,由於Rally是在OpenStack開放平台上發張起來的測試工具,作為開源軟體,沒有經過商業化的考驗,Rally在功能上有其不穩定性,所以作為測試人員,不僅僅需要知其然,更要知其所以然。

其次,Rally添加新case,是純代碼操作,還不具備loadrunner或qtp等商業軟體的「錄製「功能,這要求使用者不僅僅需要了解自己新場景的實現方式,也要對Rally架構本身有較深入的了解。

最後,作者學習Rally的過程中,在網路上幾乎查閱了所有Rally的相關文檔,有著各種各樣的Rally項目介紹、使用說明、部署文檔,但是對其架構方面的說明文檔卻一直有所欠缺,在這裡作者希望通過對自己學習rally的一些心得進行整理、分享,拋磚引玉,引導更多的人進入Rally的世界。

認識Rally:

我們先通過簡單的操作來對Rally有個整體認識.

他主要能完成什麼功能?

Rally主要完成以下功能:

Deployment:搭建、註冊被測環境;

Plugin:顯示rally插件信息;

Show:顯示OpenStack平台當前的flavors、networks、images等信息;

Task:執行測試任務;

Verify:在rally架構下操作tempest;

Bash-completion:

Version:顯示當前rally版本;

下面,我們運行rally –help查看Rally的幫助:

可以看到上面提到的7個功能對應著7個子命令,分別是version,bash-completion,show,task,plugin,verify,deployment。這些命令涵蓋了Rally的所有功能。那麼,Rally是怎麼實現他們的呢?我們將帶著這樣的疑問進入到後面的環節。

Rally程序的入口在哪裡呢?

我們運行whereis rally來查看rally程序的入口位置:

可以看出,Rally程序的入口是從Rally.cli,main開始的。

子命令動態調用

好了,現在我們對Rally有了感性的認識,大體知道他能執行的命令和入口地址,接下來,到了深入分析的時候了,先來看Rally的整體架構,其中紅框中的內容為本文討論的信息。

rally.cli.main.main

從架構圖中可以看到,Rally程序從rally.cli.main進入後,main函數把命令參數(sys.argv)和categories作為參數傳輸給了cliutils.run。categories是一個已類為value的字典:

不難看出,這些key都和前面提到的7個子命令進行對應,但是只有5個,version和bash-completion沒有進行相應的匹配,別著急,我們繼續往後看。

rally.cli.cliutils.run

Main函數把會把參數傳入到cliutils.run中,在此函數中,主要實現以下操作:

1.讀取配置文件及前面傳入的categories(和子命令同名的類為value的字典)存儲到CONF中,CONF是OpenStack的oslo_config的實例。

註:oslo_config組件,主要是負責CLI和CONF配置項的解析,此工具包在後面我們會單獨介紹。

2.對子命令為version進行處理,顯示版本信息。

3.對自命令為bash-completion進行處理,顯示bash-completion信息。

這裡解釋了前面的疑問,為什麼7個子命令在categories中只體現了5個?原來是由於version和bash-completion的功能相對比較單一,因此在這裡直接進行了處理。

4.對子命令的參數進行檢查後,通過動態的方式,調用對應類的對應方法。

已【rally deployment list】指令為例,子命令為deployment,從CONF中獲得其對應的對象(fn):rally.cli.commands.deployment.DeploymentCommands的實例,而list為DeploymentCommands類的方法,所以此指令到這裡實際調用的是DeploymentCommands類對象的list方法。

動態調用:CONF中預先裝入所有有可能被動態調用的類(categories)實例及其對應的子命令,並組成對應關係,這裡通過子命令deployment和CONF中相應key值的對應關係,動態的調用對應的類中的方法。

後面按照不同的子命令,程序會調用不同的模塊。

子命令實現

Deployment

上文已經提到,run中會動態的調用rally.cli.commands.deployment.DeploymentCommands類的相應方法實現具體的deployment命令。通過Rally查看deployment子命令的幫助信息:

和DeploymentCommands的定義對比,你會發現在DeploymentCommands類中有和子命令一一對應的方法來完成功能實現,如:create、destroy、list、use等。而這些功能的實際實現,是調用rally.api下的對應功能完成的。

Task

和deployment類似,run中會動態調用rally.cli.commands.deployment.TaskCommands類的相應方法實現具體的task命令。通過rally查看deployment子命令的幫助信息:

同樣,TaskCommands中各方法的實現也是通過調用rally.api下的對應功能完成的

Verify

和前面類似,verify調用的是rally.cli.commands.verify.VerifyCommands類的相應方法,而在verifyCommands中同樣是調用了rally.api來具體實現功能的。

Plugin

Plugin子命令同樣是調用rally.cli.commands.plugin.PluginCommands類的相應方法,但是在PluginCommands中調用的不再是rally.api,而是調用rally.common.plugin.Plugin下的方法進行實現。

從中可以看出,plugin子命令能完成的功能很少,只有list和show這2個,我想這也是未被安排到rally.api中實現的一個原因。

Show

Show子命令和前面類似,是調用rally.cli.commands.show.ShowCommands類的相應方法,但是ShowCommands的實現,主要是通過調用rally.osclient.OSClient類實現的。

這主要是show子命令主要是實現顯示OpenStack平台相應信息(networks、flavors、images等)的功能,所以直接通過OSClient調用OpenStack的client獲取相應信息。

小結:

到這裡,我們分析了Rally對子命令的處理,deployment、task、verify、plugin、show等子命令,會動態調用rally.cli.commands下對應名稱模塊中的commands類,而到這裡,也是Rally對子命令處理的完結,後面的調用都是為了實現實際功能而做的內部調用。

結合Rally的代碼模塊(目錄結構)安排也可以看出,cli模塊中存放的主要是和指令解析有關係的代碼。

而在這些Commands類中為實現具體功能而調用的方法。在這些Commands類中,主要實現的都是對子命令的解析處理,例如設置用於argparse模塊使用的命令幫助信息等。而核心功能的實現,deployment、task、verify都是調用了rally.api模塊,plugin是調用了rally.common.plugin.Plugin,而show直接調用了rally.osclient模塊,針對這幾個模塊我們在下面的章節進行具體的分析。

經典程序模塊說明:

這裡主要列舉說在Rally中使用比較頻繁的通用模塊,如果希望深入了解Rally,需要大家對這些模塊進行熟悉。

argparse

argparse是python用於解析命令行參數和選項的標準模塊,用於代替已經過時的optparse模塊。argparse模塊的作用是用於解析命令行參數。

oslo_config

OpenStack的oslo項目旨在獨立出系統中可重用的基礎功能,oslo.config就是其中一個被廣泛使用的庫,該項工作的主要目的就是解析OpenStack中命令行(CLI)或配置文件(.conf)中的配置信息。

推薦閱讀:

OpenStack中SDN泛談1 (Neutron&ODL&ONOS)
OpenStack Neutron ML2
VLAN Trunk in OpenStack Neutron and SDN
OpenStack使用Ceph存儲,Ceph到底做了什麼?
開源大時代,EasyStack格局與勝局

TAG:OpenStack |