測試產生器¶
在用戶端,LNT 隨附許多內建的測試資料產生器。本節重點介紹 LLVM 測試套件(又稱 nightly test)產生器,因為它是使用 LNT 基礎架構執行的主要測試,但請注意,LNT 也包含其他有趣資料的測試,例如 Clang 編譯時效能。
LNT 也讓新增測試資料產生器變得容易,並包含自訂資料匯入器(例如,將 buildbot 建置資訊匯入)和動態測試資料產生器(例如,濫用基礎架構來繪製圖表)的範例。
執行本機伺服器¶
設定本機 LNT 伺服器以檢視測試結果非常有用,無論是供個人使用,還是在將結果提交到公用伺服器之前預覽結果。若要設定一次性伺服器以進行測試
# Create a new installation in /tmp/FOO.
$ lnt create /tmp/FOO
created LNT configuration in '/tmp/FOO'
...
# Run a local LNT server.
$ lnt runserver /tmp/FOO &> /tmp/FOO/runserver.log &
[2] 69694
# Watch the server log.
$ tail -f /tmp/FOO/runserver.log
* Running on https://127.0.0.1:8000/
...
執行測試¶
內建測試旨在透過 lnt
工具執行。以下是用於處理內建測試的工具
lnt showtests
列出可用的測試。測試是使用可擴充的架構定義的。FIXME:指向關於如何新增測試的文件。
lnt runtest [<run options>] <test name> ... test arguments ...
執行指定的測試。「run」工具本身接受許多所有測試通用的選項。最常見的選項是
--submit=<url>
,它指定在測試完成後將結果提交到的伺服器。請參閱lnt runtest --help
以取得關於可用選項的更多資訊。其餘選項會傳遞到測試工具本身。這些選項是測試特定的,但行為良好的測試應回應
lnt runtest <test name> --help
。以下章節提供關於內建測試的特定文件。
內建測試¶
LLVM CMake 測試套件¶
llvm 測試套件可以使用 test-suite
內建測試來執行。
透過 CMake 和 lit 執行測試套件使用不同的 LNT 測試
rm -rf /tmp/BAR
lnt runtest test-suite \
--sandbox /tmp/BAR \
--cc ~/llvm.obj.64/Release+Asserts/bin/clang \
--cxx ~/llvm.obj.64/Release+Asserts/bin/clang++ \
--use-cmake=/usr/local/bin/cmake \
--use-lit=~/llvm/utils/lit/lit.py \
--test-suite ~/llvm-test-suite \
--cmake-cache Release
由於 CMake 測試套件使用 lit 來執行測試並比較其輸出,因此 LNT 需要知道您的 LLVM lit 安裝路徑。測試套件在 CMake 快取中保留了一些常見配置。--cmake-cache
標記和 --cmake-define
標記可讓您變更 LNT 為測試套件執行配置 cmake 的方式。
LLVM Makefile 測試套件 (又稱 LLVM Nightly Test)¶
注意
Makefile 測試套件已過時。請考慮改用基於 cmake 的 lnt runtest test-suite
模式。它會積極維護,收集額外的指標(例如程式碼大小),並具有額外功能(例如產生和使用 PGO 資料)。
nt
內建測試執行 LLVM 測試套件執行和效能測試,以「nightly test」配置進行。此測試允許執行許多不同的應用程式和基準測試 (例如 SPEC),具有各種編譯選項,並在幾種不同的配置中(例如,使用 LLVM 編譯器,如 clang
或 llvm-gcc
,在使用 LLVM lli
位元碼直譯器的 LLVM JIT 編譯器下執行,或測試新的程式碼產生器 pass)。
nt
測試要求 LLVM 測試套件儲存庫、可運作的 LLVM 編譯器以及 LLVM 原始碼和建置樹狀結構可用。目前,LLVM 建置樹狀結構預期已在 Release+Asserts 配置中建置。與先前的 NewNightlyTest.pl
不同,nt
工具不會檢查或建置任何內容,使用者應管理自己的 LLVM 原始碼和建置樹狀結構。理想情況下,每個元件都應基於相同的 LLVM 修訂版本(LLVM 測試套件可能除外),但這不是必需的。
測試會在使用者指定的沙箱目錄內執行 LLVM 測試套件建置和執行。預設情況下,每個測試執行都會在沙箱內的加上時間戳記的目錄中完成,並且結果會保留下來以供事後分析。目前,使用者負責清理這些目錄以管理磁碟空間。
測試始終預期使用樹狀結構外的建置來執行 – 這是一個更穩健的模型,並允許在許多測試執行中共享相同的原始碼樹狀結構。目前的一個限制是,如果先完成樹狀結構內建置,然後再完成樹狀結構外建置,則 LLVM 測試套件儲存庫將無法正常運作。非常重要的是,LLVM 測試套件儲存庫應保持原始狀態。
以下命令顯示在本機建置上執行 nt
測試套件的範例
$ rm -rf /tmp/BAR
$ lnt runtest nt \
--sandbox /tmp/BAR \
--cc ~/llvm.obj.64/Release+Asserts/bin/clang \
--cxx ~/llvm.obj.64/Release+Asserts/bin/clang++ \
--llvm-src ~/llvm \
--llvm-obj ~/llvm.obj.64 \
--test-suite ~/llvm-test-suite \
TESTER_NAME \
-j 16
2010-04-17 23:46:40: using nickname: 'TESTER_NAME__clang_DEV__i386'
2010-04-17 23:46:40: creating sandbox: '/tmp/BAR'
2010-04-17 23:46:40: starting test in '/private/tmp/BAR/test-2010-04-17_23-46-40'
2010-04-17 23:46:40: configuring...
2010-04-17 23:46:50: testing...
2010-04-17 23:51:04: loading test data...
2010-04-17 23:51:05: generating report: '/private/tmp/BAR/test-2010-04-17_23-46-40/report.json'
前七個引數都是必要的 – 它們指定沙箱路徑、要測試的編譯器以及所需原始碼和建置的路徑。TESTER_NAME
引數用於衍生此測試器的名稱(結合關於受測編譯器的某些推斷資訊)。此名稱用作測試機器的簡短識別碼;通常它應該是機器的hostname或負責測試人員的姓名。-j 16
引數是選用的,在本例中,它指定測試應使用最多 16 個處理程序平行執行。
在本例中,我們可以從輸出中看到測試建立了一個新的沙箱目錄,然後在該沙箱中的子目錄中執行了測試。測試在測試進行中輸出有限的摘要資訊。完整資訊可以在測試建置目錄中的 .log 檔案中找到(例如,configure.log
和 test.log
)。
最後一個測試步驟是在測試目錄內產生測試報告。此報告現在可以直接提交到 LNT 伺服器。例如,如果我們有一個如先前所述在本機端執行的伺服器,我們可以執行
$ lnt submit https://127.0.0.1:8000/submitRun \
/tmp/BAR/test-2010-04-17_23-46-40/report.json
STATUS: 0
OUTPUT:
IMPORT: /tmp/FOO/lnt_tmp/data-2010-04-17_16-54-35ytpQm_.plist
LOAD TIME: 0.34s
IMPORT TIME: 5.23s
ADDED: 1 machines
ADDED: 1 runs
ADDED: 1990 tests
COMMITTING RESULT: DONE
TOTAL IMPORT TIME: 5.57s
並在本機伺服器上檢視結果。
基於 LNT 的 NT 測試模組¶
為了支援更複雜的測試,或不容易整合到 LLVM 測試套件模組更嚴格的 SingleSource 或 MultiSource 佈局中的測試,nt
內建測試為 LLVM 測試套件測試提供了一種機制,該測試僅定義擴充測試模組。這些測試會傳遞測試執行的使用者配置參數,並預期以 LNT 原生格式傳回測試結果。
測試模組是透過在 LLVM 測試套件儲存庫中 LNTBased
根目錄的子目錄中提供 TestModule
檔案來定義的。TestModule
檔案預期是一個格式良好的 Python 模組,它提供一個 test_class
全域變數,該變數應為 lnt.tests.nt.TestModule
抽象基底類別的子類別。
測試類別應覆寫 execute_test
方法,該方法會傳遞一個選項字典,其中包含適用於測試執行的 NT 使用者參數,並且測試應將測試結果作為 lnt.testing.TestSamples
物件的清單傳回。
execute_test
方法會傳遞以下描述關於模組本身資訊的選項
MODULENAME
- 模組的名稱(主要用於產生結構良好的測試名稱)。
SRCROOT
- 模組原始碼目錄的路徑。
OBJROOT
- 模組應用於臨時輸出(建置產品)的目錄的路徑。保證目錄存在,但不保證是乾淨的。
該方法會傳遞以下適用於測試應如何執行的選項
THREADS
- 在測試期間執行的平行處理程序數。
BUILD_THREADS
- 建置測試時要使用的平行處理程序數(如果適用)。
該方法會傳遞以下選項,這些選項指定測試應如何以及是否遠端執行。如果存在任何這些參數,則保證所有參數都存在。
REMOTE_HOST
- 要在其上執行測試的遠端機器的hostname。
REMOTE_USER
- 要登入遠端機器的使用者。
REMOTE_PORT
- 要連線到遠端機器的埠。
REMOTE_CLIENT
- 要用於連線到遠端機器的rsh
相容用戶端。
該方法會傳遞以下選項,這些選項指定如何建置測試
CC
- 要使用的 C 編譯器命令。
CXX
- 要使用的 C++ 編譯器命令。
CFLAGS
- 用於建置 C 程式碼的編譯器標記。
CXXFLAGS
- 用於建置 C++ 程式碼的編譯器標記。
該方法會傳遞以下選用參數,這些參數指定用於各種命令的環境
COMPILE_ENVIRONMENT_OVERRIDES
[選用] - 如果給定,則為env
樣式的環境覆寫清單,用於編譯時。
LINK_ENVIRONMENT_OVERRIDES
[選用] - 如果給定,則為env
樣式的環境覆寫清單,用於連結時。
EXECUTION_ENVIRONMENT_OVERRIDES
[選用] - 如果給定,則為env
樣式的環境覆寫清單,用於執行測試時。
如需更多資訊,請參閱 LLVM 測試套件儲存庫中 LNT/Examples
目錄下的範例測試。
擷取 Linux perf 分析資訊¶
當在測試套件中使用 CMake 驅動程式時,LNT 也可以使用 linux perf 擷取分析資訊。然後可以透過 LNT WebUI 瀏覽此資訊,如 http://blog.llvm.org/2016/06/using-lnt-to-track-performance.html 中所示。
若要擷取這些分析,請使用命令列選項 --use-perf=all
。用於評估產生程式碼效能的典型命令列如下所示
lnt runtest test-suite \
--sandbox SANDBOX \
--cc ~/bin/clang \
--use-cmake=/usr/local/bin/cmake \
--use-lit=~/llvm/utils/lit/lit.py \
--test-suite ~/llvm-test-suite \
--benchmarking-only \
--build-threads 8 \
--threads 1 \
--use-perf=all \
--exec-multisample=5 \
--run-under 'taskset -c 1'
二分搜尋:--single-result
與 --single-result-predicate
¶
用於基於 CMake 的測試套件的 LNT 驅動程式隨附了用於使用 llvmlab bisect
二分搜尋一致性和效能變更的協助程式。
llvmlab bisect
是 zorg
儲存庫的一部分,允許透過建置快取輕鬆二分搜尋某些述詞。有效使用 llvmlab
的關鍵是設計良好的述詞命令 - 在「pass」時以零退出,在「fail」時以非零退出。
LNT 通常執行一個或多個測試,然後產生測試報告。除非發生內部錯誤,否則它始終以狀態零退出。--single-result
引數會變更 LNT 的行為 - 它只會執行一個特定測試,並將述詞套用於該測試的結果,以判斷 LNT 的退出狀態。
--single-result-predicate
引數定義要使用的述詞。這是一個 Python 表達式,它在包含幾個預先設定變數的上下文中執行
status
- 布林值,通過或失敗(通過為 True,失敗為 False)。
exec_time
- 執行時間(請注意,exec
是 Python 中的保留關鍵字!)
compile
(或compile_time
) - 編譯時間
從測試傳回的任何指標(例如「score」或「hash」)也會新增至上下文。
預設述詞只是 status
- 因此可以用於直接偵錯正確性迴歸。更複雜的述詞是可能的;例如,exec_time < 3.0
會假設「良好」結果少於 3 秒來進行二分搜尋。
使用 llvmlab
偵錯效能提升的完整範例
llvmlab bisect --min-rev=261265 --max-rev=261369 \
lnt runtest test-suite \
--cc '%(path)s/bin/clang' \
--sandbox SANDBOX \
--test-suite /work/llvm-test-suite \
--use-lit lit \
--run-under 'taskset -c 5' \
--cflags '-O3 -mthumb -mcpu=cortex-a57' \
--single-result MultiSource/Benchmarks/TSVC/Expansion-flt/Expansion-flt \
--single-result-predicate 'exec_time > 8.0'
產生診斷報告¶
測試套件模組可以產生診斷報告,這對於找出基準測試發生的情況可能很有用
lnt runtest test-suite \
--sandbox /tmp/BAR \
--cc ~/llvm.obj.64/Release+Asserts/bin/clang \
--cxx ~/llvm.obj.64/Release+Asserts/bin/clang++ \
--use-cmake=/usr/local/bin/cmake \
--use-lit=~/llvm/utils/lit/lit.py \
--test-suite ~/llvm-test-suite \
--cmake-cache Release \
--diagnose --only-test SingleSource/Benchmarks/Stanford/Bubblesort
這會多次執行測試套件,在報告目錄中收集有用的資訊。報告收集許多內容,例如執行分析、編譯器時間報告、中繼檔案、二進位檔案和建置資訊。
跨編譯¶
在具有 cmake 驅動程式的跨編譯設定中執行測試套件的最佳方法是盡可能使用 cmake 的內建跨編譯支援。實際上,建議的跨編譯方法是使用 cmake 工具鏈檔案(請參閱 https://cmake.dev.org.tw/cmake/help/v3.0/manual/cmake-toolchains.7.html#cross-compiling)
在 X86 機器上針對 AArch64 linux 進行跨編譯的範例命令列為
lnt runtest test-suite \
--sandbox SANDBOX \
--test-suite /work/llvm-test-suite \
--use-lit lit \
--cppflags="-O3" \
--run-under=$HOME/dev/aarch64-emu/aarch64-qemu.sh \
--cmake-define=CMAKE_TOOLCHAIN_FILE:FILEPATH=$HOME/clang_aarch64_linux.cmake
此處的關鍵部分是 CMAKE_TOOLCHAIN_FILE 定義。由於您正在進行跨編譯,因此您可能需要 –run-under 命令,因為產生的二進位檔案可能無法在本機開發機器上執行,但需要完成一些額外的工作(例如,在 qemu 模擬器下執行,或將二進位檔案傳輸到開發板)。此處不再進一步說明。
在您的工具鏈檔案中,重要的是指定定義工具鏈的 cmake 變數必須快取在 CMakeCache.txt 中,因為那是 lnt 從中讀取它們以找出在需要為 json 報告建構中繼資料時使用了哪個編譯器的位置。以下是一個範例。使變數出現在 CMakeCache.txt 中的重要關鍵字是「CACHE STRING “” FORCE」
$ cat clang_aarch64_linux.cmake
set(CMAKE_SYSTEM_NAME Linux )
set(triple aarch64-linux-gnu )
set(CMAKE_C_COMPILER /home/user/build/bin/clang CACHE STRING "" FORCE)
set(CMAKE_C_COMPILER_TARGET ${triple} CACHE STRING "" FORCE)
set(CMAKE_CXX_COMPILER /home/user/build/bin/clang++ CACHE STRING "" FORCE)
set(CMAKE_CXX_COMPILER_TARGET ${triple} CACHE STRING "" FORCE)
set(CMAKE_SYSROOT /home/user/aarch64-emu/sysroot-glibc-linaro-2.23-2016.11-aarch64-linux-gnu )
set(CMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN /home/user/aarch64-emu/gcc-linaro-6.2.1-2016.11-x86_64_aarch64-linux-gnu )
set(CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN /home/user/aarch64-emu/gcc-linaro-6.2.1-2016.11-x86_64_aarch64-linux-gnu )