本文件包含用於進行診斷和測試偵錯的程式碼研究室。目前時間: ,方便開發人員在 fuchsia.git 中編寫測試。
必要條件
設定開發環境。
本程式碼研究室假設您已完成入門指南,且已:
- 用心建構的紫紅色樹。
- 執行 Fuchsia 的裝置或模擬器 (
ffx emu
)。 - 用於為 Fuchsia 裝置或模擬器提供元件 (
fx serve
) 的工作站。
如要建構及執行本程式碼研究室中的範例,請新增下列引數
傳送至 fx set
叫用:
fx set core.x64 \
--release \
--with //examples/diagnostics/workshop \
--with //examples/diagnostics/workshop:tests
簡介
有一個範例元件會提供名為 ProfileStore 的通訊協定:
@discoverable
closed protocol ProfileStore {
strict Open(resource struct {
key string:KEY_LENGTH;
channel server_end:Profile;
});
strict OpenReader(resource struct {
key string:KEY_LENGTH;
channel server_end:ProfileReader;
});
strict Delete(struct {
key string:KEY_LENGTH;
}) -> (struct {
success bool;
});
strict CreateOrOpen(resource struct {
key string:KEY_LENGTH;
channel server_end:Profile;
});
};
透過這個通訊協定,您可以建立、刪除及檢查使用者個人資料,當中含有 名稱和餘額元件發生錯誤,無法刪除設定檔。
程式碼研究室的程式碼位於 //examples/diagnostics/workshop。
執行元件
除了提供 ProfileStore 的主要元件之外,您還可以使用許多元件
並連結至 ProfileStore。所有元件都位於
fuchsia-pkg://fuchsia.com/profile_store_example
套件。
#meta/profile_store.cm
- 提供 ProfileStore#meta/add_olive.cm
- 連線至 ProfileStore 並新增名稱為「Olive」的設定檔#meta/add_balance_olive.cm
- 連結至 ProfileStore 並將餘額新增至「橄欖綠」個人資料#meta/withdraw_balance_olive.cm
- 連結至 ProfileStore 並提領 「橄欖綠」個人資料#meta/add_jane.cm
- 連線至 ProfileStore 並新增名為「Jane」的設定檔#meta/delete_olive.cm
- 連結至 ProfileStore 並刪除「Olive」個人資料
功能會由 #meta/laboratory_server.cm
元件轉送。
您可以使用 ffx component
指令與元件互動,並從下列位置檢查輸出內容:
使用 ffx log
建構元件
首先,在殼層中執行 ffx log --tags workshop
。這個殼層會包含
元件。在另一個殼層中,執行玩具元件:
# setup server
ffx component create /core/ffx-laboratory:profile_store fuchsia-pkg://fuchsia.com/profile_store_example#meta/laboratory_server.cm
# setup first client
ffx component create /core/ffx-laboratory:profile_store/clients:add_olive fuchsia-pkg://fuchsia.com/profile_store_example#meta/add_olive.cm
# see the results of the previous two steps
ffx component show profile_store
# add a profile key and read it
ffx component start /core/ffx-laboratory:profile_store/clients:add_olive
ffx component create /core/ffx-laboratory:profile_store/clients:reader fuchsia-pkg://fuchsia.com/profile_store_example#meta/profile_reader.cm
ffx component start /core/ffx-laboratory:profile_store/clients:reader
# demonstrate persistence
ffx component stop /core/ffx-laboratory:profile_store/profile_store
ffx component start /core/ffx-laboratory:profile_store/clients:reader
# update balance
ffx component create /core/ffx-laboratory:profile_store/clients:add_balance_olive fuchsia-pkg://fuchsia.com/profile_store_example#meta/add_balance_olive.cm
ffx component start /core/ffx-laboratory:profile_store/clients:add_balance_olive
ffx component start /core/ffx-laboratory:profile_store/clients:reader
# add second profile
ffx component create /core/ffx-laboratory:profile_store/clients:add_jane fuchsia-pkg://fuchsia.com/profile_store_example#meta/add_jane.cm
ffx component start /core/ffx-laboratory:profile_store/clients:add_jane
ffx component start /core/ffx-laboratory:profile_store/clients:reader
# update balance
ffx component create /core/ffx-laboratory:profile_store/clients:withdraw_balance_olive fuchsia-pkg://fuchsia.com/profile_store_example#meta/withdraw_balance_olive.cm
ffx component start /core/ffx-laboratory:profile_store/clients:withdraw_balance_olive
ffx component start /core/ffx-laboratory:profile_store/clients:reader
# delete olive (this will not work as there is a bug in the server code)
ffx component create /core/ffx-laboratory:profile_store/clients:delete_olive fuchsia-pkg://fuchsia.com/profile_store_example#meta/delete_olive.cm
ffx component start /core/ffx-laboratory:profile_store/clients:delete_olive
ffx component start /core/ffx-laboratory:profile_store/clients:reader
使用診斷功能進行偵錯
診斷功能提供多項產品,可協助元件作者對彼此的元件進行偵錯 參與相關工作
在這個研討會中,我們將探索三大核心技術:
結構化記錄
診斷功能提供結構化記錄程式庫,可讓元件寫入記錄。 為協助找出錯誤,我們會在設定檔商店元件中新增一些記錄。
將記錄功能新增到元件時,第一步是納入記錄程式庫 複製到二進位依附元件中如要這麼做,請按照下列步驟更新 BUILD.gn:
source_set("lib") {
...
public_deps = [
...
"//sdk/lib/syslog/cpp",
]
}
當我們呼叫其中一個記錄巨集時,記錄就會初始化。不過,程式庫提供
一些應在 main()
中呼叫的公用程式,例如設定標記 (僅需要時,
為選用)。
標記之後,即可查詢一組元件的記錄檔。基於我們的目的,我們可以在
workshop
標記:
#include <lib/syslog/cpp/log_settings.h>
...
fuchsia_logging::SetTags({"workshop", "profile_store_server"});
接下來要寫入一些記錄。我們將使用 FX_SLOG
巨集
結構化索引鍵和值
例如,在收到 ProfileStore::Open
要求時,我們可以新增下列記錄,但
設定檔不存在:
#include <lib/syslog/cpp/macros.h>
...
FX_SLOG(WARNING, "Profile doesn't exist", KV("key", key.c_str()));
請嘗試新增該記錄、建構 (fx build
)、重新啟動元件 (ffx component start ...
),並
然後執行:ffx log --tags workshop
。
我們還可以新增哪些記錄來找出紀錄?請多方嘗試!
如要解決這個問題,請參閱這個修補程式。
檢查
檢查功能可讓元件公開自身的狀態。有別於記錄檔,也就是串流 檢查代表元件目前狀態的即時檢視畫面。
建議您先詳閱「檢查快速入門導覽課程」。如果您 如果想深入瞭解檢查功能,也可以按照「檢查程式碼研究室」的指示操作。
如要開始使用,請先新增程式庫依附元件:
source_set("lib") {
...
public_deps = [
...
"//sdk/lib/inspect/component/cpp",
]
}
接著,在 main.cc
中初始化檢查:
#include <lib/inspect/component/cpp/component.h>
...
// Immediately following the line defining "startup".
auto inspector = std::make_unique<inspect::ComponentInspector>(async_get_default_dispatcher(), inspect::PublishOptions{});
inspector->Health().Ok();
現在,您可以在重新啟動 profile_store
後查看「檢查」:
# Note that double \\ is necessary! ':' must be escaped in a "diagnostic selector."
ffx inspect show core/ffx-laboratory\\:profile_store/profile_store
畫面上應該會顯示「確定」元件的狀態。檢查時間最多
會很實用,且能與類別階層整合任意值
已於 inspect::Node
啟用 Root 權限,包含更多節點!嘗試修改 ProfileStore,以便編譯下列內容:
// In main.cc
std::unique_ptr<ProfileStore> profile_store =
std::make_unique<ProfileStore>(loop.dispatcher(), inspector->GetRoot().CreateChild("profiles"));
提示:如果您有更新 ProfileStoreTests
類別,則必須更新
變更 ProfileStore
的建構函式。可以直接通過
inspect::Node()
做為新參數。
設定基本檢查後,
協助防止/找出這個元件中的錯誤?
- 建議您為每個 Profile
新增 inspect::Node
,然後
並在您傳遞至 ProfileStore
的節點上使用 CreateChild
。
- 考慮使用 inspect::LazyNode
(node.CreateLazyNode(...)
)
即可動態建立階層結構
您可以在這個修補程式中找到可能的解決方法: https://fuchsia-review.googlesource.com/c/fuchsia/+/682671
分類
分類可讓您編寫規則來自動處理快照檢查並找出潛在問題 或收集快照可能包含的統計資料
如要開始使用,請前往 examples/diagnostics/workshop/triage/profile_store.triage
建立新檔案
包含下列內容:
{
select: {
profile_status: "INSPECT:core/ffx-laboratory\\:profile_store/profile_store:fuchsia.inspect.Health:status",
},
act: {
profile_status_ok: {
type: "Warning",
trigger: "profile_status != 'OK'",
print: "Profile store is not healthy.",
}
}
}
如果您按照上一節的「檢查快速入門」步驟操作,請執行
ffx triage --config examples/diagnostics/workshop/triage/
。如果 profile_store
正在執行,且
狀態回報為正常,系統不會顯示任何失敗情形!請嘗試將通話變更為
在 main.cc
的 Health().Ok()
至 Health().StartingUp()
並執行
ffx triage --config examples/diagnostics/workshop/triage/
。系統這次應該會顯示警示。
請試著編寫分類設定,這有助於找出收集到的快照中的錯誤 ] 欄位。
以下修補程式提供可能的解決方案 (採用檢查解決方案的解決方案): https://fuchsia-review.googlesource.com/c/fuchsia/+/684762
使用測試進行驗證
本節說明如何新增測試來驗證修正結果。
試著編寫有助於防止元件錯誤的新測試。您可以視需求修改 參考範例測試,或用下方的流程從頭開始建立新的測試。
新增單元測試
單元測試的程式碼結構主要取決於使用的執行階段。本區段步行 透過設定新單元測試,驗證 ProfileStore 的行為 C++ 類別。
在 examples/diagnostics/workshop/profile_store_unittest.cc
中新建包含下列內容的檔案:
#include "src/lib/testing/loop_fixture/test_loop_fixture.h"
#include <gtest/gtest.h>
#include "fuchsia/examples/diagnostics/cpp/fidl.h"
#include "lib/fidl/cpp/interface_ptr.h"
#include "profile_store.h"
class ProfileStoreTests : public gtest::TestLoopFixture {};
TEST_F(ProfileStoreTests, SampleTest) {
ProfileStore store(dispatcher());
fidl::InterfacePtr<fuchsia::examples::diagnostics::ProfileStore> store_ptr;
store.AddBinding(store_ptr.NewRequest(dispatcher()));
store_ptr->Delete("my_key", [&](bool successful) { EXPECT_FALSE(successful); });
RunLoopUntilIdle();
}
這樣做會設定最小的單元測試,用於建立 ProfileStore,並建立可進行互動的用戶端
非同步測試
接下來,您將為測試建立元件資訊清單,定義測試的執行方式。
為測試建立新的元件資訊清單:
examples/diagnostics/workshop/meta/profile_store_unittests.cm
,包含下列內容:
{
include: [
// Needed for gtest runners
"//src/sys/test_runners/gtest/default.shard.cml",
// Needed so that logs are created
"syslog/client.shard.cml",
],
program: {
binary: "bin/profile_store_unittests",
},
use: [
{
// ProfileStore uses /data to store profiles. We'll use the tmp
// storage provided to the test.
storage: "tmp",
path: "/data",
},
],
}
最後,在 examples/diagnostics/workshop/BUILD.gn
中新增建構規則:
# Builds the test binary.
executable("test_bin") {
testonly = true
output_name = "profile_store_unittests"
sources = [
"profile_store_unittest.cc",
]
deps = [
":lib",
"//src/lib/fxl/test:gtest_main",
"//src/lib/testing/loop_fixture",
]
}
# Creates a test component and test package.
fuchsia_unittest_package("profile_store_unittests") {
deps = [ ":test_bin" ]
manifest = "meta/profile_store_unittests.cml"
}
# Update the existing group("tests") to include the new package as a dep
group("tests") {
testonly = true
deps = [
# new dependency
":profile_store_unittests",
":profile_store_example_unittests",
"example-integration:tests",
]
}
接下來,請確認測試已建構並執行。
# Build is needed the first time so that fx test becomes aware of the new test.
# For subsequent test executions, fx build is automatically invoked.
fx build examples/diagnostics/workshop:tests
fx test profile_store_unittests
您現在可以修改測試程式碼,驗證行為。
新增整合測試
fx testgen
指令會自動產生整合測試樣板設定,
RealmBuilder。如要使用,需找出已編譯的元件資訊清單
加入名為 profile_store 元件的其中一欄
# find the manifest in output directory.
find $(fx get-build-dir) -name profile_store.cm
# generate integration tests.
fx testgen --cm-location find result --out-dir examples/diagnostics/workshop/tests -c
這樣應該會在 examples/diagnostics/workshop/tests
下產生一些檔案。執行
測試,一些需要更新的建構規則:
- 在新產生的
examples/diagnostics/workshop/tests/BUILD.gn
中- 將
{COMPONENT_FIDL_BUILD_TARGET}
替換為 ProfileStore 觸發條件的建構目標://examples/diagnostics/workshop/fidl:fuchsia.examples.diagnostics
- 將
{COMPONENT_BUILD_TARGET}
替換為 ProfileStore 元件的建構目標://examples/diagnostics/workshop:profile_store
/
- 將
- 在「
examples/diagnostics/workshop/BUILD.gn
」中- 新增「測試」至
group("tests")
定義中的 deps。確保 GN 可以找到新測試。
- 新增「測試」至
接下來,請確認測試已建構並執行。
# Build is needed the first time so that fx test becomes aware of the new test.
# For subsequent test executions, fx build is automatically invoked.
fx build examples/diagnostics/workshop:tests
fx test profile_store_test
測試執行後,您就可以修改樣板來編寫實用的測試。