用於 Linux 測試的 Machina 執行階段

本指南提供操作說明,說明如何使用 Machina 針對 Linux 環境執行及偵錯 Starnix 測試。

Machina 會在 Linux 虛擬機器中執行測試,並使用目標核心版本提供獨立的標準化環境。請注意,如要執行以 Machina 為基礎的 Starnix 測試,必須在本機提供 Debian 客戶端映像檔。Google 員工預設可使用這類圖片,外部開發人員則須自行提供。外部開發人員應參閱「虛擬化入門」指南,進一步瞭解如何建構及提供自己的 Debian 映像檔。

在本機執行現有的 Machina 測試

主機必備條件

Machina 是一種虛擬化環境,僅限於以 Intel 為基礎的現代主機。對於 Google 員工來說,支援 VM 的新版 Cloudtop 是理想的環境。舊版 Cloudtop 可能需要調整大小,才能使用新版圖片。確認主機與下列檢查項目相容:

  • Intel 架構

    lscpu | grep "Vendor ID"

    您應該會看到:Vendor ID: GenuineIntel。如果沒有,您需要取得以 Intel 為基礎的電腦。如果是 Google 員工,使用支援巢狀虛擬化的 Cloudtop 應該就足夠。

  • 支援虛擬化

    按照「啟用 VM 加速功能」中的操作說明進行。

  • 效能優異的現代 CPU

    if lscpu | grep -qE "Clear CPU buffers"; then echo 'CPU has performance-hindering mitigations.'; else echo 'No performance issues found.'; fi

    您應該會看到:No performance issues found。部分舊款 Intel CPU 可能有安全漏洞緩解措施,這會大幅影響 Machina 效能。

如果您的環境符合 Intel 需求,但不符合其他需求,可以考慮增加 fx test 超時時間做為解決方法。

環境設定

  1. 設定支援虛擬化的產品設定。只要主機板是 x64,大多數產品都能正常運作。設定範例如下:

    fx set fuchsia.x64 --main-pb workbench_eng.x64
  2. 新增 linux_vm_tests 目標:

    fx add-test //src/starnix/tests:linux_vm_tests
  3. 使用標準工作流程,啟動無頭模擬器和套件存放區。如不熟悉,請參閱「設定 FEMU」指南。

執行測試

測試套件與原始系統呼叫相同,但會加上 linux_ 前置字串。以下列舉一些常見的目標納入條件:

  • 執行所有 C++ 系統呼叫測試套件:

    fx test linux_syscalls_cpp_tests
  • 執行所有 Rust 系統呼叫測試套件:

    fx test linux_syscalls_rust_tests
  • 執行個別套件:

    fx test linux_fcntl_test
    fx test linux_device_mapper_test
  • 在 Starnix 和 Linux 上執行:指定目標的基本名稱,這會執行環境可能設定執行的所有變體 (Starnix、Machina、主機)。例如:

    fx test mount_test
    fx test fscrypt_test

偵錯失敗的 Machina 系統呼叫測試

瞭解記錄

系統呼叫測試可以是 GoogleTest 套件 (適用於 C++) 或 Rust 測試套件 (使用 libtest),輸出內容會透過測試架構傳送。這表示測試失敗時,stdout 中會顯示 test output。無論結果如何,您都可以使用 fx test 呼叫中的 --output arg 查看所有測試記錄。

與 Machina 執行階段相關的記錄會輸出至系統記錄 (ffx log),且通常與識別標記相關聯。目前,所有系統呼叫測試都採用一個執行階段,並使用 linux_guest 標記。但與核心端虛擬化相關的系統記錄除外,例如 Zircon 管理程序發出的記錄。這些記錄不會有與訪客相關聯的專屬 ID。

以下文件說明與一般流程相關的系統記錄。

  1. 初始訪客啟動程序:

    在下列記錄中,您會看到 starnix_test_runner 元件使用 linux_guest 標記要求 Machina 訪客。starnix_test_runner 會記錄兩行有關互動要求的資訊。第三行是來自 interactive-debian-guest 元件,可視為正在執行的 Machina 訪客元件。會接收要求並開始啟動程序。您可以看到系統中的所有記錄都標有 ID (linux_guest)。如記錄所示,Machina 客戶端會延遲啟動。這個初始啟動程序通常需要 60 秒左右的時間,才能準備好進行互動,但只有在第一次執行時才需要。

    [00043.071313][starnix_test_runner][linux_guest] INFO: Pushing data to guest (destination: /data/tests/deps/clone_exec_helper)
    [00043.071321][starnix_test_runner][linux_guest] INFO: Interaction requested, lazily starting the guest instance.
    [00046.686157][interactive-debian-guest][linux_guest] INFO: [interactive_debian_guest_impl.cc(110)] Start requested for an interactive Debian guest.
    
  2. 推送測試依附元件和二進位檔:

    啟動訪客後,初步資料就會開始推送至訪客。以下是系統呼叫測試所需的依附元件 (從套件的 /pkg/data 推送至訪客的 /data/),後面接著測試二進位檔本身:

    [00439.934416][starnix_test_runner.cm][linux_guest,starnix_test_runner] INFO: Pushing data to guest (destination: /data/tests/deps/simple_ext4.img)
    [00441.040568][starnix_test_runner.cm][linux_guest,starnix_test_runner] INFO: Successfully pushed data to guest (destination: /data/tests/deps/simple_ext4.img)
    [00444.834216][starnix_test_runner.cm][linux_guest,starnix_test_runner] INFO: Pushing data to guest (destination: /starnix_linux_fuse_test_fuse_test_bin)
    [00448.652779][starnix_test_runner.cm][linux_guest,starnix_test_runner] INFO: Successfully pushed data to guest (destination: /starnix_linux_fuse_test_fuse_test_bin)
    
  3. 測試執行和處理:

    完成環境設定步驟後,您應該會看到發出的執行指令。如果是 C++ (gTest) 套件,這會在訪客端執行測試二進位檔,並將結果檔案複製回主機進行處理:

    [00448.653126][starnix_test_runner.cm][linux_guest,starnix_test_runner] INFO: Executing command on guest: /starnix_linux_fuse_test_fuse_test_bin --gtest_output=json:/test_result-ccde95ca-acb3-4b84-af4d-f371b9582d20.json)
    [00448.848658][starnix_test_runner.cm][linux_guest,starnix_test_runner] INFO: Command '/starnix_linux_fuse_test_fuse_test_bin --gtest_output=json:/test_result-ccde95ca-acb3-4b84-af4d-f371b9582d20.json'
    ...terminated with status Status(OK), return code 0
    [00448.849066][starnix_test_runner.cm][linux_guest,starnix_test_runner] INFO: Fetching file from guest (remote_path: /test_result-ccde95ca-acb3-4b84-af4d-f371b9582d20.json)
    

    如果是 Rust (libtest) 套裝組合,測試執行元件會在訪客端個別執行每個測試案例 (傳遞 --exact --nocapture),並透過通訊端將 stdout 和 stderr 直接串流回測試框架。在這兩種情況下,測試輸出內容都會透過管道傳送至終端機上的 stdout,就像其他 fx test 呼叫一樣。

瞭解執行階段

Starnix 測試執行元件負責協調測試,可視為 Fuchsia 測試架構和 Machina 執行階段之間的黏著劑。與執行階段相關的重要事項:

C++ 系統呼叫測試 (syscall_gtest)

  • C++ 系統呼叫測試會在 CML 中以 [syscalls_gtest.cml][syscalls-gtest-cml]test_type: "syscall_gtest" 程式標記識別。
  • 處理套件要求時,Starnix 測試執行元件會尋找這個標記,並相應地分支邏輯來處理這些測試。核心處理邏輯位於 [syscalls_gtest.rs][syscalls-gtest-rs],主要進入點為 run_syscall_gtests

Rust 系統呼叫測試 (syscall_libtest)

  • Rust 系統呼叫測試會在 CML 中以 [syscalls_libtest.shard.cml][syscalls-libtest-shard-cml]test_type: "syscall_libtest" 程式標記識別。
  • 處理套件要求時,Starnix 測試執行元件會尋找這個標記,並相應地分支邏輯來處理這些測試。核心處理邏輯位於 [syscalls_libtest.rs][syscalls-libtest-rs],主要進入點為 run_syscall_libtests
  • 測試是使用 rust_syscall_test GN 範本在 [rust_syscall_test.gni][rust-syscall-test-gni] 內定義,[//src/starnix/tests/syscalls/rust/BUILD.gn][rust-syscalls-build-gn] 則用於產生 Starnix 和 Linux VM 測試元件。

雖然執行階段的內容遠不只這些核心要點,但要將所有內容都整理成文件,會非常困難。希望這些系統核心元件能為您的調查和偵錯作業提供穩固的錨點。

進階偵錯

詳細記錄 Linux 核心記錄

如果懷疑 Linux 核心本身發生問題,可以設定下列 GN 引數,啟用更詳細的 Linux 核心記錄:

redirect_guest_serial_logs = true

這會將 Linux 核心記錄導向標準系統輸出,也就是說,您可以查看 ffx log 發出的訪客核心記錄。記錄檔會在 vmm 元件下發出,並標記 (guest klog),為求明確,方便您清楚瞭解來源。舉例來說:

[00352.454169][vmm.cm][vmm] INFO: [vmm.cc(491)] (guest klog): [    0.000000] Linux version 6.6.13-amd64 (debian-kernel@lists.debian.org) (gcc-13 (Debian 13.2.0-10) 13.2.0, GNU ld (GNU Binutils for Debian) 2.41.90.20240115) #1 SMP PREEMPT_DYNAMIC Debian 6.6.13-1 (2024-01-20)

在這個記錄範例中,您會看到 vmm 元件發出 Linux 核心記錄行。vmm 在系統正常運作時間 00352.454169 發出這項記錄。(guest klog)表示 Linux 核心在 [ 0.000000] 發出該行,或從其角度來看,是正常運作的第零秒。

Shelling into Machina

您可以存取執行中 Linux 客戶端的標準指令列介面。請注意,根據預設,測試二進位檔和構件不會出現在映像檔中,因為測試執行元件支架會動態推送這些項目。如要進一步瞭解如何將測試二進位檔和構件匯入訪客,請參閱下列章節。如要存取這個殼層,請按照下列步驟操作:

  1. 請按照「虛擬化入門」指南操作,瞭解如何設定本機 GN 引數,啟用虛擬化工具。
  2. 啟動模擬器並連線至殼層:

    fx shell
  3. 啟動 Debian 客體:

    guest launch debian

    系統會將你帶往 Debian 殼層。

請注意,殼層行為可能會造成混淆:

  • exit 不會結束訪客殼層。
  • CTRL+C「不會」終止執行中的程式,而是會結束 Debian 殼層,返回 Fuchsia。

提示:如果意外按下 Ctrl+C 鍵,從 Linux 訪客返回 Fuchsia,可以使用 guest attach debian 返回殼層。

在本機修改 Debian 映像檔

有時您可能需要變更預設的 Debian 映像檔 (例如新增二進位檔或偵錯程式)。由於無法輕鬆推送構件,您必須直接修改映像檔。

  1. 掛接映像檔:在 Linux 主機上安裝工具並掛接映像檔:

    sudo apt-get install libguestfs-tools
    sudo mkdir /mnt/machina_guest_img
    sudo guestmount -a prebuilt/virtualization/packages/debian_guest/images/x64/rootfs.qcow2 -m /dev/vda /mnt/machina_guest_img/
    
  2. 與圖片互動:現在你可以將檔案複製到已掛接的目錄。舉例來說,如要複製掛接測試二進位檔和依附元件,請執行下列操作:

    sudo cp ./out/core.x64-balanced/linux_x64/linux_mount_test_bin /mnt/machina_guest_img/home/
    sudo mkdir -p /mnt/machina_guest_img/home/data/tests/deps/
    sudo cp src/starnix/tests/syscalls/cpp/data/* /mnt/machina_guest_img/home/data/tests/deps/
    
  3. 卸載映像檔:

    sudo guestunmount /mnt/machina_guest_img

卸載後,映像檔就會包含變更。接著,您就可以進入環境 (如上詳述),並視需要執行二進位檔。

更新 Debian 映像檔

目前 Debian 映像檔沒有自動捲動功能。您必須提出錯誤報告,並指派給有權上傳新構件的人員。擁有權限的使用者隨後可以修改映像檔並上傳新構件,詳情請參閱 Debian 客戶端 README