本指南將概略說明排解 Fuchsia (CTF) 相容性測試失敗問題時的常見情境,並逐一說明造成故障的原因,以及解除封鎖 CL 提交內容的方法。
CTF 測試會斷言在發布分支版本上發生軟體凍結,以及建構於 fuchsia.git
的 main
分支的軟體之間的互動。如果這些斷言因不相容而失敗,系統會封鎖提交 CL 的作業。
CTF 的用途並不是禁止破壞相容性造成的異動,而是是為了顯示這類中斷情形,以便正確處理。
情境
每個情況都會發生一個真正的相容性問題,這會導致 CTF 測試失敗,並阻擋 CL 提交作業。相容性問題可以非常簡單,只要將測試使用的現有 FIDL 通訊協定的傳回值變更過即可。我們會假設各種情境的常見情境如下 (如要瞭解更多測試情境,請參閱動機):
FIDL 用戶端在 F19 上凍結為
ctf_fuchsia_package
,稱為echo-service-tests
。這會連結至 FIDL 通訊協定並斷言回應。generate_ctf_tests.gni
包含規則template("generate_echo-service-tests")
,會將傳入的用戶端套件與在main
上建構的伺服器套件合併。(詳情請參閱使用手冊)。用戶端會在伺服器上呼叫
Echo
方法,該方法會做為輸入字串並傳回字串,如下所示:auto server_proxy = connect_to_named_protocol("my_protocol.EchoService"); ASSERT_EQ( server_proxy.echo("Hello"), "Hello" );
假設我們想變更 echo 的行為,改為傳回所傳遞字串的小寫表示法。我們可以在 main
上更新測試,以便執行下列操作:
ASSERT_EQ(
server_proxy.echo("Hello"),
"hello"
);
通過 ctf_in_development
測試,但對這個新伺服器執行使用舊斷言的凍結用戶端時,測試會失敗:
FAILURE: "hello" != "Hello"
目前已封鎖提交 CL 的功能,而且後續路徑取決於這次中斷的原因。
非蓄意破壞性變更 - 柔和轉換
在這種情況下,我們無意造成相容性中斷。如果預先建構或樹狀結構外元件依附舊行為,就會發生這種情況。針對包含 Echo
變更的平台執行這些元件,會導致非預期的行為。
在這種情況下,安全措施是輕柔轉換到新行為:
推出以新行為的新方法:
protocol Echo { // ... @available(added=20) EchoLowercase(struct {input string}) -> (string); };
將舊方法標示為已淘汰或已移除 (選用):
protocol Echo { @available(removed=20) Echo(/* ... */) -> (string); // ... };
在伺服器中實作新方法。
將
fuchsia.git
呼叫端變更為使用新方法,而非舊方法。
伺服器必須支援這兩種方法,直到系統不再支援所有 API 級別為止。在上述範例中,由於舊的 Echo 方法已在 F20 中移除 (原因為 @available(removed=20)
),因此不支援 F19。
蓄意破壞性變更 - 發布分支版本中的變更測試
在這種情況下,相容性中斷是刻意的。這可能是由以下原因造成:
我們想變更 API 的行為,並接受預先建構或樹狀結構外用戶端中斷的風險。此為實質性失敗,我們將明確確認這一點。
變更的行為僅供測試內部使用,並不代表 SDK 介面本身的破壞性變更。這會是偽陽性失敗,因為我們發現到測試不相容,而不是 SDK 不相容。
無論是哪一種情況,解決方案都是修改版本分支,如此一來,當針對 main
上的變更前或後變更程式碼執行時,測試將不再失敗。
變更執行方式如下:
查看版本分支:
fx sync-to refs/heads/releases/f19
修改斷言,使其接受兩種輸出內容 (或加上註解):
EXPECT_THAT( server_proxy.echo("Hello"), AnyOf(Eq("Hello"), Eq("hello")) );
測試您的變更是否能在
main
生效 (請見下方說明)修訂並推送變更:
git push origin HEAD:refs/for/releases/f19
將 CL 送交審核並提交。
已禁止封鎖 CL。
清除發布分支版本,以便僅接受新行為 (選用)。
EXPECT_EQ( server_proxy.echo("Hello"), "hello" );
您可以測試變更套用至 main
後是否能正常運作。您需要兩個 Fuchsia 的結帳,一個與版本分支版本同步,另一個則同步至 main
。請完成下列步驟:
在發布分支版本結帳頁面,建立新的 CTF 套件。
fx set core.x64 --with-tests //sdk/ctf fx build
在
main
結帳頁面中,建構 CTF 版本測試。fx set core.x64 --with-tests //sdk/ctf/release:tests fx build
在版本分支版本的輸出目錄中,將建構的 CTF 組合複製到「
main
」存放區。cp -fR \ $RELEASE_BRANCH_FUCHSIA_OUT_DIR/cts/* \ $MAIN_BRANCH_FUCHSIA_DIR/prebuilt/ctf/f19/linux-x64/cts/
重新建構
main
結帳功能、重新貼上裝置或重新啟動模擬器,然後執行測試。通過測試後,還原至 CIPD 的版本。
jiri run-hooks
範例:SDK 相容性中斷 (真陽性)
https://fxrev.dev/1041178 導入了 fuchsia.ui.policy.MediaButtonsListener
通訊協定的實際相容性中斷問題。新參數會新增至 MediaButtonsEvent
,並提供正確的版本管理註解,但如果參數保留為空白,且自先前的實作方式改為空白,該行為的行為就會變更。CTF 針對 F19 的測試找出了這種不相容性:
../../src/ui/tests/conformance_input_tests/media-button-validator.cc:243: Failure
Expected equality of these values:
ToString(listener.events_received()[0])
Which is: "\n volume: 0\n mic_mute: 0\n pause: 0\n camera_disable: 0\n power: 0"
ToString(MakePowerEvent())
Which is: "\n volume: 0\n mic_mute: 0\n pause: 0\n camera_disable: 0\n power: 1"
系統判定可以接受這項變更,因為這個通訊協定沒有任何指定 API 級別 19 的預先建構用戶端。
已按照上方的操作說明,將 CL https://fxrev.dev/1044994 和 https://fxrev.dev/1049612 挑選進 F19 發布分支版本中。一旦變更內容導入 main
使用的 CTF 版本後,原始 CL 就會未經修改便提交。
範例:測試控管工具相容性故障 (偽陽性)
https://fxrev.dev/1007583 造成 fuchsia.tracing.controller.Controller
通訊協定的相容性中斷。先前 StopTracing
方法設為 flexible
,而將方法從 strict
變更為 flexible
並不會安全 ABI。
這項變更發生時,WLAN hw-sim CTF 測試會當機,因為該測試會聲明在測試期間成功停止追蹤,即使這與測試的 WLAN 通訊協定無關,也不必進行更正。這是偽陽性相容性失敗,因為這只會影響測試控管本身。
被發現 https://fxrev.dev/1014607 會將追蹤失敗變成警告,而不是嚴重的斷言,而這項變更是獲選為 F18 版本分支所挑選的。一旦在 main
使用的 CTF 版本推出變更後,原始 CL 就不會進行任何修改。
刻意捨棄對特定測試的 API 級別支援
在本情境中,我們想要在每次測試時明確捨棄對 API 級別的支援。雖然 version_history.json
提供支援 API 級別的標準清單,但我們基於理由而想要捨棄特定 API 級別上特定通訊協定的相容性保證。例如,可以接受破壞舊用戶端的非關鍵子系統重大重構。
在這種情況下,我們可以修改程序,略過指定想要捨棄的 API 級別的測試:
修改
main
分支版本上的generate_ctf_tests.gni
,有條件地略過測試。template("generate_my-service-tests") { forward_variables_from(invoker, [ "test_info" ]) if (defined(invoker.api_level) && invoker.api_level == "15") { # Do not thaw this test for F15 not_needed([ "test_info" ]) group(target_name) { } } else { // ... } }
修訂並提交這個 CL。
上述範例在 F15 時略過整個構件。如果您不想略過所有測試,請參閱上一節,瞭解如何在版本分支版本中略過個別測試案例。
範例:主要重構來診斷子系統
https://fxrev.dev/1019042 刪除對不再使用的 DirectoryReady
元件事件的支援。主要用途是支援從元件 (現在使用 fuchsia.inspect.InspectSink
通訊協定發布) 取得診斷資料。
遺憾的是,以 F15 建構的元件仍會使用 DirectoryReady
發布診斷結果,而且在移除 main
後,所有針對該行為的 CTF 診斷測試都會失敗。
幸好,並沒有針對 F15 的預先建構元件,我們需要取得診斷資料。CL 提交給 Google 停用所有源自 F15 的 CTF 測試。