樹狀結構系統支援支援功能

  • 專案負責人:shayba@google.com、ananthak@google.com、fsamuel@google.com
  • 專案合作夥伴:borthakur@google.com、jasoncampbell@google.com、 lite@google.com、ppi@google.com
  • 領域:測試

問題陳述

目前,Fuchsia 平台和產品開發人員對樹狀結構外系統測試的需求不是未獲滿足,就是使用錯誤的工具,導致測試涵蓋範圍不足或測試品質不佳。

以 Fuchsia 為基礎的產品開發 (在 Fuchsia 來源樹狀結構外部進行,也就是樹狀結構外或 OOT) 很大程度依賴未經過沙箱處理的系統測試,這些測試會在平台嚴格定義的合約外部執行 Fuchsia 平台。這是因為平台元件大多不提供支援的方式來執行檢測設備,以滿足產品測試需求。測試作者已找到解決這些限制的方法,但這些解決方案會導致測試品質不佳。

如果 Fuchsia 平台開發程序受到 OOT 測試影響,導致平台合約遭到規避,Fuchsia 的更新能力就會受到威脅。

什麼是系統測試?

系統測試是在組裝完成的系統上進行的測試,目的是驗證系統是否符合特定需求。在實用測試金字塔中,系統測試可補足單元測試和整合測試的不足之處,填補測試缺口,因為只有觀察測試狀態下的完整系統,才能解決這些問題。

系統測試有時也稱為:

  • 端對端 (或 e2e) 測試,尤其是系統測試範圍超出特定目標裝置,還包括透過網路介面的遠端伺服器或控制主體機器時。

  • 關鍵使用者歷程 (CUJ) 測試,特別是當測試以模擬和自動化使用者輸入和輸出表示時,例如插入按鈕按下等輸入事件,並將 UI 狀態摘要或螢幕截圖與預期測試結果進行比較。

此外,這些測試可以進一步進行儀器化,以產生額外價值,表示為:

  • 效能測試:除了執行產品 CUJ 之外,測試架構也會收集效能資訊,例如時間、追蹤記錄、FPS 統計資料等。

  • 耐久性測試:在緊密迴圈中執行相同的 CUJ,並監控系統是否有資源洩漏 (RAM、控制代碼等) 或當機等壓力跡象。

此外,還有一個完整的系統測試類別,可執行平台功能,並在樹狀結構內開發。這些不在本文的涵蓋範圍內。

目前在 Fuchsia 上進行系統測試面臨的挑戰

非密封的舊版 (v1) 元件測試

Fuchsia 的元件架構提供廣泛的測試支援,測試環境與系統其他部分之間的高度隔離。系統仍支援舊版 (CFv1) 測試,可用於測試尚未遷移至 CFv2 的舊版元件。雖然大部分的生產元件仍為 CFv1,但由於 CFv2 測試架構更可靠,且為開發人員提供一些新功能,因此大多數測試 (>70%) 都使用 CFv2 測試架構。

基於舊版原因,v1 測試執行階段在許多方面都不具密封性,例如允許存取特定實際系統服務。因此,許多 CFv1 測試實際上會無意間充當系統測試。這些測試有許多問題,包括:

  • 測試範圍過於廣泛或未嚴格定義,因此測試失敗時,可能難以排解問題。

  • 測試可能會受到外部狀態影響,或將外部狀態當做副作用。因此,這些測試可能會與其他這類系統測試發生交叉通訊,導致無法重現的失敗 (不穩定),或是在不穩定的情況下重現失敗,例如以不同順序重新執行相同測試。

  • 測試會假設其他系統元件的實作詳細資料超出其合約範圍。

  • 元件測試架構的設計宗旨,是編寫獨立的密封單元測試和整合測試。在這種測試中,任何失敗原因都只能來自測試領域。由於預期會隔離,因此任何兩項測試都應可並行或以任何順序執行,且不會影響結果。使用已淘汰的 CFv1 功能來破壞測試沙箱並編寫系統測試,會破壞這些保證,並造成疑難排解困難。許多這類測試的作者並未意識到,他們實際上是在進行系統測試。

違反 Fuchsia 系統介面的 OOT CUJ 測試

對於 OOT 軟體,與 Fuchsia 平台互動的預期和支援方式是透過 Fuchsia 系統介面 (FSI)。不過,目前 OOT 開發人員可使用工具,讓測試作者略過這個介面,並違反平台產品合約。

Fuchsia 指令碼層 (SL4F) 是一種系統自動化架構,專為編寫全面系統測試而開發。

SL4F 的靈感來自 Android 腳本層 (SL4A)。這個工具原本是為樹狀結構內平台系統測試而設計,特別是 SL4F,對於移植「Android 通訊測試套件 (ACTS)」測試等項目很有幫助,因為這些測試會使用相同的基礎 JSON-RPC/HTTPS 通訊協定來驅動目標裝置。這項安排對 Fuchsia 連線測試非常實用。

SL4F 是系統自動化架構,因此也可用於測試 CUJ。舉例來說,SL4F 可支援平台 CUJ 測試。

不過,SL4F 並非專為 OOT 測試設計。與 SL4F 互動時,使用的通訊協定並非 FSI,因此無法提供與 FIDL 相同的演進機制。如要擴充 SL4F 的自動化功能,可以導入新的 Facade,但所有 Facade 都必須樹狀結構內開發及建構。因此,在測試定義及開發 OOT 的產品 CUJ 時,使用 SL4F 會導致下列部分問題。

另一種常見機制是使用 SSH 取得遠端殼層,並在主機和目標之間複製檔案,這類機制允許進行過於侵入性的測試。請勿將此與使用 SSH 做為通道通訊協定混淆,後者可用於 Overnet 的傳輸。

目前 Fuchsia 的工程建構版本包含 SSH Daemon,可透過未經過沙箱處理的存取權執行全域命名空間,並將 dash 殼層提供給用戶端。這個精靈也允許 SCP 功能,以類似程度的讀取/寫入權限存取全域命名空間,例如全域可變動儲存空間。這通常會成為規避 FSI 的方式,讓測試作者透過觀察或變更可變動儲存空間中的狀態,違反平台元件的支援介面,並因此依賴平台實作詳細資料,例如 Fuchsia 基礎套件的名稱。

測試作者可透過 Dart 中的 SL4F 用戶端程式庫,輕鬆使用執行個體的安全殼層和 SCP 存取權。

測試模式不穩定

SL4F 提供多種方法,供測試作者操控及觀察系統狀態。其中部分機制會略過平台產品合約和必要的抽象層。撰寫 SL4F 測試時,不一定需要使用這些機制,而且並非所有測試都必須使用這些機制。但這些邀請函的歡迎存在會將許多反模式帶入我們的 SL4F 測試庫存。

值得注意的是,由於平台無法提供完善的替代方案來滿足測試需求,因此這些模式是因應需要而開發。我們在下方列出這些模式,並非要批評平台開發人員或測試作者,而是為了瞭解及分類我們現在必須償還的技術債。

透過非合約觀察狀態

受測程式碼可能會將狀態相關資訊發送至系統記錄或透過 Inspect。這些實用工具可將執行個體的診斷資訊收集到快照中。但這些範本並非合約。Fuchsia 會使用 FIDL 定義強型別合約,這些合約可穩定運作,並具有演進機制,例如與二進位檔相容的線路格式變更和版本控管,讓未協調的用戶端和伺服器交換 FIDL 訊息。FIDL 經過精心設計,可達成這個目的,但任意文字記錄和檢查功能則不然。

以下是幾個值得注意的具體範例

測試記錄:部分耐久性測試會使用以「錯誤」或更高嚴重性等級註解的記錄,判斷產品在測試期間是否承受非預期的壓力。很遺憾,從測試作者的角度來看,測試執行期間發出的「錯誤」訊息通常實際上是良性的。因此,長期測試的作者難免會維護記錄的錯誤訊息許可清單。

在測試中檢查:部分測試驅動程式會從驅動的元件讀取檢查資訊,以觀察這些元件的狀態。由於 Inspect 是已輸入的資料,且可做為單一連貫的快照取得,因此對於元件作者來說,這是診斷元件目前狀態的實用工具。不過,如果將其做為平台元件和產品測試之間的合約,就會導致 ABI 脆弱,且經常造成中斷。這類中斷問題很難排解,因為可能是在基礎平台變更發布數週後,嘗試推出 SDK 時發生。

透過非合約操作狀態

SL4F 測試可大幅控管主機,包括在未經過沙箱處理的殼層 (即透過全域命名空間) 執行任意 SSH 指令,以及對全域不可變動和可變動儲存空間進行完整讀取/寫入存取。以下是幾個重要範例:

終止及重新啟動程序:這通常用於測試的設定和終止常式。這項意圖是正面的,測試想清除任何先前的狀態,然後重新開始。不過,受測平台元件不一定經過測試,因此可能無法多次重新啟動或以不同順序啟動,這通常會導致不穩定的行為。

這種做法的另一個問題是,OOT 測試會終止平台程序,導致程序名稱 (不屬於平台合約) 成為合約。這類違反預期介面和合約的行為,會導致平台重構更加困難,且 OOT 測試會變得更加脆弱。

操控可變動的儲存空間:這項明顯的沙箱違規行為通常用於注入使用者憑證,做為特定 CUJ 測試的設定步驟。系統不會操作預期的憑證插入介面,而是在受測程式碼讀取該狀態之前,先插入狀態。如果時間不正確,測試就會失敗。如果清除作業失敗,後續測試可能會因暴露於測試串擾而失敗。

全域可變動檔案系統存取的另一個用途,是將全域 /tmp 儲存空間目錄做為測試結果、構件和診斷資訊的暫存區,例如在測試期間收集的效能追蹤記錄。同樣地,測試可能會無法清理狀態、透過串音相互影響,或透過其他方式插入錯誤或不穩定的行為。

不同元件例項的獨立儲存空間目錄會由同一分割區管理,因為為不同元件建立個別分割區的成本高昂且缺乏彈性。在共用磁碟分割區上建立特定目錄版面配置,即可達到隔離效果。目錄版面配置會反映平台實作詳細資料,例如元件拓撲,或元件管理服務如何將該拓撲轉換為檔案系統部分。這些同樣是平台實作詳細資料,隨時可能變動,因此不應向 OOT 測試公開。

結果

在同一個測試中,同時進行開放式測試和封閉式測試,會產生不穩定的組合,導致測試品質不佳,也就是測試會設定不相關的期望,並以軟體設計不支援的方式協調及觀察狀態。

目前的情況是長期忽略系統測試工具,導致 Fuchsia 平台無法提供這類工具。儘管如此,我們發現許多異國情調的測試不符合現有類別,也不符合測試最佳做法。

更糟的是,這些測試所依賴的平台實作詳細資料,是以不允許演進的方式表示。舉例來說,FSI 的許多部分都是以 FIDL 精確定義。平台開發人員可透過 FIDL 進行 ABI 相容變更,或偵測特定變更是否會導致現有 ABI 損毀。FIDL 提供多種方式,讓開發人員變更型別和通訊協定,而不必破壞 ABI,或以受控方式導入破壞性變更:穩定的通訊協定方法序數、彈性表格、版本管理等。

相較之下,使用程序名稱做為合約 (例如為了讓測試終止程序) 就屬於這種情況。平台元件實作的程序名稱絕不會是 FSI 的一部分,部分原因是沒有演進的功能提示,任何變更都會是破壞性變更,沒有版本管理的功能提示,而且很少能同時執行舊程序和新程序,以提供暫時的相容性窗口。全域檔案系統路徑、內部檔案格式、任意文字記錄和其他這類非合約內容也適用相同規定。

缺少 OOT 支援

SL4F 用戶端可以與平台映像檔中包含的 SL4F Daemon 通訊,藉此自動化系統。平台映像檔會透過 Fuchsia SDK 捲動發布給 OOT 測試人員。Daemon 可以執行不同任務,協調及檢查系統狀態,並將這些任務分組為「門面元件」。系統的這項切面通常運作良好,因為這是穩定的合約,而且有合理的手段可隨著時間演進。

不過,開發外觀只能在樹狀結構內完成,也就是說,目前無法擴充系統自動化功能。這並非 SL4F 的意外屬性,因為 SL4F 本來就不是設計給 OOT 用戶端使用。

獨立堆疊

SL4F 提供設定、裝置探索、主機目標網路傳輸通訊協定、部分擴充機制,以及將用戶端程式庫和工具提供給 SDK 客戶的解決方案。

ffx 也解決了同樣的問題,而且可以說是做得更好。開發 ffx 外掛程式時,如果主機端外掛程式需要目標端協作元件來控制目標,則可以開發 FIDL Proxy。主機和目標之間的通訊接著會以 FIDL 定義,這與透過 HTTP 的 JSON-RPC 不同,可以成為 FSI 的一部分,並隨著平台和 SDK 的其餘部分演進為合約。部分原因在於,相較於結構定義僅存在於程式碼中的未輸入 JSON 合約,維護與 FIDL 的 ABI 相容性較為容易。

此外,ffx 堆疊更瞭解 Fuchsia 元件,例如知道何時及如何啟動測試所需的元件。此外,它還能解決 SL4F 堆疊未處理的問題,例如主機目標驗證。這樣一來,您就能在 userdebug 建構類型中使用 ffx,而 SL4F 只能在 eng 建構中使用。

其他自訂測試架構

除了上述解決方案,還有其他現成可用的測試解決方案。這些測試涵蓋完整的測試範圍,但由於未採用平台本身的測試隔離機制,因此大多會以系統測試的形式進行。

部分 OOT 合作夥伴共用同一組測試解決方案和工具,但部分內容不一致。這導致技術債不斷增加。

解決方案聲明

Fuchsia 平台團隊將在樹狀結構內和 OOT 中建立健全的系統測試解決方案。平台團隊會與產品團隊合作,瞭解產品測試需求、滿足這些需求,並協助產品團隊進行任何遷移作業。

新解決方案將採用元件架構ffx外掛程式的沙箱功能,以:

  1. 讓使用者能夠輕鬆編寫出色的測試,包括出色的系統測試。
  2. 盡量避免 (甚至完全禁止) 編寫違反 Fuchsia 平台嚴格定義和支援合約的測試。

具體情形如下:

盡可能推動元件化單元和整合測試

如果 OOT 測試可以重新實作為在測試領域中執行的元件,以產生密封單元測試或整合測試,我們就會重新實作。為啟用並推廣更健全的測試金字塔,我們將支援 OOT 元件測試,與樹狀結構內元件測試保持一致。

重新實作所有非密封的 CFv1 測試

凡是存取實際系統服務而違反密封性的現有舊版 CFv1 測試,都會以其他條件重新實作,以滿足相同或更高的測試需求。這些測試要以密封式 CFv2 元件測試、新的系統測試或其他形式重新實作,取決於受測程式碼的擁有者。

如果平台測試支援不足或缺漏 (例如 CFv1 元件擁有者無法遷移至 CFv2),相關平台團隊會與測試擁有者合作,建立必要的平台解決方案。

為產品擁有者建立新的系統測試平台解決方案

Fuchsia 平台團隊將為產品負責人開發新解決方案,撰寫符合下列條件的系統測試:

  1. 您可以開發及執行 OOT 系統測試。

  2. 您只能透過一種方式叫用這些測試並收集結果,確保無論是在本機開發人員工作流程中執行測試,還是透過某些 CI/CQ 自動化機制執行相同測試,都能遵循相同的工作流程,並在任何地方獲得一致的結果。

  3. 平台詳細資料 (例如 Fuchsia 系統介面中定義的內容) 不屬於預期合約,因此不會向 OOT 系統測試開發人員公開。如要啟用必要層級的沙箱,測試和測試架構 (如尚未遷移) 將會遷移至 CFv2。

  4. 系統測試架構會盡可能與 ffx 共用堆疊。包括設定、主機工具和用戶端程式庫發布機制、版本管理、設定、目標裝置探索、主機目標驗證、主機目標傳輸,以及遠端控制機制。

  5. 平台系統元件擁有者可以 (也將) 擴充系統測試架構,以滿足產品開發人員的測試需求。這麼做可讓平台開發人員建立可維護的 ABI,並長期擁有這些可測試性合約。

減少及淘汰舊版解決方案

平台和產品團隊將攜手合作,淘汰先前的解決方案,並在各處採用新的核准系統測試架構。除非有特殊誘因 (例如為了跨平台測試套件相容性),否則長期而言不會使用舊版測試解決方案。

優先順序

相關團隊可能會視情況決定工作優先順序。不過,我們建議您優先處理最難擁有和維護的測試,例如先解決技術債曲線的頂端。

無論選擇哪些特定工作,在考慮可採取哪些行動來償還技術債時,系統測試現代化工作都會被視為高優先順序工作。

依附元件

為縮小平台測試差距,並開發及推出新架構,需要多個平台團隊 (包括元件架構、測試架構、SDK 工具、EngProd 測試和 EngProd 基礎架構) 共同合作。

此外,所有產品合作夥伴團隊和多位平台元件擁有者也必須共同努力,找出可測試性方面的缺口,並遷移至新的測試架構和解決方案。

風險與緩解措施

系統測試的範圍並非特定元件或封裝,而是整個受測系統。因此,實際測試的程式碼並未嚴格定義。從某個架構遷移系統測試時,可能也會失去系統測試的附帶好處,也就是某些有益的測試涵蓋範圍。

部分系統測試的範圍非常廣泛,因此重新實作的門檻非常高。建議您先縮小範圍或拆分部分測試,這項步驟可能很有幫助。

部分現有系統測試沒有專屬的長期擁有者。這類廢棄軟體難以使用,而且部分遷移工作勢必會由不同人員負責。

如要採用現代化解決方案 (尤其是 OOT),必須進行 OOT 和產品端的 CFv2 遷移作業。CFv2 遷移作業已取得重大進展,但目前重點在於系統元件,尚未開始遷移 OOT 或產品端元件。因此,我們有理由預期會出現未知的封鎖程式。

與往常一樣,償還技術債務會與團隊的其他優先事項競爭。領導階層必須達成共識,才能有效執行這項轉移作業。

不適用

樹狀結構內系統測試

本文不適用於樹狀結構內開發的測試。雖然上述工作可能帶來意外收穫,有助於樹狀結構內系統測試,但樹狀結構內測試的問題描述與此處討論的內容差異甚大,因此不在此處討論。舉例來說,樹狀結構內測試可以在 Fuchsia 平台介面下方運作,同時不影響 Fuchsia 的可更新性原則和目標。

元件測試

如要瞭解元件測試 (即以一或多個元件表示的測試,這些元件會實作單元測試或整合測試),請參閱樹狀結構外元件測試支援的路線圖文件

特殊攜碼規定

在特殊情況下,您可能需要在 Fuchsia 上執行現有的測試套件,以證明與其他實作的相容性或一致性,或是與其他實作進行基準測試。在這種情況下,現有測試必須照常執行,否則無法有把握地證明相容性。這項作業基本上會定義裝置端測試自動化系統的規格。

解決這個問題的常見方法是將現有的測試架構移植到 Fuchsia。舉例來說,Fuchsia LLVM Toolchain 和 Fuchsia Rust Toolchain 團隊分別計畫移植 LLVM 和 Rust 測試架構,以便在 Fuchsia 上執行上游測試。這樣一來,Fuchsia 就能升級至更高層級的工具鍊支援,分別支援這些外部專案。

另一種常見解決方案是根據相同規格重新實作測試架構。舉例來說,Fuchsia 連線團隊實作了 SL4F,以符合 SL4A 的 JSON-RPC/HTTPS 規格,因此他們可以在 Fuchsia 上執行 ACTS 測試。這項做法的好處是能為 Fuchsia 帶來大量實用測試,並展現相容性,這在連線領域至關重要。

只要有適當的理由,並以嚴謹的方式使用,這些都是解決這個獨特問題空間的絕佳方案。舉例來說,如果我們將 LLVM 測試架構移植到 Fuchsia,然後使用這個架構編寫新的測試,但這些測試並非為了展示相容性,或與合作夥伴專案共用測試,則需要額外說明理由,否則平台團隊不建議這麼做。