2017年4月29日 星期六

淺談 Testflinger 的工作模型


原本的解決方案不符現在需求、也不適合大規模重構


隨著時間推移,業務型態也跟著逐漸改變。從只需要單純大量測試原生 Ubuntu 逐漸轉變到現在發展中、需要測試各種 Ubuntu 在各種平台上的表現。原本負責大量原生 Ubuntu 批次安裝與測試的 checkbox-satellite project ,其最初的設計似乎並沒有考慮到這些使用情境。與其大規模的重構來符合一個當初設想外的使用情境,或許是發展另外一套解決方案的時候了。

想克服的問題:分開安裝與系統調整兩個動作


我在最初構思新的解決方案的時候,最想解決的問題是 checkbox-satellite 因為奠基於 d-i 的成熟技術所帶來的限制。因為採用 d-i,所以 checkbox-satellite 可以說是不得不將安裝(provisioning)與調整系統(使系統能夠自我自動測試)兩個動作,透過 preseed、early command file 和 late command file 等等好用與成熟的機制高度地綁在一起。好處是這個 preseed 機制在 Debian 和 Ubuntu 社群長久的發展下,功能已經非常穩定、成熟與強大,完全能夠勝任快速開發安裝與調整原生 Ubuntu 的重責大任,缺點則是 checkbox-satellite 當用於非原生 Ubuntu 或是非支援 d-i 機制的 images 時,就要另外發展安裝(provisioning)與調整系統(使系統能夠自我自動測試)兩個動作的需求。

於是我設計了一套基本上是 master-client 式的 client-server model,將 provisioning 和 system configuration 分開,master 只需要分別在不同的階段去觸發這兩個動作、client 只需要針對觸發做回應即可,藉此來 decouple。我很快就意識到這是一個很直覺、所以應該會被大量實做的概念,例如 Puppet[1]、OpenLMI[2]和接下來要聊聊的 Testflinger[3]。

Testflinger 的工作模式:server、agent、cli


Testflinger 很自然地也是採用 master-client 的設計,不過可以再細分為 server、agent 與 cli。定位如下:


  • Testflinger server:負責接收來自 cli 的任務請求、指派任務給 agent 與回收 agent 執行結果。
  • Testflinger agent:負責去認領在 server 上面還沒有被處理的任務。實際與測試目標溝通、執行測試任務、回收測試結果並回報給 server。
  • Testflinger cli:負責觸發任務請求。


所以很自然地,deployment 會像這樣:


  • Testflinger server:裝在某台可以收、送 Restful 通訊機制的 server 即可。該 server 必須要有 Redis server 服務,因為 Testflinger server 透過 Redis 來管理任務佇列。
  • Testflinger agent:裝在某台可以收、送 Restful 通訊機制的機器上即可。通常會設定固定排程讓 agent 定期去 server 上查看有沒有還沒被認領的工作。
  • Testflinger cli:裝在某台可以收、送 Restful 通訊機制的機器上即可。通常是自己的筆電。


因此,所有的測試目標只要是能夠運作 ssh server(或任何其他能夠收到來自 agent 訊息的管道)以及 shell(或是任何其他能夠執行來自 agent 指令的方式)即可。至此 system configuration 的問題已經解決;只要是能夠透過 command line 完成的 configuration,使用這種工作模型,應該都可以滿足。

所以我們只剩下 provisioning 這個問題:那測試目標要怎麼預先準備好 ssh server 和 shell  呢?

使用 MAAS 安裝測試目標


MAAS 提供 bare metal provisioning 的一系列解決方案。因此直接使用 MAAS 將「安裝」這個動作本身,成為一個 Testflinger agent 指派的任務即可。只是 Testflinger agent 驅動的「測試目標」其實變成 MAAS controller,「測試內容」變成「觸發 MAAS controller 去安裝目標機器」。

將 Jenkins 做為 Testflinger cli 觸發來源


從以上討論,其實就暗示了 Testflinger 本質上是「安裝與觸發系統工作」的機制,這套機制如果配合其他的排程機制,基本上就是一套完整的自動化測試解決方案。例如我們可以考慮使用 Jenkins 定期透過 Testflinger cli 發出測試請求、並且回收統整 Testflinger server 的執行結果。




[1] https://docs.puppet.com/puppetserver/latest/services_master_puppetserver.html
[2] http://www.openlmi.org/
[3] 當然還有其他可能的解決方案,例如 Ansible、Chef、Salt 等等。我認為其中最重要的概念是區分自己要做的是「system configuration」還是「application configuration」,而去選擇最適合自己使用情境的。

2017年4月13日 星期四

bluez 與藍牙測試 - 簡介(一)

最近為了大量測試藍牙,稍微評估了一下常見的幾種工具來計畫自動測試的方法。摘要如下。

bluez(protocol stack): Linux kernel 所採納的最新 bluetooth (bt) stack
bluez(debian package): 基於 bluez(protocol stack) 所實做的 daemon 和 tools。

因此透過 dpkg -L bluez 可以知道很多對應的 daemon configuration file 和常用工具有哪些,包括:

顯然是透過 dbus 溝通[1]

/etc/dbus-1/system.d/bluetooth.conf

其中 main.conf 可以調整  discoverable time

/etc/init/bluetooth.conf
/etc/bluetooth/network.conf
/etc/bluetooth/proximity.conf
/etc/bluetooth/input.conf
/etc/bluetooth/main.conf

這裡看起來可以設定自動開啟

/lib/udev/rules.d/50-bluetooth-hci-auto-poweron.rules

常見個一堆工具;我自己比較常用 hciconfig(啟動、調整設備)[2]、hcitool(啟動、調整連線)、bluetoothctl(類似 hcitool, 但是是交互式操作)、obexctl(交互式操作 obex)[3]


/bin/hciconfig
......
/usr/bin/hciattach
/usr/bin/hcitool
/usr/bin/gatttool
/usr/bin/btmon
/usr/bin/l2test
/usr/bin/bluemoon
/usr/bin/ciptool
/usr/bin/bluetoothctl
/usr/bin/l2ping
/usr/bin/rctest
/usr/bin/btmgmt
/usr/bin/hex2hcd
/usr/bin/btattach
/usr/bin/obexctl
/usr/bin/bccmd
/usr/bin/sdptool
/usr/bin/rfcomm

daemon; 如果是使用桌機版,應該一開始開機完進入桌面環境之後就可以查閱這個 daemon 有沒有啟動了(例如 ps aux | grep bluetoothd)

/usr/sbin/bluetoothd


接下來幾篇來寫測試方式和自動化實做。


[1] 有幾次玩到 obexctl 退出的時候,系統抱怨 dbus connection error;應該可以從這裡開始著手除錯。
[2] 別忘了 hci 是 host control interface:用來統一操作 device 的介面;所以 hciconfig 就是「透過 hci 設置、調整藍牙裝置」(hci --> driver --> kernel --> bt device)
[3] object exchange. OBEX is "a communications protocol that facilitates the exchange of binary objects between devices." (wikipedia) 藍牙通訊協議也採納此協議為支援 protocol 的一部分。


distribution: Ubuntu 16.04