RFC-0256:Lacewing 測試專用的 Python 應用程式組合 | |
---|---|
狀態 | 已接受 |
領域 |
|
說明 | 建議使用已編譯的自我解壓縮 Rust 主機二進位檔來封裝 Python Lacewing 測試應用程式。 |
毛皮變化 | |
作者 | |
審查人員 | |
提交日期 (年-月-日) | 2024-05-22 |
審查日期 (年-月-日) | 2024-08-08 |
摘要
提議將 Lacewing 測試做為編譯的 Rust 主機二進位檔加入 Fuchsia 的 近期的測試專用 Python 應用程式 應用程式套件與發布 例如:駕駛規範、CTF。
本提案並未強制提供替代方案, 未來的發展方向
提振精神
由於最近在 Fuchsia IDK 中加入 RTC 驅動程式庫一致性測試 我們現在已有一套運作且承載於負載的機制 樹狀結構內 Python Lacewing E2E 測試,用於樹狀結構外 (OOT) 執行。
能向 SDK 消費者直接發布 Lacewing 測試 Fuchsia 的 2024 年發展藍圖 (例如駕駛人符合性測試)。此外,其他 需要進行版本測試的封裝和發布作業,例如 平台預期測試和主機工具 相容性測試將 也能因此受益
在擴大採用這個測試版發布模型之前,我們必須確保 確保機構能永續發展 並提前解決潛在的技術債具體而言, 目前下游 Lacewing 測試消費者必須自行提供 測試執行作業的 Python 執行階段容易發生錯誤,本提案得以解決這個問題 力求精簡。
相關人員
講師:
- abarth@google.com
審查者:
- abarth@google.com
- chaselatta@google.com
- hjfreyer@google.com
- keir@google.com
- tmandry@google.com
- tonymd@google.com
諮詢:
- awdavies@google.com
- crjohns@google.com
- cpu@google.com
- jamesr@google.com
社交功能:
這份提案是透過 Google 文件與 FEC 的成員進行社交互動。 Pigweed、工具鍊、SDK 體驗和工具團隊。這個提案也 在 FEC 會議中討論的內容,並支援正式的 RFC 比率。
目標
- 避免延遲測試二進位檔時,排除 Python 執行階段相容性問題 執行 OOT
- 將 Lacewing Python 測試封裝做為單一隱密的執行檔
- 支援 C 擴充功能程式庫 (例如 Fuchsia Controller)。
- 支援資料依附性 (例如 FIDL IR 檔案;目前 Fuchsia Controller)
- 支援在定義上組合拖車測試
- 支援 Linux 主機環境
非目標
- 支援 Windows 主機環境
- 支援 Mac 主機環境
提案
我們建議針對 Fuchsia 的即時 Python 採用以 Rust 為基礎的自訂方法 這種做法的好處是 可行,且符合上述所有目標。
總覽
執行 Lacewing 測試所需的所有 Python 元件,都會嵌入
是經過編譯的 Rust 二進位檔做為資料資源 (透過 Rust 的
include_bytes!
巨集)。執行時,Rust 二進位檔會擷取 Python 內容
放入臨時目錄,建構指令,然後執行
應用程式。
與領先業界的替代解決方案 PyInstaller 相比,後者採用以 Rust 為基礎的自訂方法 因為具有彈性 Fuchsia.git (詳情請參閱 PyInstaller 的 拒絕理由一節)。 以下總結方法之間的主要優缺點:
自訂以 Rust 為基礎的方法的優點:
- 可在 Fuchsia.git 中使用
- 已implemented並 成功在本機和基礎架構環境中執行
- 從 Fuchsia 現有的 Rust 主機工具鍊中採用隱密性保證
- 不需要對動態連結的 Python 進行額外維護 播放時長
- 無須更新 Fuchsia Controller 即可找出內嵌 FIDL-IR 檔案
PyInstaller 的優點:
- 內建一般通用支援所有 Python 應用程式支援
- 改善視野,支援非 Linux 主機平台 (例如 Windows)
實作
Lacewing Rust 二進位檔由 3 個邏輯區段組成:Lacewing 構件 以及測試執行方式
嵌入
將嵌入執行 Lacewing 測試所需的所有元件 以單一封存形式將其轉換至 Rust 二進位檔
目錄
內嵌的封存檔則包含下列項目:
- 靜態連結的 Python 執行階段及其標準程式庫 (Python 模組)
- PYZ 格式的拖延測試 (與用於下列路徑的
zipapp
套裝組合一致) Fuchsia.git) - Fuchsia 控制器共用資料庫
- FIDL IR 檔案 (目前由 Fuchsia Controller 要求)
壓縮
為求簡單起見,上述所有內容會壓縮成單一
封存。目前的實作方式採用 ZIP
格式,這會去除
linux-x64 主機二進位檔。未來的疊代作業可能會選擇
壓縮率較佳的壓縮格式,例如 zstd
(就主機導向而言,壓縮效能不重要
系統測試)。
建構
為了提供任意 Lacewing 測試,我們會將 GN 建構自動化功能新增至 動態提供 Lacewing 構件以供嵌入。
我們結合運用
rustc_embed_files()
和
rustc_binary()
GN 範本:其中第一個範本提供「測試專屬」資料資源,做為
Rust 程式庫時,後者含有「測試通用」main()
邏輯,適用於
擷取與執行。
擷取和執行
執行時,Rust 二進位檔會先將其內嵌資源解包在暫存中
目錄。接著,應用程式就會建構執行 Lacewing 測試的指令
參照擷取的內容最後,系統會執行指令
Rust 二進位檔結束。此外,我們也會設定 PYTHONPATH
,以便維持慣用性
指令中的環境變數,確保環境 Python 安裝
系統就不會用到程式庫
成效
建構時間 - 初期測試組合僅對一小部分執行 Fuchsia 的 Lacewing 測試組合,因此 Rust 二進位檔會產生建構負擔 套裝組合是可以忽略的。
「Run time」:基於 E2E 測試的性質, 這類節點通常不會 容易造成小規模啟動負擔 執行擷取作業經驗基礎架構資料顯示未最佳化的 6 秒以下 在這些測試平均執行約 1 分鐘的情況下,這些測試可忽略不計的建構。
大小:輸出的執行檔大小約為 40 MB,與 例如 PyInstaller但是 嵌入期間使用的壓縮演算法選項。
以下是改善各維度成效的機會 以上所示,隨著隨附的蕾絲測試數量增加,您可以檢視這些測試:
建構時間:建立「字根」內含 所有測試通用構件 (例如執行階段、stdlibs、C 擴充功能) 及 以測試專用的 Zip 封存檔 (例如 test.pyz) 串連在一起。「字根」ELF 接著即可透過
ZipArchive
自行擷取,以存取 Zip 內容,就像 目前提議的方法;除非是 Rust 編譯程序 而不是每次封裝的 Lacewing 測試執行時間 - 使用 GN 設定對 Rust 編譯作業進行最佳化,加快速度。 可以評估擷取時間,並匯出至效能追蹤後端 才能防止迴歸
大小:與上述的建構時間最佳化類似,會分割 Rust ELF 將二進位編碼插入各組測試「字根」以及測試專屬的 Zip 封存檔 發布大型「字根」您可以使用 測試專用的 Zip 封存檔這可讓我們節省儲存空間和網路頻寬 包含「stem」一詞。詳情請參閱 可執行大小:
人體工學
本提案改善了「OOT 拖鞋」測試執行的使用者體驗 - 整合服務供應商 只需要啟動單一測試執行檔即可
回溯相容性
新增密封模式 (Rust 套裝組合) 時,不需變更
拖拉測試來源換句話說,Lacewing 測試可在以下位置執行:
同時顯示密封 (./test
) 和非密封 (./python test.pyz
) 模式,
Python 原始碼的任何變更
測試
1) Rust 繫結程序的穩定性和 2) 產生的結果 傳說中的神秘試驗將在富希西亞的基礎架構中soak-tested。我們會 將測試穩定性與非密封的對應項目進行基準測試。如果不是很明顯 觀察到草率/失敗率的差異時,我們會考慮以 Rust 為基礎的 提供適用於實際工作環境的整合式方法 (例如 CQ 和 SDK 發行)。
風險與資源
可執行大小
假設每個隨附 Lacewing 二進位檔的儲存空間用量約為 40 MB, 能引發疑慮,因為我們將分散式測試數量增加到合理範圍內 (舉例來說,100 次測試採用 4 GB)。為減輕影響程度,建議您嘗試以下做法 擴充儲存空間和頻寬成本,但會因為 隨附拖鞋測試。
在單體 Rust 應用程式中發布所有測試。
- Lacewing 封存檔的最大元件 (Python 執行階段,標準版) libs 和 Fuchsia Controller 擴充功能都發布一次,
- 藉由這種方式減少的大小會隨著 我們發行 OOT 的 Python 應用程式
獨立發布測試。
- 與上述類似,Lacewing 封存檔最大的元件是 在單一 Rust 應用程式中發布一次。
- 測試 PYZ (500kB) 會分開發布,並提供給 以執行階段引數的形式測試應用程式
請縮減 Fuchsia Controller 的大小。
- 這個做法會因為 Fuchsia Controller 進行遷移而自然降低
採用靜態 Python 繫結 (上游執行階段邏輯至
fidlgen
)- 將移除
fidl_codec.so
- 靜態 Python FIDL 繫結較不詳盡,因此較小 比 FIDL IR 檔案
- 將移除
- 這個做法會因為 Fuchsia Controller 進行遷移而自然降低
採用靜態 Python 繫結 (上游執行階段邏輯至
按照上述說明瞭解其他壓縮格式和參數 上述。
跨平台可行性
將我們的 Python 套裝組合解決方案與 Fuchsia 的 Rust 主機工具鍊相結合 可以免費使用 Linux x64 現有的支援平台組合目前 Linux x64 已足夠使用 最迫切需求但如果使用其他代管平台 支援 (例如 Windows) 成為基本需求,因此我們需要與 Fuchsia Rust 和 Fuchsia 建構團隊,用於設定可行性。
在本文撰寫期間,目前沒有已知的非 Linux-x64 主機平台 以及 OOT 蕾絲測試的需求條件。
有限支援
目前的提案僅適用於支援 Lacewing Python 應用程式。 不過,若這種狀況發生,這種做法可以合理 。這比探索 (例如 PyInstaller/PyOxidizer)。
如果數量較多,建議考慮替代選項 要求變更,例如:
- Windows 支援
- 位元可重現性
- 請勿在幕後啟動 Python
安全性考量
Fuchsia SDK 中運送 Rust 主機二進位檔是十分完整的程序 (例如
ffx
),因此在提出申請時不會產生額外的安全性風險
Lacewing 測試採取同一個做法
隱私權注意事項
無
說明文件
無
替代方案
PyInstaller
我們刻意加入 PyInstaller 的大型部分,以供後續使用。 請參考下列發現項目,立即選擇採用以 Rust 為基礎的自訂項目 並有助於提供未來發展的背景資訊。
PyInstaller 拒絕原因
原因:PyInstaller 授權,只能使用 」是 Fuchsia.git 的「開發目標」下預先建構的構件的第 節 Fuchsia 的開放原始碼授權政策。但 PyInstaller 設計以作為來源執行,並不容易套件到預建中。在 目前,我們不是要解決這個小問題 有一個以 Rust 為基礎的解決方案、正常運作且樹狀結構內, 立即滿足客戶需求
總覽
PyInstaller 是開放原始碼軟體 用於綁定 Python 應用程式及其應用程式的第三方 Python 程式庫 轉換為獨立可執行檔,可在使用者系統上執行 。UIt 是 因為易於使用和成熟,所以 Python 應用程式封裝的空間 (使用中的版本 )。
PyInstaller 在「單一檔案」中執行時模式就會將先前啟動的執行階段 可執行檔,以及所有應用程式模組。時間 輸出執行檔執行時,PyInstaller 的系統啟動載入程式擷取其嵌入 封存 (包含 Python 解譯器,內建/使用者提供的 Python) 使用者提供的內建/使用者提供的共用程式庫和資料檔案) 暫存目錄,然後在密封的環境中執行解譯器。
我們可以利用 PyInstaller,將 Lacewing 測試納入單一草木當中 可攜式可執行檔 (Python 執行階段 + 測試模組 + 程式庫模組 + Fuchsia 要在其中執行控制器 C 擴充功能 + FIDL IR 等資料依附元件 各種 Linux 主機環境
可惜的是,靜態連結的 Python 執行階段,例如 Fuchsia 廠商的 Python 非 與 PyInstaller 相容 (相關問題:1、 2)。解決方法是 在 Chromium 的 3PP 基礎架構 (第三方套件)。建構完成後,動態連結版本 (DL-CPython3) 可做為 Fuchsia.git 預先建構的, 滿足 Fuchsia 的 Python 應用程式封裝需求。
由於建構 DL-CPython3 的原始碼與靜態 連結版本 (ST-CPython3) 版本, DL-CPython3 不需要額外取得授權。
開發中的原型
這個 Fuchsia.git CL 說明瞭 透過 PyInstaller 透過 Fuchsia 的 GN 封裝 Lacewing 測試的可行性 建構系統透過原型 CL,我們確認在 Hermetic Lacewing Python 測試執行檔,透過在 GN 時間。
目前無法說明 CL 目前在 Fuchsia 基礎架構中使用 因為使用了未提交的依附元件 原型雖然我們預計不會遇到任何基礎架構支援問題 在 Fuchsia 原始碼中提供這些依附元件。
未提交的依附元件
DL-CPython3:現在, Chromium 3PP 但尚未釘選在 Fuchsia.git 中。
PyInstaller 程式庫:PyInstaller 及其轉換 Python 依附元件 已完成 OSRB 審查,但只能在 Fuchsia.git 中做為預先建構的二進位檔使用。
Fuchsia 控制器
需更新 Fuchsia Controller,才能找出位於 指令執行 PyInstaller 執行時,其內容會解壓縮, 從臨時目錄執行使用這項 修補程式 Fuchsia Controller 成為 PyInstaller 感知的,並會在 暫存目錄。
Hermeticity
PyInstaller 的輸出經檢查後確認為隱密
metadata - Analysis.toc,當中的所有內容
來源為 $FUCHSIA_DIR
- 也就是說,沒有微光系統共用程式庫
都包含在內。
此外,在 PyInstaller 輸出內容上執行 ldd
,則會顯示一組共用
常見且穩定相容於現代的程式庫依附元件
Linux 發行版。
~/fuchsia$ ldd dist/soft_reboot_test_fc
linux-vdso.so.1
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6
/lib64/ld-linux-x86-64.so.2
為了防止語意逐漸遭受侵蝕,您可以加入建構時間檢查
,確認 PyInstaller 執行檔的 ldd
輸出內容在許可清單中。
大小
在原型內不考量大小最佳化的情況下, 透過 PyInstaller 封裝的軟重新啟動 Lacewing 測試大約為 43 MB (僅供參考,PYZ 版本的大小約為 400 KB)。
有很多機會可以縮減 PyInstaller 的大小,但無法探索。 初期測試:
- 使用 UPX 。
- 排除未使用的內建擴充功能模組。
執行階段管理和維護
Fuchsia 團隊需要同時保留 DL-CPython3 (針對版本化 Lacewing)。 測試封裝) 和 ST-CPython3 (用於其他所有),確保 功能相等,且會在 Lockstep 中更新 (例如,將 存取同一個 CIPD 版本代碼)。這需要與 Google 內部團隊合作 PEEP 軟體部署團隊,簡化第二層 3PP 設定步驟。 這些版本都是以程式輔助的方式為防止差異。
跨平台可行性
PyInstaller 不支援跨平台程式碼編譯 因此,我們需要在個別目標環境中執行 PyInstaller (例如 Windows、Mac) 產生主機平台特定執行檔。
例如,為了支援 Windows 使用者,我們需要在 使用 Windows 版本 DL-CPython3 的 Windows 電腦。在本文撰寫期間 Fuchsia 沒有這種 Windows 型建構環境,因此必須限定範圍 我們要支援建構機群至於 Windows 適用的 DL-CPython3,Chromium 3PP 已支援建構多個平台 (包括 Windows),我們應該要能大幅擴大支援範圍 視需要 Linux。
PyOxidizer
PyOxidizer 是另一個吸引人 通用的 Python 應用程式封裝選項,相較於 PyInstaller:
- 遺傳 - PyOxidizer 輸出是已編譯的二進位檔,PyInstaller 的輸出則為封存的 就必須解壓縮到 Python 位元 (例如內建的 Python 擴充功能) 指令
- 速度 - PyOxidizer 輸出內容 不需要解壓縮執行,因此啟動時間比 PyInstaller 的輸出內容。
- 安全性 - PyOxidizer 是 Rust 語言模型開發,這個語言的安全性保證優於 PyInstaller 的 Python 和 C。
儘管如此,這些優勢大多在 E2E 測試中幾乎微不足道。 相關資訊
PyOxidizer 拒絕原因
最終,PyOxidizer 並未選擇,因為不符合 goal。遊標 使用 PyOxidizer 進行探索時,並未將玩具 C 擴充功能封裝在 輸出執行檔雖然這些實驗可能 PyOxidizer 具備高度設定性,因此設定錯誤 PyOxidzer 的相對新奇程度和採用率較低,因此讓這些主題難以理解 所以目前我們有深入的探索功能