診斷與測試程式碼研究室

本文件包含用於進行診斷和測試偵錯的程式碼研究室。目前時間: ,方便開發人員在 fuchsia.git 中編寫測試。

必要條件

設定開發環境。

本程式碼研究室假設您已完成入門指南,且已:

  1. 用心建構的紫紅色樹。
  2. 執行 Fuchsia 的裝置或模擬器 (ffx emu)。
  3. 用於為 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.ccHealth().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

測試執行後,您就可以修改樣板來編寫實用的測試。